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