Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

uniregistrygen.cc

Go to the documentation of this file.
00001 /* 00002 * Worldvisions Weaver Software: 00003 * Copyright (C) 1997-2003 Net Integration Technologies, Inc. 00004 * 00005 * A generator that exposes the windows registry. 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 // FIXME: Notifications don't work for external registry changes. 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 // returns a handle to the key specified by key, or, if key specifies a value, 00064 // a handle to the key containing that value (and setting isValue = true) 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; // DuplicateHandle() does not work with regkeys 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 // maybe the last segment is a value name 00092 if (RegQueryValueEx(hLastKey, subkey, 0, NULL, NULL, NULL) == ERROR_SUCCESS) 00093 { 00094 // ... it is a value 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 // allow fetching a key's default value 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);

Generated on Tue Oct 5 01:09:19 2004 for WvStreams by doxygen 1.3.7