Correct dependency syntax and autoconf
[shibboleth/sp.git] / isapi_shib_gui / registry.Cpp
1 //==============================================================;
2 //
3 //  This source code is only intended as a supplement to existing Microsoft documentation.
4 //
5 //
6 //
7 //
8 //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
9 //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
10 //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
11 //  PURPOSE.
12 //
13 //  Copyright (C) 1999 - 2001 Microsoft Corporation.  All Rights Reserved.
14 //
15 //
16 //
17 //==============================================================;
18
19 #include <objbase.h>
20 #include <assert.h>
21 #include "Registry.h"
22 #include "Extend.h"
23 #include "GUIDs.h"
24 #include "globals.h"
25
26 // if not standalone comment out next line
27 //#define STANDALONE
28
29 // list all nodes that are extendable here
30 // List the GUID and then the description
31 // terminate with a NULL, NULL set.
32 EXTENSION_NODE _ExtendableNodes[] = {
33     {NULL, NULL}
34 };
35 // list all of the nodes that we extend
36 EXTENDER_NODE _NodeExtensions[] = 
37         PBC_EXTENDER_NODES;
38
39 ////////////////////////////////////////////////////////
40 //
41 // Internal helper functions prototypes
42 //
43
44 // Set the given key and its value.
45 BOOL setKeyAndValue(const _TCHAR* pszPath,
46                     const _TCHAR* szSubkey,
47                     const _TCHAR* szValue) ;
48
49 // Set the given key and its value in the MMC Snapin location
50 BOOL setSnapInKeyAndValue(const _TCHAR* szKey,
51                           const _TCHAR* szSubkey,
52                           const _TCHAR* szName,
53                           const _TCHAR* szValue);
54
55 // Set the given valuename under the key to value
56 BOOL setValue(const _TCHAR* szKey,
57               const _TCHAR* szValueName,
58               const _TCHAR* szValue);
59
60 BOOL setSnapInExtensionNode(const _TCHAR* szSnapID,
61                             const _TCHAR* szNodeID,
62                             const _TCHAR* szDescription);
63
64 // Delete szKeyChild and all of its descendents.
65 LONG recursiveDeleteKey(HKEY hKeyParent, const _TCHAR* szKeyChild) ;
66
67 ////////////////////////////////////////////////////////
68 //
69 // Constants
70 //
71
72 // Size of a CLSID as a string
73 //const int CLSID_STRING_SIZE = 39 ;
74
75 /////////////////////////////////////////////////////////
76 //
77 // Public function implementation
78 //
79
80 //
81 // Register the component in the registry.
82 //
83 HRESULT RegisterServer(HMODULE hModule,            // DLL module handle
84                        const CLSID& clsid,         // Class ID
85                        const _TCHAR* szFriendlyName)       //   IDs
86 {
87     // Get server location.
88     _TCHAR szModule[512] ;
89     DWORD dwResult =
90         ::GetModuleFileName(hModule,
91         szModule,
92         sizeof(szModule)/sizeof(_TCHAR)) ;
93
94     assert(dwResult != 0) ;
95
96     // Get CLSID
97     LPOLESTR wszCLSID = NULL ;
98     HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
99
100     assert(SUCCEEDED(hr)) ;
101
102     MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
103
104     // Build the key CLSID\\{...}
105     _TCHAR szKey[64] ;
106     _tcscpy(szKey, _T("CLSID\\")) ;
107         _tcscat(szKey, pszCLSID) ;
108
109     // Add the CLSID to the registry.
110     setKeyAndValue(szKey, NULL, szFriendlyName) ;
111
112     // Add the server filename subkey under the CLSID key.
113     setKeyAndValue(szKey, _T("InprocServer32"), szModule) ;
114
115     // set the threading model
116     _tcscat(szKey, _T("\\InprocServer32"));
117     setValue(szKey, _T("ThreadingModel"), _T("Apartment"));
118
119     // Free memory.
120     CoTaskMemFree(wszCLSID) ;
121
122     return S_OK ;
123 }
124
125 //
126 // Remove the component from the registry.
127 //
128 LONG UnregisterServer(const CLSID& clsid)       //   IDs
129 {
130     // Get CLSID
131     LPOLESTR wszCLSID = NULL ;
132     HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
133
134
135     // Build the key CLSID\\{...}
136     _TCHAR szKey[64] ;
137     _tcscpy(szKey, _T("CLSID\\")) ;
138
139     MAKE_TSTRPTR_FROMWIDE(pszT, wszCLSID);
140     _tcscat(szKey, pszT) ;
141
142     // Delete the CLSID Key - CLSID\{...}
143     LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
144     assert((lResult == ERROR_SUCCESS) ||
145                (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
146
147     // Free memory.
148     CoTaskMemFree(wszCLSID) ;
149
150     return S_OK ;
151 }
152
153 //
154 // Register the snap-in in the registry.
155 //
156 HRESULT RegisterSnapin(const CLSID& clsid,         // Class ID
157                        const _TCHAR* szNameString)
158 {
159     // Get CLSID
160     LPOLESTR wszCLSID = NULL ;
161     LPOLESTR wszAboutCLSID = NULL;
162     LPOLESTR wszExtendCLSID = NULL;
163     LPOLESTR wszNodeCLSID = NULL;
164     EXTENSION_NODE *pExtensionNode;
165     EXTENDER_NODE *pNodeExtension;
166     _TCHAR szKeyBuf[1024] ;
167     HKEY hKey;
168
169     HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
170
171     MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
172
173     // Add the CLSID to the registry.
174     setSnapInKeyAndValue(pszCLSID, NULL, _T("NameString"), szNameString) ;
175
176 #ifdef STANDALONE
177     setSnapInKeyAndValue(pszCLSID, _T("StandAlone"), NULL, NULL);
178 #endif
179
180     // register each of the node types in _ExtendableNodes as an extendable node
181     for (pExtensionNode = &(_ExtendableNodes[0]);*pExtensionNode->szDescription;pExtensionNode++)
182     {
183         hr = StringFromCLSID(pExtensionNode->GUID, &wszExtendCLSID);
184         MAKE_TSTRPTR_FROMWIDE(pszExtendCLSID, wszExtendCLSID);
185         setSnapInExtensionNode(pszCLSID, pszExtendCLSID, pExtensionNode->szDescription);
186         CoTaskMemFree(wszExtendCLSID);
187     }
188
189     // register each of the node extensions
190     for (pNodeExtension = &(_NodeExtensions[0]);*pNodeExtension->szDescription;pNodeExtension++)
191     {
192         hr = StringFromCLSID(pNodeExtension->guidNode, &wszExtendCLSID);
193         MAKE_TSTRPTR_FROMWIDE(pszExtendCLSID, wszExtendCLSID);
194         _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes\\"));
195         _tcscat(szKeyBuf, pszExtendCLSID);
196
197         switch (pNodeExtension->eType) {
198         case NameSpaceExtension:
199             _tcscat(szKeyBuf, _T("\\Extensions\\NameSpace"));
200             break;
201         case ContextMenuExtension:
202             _tcscat(szKeyBuf, _T("\\Extensions\\ContextMenu"));
203             break;
204         case ToolBarExtension:
205             _tcscat(szKeyBuf, _T("\\Extensions\\ToolBar"));
206             break;
207         case PropertySheetExtension:
208             _tcscat(szKeyBuf, _T("\\Extensions\\PropertySheet"));
209             break;
210         case TaskExtension:
211             _tcscat(szKeyBuf, _T("\\Extensions\\Task"));
212             break;
213         case DynamicExtension:
214             _tcscat(szKeyBuf, _T("\\Dynamic Extensions"));
215         default:
216             break;
217         }
218
219         // Create and open key and subkey.
220         long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
221             szKeyBuf,
222             0, NULL, REG_OPTION_NON_VOLATILE,
223             KEY_ALL_ACCESS, NULL,
224             &hKey, NULL) ;
225
226         if (lResult != ERROR_SUCCESS)
227         {
228             return FALSE ;
229         }
230
231         hr = StringFromCLSID(pNodeExtension->guidExtension, &wszNodeCLSID);
232         assert(SUCCEEDED(hr));
233
234         MAKE_TSTRPTR_FROMWIDE(pszNodeCLSID, wszNodeCLSID);
235         // Set the Value.
236         if (pNodeExtension->szDescription != NULL)
237         {
238             RegSetValueEx(hKey, pszNodeCLSID, 0, REG_SZ,
239                 (BYTE *)pNodeExtension->szDescription,
240                 (_tcslen(pNodeExtension->szDescription)+1)*sizeof(_TCHAR)) ;
241         }
242
243         RegCloseKey(hKey) ;
244
245         CoTaskMemFree(wszExtendCLSID);
246         CoTaskMemFree(wszNodeCLSID);
247     }
248
249
250     // Free memory.
251     CoTaskMemFree(wszCLSID) ;
252     return S_OK ;
253 }
254
255 //
256 // Unregister the snap-in in the registry.
257 //
258 HRESULT UnregisterSnapin(const CLSID& clsid)         // Class ID
259 {
260     _TCHAR szKeyBuf[1024];
261     LPOLESTR wszCLSID = NULL;
262
263     // Get CLSID
264     HRESULT hr = StringFromCLSID(clsid, &wszCLSID);
265         MAKE_TSTRPTR_FROMWIDE(pszCLSID, wszCLSID);
266     // Load the buffer with the Snap-In Location
267     _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns"));
268
269     // Copy keyname into buffer.
270     _tcscat(szKeyBuf, _T("\\"));
271     _tcscat(szKeyBuf, pszCLSID);
272
273     // Delete the CLSID Key - CLSID\{...}
274     LONG lResult = recursiveDeleteKey(HKEY_LOCAL_MACHINE, szKeyBuf);
275     assert((lResult == ERROR_SUCCESS) ||
276                (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
277
278         //Uncomment following for loop to unregister all extendable node types
279         //Note that if a snap-in's extendable node types are unregistered,
280         //any extension snap-ins for these node types will have to be re-registered
281         //in order to rebuild their entries under the SOFTWARE\Microsoft\MMC\NodeTypes key
282
283 /*
284     // Unregister each of the node types in _ExtendableNodes as an extendable node
285         // Note that this snap-in does not register any extendable node types
286
287     EXTENSION_NODE *pNode;
288         LPOLESTR wszExtendCLSID = NULL;
289
290     for (pNode = &(_ExtendableNodes[0]);*pNode->szDescription;pNode++)
291     {
292         hr = StringFromCLSID(pNode->GUID, &wszExtendCLSID);
293         MAKE_TSTRPTR_FROMWIDE(pszExtendCLSID, wszExtendCLSID);
294
295         // Load the buffer with the Snap-In Location
296         _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes\\"));
297         // Copy keyname into buffer.
298         _tcscat(szKeyBuf, pszExtendCLSID);
299         recursiveDeleteKey(HKEY_LOCAL_MACHINE, szKeyBuf);
300         CoTaskMemFree(wszExtendCLSID);
301     }
302
303 */
304
305     // free the memory
306     CoTaskMemFree(wszCLSID);
307
308     return S_OK;
309 }
310
311 //
312 // Delete a key and all of its descendents.
313 //
314 LONG recursiveDeleteKey(HKEY hKeyParent,           // Parent of key to delete
315                         const _TCHAR* lpszKeyChild)  // Key to delete
316 {
317     // Open the child.
318     HKEY hKeyChild ;
319     LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0,
320         KEY_ALL_ACCESS, &hKeyChild) ;
321     if (lRes != ERROR_SUCCESS)
322     {
323         return lRes ;
324     }
325
326     // Enumerate all of the decendents of this child.
327     FILETIME time ;
328     _TCHAR szBuffer[256] ;
329     DWORD dwSize = 256 ;
330     while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
331         NULL, NULL, &time) == S_OK)
332     {
333         // Delete the decendents of this child.
334         lRes = recursiveDeleteKey(hKeyChild, szBuffer) ;
335         if (lRes != ERROR_SUCCESS)
336         {
337             // Cleanup before exiting.
338             RegCloseKey(hKeyChild) ;
339             return lRes;
340         }
341         dwSize = 256 ;
342     }
343
344     // Close the child.
345     RegCloseKey(hKeyChild) ;
346
347     // Delete this child.
348     return RegDeleteKey(hKeyParent, lpszKeyChild) ;
349 }
350
351 //
352 // Create a key and set its value.
353 //   - This helper function was borrowed and modifed from
354 //     Kraig Brockschmidt's book Inside OLE.
355 //
356 BOOL setKeyAndValue(const _TCHAR* szKey,
357                     const _TCHAR* szSubkey,
358                     const _TCHAR* szValue)
359 {
360     HKEY hKey;
361     _TCHAR szKeyBuf[1024] ;
362
363     // Copy keyname into buffer.
364     _tcscpy(szKeyBuf, szKey) ;
365
366     // Add subkey name to buffer.
367     if (szSubkey != NULL)
368     {
369         _tcscat(szKeyBuf, _T("\\")) ;
370         _tcscat(szKeyBuf, szSubkey ) ;
371     }
372
373     // Create and open key and subkey.
374     long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
375         szKeyBuf,
376         0, NULL, REG_OPTION_NON_VOLATILE,
377         KEY_ALL_ACCESS, NULL,
378         &hKey, NULL) ;
379     if (lResult != ERROR_SUCCESS)
380     {
381         return FALSE ;
382     }
383
384     // Set the Value.
385     if (szValue != NULL)
386     {
387         RegSetValueEx(hKey, NULL, 0, REG_SZ,
388             (BYTE *)szValue,
389             (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
390     }
391
392     RegCloseKey(hKey) ;
393     return TRUE ;
394 }
395
396 //
397 // Open a key value and set it
398 //
399 BOOL setValue(const _TCHAR* szKey,
400               const _TCHAR* szValueName,
401               const _TCHAR* szValue)
402 {
403     HKEY hKey;
404     _TCHAR szKeyBuf[1024] ;
405
406     // Copy keyname into buffer.
407     _tcscpy(szKeyBuf, szKey) ;
408
409     // Create and open key and subkey.
410     long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT ,
411         szKeyBuf,
412         0, NULL, REG_OPTION_NON_VOLATILE,
413         KEY_ALL_ACCESS, NULL,
414         &hKey, NULL) ;
415     if (lResult != ERROR_SUCCESS)
416     {
417         return FALSE ;
418     }
419
420     // Set the Value.
421     if (szValue != NULL)
422     {
423         RegSetValueEx(hKey, szValueName, 0, REG_SZ,
424             (BYTE *)szValue,
425             (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
426     }
427
428     RegCloseKey(hKey) ;
429     return TRUE ;
430 }
431
432
433 //
434 // Create a key and set its value.
435 //   - This helper function was borrowed and modifed from
436 //     Kraig Brockschmidt's book Inside OLE.
437 //
438 BOOL setSnapInKeyAndValue(const _TCHAR* szKey,
439                           const _TCHAR* szSubkey,
440                           const _TCHAR* szName,
441                           const _TCHAR* szValue)
442 {
443     HKEY hKey;
444     _TCHAR szKeyBuf[1024] ;
445
446     // Load the buffer with the Snap-In Location
447     _tcscpy(szKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns"));
448
449     // Copy keyname into buffer.
450     _tcscat(szKeyBuf, _T("\\")) ;
451     _tcscat(szKeyBuf, szKey) ;
452
453     // Add subkey name to buffer.
454     if (szSubkey != NULL)
455     {
456         _tcscat(szKeyBuf, _T("\\")) ;
457         _tcscat(szKeyBuf, szSubkey ) ;
458     }
459
460     // Create and open key and subkey.
461     long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
462         szKeyBuf,
463         0, NULL, REG_OPTION_NON_VOLATILE,
464         KEY_ALL_ACCESS, NULL,
465         &hKey, NULL) ;
466     if (lResult != ERROR_SUCCESS)
467     {
468         return FALSE ;
469     }
470
471     // Set the Value.
472     if (szValue != NULL)
473     {
474         RegSetValueEx(hKey, szName, 0, REG_SZ,
475             (BYTE *)szValue,
476             (_tcslen(szValue)+1)*sizeof(_TCHAR)) ;
477     }
478
479     RegCloseKey(hKey) ;
480     return TRUE ;
481 }
482
483 BOOL setSnapInExtensionNode(const _TCHAR* szSnapID,
484                             const _TCHAR* szNodeID,
485                             const _TCHAR* szDescription)
486 {
487     HKEY hKey;
488     _TCHAR szSnapNodeKeyBuf[1024] ;
489     _TCHAR szMMCNodeKeyBuf[1024];
490
491     // Load the buffer with the Snap-In Location
492     _tcscpy(szSnapNodeKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\SnapIns\\"));
493     // add in the clisid into buffer.
494     _tcscat(szSnapNodeKeyBuf, szSnapID) ;
495     _tcscat(szSnapNodeKeyBuf, _T("\\NodeTypes\\"));
496     _tcscat(szSnapNodeKeyBuf, szNodeID) ;
497
498     // Load the buffer with the NodeTypes Location
499     _tcscpy(szMMCNodeKeyBuf, _T("SOFTWARE\\Microsoft\\MMC\\NodeTypes\\"));
500     _tcscat(szMMCNodeKeyBuf, szNodeID) ;
501
502     // Create and open the Snapin Key.
503     long lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
504         szSnapNodeKeyBuf,
505         0, NULL, REG_OPTION_NON_VOLATILE,
506         KEY_ALL_ACCESS, NULL,
507         &hKey, NULL) ;
508     if (lResult != ERROR_SUCCESS)
509     {
510         return FALSE ;
511     }
512
513     // Set the Value.
514     if (szDescription != NULL)
515     {
516         RegSetValueEx(hKey, NULL, 0, REG_SZ,
517             (BYTE *)szDescription,
518             (_tcslen(szDescription)+1)*sizeof(_TCHAR)) ;
519     }
520
521     RegCloseKey(hKey) ;
522
523     // Create and open the NodeTypes Key.
524     lResult = RegCreateKeyEx(HKEY_LOCAL_MACHINE ,
525         szMMCNodeKeyBuf,
526         0, NULL, REG_OPTION_NON_VOLATILE,
527         KEY_ALL_ACCESS, NULL,
528         &hKey, NULL) ;
529     if (lResult != ERROR_SUCCESS)
530     {
531         return FALSE ;
532     }
533
534     // Set the Value.
535     if (szDescription != NULL)
536     {
537         RegSetValueEx(hKey, NULL, 0, REG_SZ,
538             (BYTE *)szDescription,
539             (_tcslen(szDescription)+1)*sizeof(_TCHAR)) ;
540     }
541
542     RegCloseKey(hKey) ;
543
544     return TRUE ;
545 }