00001 #ifndef REGISTRY_CONFIG_IMPLEMENTATION_FILE
00002 #define REGISTRY_CONFIG_IMPLEMENTATION_FILE
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifdef __WIN32__
00019
00020
00021
00022 #include "registry_config.h"
00023
00024 #include <basis/convert_utf.h>
00025 #include <basis/function.h>
00026 #include <basis/istring.h>
00027 #include <basis/portable.h>
00028 #include <basis/string_array.h>
00029 #include <data_struct/static_memory_gremlin.h>
00030 #include <data_struct/string_table.h>
00031
00032 #include <shlwapi.h>
00033
00034 #undef LOG
00035 #ifdef DEBUG_REGISTRY_CONFIGURATOR
00036 #define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger(), s)
00037 #else
00038 #define LOG(s) {}
00039 #endif
00040
00041
00042
00043
00044 const int MAXIMUM_ENTRY_SIZE = 256 * KILOBYTE;
00045
00046
00047 const int MAXIMUM_NAME_SIZE = 16384;
00048
00049
00050
00051 SAFE_STATIC_CONST(istring_object, registry_configurator::reg_str_fake_default,
00052 ("bogus_never_should_see"));
00053
00054 registry_configurator::registry_configurator(registry_hives hive,
00055 treatment_of_defaults behavior)
00056 : configurator(behavior),
00057 _hive(hive)
00058 {}
00059
00060 registry_configurator::~registry_configurator()
00061 {}
00062
00063 void *registry_configurator::translate_hive(registry_hives hive)
00064 {
00065 switch (hive) {
00066 case hkey_classes_root: return HKEY_CLASSES_ROOT;
00067 case hkey_current_user: return HKEY_CURRENT_USER;
00068 case hkey_local_machine: return HKEY_LOCAL_MACHINE;
00069 case hkey_users: return HKEY_USERS;
00070 case hkey_current_config: return HKEY_CURRENT_CONFIG;
00071 default: return 0;
00072 }
00073 }
00074
00075 istring registry_configurator::fix_section(const istring §ion)
00076 {
00077 istring to_return = section;
00078 for (int i = 0; i < to_return.length(); i++) {
00079 if (to_return[i] == '/')
00080 to_return[i] = '\\';
00081 }
00082 return to_return;
00083 }
00084
00085 bool registry_configurator::put(const istring §ion_in, const istring &entry,
00086 const istring &to_store)
00087 {
00088 FUNCDEF("put");
00089 istring section = fix_section(section_in);
00090 if (!to_store.length()) return delete_entry(section, entry);
00091 else if (!section.length()) return false;
00092
00093 HKEY key;
00094 long ret = RegOpenKeyEx((HKEY)translate_hive(_hive),
00095 to_unicode_temp(section), 0, KEY_WRITE, &key);
00096 if (ret != ERROR_SUCCESS) {
00097 LOG("failed to open the key, trying to create it.");
00098 DWORD dispose;
00099 ret = RegCreateKeyEx((HKEY)translate_hive(_hive),
00100 to_unicode_temp(section), 0, NIL, REG_OPTION_NON_VOLATILE,
00101 KEY_ALL_ACCESS, NIL, &key, &dispose);
00102 if (ret != ERROR_SUCCESS) {
00103 LOG("failed to create the key!!");
00104 return false;
00105 }
00106 }
00107
00108 bool to_return = true;
00109 ret = RegSetValueEx(key, to_unicode_temp(entry), 0, REG_SZ,
00110 (byte *)to_store.s(), to_store.length() + 1);
00111 if (ret != ERROR_SUCCESS) {
00112 LOG(istring("failed to write the entry!"));
00113 to_return = false;
00114 }
00115
00116 RegCloseKey(key);
00117 return to_return;
00118 }
00119
00120 bool registry_configurator::get(const istring §ion_in, const istring &entry,
00121 istring &found)
00122 {
00123 FUNCDEF("get");
00124 found = "";
00125 if (!section_in) return false;
00126 istring section = fix_section(section_in);
00127 HKEY key;
00128 long ret = RegOpenKeyEx((HKEY)translate_hive(_hive),
00129 to_unicode_temp(section), 0, KEY_QUERY_VALUE, &key);
00130 if (ret != ERROR_SUCCESS) {
00131 LOG("failed to open the key!");
00132 return false;
00133 }
00134
00135 DWORD type_seen;
00136 byte *data_seen = new byte[MAXIMUM_ENTRY_SIZE];
00137 DWORD length = MAXIMUM_ENTRY_SIZE - 1;
00138 ret = RegQueryValueEx(key, to_unicode_temp(entry), 0, &type_seen, data_seen,
00139 &length);
00140 if (ret != ERROR_SUCCESS) {
00141 LOG(istring("failed to read the entry!"));
00142 return false;
00143 }
00144
00145 if (type_seen != REG_SZ) {
00146 LOG(istring("entry found was not of string type!"));
00147 RegCloseKey(key);
00148 return false;
00149 }
00150
00151 data_seen[MAXIMUM_ENTRY_SIZE - 1] = '\0';
00152
00153 found = istring((char *)data_seen);
00154
00155 delete [] data_seen;
00156
00157 RegCloseKey(key);
00158 return true;
00159 }
00160
00161 bool registry_configurator::get_section(const istring §ion_in,
00162 string_table &info)
00163 {
00164 FUNCDEF("get_section");
00165 info.reset();
00166 if (!section_in.length()) return false;
00167 istring section = fix_section(section_in);
00168 HKEY key;
00169 long ret = RegOpenKeyEx((HKEY)translate_hive(_hive),
00170 to_unicode_temp(section), 0, KEY_QUERY_VALUE, &key);
00171 if (ret != ERROR_SUCCESS) {
00172 LOG("failed to open the key!");
00173 return false;
00174 }
00175
00176 DWORD type_seen;
00177 byte *data_seen = new byte[MAXIMUM_ENTRY_SIZE];
00178 flexichar *name_seen = new flexichar[MAXIMUM_NAME_SIZE];
00179 DWORD name_length;
00180 for (DWORD index = 0; index++; ) {
00181 DWORD length = MAXIMUM_ENTRY_SIZE - 1;
00182 LONG ret = RegEnumValue(key, index, name_seen, &name_length, 0,
00183 &type_seen, data_seen, &length);
00184 if ( (ret == ERROR_SUCCESS) && (type_seen == REG_SZ) ) {
00185
00186 istring name = from_unicode_temp(name_seen);
00187 istring content = from_unicode_temp((flexichar *)data_seen);
00188 info.add(name, content);
00189 }
00190 }
00191
00192 delete [] data_seen;
00193 delete [] name_seen;
00194
00195 RegCloseKey(key);
00196
00197 return true;
00198 }
00199
00200 bool registry_configurator::section_exists(const istring §ion_in)
00201 {
00202 FUNCDEF("section_exists");
00203 if (!section_in.length()) return false;
00204 istring section = fix_section(section_in);
00205 HKEY key;
00206 long ret = RegOpenKeyEx((HKEY)translate_hive(_hive),
00207 to_unicode_temp(section), 0, KEY_QUERY_VALUE, &key);
00208 if (ret != ERROR_SUCCESS) {
00209 LOG("failed to open the key!");
00210 return false;
00211 }
00212
00213 RegCloseKey(key);
00214
00215 return true;
00216 }
00217
00218 bool registry_configurator::delete_section(const istring §ion_in)
00219 {
00220 FUNCDEF("delete_section");
00221 if (!section_in.length()) return false;
00222 istring section = fix_section(section_in);
00223
00224 long ret = SHDeleteKey((HKEY)translate_hive(_hive),
00225 to_unicode_temp(section));
00226 if (ret != ERROR_SUCCESS) {
00227 LOG("failed to delete the key!");
00228 return false;
00229 }
00230 return true;
00231 }
00232
00233 bool registry_configurator::delete_entry(const istring §ion_in,
00234 const istring &entry)
00235 {
00236 FUNCDEF("delete_entry");
00237 if (!section_in.length()) return false;
00238 istring section = fix_section(section_in);
00239
00240 HKEY key;
00241 long ret = RegOpenKeyEx((HKEY)translate_hive(_hive),
00242 to_unicode_temp(section), 0, KEY_SET_VALUE, &key);
00243 if (ret != ERROR_SUCCESS) {
00244 LOG("failed to open the key!");
00245 return false;
00246 }
00247
00248 bool to_return = true;
00249 ret = RegDeleteValue(key, to_unicode_temp(entry));
00250 if (ret != ERROR_SUCCESS) {
00251 LOG(istring("failed to delete the entry!"));
00252 to_return = false;
00253 }
00254
00255 RegCloseKey(key);
00256 return to_return;
00257 }
00258
00259 bool registry_configurator::put_section(const istring §ion_in,
00260 const string_table &info)
00261 {
00262 if (!section_in) return false;
00263 istring section = fix_section(section_in);
00264 bool failures = false;
00265 for (int i = 0; i < info.symbols(); i++) {
00266 bool worked = put(section, info.name(i), info[i]);
00267 if (!worked) failures = true;
00268 }
00269 return !failures;
00270 }
00271
00272 #endif // __WIN32__
00273
00274
00275 #endif //REGISTRY_CONFIG_IMPLEMENTATION_FILE
00276