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.

327 lines
7.7 KiB

  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. SHFusionInitializeFromModule(hinst);
  79. #ifdef DEBUG
  80. CcshellGetDebugFlags();
  81. if (g_dwBreakFlags & BF_ONDLLLOAD)
  82. DebugBreak();
  83. #endif
  84. g_hinst = hinst;
  85. g_cxIcon = GetSystemMetrics(SM_CXICON);
  86. g_cyIcon = GetSystemMetrics(SM_CYICON);
  87. g_bMirroredOS = IS_MIRRORING_ENABLED();
  88. #ifdef WX86
  89. bWx86Enabled = IsWx86Enabled();
  90. #endif
  91. break;
  92. case DLL_PROCESS_DETACH:
  93. #ifndef DOWNLEVEL
  94. _Module.Term();
  95. #endif //DOWNLEVEL
  96. SHFusionUninitialize();
  97. break;
  98. case DLL_THREAD_ATTACH:
  99. case DLL_THREAD_DETACH:
  100. // We shouldn't get these because we called
  101. // DisableThreadLibraryCalls().
  102. ASSERT_MSG(0, "DllMain received DLL_THREAD_ATTACH/DETACH! We're not expecting this.");
  103. break;
  104. default:
  105. break;
  106. }
  107. return TRUE;
  108. }
  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. #ifdef DEBUG
  163. if (IsFlagSet(g_dwBreakFlags, BF_ONAPIENTER))
  164. {
  165. TraceMsg(TF_ALWAYS, "Stopping in DllInstall");
  166. DEBUG_BREAK;
  167. }
  168. #endif
  169. if (bInstall)
  170. {
  171. // Delete any old registration entries, then add the new ones.
  172. // Keep ADVPACK.DLL loaded across multiple calls to RegInstall.
  173. // (The inf engine doesn't guarantee DelReg/AddReg order, that's
  174. // why we explicitly unreg and reg here.)
  175. //
  176. hr = THR(_CallRegInstall("RegDll", FALSE));
  177. if (SUCCEEDED(hrExternal))
  178. hrExternal = hr;
  179. }
  180. else
  181. {
  182. hr = THR(_CallRegInstall("UnregDll", TRUE));
  183. if (SUCCEEDED(hrExternal))
  184. hrExternal = hr;
  185. }
  186. return hrExternal;
  187. }
  188. /*----------------------------------------------------------
  189. Purpose: Returns a class factory to create an object of
  190. the requested type.
  191. */
  192. STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **ppv)
  193. {
  194. TraceMsg(TF_OBJLIFE, "DllGetClassObject called with riid=%x (%x)", riid, &riid);
  195. #ifdef _MERGE_PROXYSTUB
  196. if (PrxDllGetClassObject(rclsid, riid, ppv) == S_OK)
  197. return S_OK;
  198. #endif
  199. if (riid == IID_IClassFactory || riid == IID_IUnknown)
  200. {
  201. // Try our native class factory
  202. HRESULT hres = GetClassObject(rclsid, riid, ppv);
  203. #ifndef DOWNLEVEL
  204. if (FAILED(hres))
  205. {
  206. // Try the ATL class factory
  207. hres = _Module.GetClassObject(rclsid, riid, ppv);
  208. }
  209. #endif //DOWNLEVEL
  210. return hres;
  211. }
  212. *ppv = NULL;
  213. return CLASS_E_CLASSNOTAVAILABLE;
  214. }
  215. STDAPI DllCanUnloadNow(void)
  216. {
  217. #ifdef _MERGE_PROXYSTUB
  218. if (PrxDllCanUnloadNow() != S_OK)
  219. return S_FALSE;
  220. #endif
  221. #ifndef DOWNLEVEL
  222. // This component uses ATL and natively-implemented COM objects
  223. if (0 != g_cRefThisDll || 0 != _Module.GetLockCount())
  224. return S_FALSE;
  225. #endif //DOWNLEVEL
  226. TraceMsg(DM_TRACE, "DllCanUnloadNow returning S_OK (bye, bye...)");
  227. return S_OK;
  228. }
  229. STDAPI_(void) DllAddRef(void)
  230. {
  231. InterlockedIncrement(&g_cRefThisDll);
  232. ASSERT(g_cRefThisDll < 1000); // reasonable upper limit
  233. }
  234. STDAPI_(void) DllRelease(void)
  235. {
  236. InterlockedDecrement(&g_cRefThisDll);
  237. ASSERT(g_cRefThisDll >= 0); // don't underflow
  238. }
  239. STDAPI DllRegisterServer(void)
  240. {
  241. HRESULT hres = S_OK;
  242. #ifdef _MERGE_PROXYSTUB
  243. hres = THR(PrxDllRegisterServer());
  244. if (FAILED(hres))
  245. return hres;
  246. #endif
  247. #ifndef DOWNLEVEL
  248. // registers object, typelib and all interfaces in typelib
  249. hres = THR(_Module.RegisterServer(TRUE));
  250. #endif //DOWNLEVEL
  251. return hres;
  252. }
  253. STDAPI DllUnregisterServer(void)
  254. {
  255. #ifdef _MERGE_PROXYSTUB
  256. PrxDllUnregisterServer();
  257. #endif
  258. #ifndef DOWNLEVEL
  259. _Module.UnregisterServer();
  260. #endif //DOWNLEVEL
  261. return S_OK;
  262. }