home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / atl / atltangram / mfctangram / registry.cpp < prev    next >
C/C++ Source or Header  |  1998-03-26  |  8KB  |  303 lines

  1. // Registry.cpp -   Implementation of registry functions.
  2. //
  3. // This is a part of the Active Template Library.
  4. // Copyright (C) 1996-1998 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Active Template Library Reference and related
  9. // electronic documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Active Template Library product.
  12.  
  13. #include <objbase.h>
  14. #include <assert.h>
  15. #include "Registry.h"
  16. #include "util.h"
  17. #include "util.cpp"
  18.  
  19. ////////////////////////////////////////////////////////
  20. //
  21. // Internal helper functions prototypes
  22. //
  23.  
  24. // Set the given key and its value.
  25. BOOL setKeyAndValue(const char* pszPath,
  26.                     const char* szSubkey,
  27.                     const char* szValue,
  28.                     const char* szName = NULL) ;
  29.  
  30. // Convert a CLSID into a char string.
  31. void CLSIDtochar(   const CLSID& clsid,
  32.                     char* szCLSID,
  33.                     int length) ;
  34.  
  35. // Determine if a particular subkey exists.
  36. BOOL SubkeyExists(const char* pszPath,
  37.                   const char* szSubkey) ;
  38.  
  39. // Delete szKeyChild and all of its descendents.
  40. LONG recursiveDeleteKey(HKEY hKeyParent, const char* szKeyChild) ;
  41.  
  42. /////////////////////////////////////////////////////////
  43. //
  44. // Public function implementation
  45. //
  46. /////////////////////////////////////////////////////////
  47. //
  48. // Register the component in the registry.
  49. //
  50. HRESULT RegisterServer( HMODULE hModule,                // DLL module handle
  51.                         const CLSID& clsid,             // Class ID
  52.                         const char* szFriendlyName,     // Friendly Name
  53.                         const char* szVerIndProgID,     // Programmatic
  54.                         const char* szProgID)           //  IDs
  55. {
  56.     // Get server location.
  57.     char szModule[512] ;
  58.     DWORD dwResult =
  59.         ::GetModuleFileName(hModule,
  60.                             szModule,
  61.                             sizeof(szModule)/sizeof(char)) ;
  62.     assert(dwResult != 0) ;
  63.  
  64.     // Convert a CLSID into a char string.
  65.     char szCLSID[CLSID_STRING_SIZE] ;
  66.     CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  67.  
  68.     // Build the key CLSID\\{...}
  69.     char szKey[64] ;
  70.     strcpy(szKey, "CLSID\\");
  71.     strcat(szKey, szCLSID) ;
  72.  
  73.     // Add the CLSID to the registry.
  74.     setKeyAndValue(szKey, NULL, szFriendlyName) ;
  75.  
  76.     // Add server filename key
  77. #ifdef _OUTPROC_SERVER_
  78.     setKeyAndValue(szKey, "LocalServer32", szModule) ;
  79. #else
  80.     setKeyAndValue(szKey, "InprocServer32", szModule) ;
  81. #endif
  82.  
  83.     // Add the ProgID subkey under the CLSID key.
  84.     setKeyAndValue(szKey, "ProgID", szProgID) ;
  85.  
  86.     // Add the version-independent ProgID subkey under CLSID key.
  87.     setKeyAndValue( szKey, "VersionIndependentProgID",
  88.                     szVerIndProgID) ;
  89.  
  90.     // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT.
  91.     setKeyAndValue(szVerIndProgID, NULL, szFriendlyName);
  92.     setKeyAndValue(szVerIndProgID, "CLSID", szCLSID) ;
  93.     setKeyAndValue(szVerIndProgID, "CurVer", szProgID) ;
  94.  
  95.     // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT.
  96.     setKeyAndValue(szProgID, NULL, szFriendlyName);
  97.     setKeyAndValue(szProgID, "CLSID", szCLSID) ;
  98.  
  99.     return S_OK;
  100. }
  101.  
  102. /////////////////////////////////////////////////////////
  103. //
  104. // Remove the component from the registry.
  105. //
  106. LONG UnregisterServer(  const CLSID& clsid,
  107.                         const char* szVerIndProgID,
  108.                         const char* szProgID)
  109. {
  110.     // Convert the CLSID into a char.
  111.     char szCLSID[CLSID_STRING_SIZE] ;
  112.     CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ;
  113.  
  114.     // Build the key CLSID\\{...}
  115.     char szKey[80] ;
  116.     strcpy(szKey, "CLSID\\");
  117.     strcat(szKey, szCLSID) ;
  118.  
  119.     // Check for a another server for this component.
  120. #ifdef _OUTPROC_SERVER_
  121.     if (SubkeyExists(szKey, "InprocServer32"))
  122. #else
  123.     if (SubkeyExists(szKey, "LocalServer32"))
  124. #endif
  125.     {
  126.         // Delete only the path for this server.
  127. #ifdef _OUTPROC_SERVER_
  128.         strcat(szKey, "\\LocalServer32") ;
  129. #else
  130.         strcat(szKey, "\\InprocServer32") ;
  131. #endif
  132.         LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
  133.         assert(lResult == ERROR_SUCCESS) ;
  134.     }
  135.     else
  136.     {
  137.         // Delete all related keys.
  138.         // Delete the CLSID Key - CLSID\{...}
  139.         LONG lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ;
  140.         assert((lResult == ERROR_SUCCESS) ||
  141.                (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  142.  
  143.         // Delete the version-independent ProgID Key.
  144.         lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ;
  145.         assert((lResult == ERROR_SUCCESS) ||
  146.                (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  147.  
  148.         // Delete the ProgID key.
  149.         lResult = recursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ;
  150.         assert((lResult == ERROR_SUCCESS) ||
  151.                (lResult == ERROR_FILE_NOT_FOUND)) ; // Subkey may not exist.
  152.     }
  153.     return S_OK;
  154. }
  155.  
  156. ///////////////////////////////////////////////////////////
  157. //
  158. // Internal helper functions
  159. //
  160. /////////////////////////////////////////////////////////
  161. //
  162. // Convert a CLSID to a char string.
  163. //
  164. void CLSIDtochar(   const CLSID& clsid,
  165.                     char* szCLSID,
  166.                     int length)
  167. {
  168.     assert(length >= CLSID_STRING_SIZE) ;
  169.     // Get CLSID
  170.     LPOLESTR wszCLSID = NULL ;
  171.     HRESULT hr = StringFromCLSID(clsid, &wszCLSID) ;
  172.     assert(SUCCEEDED(hr)) ;
  173.  
  174.     // Convert from wide characters to non-wide characters.
  175.     wcstombs(szCLSID, wszCLSID, length);
  176.  
  177.     // Free memory.
  178.     CoTaskMemFree(wszCLSID) ;
  179. }
  180.  
  181. /////////////////////////////////////////////////////////
  182. //
  183. // Delete a key and all of its descendents.
  184. //
  185. LONG recursiveDeleteKey(HKEY hKeyParent,            // Parent of key to delete.
  186.                         const char* lpszKeyChild)   // Key to delete.
  187. {
  188.     // Open the child.
  189.     HKEY hKeyChild;
  190.     LONG lRes = RegOpenKeyEx(   hKeyParent, lpszKeyChild, 0,
  191.                                 KEY_ALL_ACCESS, &hKeyChild);
  192.     if (lRes != ERROR_SUCCESS)
  193.     {
  194.         return lRes;
  195.     }
  196.  
  197.     // Enumerate all of the decendents of this child.
  198.     FILETIME time;
  199.     char szBuffer[256];
  200.     DWORD dwSize = 256;
  201.     while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL,
  202.                         NULL, NULL, &time) == S_OK)
  203.     {
  204.         // Delete the decendents of this child.
  205.         lRes = recursiveDeleteKey(hKeyChild, szBuffer);
  206.         if (lRes != ERROR_SUCCESS)
  207.         {
  208.             // Cleanup before exiting.
  209.             RegCloseKey(hKeyChild);
  210.             return lRes;
  211.         }
  212.         dwSize = 256;
  213.     }
  214.  
  215.     // Close the child.
  216.     RegCloseKey(hKeyChild);
  217.  
  218.     // Delete this child.
  219.     return RegDeleteKey(hKeyParent, lpszKeyChild);
  220. }
  221.  
  222. /////////////////////////////////////////////////////////
  223. //
  224. // Determine if a particular subkey exists.
  225. //
  226. BOOL SubkeyExists(const char* pszPath,    // Path of key to check
  227.                   const char* szSubkey)   // Key to check
  228. {
  229.     HKEY hKey ;
  230.     char szKeyBuf[80] ;
  231.  
  232.     // Copy keyname into buffer.
  233.     strcpy(szKeyBuf, pszPath) ;
  234.  
  235.     // Add subkey name to buffer.
  236.     if (szSubkey != NULL)
  237.     {
  238.         strcat(szKeyBuf, "\\") ;
  239.         strcat(szKeyBuf, szSubkey ) ;
  240.     }
  241.  
  242.     // Determine if key exists by trying to open it.
  243.     LONG lResult = ::RegOpenKeyEx(HKEY_CLASSES_ROOT,
  244.                                   szKeyBuf,
  245.                                   0,
  246.                                   KEY_ALL_ACCESS,
  247.                                   &hKey) ;
  248.     if (lResult == ERROR_SUCCESS)
  249.     {
  250.         RegCloseKey(hKey) ;
  251.         return TRUE ;
  252.     }
  253.     return FALSE ;
  254. }
  255.  
  256. /////////////////////////////////////////////////////////
  257. //
  258. // Create a key and set its value.
  259. //
  260. // This helper function was borrowed and modifed from Kraig Brockschmidt's
  261. // book Inside OLE.
  262. //
  263. BOOL setKeyAndValue(const char* szKey,
  264.                     const char* szSubkey,
  265.                     const char* szValue,
  266.                     const char* szName)
  267. {
  268.     HKEY hKey;
  269.     char szKeyBuf[1024] ;
  270.  
  271.     // Copy keyname into buffer.
  272.     strcpy(szKeyBuf, szKey);
  273.  
  274.     // Add subkey name to buffer.
  275.     if (szSubkey != NULL)
  276.     {
  277.         strcat(szKeyBuf, "\\");
  278.         strcat(szKeyBuf, szSubkey );
  279.     }
  280.  
  281.     // Create and open key and subkey.
  282.     long lResult = RegCreateKeyEx(  HKEY_CLASSES_ROOT,
  283.                                     szKeyBuf,
  284.                                     0, NULL, REG_OPTION_NON_VOLATILE,
  285.                                     KEY_ALL_ACCESS, NULL,
  286.                                     &hKey, NULL) ;
  287.     if (lResult != ERROR_SUCCESS)
  288.     {
  289.         return FALSE ;
  290.     }
  291.  
  292.     // Set the Value.
  293.     if (szValue != NULL)
  294.     {
  295.          RegSetValueEx(hKey, szName, 0, REG_SZ,
  296.                             (BYTE *)szValue,
  297.                             strlen(szValue)+1);
  298.     }
  299.  
  300.     RegCloseKey(hKey);
  301.     return TRUE;
  302. }
  303.