1 | /*
|
---|
2 | * Regster/Unregister servers. (for internal use)
|
---|
3 | *
|
---|
4 | * hidenori@a2.ctktv.ne.jp
|
---|
5 | */
|
---|
6 |
|
---|
7 | #include "config.h"
|
---|
8 |
|
---|
9 | #include "windef.h"
|
---|
10 | #include "winbase.h"
|
---|
11 | #include "wingdi.h"
|
---|
12 | #include "winuser.h"
|
---|
13 | #include "winerror.h"
|
---|
14 | #include "winreg.h"
|
---|
15 | #include "uuids.h"
|
---|
16 | #include "wine/unicode.h"
|
---|
17 |
|
---|
18 | #include "debugtools.h"
|
---|
19 | DEFAULT_DEBUG_CHANNEL(quartz);
|
---|
20 |
|
---|
21 | #include "regsvr.h"
|
---|
22 |
|
---|
23 | #ifndef NUMELEMS
|
---|
24 | #define NUMELEMS(elem) (sizeof(elem)/sizeof((elem)[0]))
|
---|
25 | #endif /* NUMELEMS */
|
---|
26 |
|
---|
27 | const WCHAR QUARTZ_wszREG_SZ[] =
|
---|
28 | {'R','E','G','_','S','Z',0};
|
---|
29 | const WCHAR QUARTZ_wszInprocServer32[] =
|
---|
30 | {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
|
---|
31 | const WCHAR QUARTZ_wszThreadingModel[] =
|
---|
32 | {'T','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
|
---|
33 | const WCHAR QUARTZ_wszBoth[] =
|
---|
34 | {'B','o','t','h',0};
|
---|
35 | const WCHAR QUARTZ_wszCLSID[] =
|
---|
36 | {'C','L','S','I','D',0};
|
---|
37 | const WCHAR QUARTZ_wszFilterData[] =
|
---|
38 | {'F','i','l','t','e','r',' ','D','a','t','a',0};
|
---|
39 | const WCHAR QUARTZ_wszFriendlyName[] =
|
---|
40 | {'F','r','i','e','n','d','l','y','N','a','m','e',0};
|
---|
41 | const WCHAR QUARTZ_wszInstance[] =
|
---|
42 | {'I','n','s','t','a','n','c','e',0};
|
---|
43 | const WCHAR QUARTZ_wszMerit[] =
|
---|
44 | {'M','e','r','i','t',0};
|
---|
45 |
|
---|
46 | static
|
---|
47 | void QUARTZ_CatPathSepW( WCHAR* pBuf )
|
---|
48 | {
|
---|
49 | int len = strlenW(pBuf);
|
---|
50 | pBuf[len] = '\\';
|
---|
51 | pBuf[len+1] = 0;
|
---|
52 | }
|
---|
53 |
|
---|
54 | static
|
---|
55 | void QUARTZ_GUIDtoString( WCHAR* pBuf, const GUID* pguid )
|
---|
56 | {
|
---|
57 | /* W"{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}" */
|
---|
58 | static const WCHAR wszFmt[] =
|
---|
59 | {'{','%','0','8','X','-','%','0','4','X','-','%','0','4','X',
|
---|
60 | '-','%','0','2','X','%','0','2','X','-','%','0','2','X','%',
|
---|
61 | '0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
|
---|
62 | '%','0','2','X','}',0};
|
---|
63 |
|
---|
64 | wsprintfW( pBuf, wszFmt,
|
---|
65 | pguid->Data1, pguid->Data2, pguid->Data3,
|
---|
66 | pguid->Data4[0], pguid->Data4[1],
|
---|
67 | pguid->Data4[2], pguid->Data4[3],
|
---|
68 | pguid->Data4[4], pguid->Data4[5],
|
---|
69 | pguid->Data4[6], pguid->Data4[7] );
|
---|
70 | }
|
---|
71 |
|
---|
72 | static
|
---|
73 | LONG QUARTZ_RegOpenKeyW(
|
---|
74 | HKEY hkRoot, LPCWSTR lpszPath,
|
---|
75 | REGSAM rsAccess, HKEY* phKey,
|
---|
76 | BOOL fCreateKey )
|
---|
77 | {
|
---|
78 | DWORD dwDisp;
|
---|
79 | WCHAR wszREG_SZ[ NUMELEMS(QUARTZ_wszREG_SZ) ];
|
---|
80 |
|
---|
81 | memcpy(wszREG_SZ,QUARTZ_wszREG_SZ,sizeof(QUARTZ_wszREG_SZ) );
|
---|
82 |
|
---|
83 | if ( fCreateKey )
|
---|
84 | return RegCreateKeyExW(
|
---|
85 | hkRoot, lpszPath, 0, wszREG_SZ,
|
---|
86 | REG_OPTION_NON_VOLATILE, rsAccess, NULL, phKey, &dwDisp );
|
---|
87 | else
|
---|
88 | return RegOpenKeyExW(
|
---|
89 | hkRoot, lpszPath, 0, rsAccess, phKey );
|
---|
90 | }
|
---|
91 |
|
---|
92 | static
|
---|
93 | LONG QUARTZ_RegSetValueString(
|
---|
94 | HKEY hKey, LPCWSTR lpszName, LPCWSTR lpValue )
|
---|
95 | {
|
---|
96 | return RegSetValueExW(
|
---|
97 | hKey, lpszName, 0, REG_SZ,
|
---|
98 | (const BYTE*)lpValue,
|
---|
99 | sizeof(lpValue[0]) * (strlenW(lpValue)+1) );
|
---|
100 | }
|
---|
101 |
|
---|
102 | static
|
---|
103 | LONG QUARTZ_RegSetValueDWord(
|
---|
104 | HKEY hKey, LPCWSTR lpszName, DWORD dwValue )
|
---|
105 | {
|
---|
106 | return RegSetValueExW(
|
---|
107 | hKey, lpszName, 0, REG_DWORD,
|
---|
108 | (const BYTE*)(&dwValue), sizeof(DWORD) );
|
---|
109 | }
|
---|
110 |
|
---|
111 | static
|
---|
112 | LONG QUARTZ_RegSetValueBinary(
|
---|
113 | HKEY hKey, LPCWSTR lpszName,
|
---|
114 | const BYTE* pData, int iLenOfData )
|
---|
115 | {
|
---|
116 | return RegSetValueExW(
|
---|
117 | hKey, lpszName, 0, REG_BINARY, pData, iLenOfData );
|
---|
118 | }
|
---|
119 |
|
---|
120 | HRESULT QUARTZ_CreateCLSIDPath(
|
---|
121 | WCHAR* pwszBuf, DWORD dwBufLen,
|
---|
122 | const CLSID* pclsid,
|
---|
123 | LPCWSTR lpszPathFromCLSID )
|
---|
124 | {
|
---|
125 | int avail;
|
---|
126 |
|
---|
127 | strcpyW( pwszBuf, QUARTZ_wszCLSID );
|
---|
128 | QUARTZ_CatPathSepW( pwszBuf+5 );
|
---|
129 | QUARTZ_GUIDtoString( pwszBuf+6, pclsid );
|
---|
130 | if ( lpszPathFromCLSID != NULL )
|
---|
131 | {
|
---|
132 | avail = (int)dwBufLen - strlenW(pwszBuf) - 8;
|
---|
133 | if ( avail <= strlenW(lpszPathFromCLSID) )
|
---|
134 | return E_FAIL;
|
---|
135 | QUARTZ_CatPathSepW( pwszBuf );
|
---|
136 | strcatW( pwszBuf, lpszPathFromCLSID );
|
---|
137 | }
|
---|
138 |
|
---|
139 | return NOERROR;
|
---|
140 | }
|
---|
141 |
|
---|
142 | HRESULT QUARTZ_OpenCLSIDKey(
|
---|
143 | HKEY* phKey, /* [OUT] hKey */
|
---|
144 | REGSAM rsAccess, /* [IN] access */
|
---|
145 | BOOL fCreate, /* TRUE = RegCreateKey, FALSE = RegOpenKey */
|
---|
146 | const CLSID* pclsid, /* CLSID */
|
---|
147 | LPCWSTR lpszPathFromCLSID ) /* related path from CLSID */
|
---|
148 | {
|
---|
149 | WCHAR szKey[ 1024 ];
|
---|
150 | HRESULT hr;
|
---|
151 | LONG lr;
|
---|
152 |
|
---|
153 | hr = QUARTZ_CreateCLSIDPath(
|
---|
154 | szKey, NUMELEMS(szKey),
|
---|
155 | pclsid, lpszPathFromCLSID );
|
---|
156 | if ( FAILED(hr) )
|
---|
157 | return hr;
|
---|
158 |
|
---|
159 | lr = QUARTZ_RegOpenKeyW(
|
---|
160 | HKEY_CLASSES_ROOT, szKey, rsAccess, phKey, fCreate );
|
---|
161 | if ( lr != ERROR_SUCCESS )
|
---|
162 | return E_FAIL;
|
---|
163 |
|
---|
164 | return S_OK;
|
---|
165 | }
|
---|
166 |
|
---|
167 |
|
---|
168 |
|
---|
169 | HRESULT QUARTZ_RegisterAMovieDLLServer(
|
---|
170 | const CLSID* pclsid, /* [IN] CLSID */
|
---|
171 | LPCWSTR lpFriendlyName, /* [IN] Friendly name */
|
---|
172 | LPCWSTR lpNameOfDLL, /* [IN] name of the registered DLL */
|
---|
173 | BOOL fRegister ) /* [IN] TRUE = register, FALSE = unregister */
|
---|
174 | {
|
---|
175 | HRESULT hr;
|
---|
176 | HKEY hKey;
|
---|
177 |
|
---|
178 | if ( fRegister )
|
---|
179 | {
|
---|
180 | hr = QUARTZ_OpenCLSIDKey(
|
---|
181 | &hKey, KEY_ALL_ACCESS, TRUE,
|
---|
182 | pclsid, NULL );
|
---|
183 | if ( FAILED(hr) )
|
---|
184 | return hr;
|
---|
185 |
|
---|
186 | if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString(
|
---|
187 | hKey, NULL, lpFriendlyName ) != ERROR_SUCCESS )
|
---|
188 | hr = E_FAIL;
|
---|
189 |
|
---|
190 | RegCloseKey( hKey );
|
---|
191 | if ( FAILED(hr) )
|
---|
192 | return hr;
|
---|
193 |
|
---|
194 | hr = QUARTZ_OpenCLSIDKey(
|
---|
195 | &hKey, KEY_ALL_ACCESS, TRUE,
|
---|
196 | pclsid, QUARTZ_wszInprocServer32 );
|
---|
197 | if ( FAILED(hr) )
|
---|
198 | return hr;
|
---|
199 |
|
---|
200 | if ( QUARTZ_RegSetValueString(
|
---|
201 | hKey, NULL, lpNameOfDLL ) != ERROR_SUCCESS )
|
---|
202 | hr = E_FAIL;
|
---|
203 | if ( QUARTZ_RegSetValueString(
|
---|
204 | hKey, QUARTZ_wszThreadingModel,
|
---|
205 | QUARTZ_wszBoth ) != ERROR_SUCCESS )
|
---|
206 | hr = E_FAIL;
|
---|
207 |
|
---|
208 | RegCloseKey( hKey );
|
---|
209 | if ( FAILED(hr) )
|
---|
210 | return hr;
|
---|
211 | }
|
---|
212 | else
|
---|
213 | {
|
---|
214 | hr = QUARTZ_OpenCLSIDKey(
|
---|
215 | &hKey, KEY_ALL_ACCESS, FALSE,
|
---|
216 | pclsid, NULL );
|
---|
217 | if ( FAILED(hr) )
|
---|
218 | return NOERROR;
|
---|
219 |
|
---|
220 | RegDeleteValueW( hKey, NULL );
|
---|
221 | RegDeleteValueW( hKey, QUARTZ_wszThreadingModel );
|
---|
222 |
|
---|
223 | RegCloseKey( hKey );
|
---|
224 | if ( FAILED(hr) )
|
---|
225 | return hr;
|
---|
226 |
|
---|
227 | /* I think key should be deleted only if no subkey exists. */
|
---|
228 | FIXME( "unregister %s - key should be removed!\n",
|
---|
229 | debugstr_guid(pclsid) );
|
---|
230 | }
|
---|
231 |
|
---|
232 | return NOERROR;
|
---|
233 | }
|
---|
234 |
|
---|
235 |
|
---|
236 | HRESULT QUARTZ_RegisterCategory(
|
---|
237 | const CLSID* pguidFilterCategory, /* [IN] Category */
|
---|
238 | LPCWSTR lpFriendlyName, /* [IN] friendly name */
|
---|
239 | DWORD dwMerit, /* [IN] merit */
|
---|
240 | BOOL fRegister ) /* [IN] TRUE = register, FALSE = unregister */
|
---|
241 | {
|
---|
242 | HRESULT hr;
|
---|
243 | HKEY hKey;
|
---|
244 | WCHAR szFilterPath[ 256 ];
|
---|
245 | WCHAR szCLSID[ 256 ];
|
---|
246 |
|
---|
247 | QUARTZ_GUIDtoString( szCLSID, pguidFilterCategory );
|
---|
248 | strcpyW( szFilterPath, QUARTZ_wszInstance );
|
---|
249 | QUARTZ_CatPathSepW( szFilterPath );
|
---|
250 | strcatW( szFilterPath, szCLSID );
|
---|
251 |
|
---|
252 | if ( fRegister )
|
---|
253 | {
|
---|
254 | hr = QUARTZ_OpenCLSIDKey(
|
---|
255 | &hKey, KEY_ALL_ACCESS, TRUE,
|
---|
256 | &CLSID_ActiveMovieCategories, szFilterPath );
|
---|
257 | if ( FAILED(hr) )
|
---|
258 | return hr;
|
---|
259 |
|
---|
260 | if ( QUARTZ_RegSetValueString(
|
---|
261 | hKey, QUARTZ_wszCLSID, szCLSID ) != ERROR_SUCCESS )
|
---|
262 | hr = E_FAIL;
|
---|
263 | if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString(
|
---|
264 | hKey, QUARTZ_wszFriendlyName,
|
---|
265 | lpFriendlyName ) != ERROR_SUCCESS )
|
---|
266 | hr = E_FAIL;
|
---|
267 | if ( dwMerit != 0 &&
|
---|
268 | QUARTZ_RegSetValueDWord(
|
---|
269 | hKey, QUARTZ_wszMerit, dwMerit ) != ERROR_SUCCESS )
|
---|
270 | hr = E_FAIL;
|
---|
271 |
|
---|
272 | RegCloseKey( hKey );
|
---|
273 | if ( FAILED(hr) )
|
---|
274 | return hr;
|
---|
275 | }
|
---|
276 | else
|
---|
277 | {
|
---|
278 | hr = QUARTZ_OpenCLSIDKey(
|
---|
279 | &hKey, KEY_ALL_ACCESS, FALSE,
|
---|
280 | &CLSID_ActiveMovieCategories, szFilterPath );
|
---|
281 | if ( FAILED(hr) )
|
---|
282 | return NOERROR;
|
---|
283 |
|
---|
284 | RegDeleteValueW( hKey, QUARTZ_wszCLSID );
|
---|
285 | RegDeleteValueW( hKey, QUARTZ_wszFriendlyName );
|
---|
286 | RegDeleteValueW( hKey, QUARTZ_wszMerit );
|
---|
287 |
|
---|
288 | RegCloseKey( hKey );
|
---|
289 | if ( FAILED(hr) )
|
---|
290 | return hr;
|
---|
291 |
|
---|
292 | /* I think key should be deleted only if no subkey exists. */
|
---|
293 | FIXME( "unregister category %s - key should be removed!\n",
|
---|
294 | debugstr_guid(pguidFilterCategory) );
|
---|
295 | }
|
---|
296 |
|
---|
297 | return NOERROR;
|
---|
298 | }
|
---|
299 |
|
---|
300 |
|
---|
301 | HRESULT QUARTZ_RegisterAMovieFilter(
|
---|
302 | const CLSID* pguidFilterCategory, /* [IN] Category */
|
---|
303 | const CLSID* pclsid, /* [IN] CLSID of this filter */
|
---|
304 | const BYTE* pbFilterData, /* [IN] filter data(no spec) */
|
---|
305 | DWORD cbFilterData, /* [IN] size of the filter data */
|
---|
306 | LPCWSTR lpFriendlyName, /* [IN] friendly name */
|
---|
307 | LPCWSTR lpInstance, /* [IN] instance */
|
---|
308 | BOOL fRegister ) /* [IN] TRUE = register, FALSE = unregister */
|
---|
309 | {
|
---|
310 | HRESULT hr;
|
---|
311 | HKEY hKey;
|
---|
312 | WCHAR szFilterPath[ 256 ];
|
---|
313 | WCHAR szCLSID[ 256 ];
|
---|
314 |
|
---|
315 | QUARTZ_GUIDtoString( szCLSID, pclsid );
|
---|
316 | strcpyW( szFilterPath, QUARTZ_wszInstance );
|
---|
317 | QUARTZ_CatPathSepW( szFilterPath );
|
---|
318 | strcatW( szFilterPath, ( lpInstance != NULL ) ? lpInstance : szCLSID );
|
---|
319 |
|
---|
320 | if ( fRegister )
|
---|
321 | {
|
---|
322 | hr = QUARTZ_OpenCLSIDKey(
|
---|
323 | &hKey, KEY_ALL_ACCESS, TRUE,
|
---|
324 | pguidFilterCategory, szFilterPath );
|
---|
325 | if ( FAILED(hr) )
|
---|
326 | return hr;
|
---|
327 |
|
---|
328 | if ( QUARTZ_RegSetValueString(
|
---|
329 | hKey, QUARTZ_wszCLSID, szCLSID ) != ERROR_SUCCESS )
|
---|
330 | hr = E_FAIL;
|
---|
331 | if ( pbFilterData != NULL && cbFilterData > 0 &&
|
---|
332 | QUARTZ_RegSetValueBinary(
|
---|
333 | hKey, QUARTZ_wszFilterData,
|
---|
334 | pbFilterData, cbFilterData ) != ERROR_SUCCESS )
|
---|
335 | hr = E_FAIL;
|
---|
336 | if ( lpFriendlyName != NULL && QUARTZ_RegSetValueString(
|
---|
337 | hKey, QUARTZ_wszFriendlyName,
|
---|
338 | lpFriendlyName ) != ERROR_SUCCESS )
|
---|
339 | hr = E_FAIL;
|
---|
340 |
|
---|
341 | RegCloseKey( hKey );
|
---|
342 | if ( FAILED(hr) )
|
---|
343 | return hr;
|
---|
344 | }
|
---|
345 | else
|
---|
346 | {
|
---|
347 | hr = QUARTZ_OpenCLSIDKey(
|
---|
348 | &hKey, KEY_ALL_ACCESS, FALSE,
|
---|
349 | pguidFilterCategory, szFilterPath );
|
---|
350 | if ( FAILED(hr) )
|
---|
351 | return NOERROR;
|
---|
352 |
|
---|
353 | RegDeleteValueW( hKey, QUARTZ_wszCLSID );
|
---|
354 | RegDeleteValueW( hKey, QUARTZ_wszFilterData );
|
---|
355 | RegDeleteValueW( hKey, QUARTZ_wszFriendlyName );
|
---|
356 |
|
---|
357 | RegCloseKey( hKey );
|
---|
358 | if ( FAILED(hr) )
|
---|
359 | return hr;
|
---|
360 |
|
---|
361 | /* I think key should be deleted only if no subkey exists. */
|
---|
362 | FIXME( "unregister category %s filter %s - key should be removed!\n",
|
---|
363 | debugstr_guid(pguidFilterCategory),
|
---|
364 | debugstr_guid(pclsid) );
|
---|
365 | }
|
---|
366 |
|
---|
367 | return NOERROR;
|
---|
368 | }
|
---|
369 |
|
---|
370 |
|
---|
371 |
|
---|