msvcrt: Follow Vista behaviour in wcscpy_s.
[wine.git] / dlls / qedit / regsvr.c
blob9ff18528523bbd7b45624c4315ba15122048fb0f
1 /*
2 * self-registerable dll functions for qedit.dll
4 * Copyright (C) 2008 Google (Lei Zhang)
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #include "qedit_private.h"
22 #include "winreg.h"
24 #include "wine/debug.h"
26 WINE_DEFAULT_DEBUG_CHANNEL(qedit);
28 struct regsvr_coclass
30 CLSID const *clsid; /* NULL for end of list */
31 LPCSTR name; /* can be NULL to omit */
32 LPCSTR ips; /* can be NULL to omit */
33 LPCSTR ips32; /* can be NULL to omit */
34 LPCSTR ips32_tmodel; /* can be NULL to omit */
35 LPCSTR progid; /* can be NULL to omit */
36 LPCSTR viprogid; /* can be NULL to omit */
37 LPCSTR progid_extra; /* can be NULL to omit */
40 static HRESULT register_coclasses(struct regsvr_coclass const *list);
41 static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
43 /***********************************************************************
44 * static string constants
46 static WCHAR const clsid_keyname[6] = {
47 'C', 'L', 'S', 'I', 'D', 0 };
48 static WCHAR const curver_keyname[7] = {
49 'C', 'u', 'r', 'V', 'e', 'r', 0 };
50 static WCHAR const ips_keyname[13] = {
51 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', 0 };
52 static WCHAR const ips32_keyname[15] = {
53 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', '3', '2', 0 };
54 static WCHAR const progid_keyname[7] = {
55 'P', 'r', 'o', 'g', 'I', 'D', 0 };
56 static WCHAR const viprogid_keyname[25] = {
57 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
58 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
59 0 };
60 static char const tmodel_valuename[] = "ThreadingModel";
62 /***********************************************************************
63 * static helper functions
65 static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
66 WCHAR const *value);
67 static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
68 char const *value);
69 static LONG register_progid(WCHAR const *clsid,
70 char const *progid, char const *curver_progid,
71 char const *name, char const *extra);
75 /***********************************************************************
76 * register_coclasses
78 static HRESULT register_coclasses(struct regsvr_coclass const *list)
80 LONG res = ERROR_SUCCESS;
81 HKEY coclass_key;
83 res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
84 KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
85 if (res != ERROR_SUCCESS) goto error_return;
87 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
88 WCHAR buf[39];
89 HKEY clsid_key;
91 StringFromGUID2(list->clsid, buf, 39);
92 res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
93 KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
94 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
96 if (list->name) {
97 res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
98 (CONST BYTE*)(list->name),
99 strlen(list->name) + 1);
100 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
103 if (list->ips) {
104 res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
105 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
108 if (list->ips32) {
109 HKEY ips32_key;
111 res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
112 KEY_READ | KEY_WRITE, NULL,
113 &ips32_key, NULL);
114 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
116 res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
117 (CONST BYTE*)list->ips32,
118 lstrlenA(list->ips32) + 1);
119 if (res == ERROR_SUCCESS && list->ips32_tmodel)
120 res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
121 (CONST BYTE*)list->ips32_tmodel,
122 strlen(list->ips32_tmodel) + 1);
123 RegCloseKey(ips32_key);
124 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
127 if (list->progid) {
128 res = register_key_defvalueA(clsid_key, progid_keyname,
129 list->progid);
130 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
132 res = register_progid(buf, list->progid, NULL,
133 list->name, list->progid_extra);
134 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
137 if (list->viprogid) {
138 res = register_key_defvalueA(clsid_key, viprogid_keyname,
139 list->viprogid);
140 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
142 res = register_progid(buf, list->viprogid, list->progid,
143 list->name, list->progid_extra);
144 if (res != ERROR_SUCCESS) goto error_close_clsid_key;
147 error_close_clsid_key:
148 RegCloseKey(clsid_key);
151 error_close_coclass_key:
152 RegCloseKey(coclass_key);
153 error_return:
154 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
157 /***********************************************************************
158 * unregister_coclasses
160 static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
162 LONG res = ERROR_SUCCESS;
163 HKEY coclass_key;
165 res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
166 KEY_READ | KEY_WRITE, &coclass_key);
167 if (res == ERROR_FILE_NOT_FOUND) return S_OK;
168 if (res != ERROR_SUCCESS) goto error_return;
170 for (; res == ERROR_SUCCESS && list->clsid; ++list) {
171 WCHAR buf[39];
173 StringFromGUID2(list->clsid, buf, 39);
174 res = RegDeleteTreeW(coclass_key, buf);
175 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
176 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
178 if (list->progid) {
179 res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
180 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
181 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
184 if (list->viprogid) {
185 res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
186 if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
187 if (res != ERROR_SUCCESS) goto error_close_coclass_key;
191 error_close_coclass_key:
192 RegCloseKey(coclass_key);
193 error_return:
194 return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
197 /***********************************************************************
198 * regsvr_key_defvalueW
200 static LONG register_key_defvalueW(
201 HKEY base,
202 WCHAR const *name,
203 WCHAR const *value)
205 LONG res;
206 HKEY key;
208 res = RegCreateKeyExW(base, name, 0, NULL, 0,
209 KEY_READ | KEY_WRITE, NULL, &key, NULL);
210 if (res != ERROR_SUCCESS) return res;
211 res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
212 (lstrlenW(value) + 1) * sizeof(WCHAR));
213 RegCloseKey(key);
214 return res;
217 /***********************************************************************
218 * regsvr_key_defvalueA
220 static LONG register_key_defvalueA(
221 HKEY base,
222 WCHAR const *name,
223 char const *value)
225 LONG res;
226 HKEY key;
228 res = RegCreateKeyExW(base, name, 0, NULL, 0,
229 KEY_READ | KEY_WRITE, NULL, &key, NULL);
230 if (res != ERROR_SUCCESS) return res;
231 res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
232 lstrlenA(value) + 1);
233 RegCloseKey(key);
234 return res;
237 /***********************************************************************
238 * regsvr_progid
240 static LONG register_progid(
241 WCHAR const *clsid,
242 char const *progid,
243 char const *curver_progid,
244 char const *name,
245 char const *extra)
247 LONG res;
248 HKEY progid_key;
250 res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
251 NULL, 0, KEY_READ | KEY_WRITE, NULL,
252 &progid_key, NULL);
253 if (res != ERROR_SUCCESS) return res;
255 if (name) {
256 res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
257 (CONST BYTE*)name, strlen(name) + 1);
258 if (res != ERROR_SUCCESS) goto error_close_progid_key;
261 if (clsid) {
262 res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
263 if (res != ERROR_SUCCESS) goto error_close_progid_key;
266 if (curver_progid) {
267 res = register_key_defvalueA(progid_key, curver_keyname,
268 curver_progid);
269 if (res != ERROR_SUCCESS) goto error_close_progid_key;
272 if (extra) {
273 HKEY extra_key;
275 res = RegCreateKeyExA(progid_key, extra, 0,
276 NULL, 0, KEY_READ | KEY_WRITE, NULL,
277 &extra_key, NULL);
278 if (res == ERROR_SUCCESS)
279 RegCloseKey(extra_key);
282 error_close_progid_key:
283 RegCloseKey(progid_key);
284 return res;
287 /***********************************************************************
288 * coclass list
290 static struct regsvr_coclass const coclass_list[] = {
291 { &CLSID_MediaDet,
292 "MediaDet",
293 NULL,
294 "qedit.dll",
295 "Both"
297 { NULL } /* list terminator */
300 /***********************************************************************
301 * DllRegisterServer (QEDIT.@)
303 HRESULT WINAPI DllRegisterServer(void)
305 HRESULT hr;
307 TRACE("\n");
309 hr = register_coclasses(coclass_list);
310 return hr;
313 /***********************************************************************
314 * DllUnregisterServer (QEDIT.@)
316 HRESULT WINAPI DllUnregisterServer(void)
318 HRESULT hr;
320 TRACE("\n");
322 hr = unregister_coclasses(coclass_list);
323 return S_OK;