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 Sat Feb 21 21:05:22 2004 for WvStreams by doxygen 1.3.5