#include #include #include "common.h" #include "registry.h" // Safe String #define STRSAFE_NO_DEPRECATE #include "strsafe.h" //////////////////////////////////////////////////////// // // Internal helper functions prototypes // #ifndef UNDER_CE // Set the given key and its value. BOOL SetKeyAndValue(const char* pszPath, const char* szSubkey, const char* szValue, const char* szName=NULL) ; // Convert a CLSID into a char string. void CLSIDtochar(const CLSID& clsid, char* szCLSID, int length) ; // Delete szKeyChild and all of its descendents. LONG RecursiveDeleteKey(HKEY hKeyParent, const char* szKeyChild) ; #else // UNDER_CE // Set the given key and its value. BOOL SetKeyAndValue(LPCTSTR pszPath, LPCTSTR szSubkey, LPCTSTR szValue, LPCTSTR szName=NULL) ; // Convert a CLSID into a char string. void CLSIDtochar(const CLSID& clsid, LPTSTR szCLSID, int length) ; // Delete szKeyChild and all of its descendents. LONG RecursiveDeleteKey(HKEY hKeyParent, LPCTSTR szKeyChild) ; #endif // UNDER_CE //////////////////////////////////////////////////////// // // Constants // // Size of a CLSID as a string const int CLSID_STRING_SIZE = 39 ; ///////////////////////////////////////////////////////// // // Public function implementation // // // Register the component in the registry. // #ifndef UNDER_CE HRESULT Register(HMODULE hModule, // DLL module handle const CLSID& clsid, // Class ID const char* szFriendlyName, // Friendly Name const char* szVerIndProgID, // Programmatic const char* szProgID) // IDs #else // UNDER_CE HRESULT Register(HMODULE hModule, // DLL module handle const CLSID& clsid, // Class ID LPCTSTR szFriendlyName, // Friendly Name LPCTSTR szVerIndProgID, // Programmatic LPCTSTR szProgID) // IDs #endif // UNDER_CE { // Get server location. #ifndef UNDER_CE char szModule[512] ; //DWORD dwResult = ::GetModuleFileName(hModule, szModule, sizeof(szModule)/sizeof(char)) ; #else // UNDER_CE TCHAR szModule[512]; //DWORD dwResult = ::GetModuleFileName(hModule, szModule, sizeof(szModule)/sizeof(TCHAR)) ; #endif // UNDER_CE // Convert the CLSID into a char. #ifndef UNDER_CE char szCLSID[CLSID_STRING_SIZE] ; CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ; #else // UNDER_CE TCHAR szCLSID[CLSID_STRING_SIZE]; CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR)); #endif // UNDER_CE // Build the key CLSID\\{...} #ifndef UNDER_CE char szKey[64] ; StringCchCopy(szKey, ARRAYSIZE(szKey), "CLSID\\") ; StringCchCat(szKey, ARRAYSIZE(szKey), szCLSID) ; #else // UNDER_CE TCHAR szKey[64] ; lstrcpy(szKey, TEXT("CLSID\\")) ; lstrcat(szKey, szCLSID) ; #endif // UNDER_CE // Add the CLSID to the registry. SetKeyAndValue(szKey, NULL, szFriendlyName) ; // Add the server filename subkey under the CLSID key. #ifndef UNDER_CE SetKeyAndValue(szKey, "InprocServer32", szModule) ; SetKeyAndValue(szKey, "InprocServer32", "Apartment", "ThreadingModel") ; #else // UNDER_CE SetKeyAndValue(szKey, TEXT("InprocServer32"), szModule) ; SetKeyAndValue(szKey, TEXT("InprocServer32"), TEXT("Apartment"), TEXT("ThreadingModel")) ; #endif // UNDER_CE // Add the ProgID subkey under the CLSID key. #ifndef UNDER_CE SetKeyAndValue(szKey, "ProgID", szProgID) ; #else // UNDER_CE SetKeyAndValue(szKey, TEXT("ProgID"), szProgID) ; #endif // UNDER_CE // Add the version-independent ProgID subkey under CLSID key. #ifndef UNDER_CE SetKeyAndValue(szKey, "VersionIndependentProgID", szVerIndProgID) ; #else // UNDER_CE SetKeyAndValue(szKey, TEXT("VersionIndependentProgID"), szVerIndProgID) ; #endif // UNDER_CE // Add the version-independent ProgID subkey under HKEY_CLASSES_ROOT. #ifndef UNDER_CE SetKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ; SetKeyAndValue(szVerIndProgID, "CLSID", szCLSID) ; SetKeyAndValue(szVerIndProgID, "CurVer", szProgID) ; #else // UNDER_CE SetKeyAndValue(szVerIndProgID, NULL, szFriendlyName) ; SetKeyAndValue(szVerIndProgID, TEXT("CLSID"), szCLSID) ; SetKeyAndValue(szVerIndProgID, TEXT("CurVer"), szProgID) ; #endif // UNDER_CE // Add the versioned ProgID subkey under HKEY_CLASSES_ROOT. #ifndef UNDER_CE SetKeyAndValue(szProgID, NULL, szFriendlyName) ; SetKeyAndValue(szProgID, "CLSID", szCLSID) ; #else // UNDER_CE SetKeyAndValue(szProgID, NULL, szFriendlyName) ; SetKeyAndValue(szProgID, TEXT("CLSID"), szCLSID) ; #endif // UNDER_CE return S_OK ; } // // Remove the component from the registry. // #ifndef UNDER_CE LONG Unregister(const CLSID& clsid, // Class ID const char* szVerIndProgID, // Programmatic const char* szProgID) // IDs #else // UNDER_CE LONG Unregister(const CLSID& clsid, // Class ID LPCTSTR szVerIndProgID, // Programmatic LPCTSTR szProgID) // IDs #endif // UNDER_CE { // Convert the CLSID into a char. #ifndef UNDER_CE char szCLSID[CLSID_STRING_SIZE] ; CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)) ; #else // UNDER_CE TCHAR szCLSID[CLSID_STRING_SIZE] ; CLSIDtochar(clsid, szCLSID, sizeof(szCLSID)/sizeof(TCHAR)); #endif // UNDER_CE // Build the key CLSID\\{...} #ifndef UNDER_CE char szKey[64] ; StringCchCopy(szKey, ARRAYSIZE(szKey), "CLSID\\") ; StringCchCat(szKey, ARRAYSIZE(szKey), szCLSID) ; #else // UNDER_CE TCHAR szKey[64] ; lstrcpy(szKey, TEXT("CLSID\\")) ; lstrcat(szKey, szCLSID) ; #endif // UNDER_CE // Delete the CLSID Key - CLSID\{...} LONG lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szKey) ; // Delete the version-independent ProgID Key. lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szVerIndProgID) ; // Delete the ProgID key. lResult = RecursiveDeleteKey(HKEY_CLASSES_ROOT, szProgID) ; return S_OK ; } void SelfRegisterCategory(BOOL bRegister, const CATID &catId, REFCLSID clsId) { #ifndef UNDER_CE CHAR szCLSID[256]; CHAR szKey[1024]; CHAR szSub[1024]; CLSIDtochar(clsId, szCLSID, sizeof(szCLSID)); StringCchPrintf(szKey, ARRAYSIZE(szKey), "CLSID\\%s\\Implemented Categories", szCLSID); CLSIDtochar(catId, szSub, sizeof(szSub)); #else // UNDER_CE TCHAR szCLSID[256]; TCHAR szKey[1024]; TCHAR szSub[1024]; CLSIDtochar(clsId, szCLSID, sizeof(szCLSID)/sizeof(TCHAR)); wsprintf(szKey, TEXT("CLSID\\%s\\Implemented Categories"), szCLSID); CLSIDtochar(catId, szSub, sizeof(szSub)/sizeof(TCHAR)); #endif // UNDER_CE SetKeyAndValue(szKey, szSub, NULL, NULL); return; UNREFERENCED_PARAMETER(bRegister); } void RegisterCategory(BOOL bRegister, const CATID &catId, REFCLSID clsId) { // Create the standard COM Category Manager ICatRegister* pICatRegister = NULL ; HRESULT hr = ::CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL, CLSCTX_ALL, IID_ICatRegister, (void**)&pICatRegister) ; if (FAILED(hr)){ //ErrorMessage("Could not create the ComCat component.", hr); SelfRegisterCategory(bRegister, catId, clsId); return ; } // Array of Categories int cIDs = 1 ; CATID IDs[1] ; IDs[0] = catId; // Register or Unregister if(bRegister) { hr = pICatRegister->RegisterClassImplCategories(clsId, cIDs, IDs); //ASSERT_HRESULT(hr) ; } else { // Unregister the component from its categories. hr = pICatRegister->UnRegisterClassImplCategories(clsId, cIDs, IDs); } if(pICatRegister) { pICatRegister->Release() ; } } /////////////////////////////////////////////////////////// // // Internal helper functions // // Convert a CLSID to a char string. #ifndef UNDER_CE void CLSIDtochar(const CLSID& clsid, char* szCLSID, int length) #else // UNDER_CE void CLSIDtochar(const CLSID& clsid, LPTSTR szCLSID, int length) #endif // UNDER_CE { // Get CLSID LPOLESTR wszCLSID = NULL ; //HRESULT hr = StringFromCLSID(clsid, &wszCLSID); StringFromCLSID(clsid, &wszCLSID); if (wszCLSID != NULL) { // Covert from wide characters to non-wide. #ifndef UNDER_CE // #ifndef UNICODE wcstombs(szCLSID, wszCLSID, length); #else // UNDER_CE wcsncpy(szCLSID, wszCLSID, length); szCLSID[length-1] = TEXT('\0'); #endif // UNDER_CE // Free memory. CoTaskMemFree(wszCLSID) ; } } // // Delete a key and all of its descendents. // #ifndef UNDER_CE LONG RecursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete const char* lpszKeyChild) // Key to delete #else // UNDER_CE LONG RecursiveDeleteKey(HKEY hKeyParent, // Parent of key to delete LPCTSTR lpszKeyChild) // Key to delete #endif // UNDER_CE { // Open the child. HKEY hKeyChild ; LONG lRes = RegOpenKeyEx(hKeyParent, lpszKeyChild, 0, KEY_ALL_ACCESS, &hKeyChild) ; if (lRes != ERROR_SUCCESS) { return lRes ; } // Enumerate all of the decendents of this child. FILETIME time ; #ifndef UNDER_CE char szBuffer[256] ; #else // UNDER_CE TCHAR szBuffer[256]; #endif // UNDER_CE DWORD dwSize = 256 ; while (RegEnumKeyEx(hKeyChild, 0, szBuffer, &dwSize, NULL, NULL, NULL, &time) == S_OK) { // Delete the decendents of this child. lRes = RecursiveDeleteKey(hKeyChild, szBuffer) ; if (lRes != ERROR_SUCCESS) { // Cleanup before exiting. RegCloseKey(hKeyChild) ; return lRes; } dwSize = 256 ; } // Close the child. RegCloseKey(hKeyChild) ; // Delete this child. return RegDeleteKey(hKeyParent, lpszKeyChild) ; } // // Create a key and set its value. // - This helper function was borrowed and modifed from // Kraig Brockschmidt's book Inside OLE. // #ifndef UNDER_CE BOOL SetKeyAndValue(const char* szKey, const char* szSubkey, const char* szValue, const char* szName) #else // UNDER_CE BOOL SetKeyAndValue(LPCTSTR szKey, LPCTSTR szSubkey, LPCTSTR szValue, LPCTSTR szName) #endif // UNDER_CE { HKEY hKey; #ifndef UNDER_CE char szKeyBuf[1024] ; #else // UNDER_CE TCHAR szKeyBuf[1024]; #endif // UNDER_CE // Copy keyname into buffer. #ifndef UNDER_CE StringCchCopyA(szKeyBuf, ARRAYSIZE(szKeyBuf), szKey); #else // UNDER_CE lstrcpy(szKeyBuf, szKey); #endif // UNDER_CE // Add subkey name to buffer. if (szSubkey != NULL) { #ifndef UNDER_CE StringCchCat(szKeyBuf, ARRAYSIZE(szKeyBuf), "\\") ; StringCchCat(szKeyBuf, ARRAYSIZE(szKeyBuf), szSubkey ) ; #else // UNDER_CE lstrcat(szKeyBuf, TEXT("\\")) ; lstrcat(szKeyBuf, szSubkey ) ; #endif // UNDER_CE } // Create and open key and subkey. #ifndef UNDER_CE long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT , szKeyBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, NULL) ; #else // UNDER_CE DWORD dwDisposition; // Under WinCE, Must set lpdwDisposition. long lResult = RegCreateKeyEx(HKEY_CLASSES_ROOT, szKeyBuf, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition); #endif // UNDER_CE if (lResult != ERROR_SUCCESS) { return FALSE ; } // Set the Value. if (szValue != NULL) { #ifndef UNDER_CE RegSetValueEx(hKey, szName, 0, REG_SZ, (BYTE *)szValue, lstrlen(szValue)+1) ; #else // UNDER_CE RegSetValueEx(hKey, szName, 0, REG_SZ, (BYTE *)szValue, (lstrlen(szValue)+1) * sizeof(TCHAR)); #endif // UNDER_CE } RegCloseKey(hKey) ; return TRUE ; }