Completed implementation of comcat.dll, incl. Dll[Un]RegisterServer.
[wine.git] / dlls / comcat / regsvr.c
blobc2fad67e95daf193e9c13bca51e27552e876b6a4
1 /*
2 * self-registerable dll helper functions
4 * Copyright (C) 2002 John K. Hohm
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #include "windef.h"
22 #include "winbase.h"
23 #include "winuser.h"
24 #include "winreg.h"
25 #include "winerror.h"
27 #include "regsvr.h"
29 static HRESULT recursive_delete_key(HKEY key);
31 /***********************************************************************
32 * regsvr_register
34 HRESULT regsvr_register(struct regsvr_entry const *entries, size_t count)
36 HKEY keys[count];
37 struct regsvr_entry const *e;
38 int i;
39 HRESULT res = S_OK;
41 /* Create keys and set values. */
42 for (i = 0, e = entries; i < count; ++i, ++e) {
43 /* predefined HKEY_'s are all >= 0x80000000 */
44 HKEY parent_key = e->parent < 0x80000000 ?
45 keys[e->parent] : (HKEY)e->parent;
46 if (e->value == NULL) {
47 res = RegCreateKeyExW(parent_key, e->name, 0, NULL, 0,
48 KEY_READ | KEY_WRITE, NULL, &keys[i], NULL);
49 } else {
50 res = RegSetValueExW(parent_key, e->name, 0, REG_SZ,
51 (CONST BYTE*)e->value,
52 (lstrlenW(e->value) + 1) * sizeof(WCHAR));
54 if (res != ERROR_SUCCESS) break;
57 /* Close keys. */
58 for (--i, --e; 0 <= i; --i, --e) {
59 if (e->value == NULL) RegCloseKey(keys[i]);
62 return res == ERROR_SUCCESS ? S_OK : HRESULT_FROM_WIN32(res);
65 /***********************************************************************
66 * regsvr_unregister
68 HRESULT regsvr_unregister(struct regsvr_entry const *entries, size_t count)
70 HKEY keys[count];
71 struct regsvr_entry const *e;
72 int i;
73 HRESULT res = S_OK;
75 /* Open (and possibly delete) keys. */
76 for (i = 0, e = entries; i < count; ++i, ++e) {
77 /* predefined HKEY_'s are all >= 0x80000000 */
78 HKEY parent_key = e->parent < 0x80000000 ?
79 keys[e->parent] : (HKEY)e->parent;
80 if (e->value == NULL && parent_key) {
81 res = RegOpenKeyExW(parent_key, e->name, 0,
82 KEY_READ | KEY_WRITE, &keys[i]);
83 if (res == ERROR_SUCCESS && e->unreg_del)
84 res = recursive_delete_key(keys[i]);
85 if (res == ERROR_FILE_NOT_FOUND) continue;
86 if (res != ERROR_SUCCESS) break;
87 } else keys[i] = 0;
90 /* Close keys. */
91 for (--i; 0 <= i; --i) {
92 if (keys[i]) RegCloseKey(keys[i]);
95 return res != ERROR_SUCCESS && res != ERROR_FILE_NOT_FOUND ?
96 HRESULT_FROM_WIN32(res) : S_OK;
99 /***********************************************************************
100 * recursive_delete_key
102 static LONG recursive_delete_key(HKEY key)
104 LONG res;
105 DWORD index;
106 WCHAR subkey_name[MAX_PATH];
107 DWORD cName;
108 HKEY subkey;
110 for (index = 0; ; ++index) {
111 cName = sizeof subkey_name / sizeof(WCHAR);
112 res = RegEnumKeyExW(key, index, subkey_name, &cName,
113 NULL, NULL, NULL, NULL);
114 if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
115 res = ERROR_SUCCESS; /* presumably we're done enumerating */
116 break;
118 res = RegOpenKeyExW(key, subkey_name, 0,
119 KEY_READ | KEY_WRITE, &subkey);
120 if (res == ERROR_FILE_NOT_FOUND) continue;
121 if (res != ERROR_SUCCESS) break;
123 res = recursive_delete_key(subkey);
124 RegCloseKey(subkey);
125 if (res != ERROR_SUCCESS) break;
128 if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
129 return res;