/* * 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; }