131 lines
3.8 KiB
C
131 lines
3.8 KiB
C
/*
|
|
* 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;
|
|
}
|