Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
6.4 KiB

  1. // dllreg.cpp -- autmatic registration and unregistration
  2. //
  3. #include "priv.h"
  4. #include "guids.h"
  5. //#include "installwv.h"
  6. #include <advpub.h>
  7. #include <comcat.h>
  8. //#include <msieftp.h>
  9. #include "Deskbands.h"
  10. // helper macros
  11. // ADVPACK will return E_UNEXPECTED if you try to uninstall (which does a registry restore)
  12. // on an INF section that was never installed. We uninstall sections that may never have
  13. // been installed, so this MACRO will quiet these errors.
  14. #define QuietInstallNoOp(hr) ((E_UNEXPECTED == hr) ? S_OK : hr)
  15. const CHAR c_szIexploreKey[] = "Software\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE";
  16. /*----------------------------------------------------------
  17. Purpose: Queries the registry for the location of the path
  18. of Internet Explorer and returns it in pszBuf.
  19. Returns: TRUE on success
  20. FALSE if path cannot be determined
  21. Cond: --
  22. */
  23. BOOL
  24. GetIEPath(
  25. OUT LPSTR pszBuf,
  26. IN DWORD cchBuf)
  27. {
  28. BOOL bRet = FALSE;
  29. HKEY hkey;
  30. *pszBuf = '\0';
  31. // Get the path of Internet Explorer
  32. if (NO_ERROR != RegOpenKeyA(HKEY_LOCAL_MACHINE, c_szIexploreKey, &hkey))
  33. {
  34. }
  35. else
  36. {
  37. DWORD cbBrowser;
  38. DWORD dwType;
  39. lstrcatA(pszBuf, "\"");
  40. cbBrowser = CbFromCchA(cchBuf - lstrlenA(" -nohome") - 4);
  41. if (NO_ERROR != RegQueryValueExA(hkey, "", NULL, &dwType,
  42. (LPBYTE)&pszBuf[1], &cbBrowser))
  43. {
  44. }
  45. else
  46. {
  47. bRet = TRUE;
  48. }
  49. lstrcatA(pszBuf, "\"");
  50. RegCloseKey(hkey);
  51. }
  52. return bRet;
  53. }
  54. /*----------------------------------------------------------
  55. Purpose: Calls the ADVPACK entry-point which executes an inf
  56. file section.
  57. Returns:
  58. Cond: --
  59. */
  60. HRESULT CallRegInstall(LPSTR szSection)
  61. {
  62. HRESULT hr = E_FAIL;
  63. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  64. if (hinstAdvPack)
  65. {
  66. REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  67. if (pfnri)
  68. {
  69. char szIEPath[MAX_PATH];
  70. STRENTRY seReg[] = {
  71. { "MSIEXPLORE", szIEPath },
  72. // These two NT-specific entries must be at the end
  73. { "25", "%SystemRoot%" },
  74. { "11", "%SystemRoot%\\system32" },
  75. };
  76. STRTABLE stReg = { ARRAYSIZE(seReg) - 2, seReg };
  77. // Get the location of iexplore from the registry
  78. if ( !EVAL(GetIEPath(szIEPath, ARRAYSIZE(szIEPath))) )
  79. {
  80. // Failed, just say "iexplore"
  81. lstrcpyA(szIEPath, "iexplore.exe");
  82. }
  83. #if 0 // Disable ---------------------
  84. if (g_fRunningOnNT)
  85. {
  86. // If on NT, we want custom action for %25% %11%
  87. // so that it uses %SystemRoot% in writing the
  88. // path to the registry.
  89. stReg.cEntries += 2;
  90. }
  91. #endif // 0
  92. hr = pfnri(g_hinst, szSection, &stReg);
  93. }
  94. FreeLibrary(hinstAdvPack);
  95. }
  96. return hr;
  97. }
  98. STDAPI DllRegisterServer(void)
  99. {
  100. HRESULT hr;
  101. // Delete any old registration entries, then add the new ones.
  102. // Keep ADVPACK.DLL loaded across multiple calls to RegInstall.
  103. // (The inf engine doesn't guarantee DelReg/AddReg order, that's
  104. // why we explicitly unreg and reg here.)
  105. //
  106. HINSTANCE hinstFTP = LoadLibrary(TEXT("MSIEFTP.DLL"));
  107. HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  108. hr = CallRegInstall("ShellExtensionInstall");
  109. if (hinstAdvPack)
  110. FreeLibrary(hinstAdvPack);
  111. if (EVAL(hinstFTP)) // We need hinstFTP or we can't install the webview files.
  112. FreeLibrary(hinstFTP);
  113. return hr;
  114. }
  115. STDAPI DllUnregisterServer(void)
  116. {
  117. HRESULT hr;
  118. // UnInstall the registry values
  119. hr = CallRegInstall("FtpShellExtensionUninstall");
  120. return hr;
  121. }
  122. void RegisterOneCategory(const CATID *pcatidCat, UINT idResCat, const CATID * const *pcatidImpl, BOOL fRegister)
  123. {
  124. ICatRegister* pcr;
  125. HRESULT hres = CoCreateInstance(CLSID_StdComponentCategoriesMgr, NULL,
  126. CLSCTX_INPROC_SERVER, IID_ICatRegister, (LPVOID*)&pcr);
  127. if (pcr)
  128. {
  129. if (fRegister)
  130. {
  131. // register the category
  132. CATEGORYINFO catinfo = {0};
  133. catinfo.catid = *pcatidCat;
  134. catinfo.lcid = LOCALE_USER_DEFAULT;
  135. LoadString(HINST_THISDLL, idResCat, catinfo.szDescription, ARRAYSIZE(catinfo.szDescription));
  136. hres = pcr->RegisterCategories(1, &catinfo);
  137. // register the classes that implement categories
  138. for ( ; *pcatidImpl != NULL; pcatidImpl++)
  139. {
  140. CLSID clsid = **pcatidImpl;
  141. CATID catid = *pcatidCat;
  142. hres = pcr->RegisterClassImplCategories(clsid, 1, &catid);
  143. }
  144. }
  145. #if 0
  146. else
  147. {
  148. // unregister the classes that implement categories
  149. for ( ; *pcatidImpl != NULL; pcatidImpl++)
  150. {
  151. CLSID clsid = **pcatidImpl;
  152. CATID catid = *pcatidCat;
  153. hres = pcr->UnRegisterClassImplCategories(clsid, 1, &catid);
  154. }
  155. if (eRegister == CCR_UNREG) {
  156. // unregister the category
  157. CATID catid = *pcatidCat;
  158. hres = pcr->UnRegisterCategories(1, &catid);
  159. }
  160. }
  161. #endif
  162. pcr->Release();
  163. }
  164. }
  165. void RegisterCategories(BOOL fRegister)
  166. {
  167. RegisterOneCategory(&CATID_DeskBand, IDS_COMCAT_DESKBANDS, c_DeskBandClasses, fRegister);
  168. RegisterOneCategory(&CATID_InfoBand, IDS_COMCAT_DESKBANDS, c_InfoBandClasses, fRegister);
  169. }
  170. /*----------------------------------------------------------
  171. Purpose: Install/uninstall user settings
  172. Description: Note that this function has special error handling.
  173. The function will keep hrExternal with the worse error
  174. but will only stop executing util the internal error (hr)
  175. gets really bad. This is because we need the external
  176. error to catch incorrectly authored INFs but the internal
  177. error to be robust in attempting to install other INF sections
  178. even if one doesn't make it.
  179. */
  180. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
  181. {
  182. RegisterCategories(bInstall);
  183. return S_OK;
  184. }