2 * Copyright 2009 Vincent Povirk for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 #define NONAMELESSUNION
20 #define NONAMELESSSTRUCT
36 #include "wine/debug.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(wincodecs
);
40 /***********************************************************************
41 * interface for self-registering
45 CLSID
const *clsid
; /* NULL for end of list */
46 LPCSTR name
; /* can be NULL to omit */
47 LPCSTR ips
; /* can be NULL to omit */
48 LPCSTR ips32
; /* can be NULL to omit */
49 LPCSTR ips32_tmodel
; /* can be NULL to omit */
50 LPCSTR progid
; /* can be NULL to omit */
51 LPCSTR viprogid
; /* can be NULL to omit */
52 LPCSTR progid_extra
; /* can be NULL to omit */
55 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
);
56 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
);
58 /***********************************************************************
59 * static string constants
61 static WCHAR
const clsid_keyname
[6] = {
62 'C', 'L', 'S', 'I', 'D', 0 };
63 static WCHAR
const curver_keyname
[7] = {
64 'C', 'u', 'r', 'V', 'e', 'r', 0 };
65 static WCHAR
const ips_keyname
[13] = {
66 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
68 static WCHAR
const ips32_keyname
[15] = {
69 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
71 static WCHAR
const progid_keyname
[7] = {
72 'P', 'r', 'o', 'g', 'I', 'D', 0 };
73 static WCHAR
const viprogid_keyname
[25] = {
74 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
75 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
77 static char const tmodel_valuename
[] = "ThreadingModel";
79 /***********************************************************************
80 * static helper functions
82 static LONG
register_key_defvalueW(HKEY base
, WCHAR
const *name
,
84 static LONG
register_key_defvalueA(HKEY base
, WCHAR
const *name
,
86 static LONG
register_progid(WCHAR
const *clsid
,
87 char const *progid
, char const *curver_progid
,
88 char const *name
, char const *extra
);
90 /***********************************************************************
93 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
)
95 LONG res
= ERROR_SUCCESS
;
98 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
99 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
100 if (res
!= ERROR_SUCCESS
) goto error_return
;
102 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
106 StringFromGUID2(list
->clsid
, buf
, 39);
107 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
108 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
109 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
112 res
= RegSetValueExA(clsid_key
, NULL
, 0, REG_SZ
,
113 (CONST BYTE
*)(list
->name
),
114 strlen(list
->name
) + 1);
115 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
119 res
= register_key_defvalueA(clsid_key
, ips_keyname
, list
->ips
);
120 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
126 res
= RegCreateKeyExW(clsid_key
, ips32_keyname
, 0, NULL
, 0,
127 KEY_READ
| KEY_WRITE
, NULL
,
129 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
131 res
= RegSetValueExA(ips32_key
, NULL
, 0, REG_SZ
,
132 (CONST BYTE
*)list
->ips32
,
133 lstrlenA(list
->ips32
) + 1);
134 if (res
== ERROR_SUCCESS
&& list
->ips32_tmodel
)
135 res
= RegSetValueExA(ips32_key
, tmodel_valuename
, 0, REG_SZ
,
136 (CONST BYTE
*)list
->ips32_tmodel
,
137 strlen(list
->ips32_tmodel
) + 1);
138 RegCloseKey(ips32_key
);
139 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
143 res
= register_key_defvalueA(clsid_key
, progid_keyname
,
145 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
147 res
= register_progid(buf
, list
->progid
, NULL
,
148 list
->name
, list
->progid_extra
);
149 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
152 if (list
->viprogid
) {
153 res
= register_key_defvalueA(clsid_key
, viprogid_keyname
,
155 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
157 res
= register_progid(buf
, list
->viprogid
, list
->progid
,
158 list
->name
, list
->progid_extra
);
159 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
162 error_close_clsid_key
:
163 RegCloseKey(clsid_key
);
166 error_close_coclass_key
:
167 RegCloseKey(coclass_key
);
169 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
172 /***********************************************************************
173 * unregister_coclasses
175 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
)
177 LONG res
= ERROR_SUCCESS
;
180 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
181 KEY_READ
| KEY_WRITE
, &coclass_key
);
182 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
183 if (res
!= ERROR_SUCCESS
) goto error_return
;
185 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
188 StringFromGUID2(list
->clsid
, buf
, 39);
189 res
= RegDeleteTreeW(coclass_key
, buf
);
190 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
191 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
194 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->progid
);
195 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
196 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
199 if (list
->viprogid
) {
200 res
= RegDeleteTreeA(HKEY_CLASSES_ROOT
, list
->viprogid
);
201 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
202 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
206 error_close_coclass_key
:
207 RegCloseKey(coclass_key
);
209 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
212 /***********************************************************************
213 * register_key_defvalueW
215 static LONG
register_key_defvalueW(
223 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
224 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
225 if (res
!= ERROR_SUCCESS
) return res
;
226 res
= RegSetValueExW(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
227 (lstrlenW(value
) + 1) * sizeof(WCHAR
));
232 /***********************************************************************
233 * register_key_defvalueA
235 static LONG
register_key_defvalueA(
243 res
= RegCreateKeyExW(base
, name
, 0, NULL
, 0,
244 KEY_READ
| KEY_WRITE
, NULL
, &key
, NULL
);
245 if (res
!= ERROR_SUCCESS
) return res
;
246 res
= RegSetValueExA(key
, NULL
, 0, REG_SZ
, (CONST BYTE
*)value
,
247 lstrlenA(value
) + 1);
252 /***********************************************************************
255 static LONG
register_progid(
258 char const *curver_progid
,
265 res
= RegCreateKeyExA(HKEY_CLASSES_ROOT
, progid
, 0,
266 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
268 if (res
!= ERROR_SUCCESS
) return res
;
271 res
= RegSetValueExA(progid_key
, NULL
, 0, REG_SZ
,
272 (CONST BYTE
*)name
, strlen(name
) + 1);
273 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
277 res
= register_key_defvalueW(progid_key
, clsid_keyname
, clsid
);
278 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
282 res
= register_key_defvalueA(progid_key
, curver_keyname
,
284 if (res
!= ERROR_SUCCESS
) goto error_close_progid_key
;
290 res
= RegCreateKeyExA(progid_key
, extra
, 0,
291 NULL
, 0, KEY_READ
| KEY_WRITE
, NULL
,
293 if (res
== ERROR_SUCCESS
)
294 RegCloseKey(extra_key
);
297 error_close_progid_key
:
298 RegCloseKey(progid_key
);
302 /***********************************************************************
305 static struct regsvr_coclass
const coclass_list
[] = {
306 { &CLSID_WICImagingFactory
,
307 "WIC Imaging Factory",
312 { &CLSID_WICBmpDecoder
,
318 { NULL
} /* list terminator */
321 HRESULT WINAPI
DllRegisterServer(void)
327 hr
= register_coclasses(coclass_list
);
331 HRESULT WINAPI
DllUnregisterServer(void)
337 hr
= unregister_coclasses(coclass_list
);