00001
00002
00003
00004
00005
00006
00007 #include "uniregistrygen.h"
00008 #include "wvmoniker.h"
00009
00010 UniRegistryGen::UniRegistryGen(WvString _moniker) :
00011 m_log(_moniker), m_hRoot(0)
00012 {
00013 UniConfKey key = _moniker;
00014 WvString hive = key.first().printable();
00015 if (strcmp("HKEY_CLASSES_ROOT", hive) == 0)
00016 {
00017 m_hRoot = HKEY_CLASSES_ROOT;
00018 }
00019 else if (strcmp("HKEY_CURRENT_USER", hive) == 0)
00020 {
00021 m_hRoot = HKEY_CURRENT_USER;
00022 }
00023 else if (strcmp("HKEY_LOCAL_MACHINE", hive) == 0)
00024 {
00025 m_hRoot = HKEY_LOCAL_MACHINE;
00026 }
00027 else if (strcmp("HKEY_USERS", hive) == 0)
00028 {
00029 m_hRoot = HKEY_USERS;
00030 }
00031
00032 m_hRoot = follow_path(key.range(1, key.numsegments()), true, NULL);
00033
00034 #if 0
00035
00036
00037 hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
00038 RegNotifyChangeKeyValue(
00039 m_hRoot,
00040 TRUE,
00041 REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_ATTRIBUTES |
00042 REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_CHANGE_SECURITY,
00043 hEvent,
00044 TRUE
00045 );
00046 #endif
00047 }
00048
00049 UniRegistryGen::~UniRegistryGen()
00050 {
00051 if (m_hRoot)
00052 {
00053 LONG result = RegCloseKey(m_hRoot);
00054 m_hRoot = 0;
00055 }
00056 }
00057
00058 bool UniRegistryGen::isok()
00059 {
00060 return m_hRoot != 0;
00061 }
00062
00063
00064
00065 HKEY UniRegistryGen::follow_path(const UniConfKey &key, bool create, bool *isValue)
00066 {
00067 const REGSAM samDesired = KEY_READ | KEY_WRITE;
00068 LONG result;
00069 HKEY hLastKey = m_hRoot;
00070 int n = key.numsegments();
00071
00072 if (isValue) *isValue = false;
00073
00074 for (int i=0;i<n;i++)
00075 {
00076 WvString subkey = key.segment(i).printable();
00077 HKEY hNextKey;
00078
00079 if (create)
00080 {
00081 result = RegCreateKeyEx(hLastKey, subkey, 0, NULL, 0, samDesired,
00082 NULL, &hNextKey, NULL);
00083 }
00084 else
00085 {
00086 result = RegOpenKeyEx(hLastKey, subkey, 0, samDesired, &hNextKey);
00087 }
00088
00089 if ((result == ERROR_FILE_NOT_FOUND) && (i == n-1))
00090 {
00091
00092 if (RegQueryValueEx(hLastKey, subkey, 0, NULL, NULL, NULL) == ERROR_SUCCESS)
00093 {
00094
00095 if (isValue) *isValue = true;
00096 break;
00097 }
00098 }
00099 if (result != ERROR_SUCCESS)
00100 {
00101 return 0;
00102 }
00103
00104
00105 if (i > 0)
00106 {
00107 RegCloseKey(hLastKey);
00108 }
00109 hLastKey = hNextKey;
00110 }
00111
00112 return hLastKey;
00113 }
00114
00115 WvString UniRegistryGen::get(const UniConfKey &key)
00116 {
00117 WvString retval = WvString::null;
00118 bool isvalue;
00119 DWORD type;
00120 TCHAR data[1024];
00121 DWORD size = sizeof(data);
00122 WvString value = key.last().printable();
00123
00124 HKEY hKey = follow_path(key, false, &isvalue);
00125 if (!isvalue)
00126 {
00127
00128 value = WvString::null;
00129 }
00130
00131 LONG result = RegQueryValueEx(
00132 hKey,
00133 value.cstr(),
00134 0,
00135 &type,
00136 (BYTE *) data,
00137 &size
00138 );
00139
00140 if (result == ERROR_SUCCESS)
00141 {
00142 switch (type)
00143 {
00144 case REG_DWORD:
00145 retval.setsize(11);
00146 itoa(*((int *) data), retval.edit(), 10);
00147 break;
00148 case REG_SZ:
00149 retval = data;
00150 break;
00151 default:
00152 break;
00153 };
00154 }
00155
00156 if (hKey != m_hRoot) RegCloseKey(hKey);
00157 return retval;
00158 }
00159
00160 void UniRegistryGen::set(const UniConfKey &key, WvStringParm value)
00161 {
00162 LONG result;
00163 HKEY hKey = follow_path(key.first( key.numsegments()-1 ), true, NULL);
00164 if (hKey)
00165 {
00166 result = RegSetValueEx(
00167 hKey,
00168 key.last().printable(),
00169 0,
00170 REG_SZ,
00171 (BYTE *) value.cstr(),
00172 strlen(value)+1
00173 );
00174 if (result == ERROR_SUCCESS)
00175 {
00176 delta(key, value);
00177 }
00178 }
00179 if (hKey != m_hRoot) RegCloseKey(hKey);
00180 }
00181
00182 bool UniRegistryGen::exists(const UniConfKey &key)
00183 {
00184 return get(key) == WvString::null;
00185 }
00186
00187 bool UniRegistryGen::haschildren(const UniConfKey &key)
00188 {
00189 bool isValue;
00190 HKEY hKey = follow_path(key, false, &isValue);
00191 bool retval = false;
00192 if (hKey && !isValue)
00193 {
00194 FILETIME dontcare;
00195 TCHAR data[1024];
00196 DWORD size = sizeof(data);
00197 LONG result = RegEnumKeyEx(hKey, 0, data, &size, 0,
00198 NULL, NULL, &dontcare);
00199 retval = ((result == ERROR_SUCCESS) || (result == ERROR_MORE_DATA));
00200 }
00201
00202 if (hKey != m_hRoot) RegCloseKey(hKey);
00203
00204 return retval;
00205 }
00206
00207 UniConfGen::Iter *UniRegistryGen::iterator(const UniConfKey &key)
00208 {
00209 return new NullIter();
00210 }
00211
00212 static UniConfGen *creator(WvStringParm s, IObject *, void *)
00213 {
00214 return new UniRegistryGen(s);
00215 }
00216
00217 #pragma warning(disable : 4073)
00218 #pragma init_seg(lib)
00219 WvMoniker<UniConfGen> UniRegistryGenMoniker("registry", creator);