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

Windows Kernel

Development Platform:

Visual C++

  1. /***************************************************************************
  2.  *  dll.c
  3.  *
  4.  *  Standard DLL entry-point functions 
  5.  *
  6.  ***************************************************************************/
  7. // Note: Proxy/Stub Information from ATL
  8. //
  9. //      To merge the proxy/stub code into the object DLL, add the file 
  10. //      dlldatax.c to the project.  Make sure precompiled headers 
  11. //      are turned off for this file, and add _MERGE_PROXYSTUB to the 
  12. //      defines for the project.  
  13. //
  14. //      If you are not running WinNT4.0 or Win95 with DCOM, then you
  15. //      need to remove the following define from dlldatax.c
  16. //      #define _WIN32_WINNT 0x0400
  17. //
  18. //      Further, if you are running MIDL without /Oicf switch, you also 
  19. //      need to remove the following define from dlldatax.c.
  20. //      #define USE_STUBLESS_PROXY
  21. //
  22. //      Modify the custom build rule for shappmgr.idl by adding the following 
  23. //      files to the Outputs.
  24. //          shappmgr_p.c
  25. //          dlldata.c
  26. //      To build a separate proxy/stub DLL, 
  27. //      run nmake -f shappmgrps.mk in the project directory.
  28. #include "priv.h"
  29. #include "sccls.h"
  30. #ifndef DOWNLEVEL
  31. #include "adcctl.h"
  32. #endif //DOWNLEVEL
  33. #include <ntverp.h>
  34. #include <advpub.h>         // For REGINSTALL
  35. // Define GUIDs
  36. extern "C" 
  37. {
  38. HINSTANCE g_hinst = NULL;
  39. int g_cxIcon;
  40. int g_cyIcon;
  41. BOOL g_bMirroredOS;
  42. LONG    g_cRefThisDll = 0;      // per-instance
  43. #ifdef WX86
  44. //
  45. // from uninstal.c
  46. //
  47. extern BOOL bWx86Enabled;
  48. BOOL IsWx86Enabled(VOID);
  49. #endif
  50. };
  51. #ifndef DOWNLEVEL
  52. CComModule _Module;         // ATL module object
  53. BEGIN_OBJECT_MAP(ObjectMap)
  54.     OBJECT_ENTRY(CLSID_ADCCtl, CADCCtl)
  55. END_OBJECT_MAP()
  56. #endif //DOWNLEVEL
  57. /*----------------------------------------------------------
  58. Purpose: DllEntryPoint
  59. */
  60. BOOL 
  61. APIENTRY 
  62. DllMain(
  63.     IN HINSTANCE hinst, 
  64.     IN DWORD dwReason, 
  65.     IN LPVOID lpReserved)
  66. {
  67. #ifdef _MERGE_PROXYSTUB
  68.     if (!PrxDllMain(hInstance, dwReason, lpReserved))
  69.         return FALSE;
  70. #endif
  71.     switch(dwReason) 
  72.     {
  73.     case DLL_PROCESS_ATTACH:
  74. #ifndef DOWNLEVEL
  75.         _Module.Init(ObjectMap, hinst);
  76. #endif //DOWNLEVEL
  77.         DisableThreadLibraryCalls(hinst);
  78.      
  79. #ifdef DEBUG
  80.         CcshellGetDebugFlags();
  81.         
  82.         if (g_dwBreakFlags & BF_ONDLLLOAD)
  83.             DebugBreak();
  84. #endif
  85.         g_hinst = hinst;
  86.         g_cxIcon = GetSystemMetrics(SM_CXICON);
  87.         g_cyIcon = GetSystemMetrics(SM_CYICON);
  88.         g_bMirroredOS = IS_MIRRORING_ENABLED();
  89. #ifdef WX86
  90.         bWx86Enabled = IsWx86Enabled();
  91. #endif
  92.         break;
  93.         
  94.     case DLL_PROCESS_DETACH:
  95. #ifndef DOWNLEVEL
  96.         _Module.Term();
  97. #endif //DOWNLEVEL
  98.         break;
  99.     case DLL_THREAD_ATTACH:
  100.     case DLL_THREAD_DETACH:
  101.         // We shouldn't get these because we called 
  102.         // DisableThreadLibraryCalls(). 
  103.         ASSERT_MSG(0, "DllMain received DLL_THREAD_ATTACH/DETACH!  We're not expecting this.");
  104.         break;
  105.     default:
  106.         break;
  107.     } 
  108.     return TRUE;
  109. /*----------------------------------------------------------
  110. Purpose: This function provides the DLL version info.  This 
  111.          allows the caller to distinguish running NT SUR vs.
  112.          Win95 shell vs. Nashville, etc.
  113.          The caller must GetProcAddress this function.  
  114. Returns: NO_ERROR
  115.          ERROR_INVALID_PARAMETER if pinfo is invalid
  116. */
  117. // All we have to do is declare this puppy and CCDllGetVersion does the rest
  118. DLLVER_DUALBINARY(VER_PRODUCTVERSION_DW, VER_PRODUCTBUILD_QFE);
  119. /*----------------------------------------------------------
  120. Purpose: Calls the ADVPACK entry-point which executes an inf
  121.          file section.
  122. */
  123. HRESULT _CallRegInstall(LPCSTR szSection, BOOL bUninstall)
  124. {
  125.     HRESULT hr = E_FAIL;
  126.     HINSTANCE hinstAdvPack = LoadLibrary(TEXT("ADVPACK.DLL"));
  127.     if (hinstAdvPack)
  128.     {
  129.         REGINSTALL pfnri = (REGINSTALL)GetProcAddress(hinstAdvPack, "RegInstall");
  130.         if (pfnri)
  131.         {
  132. #ifdef WINNT                
  133.             STRENTRY seReg[] = {
  134.                 { "25", "%SystemRoot%" },
  135.                 { "11", "%SystemRoot%\system32" },
  136.             };
  137.             STRTABLE stReg = { ARRAYSIZE(seReg), seReg };
  138.             hr = pfnri(g_hinst, szSection, &stReg);
  139. #else
  140.             hr = pfnri(g_hinst, szSection, NULL);
  141. #endif                
  142.             if (bUninstall)
  143.             {
  144.                 // ADVPACK will return E_UNEXPECTED if you try to uninstall 
  145.                 // (which does a registry restore) on an INF section that was 
  146.                 // never installed.  We uninstall sections that may never have
  147.                 // been installed, so ignore this error
  148.                 hr = ((E_UNEXPECTED == hr) ? S_OK : hr);
  149.             }
  150.         }
  151.         FreeLibrary(hinstAdvPack);
  152.     }
  153.     return hr;
  154. }
  155. /*----------------------------------------------------------
  156. Purpose: Install/uninstall user settings
  157. */
  158. STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
  159. {
  160.     HRESULT hr = S_OK;
  161.     HRESULT hrExternal = S_OK;
  162.     ASSERT(IS_VALID_STRING_PTRW(pszCmdLine, -1));
  163. #ifdef DEBUG
  164.     if (IsFlagSet(g_dwBreakFlags, BF_ONAPIENTER))
  165.     {
  166.         TraceMsg(TF_ALWAYS, "Stopping in DllInstall");
  167.         DEBUG_BREAK;
  168.     }
  169. #endif
  170.     if (bInstall)
  171.     {
  172.         // Delete any old registration entries, then add the new ones.
  173.         // Keep ADVPACK.DLL loaded across multiple calls to RegInstall.
  174.         // (The inf engine doesn't guarantee DelReg/AddReg order, that's
  175.         // why we explicitly unreg and reg here.)
  176.         //
  177.         hr = THR(_CallRegInstall("RegDll", FALSE));
  178.         if (SUCCEEDED(hrExternal))
  179.             hrExternal = hr;
  180.     }
  181.     else
  182.     {
  183.         hr = THR(_CallRegInstall("UnregDll", TRUE));
  184.         if (SUCCEEDED(hrExternal))
  185.             hrExternal = hr;
  186.     }
  187.     return hrExternal;
  188. }
  189. /*----------------------------------------------------------
  190. Purpose: Returns a class factory to create an object of
  191.          the requested type.
  192. */
  193. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  194. {
  195.     TraceMsg(TF_OBJLIFE, "DllGetClassObject called with riid=%x (%x)", riid, &riid);
  196. #ifdef _MERGE_PROXYSTUB
  197.     if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
  198.         return S_OK;
  199. #endif
  200.     if (riid == IID_IClassFactory || riid == IID_IUnknown)
  201.     {
  202.         // Try our native class factory
  203.         HRESULT hres = GetClassObject(rclsid, riid, ppv);
  204. #ifndef DOWNLEVEL
  205.         if (FAILED(hres))
  206.         {
  207.             // Try the ATL class factory
  208.             hres = _Module.GetClassObject(rclsid, riid, ppv);
  209.         }
  210. #endif //DOWNLEVEL
  211.         return hres;
  212.     }
  213.     *ppv = NULL;
  214.     return CLASS_E_CLASSNOTAVAILABLE;
  215. }
  216. STDAPI DllCanUnloadNow(void)
  217. {
  218. #ifdef _MERGE_PROXYSTUB
  219.     if (PrxDllCanUnloadNow() != S_OK)
  220.         return S_FALSE;
  221. #endif
  222. #ifndef DOWNLEVEL
  223.     // This component uses ATL and natively-implemented COM objects
  224.     if (0 != g_cRefThisDll || 0 != _Module.GetLockCount())
  225.         return S_FALSE;
  226. #endif //DOWNLEVEL
  227.     TraceMsg(DM_TRACE, "DllCanUnloadNow returning S_OK (bye, bye...)");
  228.     return S_OK;
  229. }
  230. STDAPI_(void) DllAddRef(void)
  231. {
  232.     InterlockedIncrement(&g_cRefThisDll);
  233.     ASSERT(g_cRefThisDll < 1000);   // reasonable upper limit
  234. }
  235. STDAPI_(void) DllRelease(void)
  236. {
  237.     InterlockedDecrement(&g_cRefThisDll);
  238.     ASSERT(g_cRefThisDll >= 0);      // don't underflow
  239. }
  240. STDAPI DllRegisterServer(void)
  241. {
  242.     HRESULT hres = S_OK;
  243.     
  244. #ifdef _MERGE_PROXYSTUB
  245.     hres = THR(PrxDllRegisterServer());
  246.     if (FAILED(hres))
  247.         return hres;
  248. #endif
  249. #ifndef DOWNLEVEL
  250.     // registers object, typelib and all interfaces in typelib
  251.     hres = THR(_Module.RegisterServer(TRUE));
  252. #endif //DOWNLEVEL
  253.     return hres;
  254. }
  255. STDAPI DllUnregisterServer(void)
  256. {
  257. #ifdef _MERGE_PROXYSTUB
  258.     PrxDllUnregisterServer();
  259. #endif
  260. #ifndef DOWNLEVEL
  261.     _Module.UnregisterServer();
  262. #endif //DOWNLEVEL
  263.     return S_OK;
  264. }