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