home *** CD-ROM | disk | FTP | other *** search
/ Beginning Direct3D Game Programming / Direct3D.iso / directx / dxf / samples / multimedia / directinput / diconfig / registry.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2000-09-22  |  8.4 KB  |  311 lines

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