00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 #include "windowsRegistry.h"
00020 #include "config_express.h"
00021 
00022 #ifdef WIN32_VC
00023 
00024 #include <windows.h>
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 bool WindowsRegistry::
00037 set_string_value(const string &key, const string &name, const string &value) {
00038   TextEncoder encoder;
00039   wstring wvalue = encoder.decode_text(value);
00040 
00041   bool okflag = true;
00042 
00043   
00044   
00045   
00046 
00047   
00048   
00049   wvalue += (wchar_t)0;
00050   int mb_result_len =
00051     WideCharToMultiByte(CP_ACP, 0,
00052                         wvalue.data(), wvalue.length(),
00053                         NULL, 0,
00054                         NULL, NULL);
00055   if (mb_result_len == 0) {
00056     express_cat.error()
00057       << "Unable to convert " << value << " from Unicode to MultiByte form.\n";
00058     return false;
00059   }
00060 
00061   char *mb_result = (char *)alloca(mb_result_len);
00062   WideCharToMultiByte(CP_ACP, 0,
00063                       wvalue.data(), wvalue.length(),
00064                       mb_result, mb_result_len,
00065                       NULL, NULL);
00066 
00067   if (express_cat.is_debug()) {
00068     express_cat.debug()
00069       << "Converted '" << value << "' to '" << mb_result
00070       << "' for storing in registry.\n";
00071   }
00072 
00073   return do_set(key, name, REG_SZ, mb_result, mb_result_len);
00074 }
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 bool WindowsRegistry::
00084 set_int_value(const string &key, const string &name, int value) {
00085   DWORD dw = value;
00086   return do_set(key, name, REG_DWORD, &dw, sizeof(dw));
00087 }
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 WindowsRegistry::Type WindowsRegistry::
00096 get_key_type(const string &key, const string &name) {
00097   int data_type;
00098   string data;
00099   if (!do_get(key, name, data_type, data)) {
00100     return T_none;
00101   }
00102 
00103   switch (data_type) {
00104   case REG_SZ:
00105     return T_string;
00106 
00107   case REG_DWORD:
00108     return T_int;
00109 
00110   default:
00111     return T_none;
00112   }
00113 }
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 string WindowsRegistry::
00126 get_string_value(const string &key, const string &name,
00127                  const string &default_value) {
00128   int data_type;
00129   string data;
00130   if (!do_get(key, name, data_type, data)) {
00131     return default_value;
00132   }
00133 
00134   if (data_type != REG_SZ) {
00135     express_cat.warning()
00136       << "Registry key " << key << " does not contain a string value.\n";
00137     return default_value;
00138   }
00139 
00140   
00141   
00142   
00143   int wide_result_len =
00144     MultiByteToWideChar(CP_ACP, 0,
00145                         data.data(), data.length(),
00146                         NULL, 0);
00147   if (wide_result_len == 0) {
00148     express_cat.error()
00149       << "Unable to convert " << data << " from MultiByte to Unicode form.\n";
00150     return data;
00151   }
00152 
00153   wchar_t *wide_result = (wchar_t *)alloca(wide_result_len * sizeof(wchar_t));
00154   MultiByteToWideChar(CP_ACP, 0,
00155                       data.data(), data.length(),
00156                       wide_result, wide_result_len);
00157 
00158   wstring wdata(wide_result, wide_result_len);
00159 
00160   TextEncoder encoder;
00161   string result = encoder.encode_wtext(wdata);
00162 
00163   if (express_cat.is_debug()) {
00164     express_cat.debug()
00165       << "Converted '" << data << "' from registry to '" << result << "'\n";
00166   }
00167 
00168   return result;
00169 }
00170 
00171 
00172 
00173 
00174 
00175 
00176 
00177 
00178 
00179 int WindowsRegistry::
00180 get_int_value(const string &key, const string &name, int default_value) {
00181   int data_type;
00182   string data;
00183   if (!do_get(key, name, data_type, data)) {
00184     return default_value;
00185   }
00186 
00187   if (data_type != REG_DWORD) {
00188     express_cat.warning()
00189       << "Registry key " << key << " does not contain an integer value.\n";
00190     return default_value;
00191   }
00192   
00193   
00194   nassertr(data.length() == sizeof(DWORD), default_value);
00195   DWORD dw = *(DWORD *)data.data();
00196   return dw;
00197 }
00198 
00199 
00200 
00201 
00202 
00203 
00204 
00205 bool WindowsRegistry::
00206 do_set(const string &key, const string &name,
00207        int data_type, const void *data, int data_length) {
00208   HKEY hkey;
00209   LONG error;
00210 
00211   error =
00212     RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_SET_VALUE, &hkey);
00213   if (error != ERROR_SUCCESS) {
00214     express_cat.error()
00215       << "Unable to open registry key " << key
00216       << ": " << format_message(error) << "\n";
00217     return false;
00218   }
00219 
00220   bool okflag = true;
00221 
00222   error =
00223     RegSetValueEx(hkey, name.c_str(), 0, data_type, 
00224                   (CONST BYTE *)data, data_length);
00225   if (error != ERROR_SUCCESS) {
00226     express_cat.error()
00227       << "Unable to set registry key " << key << " name " << name 
00228       << ": " << format_message(error) << "\n";
00229     okflag = false;
00230   }
00231 
00232   error = RegCloseKey(hkey);
00233   if (error != ERROR_SUCCESS) {
00234     express_cat.warning()
00235       << "Unable to close opened registry key " << key
00236       << ": " << format_message(error) << "\n";
00237   }
00238 
00239   return okflag;
00240 }
00241 
00242 
00243 
00244 
00245 
00246 
00247 
00248 
00249 bool WindowsRegistry::
00250 do_get(const string &key, const string &name, int &data_type, string &data) {
00251   HKEY hkey;
00252   LONG error;
00253 
00254   error =
00255     RegOpenKeyEx(HKEY_LOCAL_MACHINE, key.c_str(), 0, KEY_QUERY_VALUE, &hkey);
00256   if (error != ERROR_SUCCESS) {
00257     express_cat.debug()
00258       << "Unable to open registry key " << key
00259       << ": " << format_message(error) << "\n";
00260     return false;
00261   }
00262 
00263   bool okflag = true;
00264 
00265   
00266   
00267   static const size_t init_buffer_size = 1024;
00268   char init_buffer[init_buffer_size];
00269   DWORD buffer_size = init_buffer_size;
00270   DWORD dw_data_type;
00271 
00272   error =
00273     RegQueryValueEx(hkey, name.c_str(), 0, &dw_data_type, 
00274                     (BYTE *)init_buffer, &buffer_size);
00275   if (error == ERROR_SUCCESS) {
00276     data_type = dw_data_type;
00277     if (data_type == REG_SZ || 
00278         data_type == REG_MULTI_SZ || 
00279         data_type == REG_EXPAND_SZ) {
00280       
00281       buffer_size--;
00282     }
00283     data = string(init_buffer, buffer_size);
00284 
00285   } else if (error == ERROR_MORE_DATA) {
00286     
00287 
00288     
00289     
00290     
00291     
00292     char *new_buffer = new char[buffer_size];
00293     error =
00294       RegQueryValueEx(hkey, name.c_str(), 0, &dw_data_type, 
00295                       (BYTE *)new_buffer, &buffer_size);
00296     if (error == ERROR_SUCCESS) {
00297       data_type = dw_data_type;
00298       if (data_type == REG_SZ || 
00299           data_type == REG_MULTI_SZ || 
00300           data_type == REG_EXPAND_SZ) {
00301         
00302         buffer_size--;
00303       }
00304       data = string(new_buffer, buffer_size);
00305     }
00306     delete new_buffer;
00307   }
00308 
00309   if (error != ERROR_SUCCESS) {
00310     express_cat.error()
00311       << "Unable to get registry key " << key << " name " << name 
00312       << ": " << format_message(error) << "\n";
00313     okflag = false;
00314   }
00315 
00316   error = RegCloseKey(hkey);
00317   if (error != ERROR_SUCCESS) {
00318     express_cat.warning()
00319       << "Unable to close opened registry key " << key
00320       << ": " << format_message(error) << "\n";
00321   }
00322 
00323   return okflag;
00324 }
00325 
00326 
00327 
00328 
00329 
00330 
00331 
00332 string WindowsRegistry::
00333 format_message(int error_code) {
00334   PVOID buffer;
00335   DWORD length = 
00336     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
00337                   NULL, error_code, 0, (LPTSTR)&buffer, 0, NULL);
00338   if (length == 0) {
00339     return "Unknown error message";
00340   }
00341   string result((const char *)buffer, length);
00342   LocalFree(buffer);
00343   return result;
00344 }
00345 
00346 #endif  // WIN32_VC