| /* |
| * self-registerable dll helper functions |
| * |
| * Copyright (C) 2002 John K. Hohm |
| * |
| * This library is free software; you can redistribute it and/or |
| * modify it under the terms of the GNU Lesser General Public |
| * License as published by the Free Software Foundation; either |
| * version 2.1 of the License, or (at your option) any later version. |
| * |
| * This library is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| * Lesser General Public License for more details. |
| * |
| * You should have received a copy of the GNU Lesser General Public |
| * License along with this library; if not, write to the Free Software |
| * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| */ |
| |
| #include "windef.h" |
| #include "winbase.h" |
| #include "winuser.h" |
| #include "winreg.h" |
| #include "winerror.h" |
| |
| #include "regsvr.h" |
| |
| static HRESULT recursive_delete_key(HKEY key); |
| |
| /*********************************************************************** |
| * regsvr_register |
| */ |
| HRESULT regsvr_register(struct regsvr_entry const *entries, size_t count) |
| { |
| HKEY keys[count]; |
| struct regsvr_entry const *e; |
| int i; |
| HRESULT res = S_OK; |
| |
| /* Create keys and set values. */ |
| for (i = 0, e = entries; i < count; ++i, ++e) { |
| /* predefined HKEY_'s are all >= 0x80000000 */ |
| HKEY parent_key = e->parent < 0x80000000 ? |
| keys[e->parent] : (HKEY)e->parent; |
| if (e->value == NULL) { |
| res = RegCreateKeyExW(parent_key, e->name, 0, NULL, 0, |
| KEY_READ | KEY_WRITE, NULL, &keys[i], NULL); |
| } else { |
| res = RegSetValueExW(parent_key, e->name, 0, REG_SZ, |
| (CONST BYTE*)e->value, |
| (lstrlenW(e->value) + 1) * sizeof(WCHAR)); |
| } |
| if (res != ERROR_SUCCESS) break; |
| } |
| |
| /* Close keys. */ |
| for (--i, --e; 0 <= i; --i, --e) { |
| if (e->value == NULL) RegCloseKey(keys[i]); |
| } |
| |
| return res == ERROR_SUCCESS ? S_OK : HRESULT_FROM_WIN32(res); |
| } |
| |
| /*********************************************************************** |
| * regsvr_unregister |
| */ |
| HRESULT regsvr_unregister(struct regsvr_entry const *entries, size_t count) |
| { |
| HKEY keys[count]; |
| struct regsvr_entry const *e; |
| int i; |
| HRESULT res = S_OK; |
| |
| /* Open (and possibly delete) keys. */ |
| for (i = 0, e = entries; i < count; ++i, ++e) { |
| /* predefined HKEY_'s are all >= 0x80000000 */ |
| HKEY parent_key = e->parent < 0x80000000 ? |
| keys[e->parent] : (HKEY)e->parent; |
| if (e->value == NULL && parent_key) { |
| res = RegOpenKeyExW(parent_key, e->name, 0, |
| KEY_READ | KEY_WRITE, &keys[i]); |
| if (res == ERROR_SUCCESS && e->unreg_del) |
| res = recursive_delete_key(keys[i]); |
| if (res == ERROR_FILE_NOT_FOUND) continue; |
| if (res != ERROR_SUCCESS) break; |
| } else keys[i] = 0; |
| } |
| |
| /* Close keys. */ |
| for (--i; 0 <= i; --i) { |
| if (keys[i]) RegCloseKey(keys[i]); |
| } |
| |
| return res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND ? |
| HRESULT_FROM_WIN32(res) : S_OK; |
| } |
| |
| /*********************************************************************** |
| * recursive_delete_key |
| */ |
| static LONG recursive_delete_key(HKEY key) |
| { |
| LONG res; |
| DWORD index; |
| WCHAR subkey_name[MAX_PATH]; |
| DWORD cName; |
| HKEY subkey; |
| |
| for (index = 0; ; ++index) { |
| cName = sizeof subkey_name / sizeof(WCHAR); |
| res = RegEnumKeyExW(key, index, subkey_name, &cName, |
| NULL, NULL, NULL, NULL); |
| if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) { |
| res = ERROR_SUCCESS; /* presumably we're done enumerating */ |
| break; |
| } |
| res = RegOpenKeyExW(key, subkey_name, 0, |
| KEY_READ | KEY_WRITE, &subkey); |
| if (res == ERROR_FILE_NOT_FOUND) continue; |
| if (res != ERROR_SUCCESS) break; |
| |
| res = recursive_delete_key(subkey); |
| RegCloseKey(subkey); |
| if (res != ERROR_SUCCESS) break; |
| } |
| |
| if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0); |
| return res; |
| } |