//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 1995. // // File: selfreg.cxx // // Contents: Taken from Office96 // Source file for the common self registration code used by all the // sub projects of Sweeper project. They are // UrlMon // UrlMnPrx // // Exports: HrDllRegisterServer() // HrDllUnregisterServer() // // Classes: // // Functions: // // History: 5-03-96 JohannP (Johann Posch) Created // //---------------------------------------------------------------------------- #include #include "selfreg.hxx" HINSTANCE g_hinstDll = NULL; PFNLOADSTRING g_pfnLoadString = NULL; //+--------------------------------------------------------------------------- // // Function: GetDllFullPath // // Synopsis: // // Arguments: [lpszExeName] -- // [cch] -- // // Returns: // // History: 95 OfficeXX created // 5-03-96 JohannP (Johann Posch) port urlmon // // Notes: // //---------------------------------------------------------------------------- BOOL GetDllFullPath( LPSTR lpszExeName, DWORD cch ) { if ( NULL == g_hinstDll ) { UrlMkAssert(( FALSE && "NULL hInst")); return FALSE; } *lpszExeName = NULL; if ( GetModuleFileName( g_hinstDll, lpszExeName, cch ) == 0) { UrlMkAssert(( FALSE && "GetModuleFileName Failed")); return FALSE; } return TRUE; } inline BOOL IsASeparator( char ch ) { return (ch == '\\' || ch == '/' || ch == ':'); } //+--------------------------------------------------------------------------- // // Function: ParseAFileName // // Synopsis: // // Arguments: [szFileName] -- // [piRetLen] -- // // Returns: // // History: 95 OfficeXX created // 5-03-96 JohannP (Johann Posch) port urlmon // // Notes: // //---------------------------------------------------------------------------- LPSTR ParseAFileName( LPSTR szFileName, int *piRetLen) { LPSTR pszFile; // Start at the end of the filename. pszFile = szFileName + ( lstrlen(szFileName) - 1 ); // Back up to a '\\' or beginning or something!! We just want a file // name!. Whatever comes first. while ( pszFile > szFileName && !IsASeparator(*pszFile ) ) pszFile = CharPrev(szFileName, pszFile); if ( pszFile != szFileName ) pszFile = CharNext(pszFile); if ( piRetLen ) *piRetLen = lstrlen(pszFile); return pszFile; } //+--------------------------------------------------------------------------- // // Function: FRegisterEntries // // Synopsis: FRegisterEntries: Register a group of reg entries off a base key. // // Arguments: [hkRoot] -- // [rgEntries] -- // [dwEntries] -- // [pszPath] -- // [pszBinderName] -- // // Returns: // // History: 95 OfficeXX created // 5-03-96 JohannP (Johann Posch) port urlmon // // Notes: // //---------------------------------------------------------------------------- BOOL FRegisterEntries(HKEY hkRoot, const REGENTRY rgEntries[], DWORD dwEntries, char *pszPath, char *pszBinderName) { HKEY hkey = NULL; LONG lRet; char szValue[1024]; char szResString[1024]; char szKeyName[1024]; BOOL fRet = FALSE; int i; for (i = 0; i < (int)dwEntries; i++) { // We work with a copy of the entry, since we might modify it REGENTRY reCurrentEntry = rgEntries[i]; if (reCurrentEntry.iKeyType == KEYTYPE_RESID) { int cch; if (g_pfnLoadString == NULL) return FALSE; cch = g_pfnLoadString(g_hinstDll, (UINT) PtrToUlong(reCurrentEntry.pszKey), szKeyName, sizeof(szKeyName)); if (cch > 0 && cch <= 1024) { reCurrentEntry.pszKey = szKeyName; } else { UrlMkAssert(( FALSE && "LoadString Failed ( 1)")); continue; } } lRet = RegCreateKey(hkRoot, reCurrentEntry.pszKey, &hkey); if (lRet != ERROR_SUCCESS) { UrlMkAssert(( FALSE && "RegCreateKey Failed ( 1)")); continue; } // If the type is REG_RESID, then pbData holds the resource ID. We // load the resource string, then modify our reCurrentEntry to point // to it. if (reCurrentEntry.dwType == REG_RESID) { int cch; if (g_pfnLoadString == NULL) return FALSE; cch = g_pfnLoadString(g_hinstDll, (UINT) PtrToUlong(reCurrentEntry.pbData), szResString, sizeof(szResString)); if (cch > 0 && cch <= 1024) { reCurrentEntry.dwType = REG_SZ; reCurrentEntry.pbData = (BYTE*) szResString; } else { UrlMkAssert(( FALSE && "LoadString Failed (2)")); reCurrentEntry.pbData = NULL; } } // Set the value if there is one if (reCurrentEntry.pbData != NULL || reCurrentEntry.dwType != REG_SZ) { switch (reCurrentEntry.dwType) { case REG_SZ: // Replace the first %s with the path, and the second // %s with the name of the binder app (may not do anything). if (pszPath != NULL && pszBinderName != NULL) { wsprintf(szValue, (char*)reCurrentEntry.pbData, pszPath, pszBinderName); lRet = RegSetValueEx(hkey, reCurrentEntry.pszValueName, 0, REG_SZ, (BYTE*)szValue, lstrlen(szValue)+1); #if DBG == 1 if ( ERROR_SUCCESS != lRet ) UrlMkAssert(( FALSE && "RegSetValueEx Failed ( 1)")); #endif } break; case REG_DWORD: lRet = RegSetValueEx(hkey, reCurrentEntry.pszValueName, 0, REG_DWORD, (BYTE*)&reCurrentEntry.pbData, sizeof(DWORD)); #if DBG == 1 if ( ERROR_SUCCESS != lRet ) UrlMkAssert(( FALSE && "RegSetValueEx Failed (2)")); #endif break; default: UrlMkAssert(( FALSE && "Unexpected reg entry type")); // Unexpected type: ignore break; } } // Close the subkey RegCloseKey(hkey); hkey = NULL; } fRet = TRUE; // Close the base key if it was open if (hkey) RegCloseKey(hkey); return fRet; } /* * FRegisterEntryGroups: Register several groups of reg entries. */ BOOL FRegisterEntryGroups(const REGENTRYGROUP *rgRegEntryGroups, char *pszPath, char *pszBinderName) { BOOL fError = FALSE; int i; // Keep going even if we get some errors for (i=0; rgRegEntryGroups[i].hkRoot != NULL; i++) { if (!FRegisterEntries(rgRegEntryGroups[i].hkRoot, rgRegEntryGroups[i].rgEntries, rgRegEntryGroups[i].dwEntries,pszPath, pszBinderName)) { fError = TRUE; } } return !fError; } //+--------------------------------------------------------------------------- // // Function: FDeleteEntries // // Synopsis: Delete a group of reg entries off a base key. // // Arguments: [hkRoot] -- // [rgEntries] -- // [dwEntries] -- // // Returns: // // History: 95 OfficeXX created // 5-03-96 JohannP (Johann Posch) port urlmon // // Notes: // //---------------------------------------------------------------------------- BOOL FDeleteEntries(HKEY hkRoot, const REGENTRY rgEntries[], DWORD dwEntries) { LONG lRet; int i; char szKeyName[1024]; PSTR pKey; // Delete in reverse order, to kill children before parent for (i = (int)dwEntries - 1; i >= 0; i--) { pKey = NULL; if (rgEntries[i].iKeyType == KEYTYPE_RESID) { int cch; cch = g_pfnLoadString(g_hinstDll, (UINT) PtrToUlong(rgEntries[i].pszKey), szKeyName, sizeof(szKeyName)); if (cch > 0 && cch <= 1024) { pKey = szKeyName; } else { UrlMkAssert(( FALSE && "LoadString Failed (FDeleteEntries)")); continue; } } else { if ( KEYTYPE_STRING != rgEntries[i].iKeyType ) { UrlMkAssert(( FALSE && "Unknown Key Type")); continue; } pKey = rgEntries[i].pszKey; } if (pKey != NULL) { // Delete the current key if it has no subkeys. // Ignore the return value. lRet = RegDeleteKey(hkRoot, pKey); } } return TRUE; } //+--------------------------------------------------------------------------- // // Function: FDeleteEntryGroups // // Synopsis: Delete the base keys of all the given groups. // // Arguments: [rgRegEntryGroups] -- // // Returns: // // History: 95 OfficeXX created // 5-03-96 JohannP (Johann Posch) port urlmon // // Notes: // //---------------------------------------------------------------------------- BOOL FDeleteEntryGroups(const REGENTRYGROUP *rgRegEntryGroups) { BOOL fError = FALSE; // Keep going even if we get some errors for (int i=0; rgRegEntryGroups[i].hkRoot != NULL; i++) { if (!FDeleteEntries(rgRegEntryGroups[i].hkRoot, rgRegEntryGroups[i].rgEntries, rgRegEntryGroups[i].dwEntries)) { fError = TRUE; } } return !fError; } #ifdef NOT_USED /* * FDeleteSubtree - Delete given key and all subkeys */ BOOL FDeleteSubtree(HKEY hkRoot, char *pszKey) { HKEY hkey = NULL; LONG lRet; char szSubKey[MAX_PATH]; lRet = RegOpenKey(hkRoot, pszKey, &hkey); if (lRet != ERROR_SUCCESS) goto End; // remove all subkeys for (;;) { lRet = RegEnumKey(hkey, 0, szSubKey, sizeof szSubKey); if (lRet == ERROR_NO_MORE_ITEMS) break; if (lRet != ERROR_SUCCESS) goto End; if (!FDeleteSubtree(hkey, szSubKey)) goto End; } End: if (hkey != NULL) RegCloseKey (hkey); lRet = RegDeleteKey(hkRoot, pszKey); return (lRet == ERROR_SUCCESS); } #endif // NOT_USED //+--------------------------------------------------------------------------- // // Function: HrDllRegisterServer // // Synopsis: registers an entrygroup // // Arguments: [HINSTANCE] -- // [hinstDll] -- // [pfnLoadString] -- // [pszAppName] -- // // Returns: // // History: 95 OfficeXX created // 5-03-96 JohannP (Johann Posch) port urlmon // // Notes: // //---------------------------------------------------------------------------- HRESULT HrDllRegisterServer(const REGENTRYGROUP *rgRegEntryGroups,HINSTANCE hinstDll, PFNLOADSTRING pfnLoadString, char *pszAppName) { // REVIEW: for Windows dll, do we want to register full path? BOOL fRet = TRUE; char szFullPath[MAX_PATH]; char szFileName[MAX_PATH]; char *pszFileName; g_hinstDll = hinstDll; if ((g_pfnLoadString = pfnLoadString) == NULL) // set the pointer to windows LoadString() api g_pfnLoadString = (PFNLOADSTRING) LoadString; if (!GetDllFullPath(szFullPath, MAX_PATH)) return E_FAIL; pszFileName = ParseAFileName(szFullPath, NULL); if (pszAppName != NULL) lstrcpy(szFileName, pszAppName); else lstrcpy(szFileName, pszFileName); // Terminate the path at the file name *pszFileName = '\0'; #ifdef UNIX /* On Unix, we find the location of the dll using LD_LIBRARY_PATH * which is included in the wrapper script * So, we do not want to specify the whole path for the dll in the * registry. */ *szFullPath = '\0'; #endif /* UNIX */ fRet = FRegisterEntryGroups(rgRegEntryGroups, szFullPath, szFileName); g_hinstDll = NULL; g_pfnLoadString = NULL; return fRet ? NOERROR : E_FAIL; } //+--------------------------------------------------------------------------- // // Function: HrDllUnregisterServer // // Synopsis: unregisters an entrygroup // // Arguments: [HINSTANCE] -- // [hinstDll] -- // [pfnLoadString] -- // // Returns: // // History: 95 OfficeXX created // 5-03-96 JohannP (Johann Posch) port urlmon // // Notes: // //---------------------------------------------------------------------------- HRESULT HrDllUnregisterServer(const REGENTRYGROUP *rgRegEntryGroups,HINSTANCE hinstDll, PFNLOADSTRING pfnLoadString) { g_hinstDll = hinstDll; if ((g_pfnLoadString = pfnLoadString) == NULL) // set the pointer to windows LoadString() api g_pfnLoadString = (PFNLOADSTRING) LoadString; FDeleteEntryGroups(rgRegEntryGroups); g_hinstDll = NULL; g_pfnLoadString = NULL; return NOERROR; }