2 * Copyright 2009 Vincent Povirk for CodeWeavers
3 * Copyright 2009 Maarten Lankhorst
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define NONAMELESSUNION
21 #define NONAMELESSSTRUCT
35 #include "mmdeviceapi.h"
37 #include "wine/debug.h"
38 #include "wine/unicode.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(mmdevapi
);
42 /***********************************************************************
43 * interface for self-registering
47 CLSID
const *clsid
; /* NULL for end of list */
48 LPCSTR name
; /* can be NULL to omit */
49 LPCSTR ips32
; /* can be NULL to omit */
50 LPCSTR ips32_tmodel
; /* can be NULL to omit */
53 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
);
54 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
);
56 /***********************************************************************
57 * static string constants
59 static WCHAR
const clsid_keyname
[] = {
60 'C', 'L', 'S', 'I', 'D', 0 };
61 static WCHAR
const ips32_keyname
[] = {
62 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
64 static WCHAR
const progid_keyname
[] = {
65 'P', 'r', 'o', 'g', 'I', 'D', 0 };
66 static WCHAR
const viprogid_keyname
[] = {
67 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
68 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
70 static char const tmodel_valuename
[] = "ThreadingModel";
72 /***********************************************************************
75 static HRESULT
register_coclasses(struct regsvr_coclass
const *list
)
77 LONG res
= ERROR_SUCCESS
;
80 res
= RegCreateKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0, NULL
, 0,
81 KEY_READ
| KEY_WRITE
, NULL
, &coclass_key
, NULL
);
82 if (res
!= ERROR_SUCCESS
) goto error_return
;
84 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
88 StringFromGUID2(list
->clsid
, buf
, 39);
89 res
= RegCreateKeyExW(coclass_key
, buf
, 0, NULL
, 0,
90 KEY_READ
| KEY_WRITE
, NULL
, &clsid_key
, NULL
);
91 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
94 res
= RegSetValueExA(clsid_key
, NULL
, 0, REG_SZ
,
95 (CONST BYTE
*)(list
->name
),
96 strlen(list
->name
) + 1);
97 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
103 res
= RegCreateKeyExW(clsid_key
, ips32_keyname
, 0, NULL
, 0,
104 KEY_READ
| KEY_WRITE
, NULL
,
106 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
108 res
= RegSetValueExA(ips32_key
, NULL
, 0, REG_SZ
,
109 (CONST BYTE
*)list
->ips32
,
110 lstrlenA(list
->ips32
) + 1);
111 if (res
== ERROR_SUCCESS
&& list
->ips32_tmodel
)
112 res
= RegSetValueExA(ips32_key
, tmodel_valuename
, 0, REG_SZ
,
113 (CONST BYTE
*)list
->ips32_tmodel
,
114 strlen(list
->ips32_tmodel
) + 1);
115 RegCloseKey(ips32_key
);
116 if (res
!= ERROR_SUCCESS
) goto error_close_clsid_key
;
119 error_close_clsid_key
:
120 RegCloseKey(clsid_key
);
123 error_close_coclass_key
:
124 RegCloseKey(coclass_key
);
126 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
129 /***********************************************************************
130 * unregister_coclasses
132 static HRESULT
unregister_coclasses(struct regsvr_coclass
const *list
)
134 LONG res
= ERROR_SUCCESS
;
137 res
= RegOpenKeyExW(HKEY_CLASSES_ROOT
, clsid_keyname
, 0,
138 KEY_READ
| KEY_WRITE
, &coclass_key
);
139 if (res
== ERROR_FILE_NOT_FOUND
) return S_OK
;
140 if (res
!= ERROR_SUCCESS
) goto error_return
;
142 for (; res
== ERROR_SUCCESS
&& list
->clsid
; ++list
) {
145 StringFromGUID2(list
->clsid
, buf
, 39);
146 res
= RegDeleteTreeW(coclass_key
, buf
);
147 if (res
== ERROR_FILE_NOT_FOUND
) res
= ERROR_SUCCESS
;
148 if (res
!= ERROR_SUCCESS
) goto error_close_coclass_key
;
151 error_close_coclass_key
:
152 RegCloseKey(coclass_key
);
154 return res
!= ERROR_SUCCESS
? HRESULT_FROM_WIN32(res
) : S_OK
;
157 /***********************************************************************
160 static struct regsvr_coclass
const coclass_list
[] = {
161 { &CLSID_MMDeviceEnumerator
,
162 "MMDeviceEnumerator class",
166 { NULL
} /* list terminator */
169 HRESULT WINAPI
DllRegisterServer(void)
173 return register_coclasses(coclass_list
);
176 HRESULT WINAPI
DllUnregisterServer(void)
180 return unregister_coclasses(coclass_list
);