dllreg.cpp
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 7k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. // dllreg.c -- autmatic registration and unregistration
  2. //
  3. #include "priv.h"
  4. #include <advpub.h>
  5. STDAPI CDeskHtmlProp_RegUnReg(BOOL bReg);
  6. //=--------------------------------------------------------------------------=
  7. // miscellaneous [useful] numerical constants
  8. //=--------------------------------------------------------------------------=
  9. // the length of a guid once printed out with -'s, leading and trailing bracket,
  10. // plus 1 for NULL
  11. //
  12. #define GUID_STR_LEN    40
  13. //
  14. // helper macros
  15. //
  16. #define RegOpenK(hk, psz, phk) if (ERROR_SUCCESS != RegOpenKeyEx(hk, psz, 0, KEY_READ|KEY_WRITE, phk)) return FALSE
  17. // ADVPACK will return E_UNEXPECTED if you try to uninstall (which does a registry restore)
  18. // on an INF section that was never installed.  We uninstall sections that may never have
  19. // been installed, so this MACRO will quiet these errors.
  20. #define QuietInstallNoOp(hr)   ((E_UNEXPECTED == hr) ? S_OK : hr)
  21. //
  22. // The actual functions called
  23. //
  24. /*----------------------------------------------------------
  25. Purpose: Calls the ADVPACK entry-point which executes an inf
  26.          file section.
  27. Returns: 
  28. Cond:    --
  29. */
  30. HRESULT 
  31. CallRegInstall(
  32.     LPSTR szSection)
  33. {
  34.     HRESULT hr = E_FAIL;
  35.     HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  36.     if (hinstAdvPack)
  37.     {
  38.         REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  39.         if (pfnri)
  40.         {
  41.             static STRENTRY seReg[] = {
  42.                 // These two NT-specific entries must be at the end
  43.                 { "25", "%SystemRoot%" },
  44.                 { "11", "%SystemRoot%\system32" },
  45.             };
  46.             STRTABLE stReg = { ARRAYSIZE(seReg) - 2, seReg };
  47.             if (g_fRunningOnNT)
  48.             {
  49.                 // If on NT, we want custom action for %25% %11%
  50.                 // so that it uses %SystemRoot% in writing the
  51.                 // path to the registry.
  52.                 stReg.cEntries += 2;
  53.             }
  54.             hr = pfnri(g_hinst, szSection, &stReg);
  55.             if (FAILED(QuietInstallNoOp(hr)))
  56.                 TraceMsg(DM_ERROR, "DLLREG CallRegInstall("%s") failed.  hr=%lx", szSection, (DWORD) hr);
  57.         }
  58.         else
  59.             TraceMsg(DM_ERROR, "DLLREG CallRegInstall() calling GetProcAddress(hinstAdvPack, "RegInstall") failed");
  60.         FreeLibrary(hinstAdvPack);
  61.     }
  62.     else
  63.         TraceMsg(DM_ERROR, "DLLREG CallRegInstall() Failed to load ADVPACK.DLL");
  64.     return hr;
  65. }
  66. BOOL UnregisterTypeLibrary(const CLSID* piidLibrary)
  67. {
  68.     TCHAR szScratch[GUIDSTR_MAX];
  69.     HKEY hk;
  70.     BOOL f = FALSE;
  71.     // convert the libid into a string.
  72.     //
  73.     SHStringFromGUID(*piidLibrary, szScratch, ARRAYSIZE(szScratch));
  74.     if (RegOpenKey(HKEY_CLASSES_ROOT, TEXT("TypeLib"), &hk) == ERROR_SUCCESS)
  75.     {
  76.         f = RegDeleteKey(hk, szScratch);
  77.         RegCloseKey(hk);
  78.     }
  79.     
  80.     return f;
  81. }
  82. HRESULT Shell32RegTypeLib(void)
  83. {
  84.     TCHAR szPath[MAX_PATH];
  85.     WCHAR wszPath[MAX_PATH];
  86.     // Load and register our type library.
  87.     //
  88.     GetModuleFileName(HINST_THISDLL, szPath, ARRAYSIZE(szPath));
  89.     SHTCharToUnicode(szPath, wszPath, ARRAYSIZE(wszPath));
  90.     ITypeLib *pTypeLib;
  91.     HRESULT hr = LoadTypeLib(wszPath, &pTypeLib);
  92.     if (SUCCEEDED(hr))
  93.     {
  94.         // call the unregister type library as we had some old junk that
  95.         // was registered by a previous version of OleAut32, which is now causing
  96.         // the current version to not work on NT...
  97.         UnregisterTypeLibrary(&LIBID_Shell32);
  98.         hr = RegisterTypeLib(pTypeLib, wszPath, NULL);
  99.         if (FAILED(hr))
  100.         {
  101.             TraceMsg(TF_WARNING, "SHELL32: RegisterTypeLib failed (%x)", hr);
  102.         }
  103.         pTypeLib->Release();
  104.     }
  105.     else
  106.     {
  107.         TraceMsg(TF_WARNING, "SHELL32: LoadTypeLib failed (%x)", hr);
  108.     }
  109.     return hr;
  110. }
  111. STDAPI
  112. DllRegisterServer(void)
  113. {
  114.     HRESULT hr = S_OK;
  115.     HRESULT hrExternal = S_OK;
  116.     TraceMsg(DM_TRACE, "DLLREG DllRegisterServer() Beginning");
  117. #ifdef DEBUG
  118.     if (IsFlagSet(g_dwBreakFlags, BF_ONAPIENTER))
  119.     {
  120.         TraceMsg(TF_ALWAYS, "Stopping in DllRegisterServer");
  121.         DEBUG_BREAK;
  122.     }
  123. #endif
  124.     //
  125.     //  SHDOC401 is used only in the "the shell is in IE 4.01 integrated mode"
  126.     //  case.  We detect this by sniffing the shell32 version.
  127.     //
  128.     //  less than v4 - not integrated; do nothing
  129.     //            v4 - integrated IE4.x; install
  130.     //            v5 - integrated IE5.x or higher; do nothing
  131.     //
  132.     //  We don't use WhichPlatform() because WhichPlatform() does not
  133.     //  to distinguish between IE4 shell32 and IE5 shell32 (it calls them
  134.     //  both "integrated").
  135.     if (g_uiShell32 != 4) {
  136.         TraceMsg(TF_ALWAYS, "Skipping DllRegisterServer because shell32 is not 4.x");
  137.         return S_OK;
  138.     }
  139.     hr = CallRegInstall("RegDll");
  140.     if (SUCCEEDED(hrExternal))
  141.         hrExternal = hr;
  142.     if (FAILED(hr))
  143.         TraceMsg(DM_ERROR, "DLLREG DllRegisterServer() failed calling CallRegInstall("RegDll").  hr=%lx", (DWORD) hr);
  144.     hr = Shell32RegTypeLib();
  145.     if (SUCCEEDED(hrExternal))
  146.         hrExternal = hr;
  147.     if (FAILED(hr))
  148.         TraceMsg(DM_ERROR, "DLLREG DllRegisterServer() failed calling CallRegInstall("RegDll").  hr=%lx", (DWORD) hr);
  149.     if (g_fRunningOnNT)
  150.     {
  151.         hr = CallRegInstall("RegDllNT");
  152.         if (SUCCEEDED(hrExternal))
  153.             hrExternal = hr;
  154.     }
  155.     
  156.     return hrExternal;
  157. }
  158. STDAPI DllUnregisterServer(void)
  159. {
  160.     HRESULT hr;
  161.     TraceMsg(DM_TRACE, "DLLREG DllUnregisterServer() Beginning");
  162.     // UnInstall the registry values
  163.     hr = CallRegInstall("UnregDll");
  164.     // ADVPACK will return E_UNEXPECTED if you try to uninstall
  165.     // (which does a registry restore) on an INF section that was
  166.     // never installed.  We uninstall sections that may never have
  167.     // been installed, so ignore this error 
  168.     hr = (E_UNEXPECTED == hr) ? S_OK : hr;
  169.     ASSERT(SUCCEEDED(hr));  // Make sure uninstall succeeded.
  170.     UnregisterTypeLibrary(&LIBID_Shell32);
  171.     return hr;
  172. }
  173. /*----------------------------------------------------------
  174. Purpose: Install/uninstall user settings
  175. Description: Nothing to do here.
  176. */
  177. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
  178. {
  179.     HRESULT hr = S_OK;
  180.     HRESULT hrExternal = S_OK;
  181.     if (bInstall)
  182.     {
  183.         if (g_uiShell32 != 4) {
  184.             TraceMsg(TF_ALWAYS, "Skipping DllInstall because shell32 is not 4.x");
  185.             return S_OK;
  186.         }
  187.         // The "RegDllAlways" section will always be run independent of what
  188.         // platform we are on.
  189.         hr = CallRegInstall("RegDllAlways");
  190.         if (SUCCEEDED(hrExternal))
  191.             hrExternal = hr;
  192.         if (FAILED(hr))
  193.             TraceMsg(DM_ERROR, "DLLREG DllRegisterServer() failed calling CallRegInstall("RegDllAlways").  hr=%lx", (DWORD) hr);
  194.     }
  195.     // We need to do this because this is the code that populates the branch of registry
  196.     // needed for the ActiveDesktop.
  197.     CDeskHtmlProp_RegUnReg(bInstall);  
  198.     return hrExternal;
  199. }