Leaked source code of windows server 2003
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.

556 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: libmain.cxx
  7. //
  8. // Contents: LibMain for oleds.dll
  9. //
  10. // Functions: LibMain, DllGetClassObject
  11. //
  12. // History: 25-Oct-94 KrishnaG Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "winnt.hxx"
  16. #pragma hdrstop
  17. HINSTANCE g_hInst = NULL;
  18. extern HMODULE g_hActiveDs;
  19. WCHAR * szWinNTPrefix = L"@WinNT!";
  20. HANDLE FpnwLoadLibSemaphore = NULL;
  21. //
  22. // Strings that are loaded depending on locality
  23. //
  24. WCHAR g_szBuiltin[100];
  25. WCHAR g_szNT_Authority[100];
  26. WCHAR g_szEveryone[100];
  27. BOOL g_fStringsLoaded = FALSE;
  28. //
  29. // 3rd party extension
  30. //
  31. extern PCLASS_ENTRY gpClassHead;
  32. extern CRITICAL_SECTION g_ExtCritSect;
  33. extern CRITICAL_SECTION g_TypeInfoCritSect;
  34. //
  35. // Disabled as it causes link warnings
  36. // extern CRITICAL_SECTION g_DispTypeInfoCritSect;
  37. //
  38. //---------------------------------------------------------------------------
  39. // ADs debug print, mem leak and object tracking-related stuff
  40. //---------------------------------------------------------------------------
  41. DECLARE_INFOLEVEL(ADs)
  42. //+---------------------------------------------------------------------------
  43. //
  44. // Function: ShutDown
  45. //
  46. // Synopsis: Function to handle printing out heap debugging display
  47. //
  48. //----------------------------------------------------------------------------
  49. inline VOID ShutDown()
  50. {
  51. #if DBG==1
  52. #ifndef MSVC
  53. DUMP_TRACKING_INFO_DELETE();
  54. DeleteCriticalSection(&g_csOT);
  55. #endif // ifndef MSVC
  56. DeleteCriticalSection(&g_csDP);
  57. #endif
  58. }
  59. extern "C" DWORD heapInfoLevel;
  60. extern "C" DWORD OtInfoLevel;
  61. extern "C" DWORD ADsInfoLevel;
  62. //+---------------------------------------------------------------------------
  63. //
  64. // Function: GetINIHeapInfoLevel
  65. //
  66. // Synopsis: Gets various infolevel values from win.ini
  67. //
  68. //----------------------------------------------------------------------------
  69. inline VOID GetINIHeapInfoLevel()
  70. {
  71. #if DBG==1
  72. const INT MAXINFOLEN=11;
  73. WCHAR awcs[MAXINFOLEN];
  74. #ifndef MSVC
  75. if (GetProfileString(L"winnt",L"heapInfoLevel", L"00000003", awcs,MAXINFOLEN))
  76. heapInfoLevel = wcstoul(awcs, NULL, 16);
  77. if (GetProfileString(L"winnt",L"Ot", L"00000003", awcs, MAXINFOLEN))
  78. OtInfoLevel = wcstoul(awcs, NULL, 16);
  79. #endif // MSVC
  80. if (GetProfileString(L"winnt",L"ADsInfoLevel", L"00000003", awcs,MAXINFOLEN))
  81. ADsInfoLevel = wcstoul(awcs, NULL, 16);
  82. #endif
  83. }
  84. // Globals
  85. ULONG g_ulObjCount = 0; // Number of objects alive in oleds.dll
  86. //+------------------------------------------------------------------------
  87. //
  88. // Macro that calculates the number of elements in a statically-defined
  89. // array.
  90. //
  91. // Note - I swiped this from ADsary.cxx - A type-safe array class. Remember
  92. // to swipe the whole thing as required.
  93. //-------------------------------------------------------------------------
  94. #define ARRAY_SIZE(_a) (sizeof(_a) / sizeof(_a[0]))
  95. CWinNTProviderCF g_cfProvider;
  96. CWinNTNamespaceCF g_cfNamespace;
  97. CWinNTSystemInfoCF g_cfWinNTSystemInfo;
  98. //CWinNTDomainCF g_cfDomain;
  99. //+------------------------------------------------------------------------
  100. //
  101. // oleds class factories
  102. //
  103. //-------------------------------------------------------------------------
  104. struct CLSCACHE
  105. {
  106. const CLSID * pclsid;
  107. IClassFactory * pCF;
  108. };
  109. CLSCACHE g_aclscache[] =
  110. {
  111. &CLSID_WinNTProvider, &g_cfProvider,
  112. &CLSID_WinNTNamespace, &g_cfNamespace,
  113. &CLSID_WinNTSystemInfo, &g_cfWinNTSystemInfo
  114. };
  115. //+---------------------------------------------------------------
  116. //
  117. // Function: DllGetClassObject
  118. //
  119. // Synopsis: Standard DLL entrypoint for locating class factories
  120. //
  121. //----------------------------------------------------------------
  122. STDAPI
  123. DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID FAR* ppv)
  124. {
  125. HRESULT hr;
  126. size_t i;
  127. for (i = 0; i < ARRAY_SIZE(g_aclscache); i++)
  128. {
  129. if (IsEqualCLSID(clsid, *g_aclscache[i].pclsid))
  130. {
  131. hr = g_aclscache[i].pCF->QueryInterface(iid, ppv);
  132. RRETURN(hr);
  133. }
  134. }
  135. *ppv = NULL;
  136. //
  137. // Add Debugging Code to indicate that the oleds.DllGetClassObject has been called with an unknown CLSID.
  138. //
  139. return E_NOINTERFACE;
  140. }
  141. //+---------------------------------------------------------------
  142. //
  143. // Function: DllCanUnloadNow
  144. //
  145. // Synopsis: Standard DLL entrypoint to determine if DLL can be unloaded
  146. //
  147. //---------------------------------------------------------------
  148. STDAPI
  149. DllCanUnloadNow(void)
  150. {
  151. HRESULT hr;
  152. hr = S_FALSE;
  153. if (AggregatorDllCanUnload() ) {
  154. hr = S_OK;
  155. }
  156. return hr;
  157. }
  158. void LoadLocalizedStrings()
  159. {
  160. if (g_fStringsLoaded) {
  161. return;
  162. }
  163. if (!LoadStringW(
  164. g_hInst,
  165. ADS_WINNT_BUILTIN,
  166. g_szBuiltin,
  167. sizeof( g_szBuiltin ) / sizeof( WCHAR )
  168. )
  169. ) {
  170. wcscpy(g_szBuiltin, L"BUILTIN");
  171. }
  172. if (!LoadStringW(
  173. g_hInst,
  174. ADS_WINNT_NT_AUTHORITY,
  175. g_szNT_Authority,
  176. sizeof( g_szNT_Authority ) / sizeof( WCHAR )
  177. )
  178. ) {
  179. wcscpy(g_szNT_Authority, L"NT AUTHORITY");
  180. }
  181. if (!LoadStringW(
  182. g_hInst,
  183. ADS_WINNT_EVERYONE,
  184. g_szEveryone,
  185. sizeof( g_szEveryone ) / sizeof( WCHAR )
  186. )
  187. ) {
  188. wcscpy(g_szEveryone, L"Everyone");
  189. }
  190. }
  191. //+---------------------------------------------------------------
  192. //
  193. // Function: LibMain
  194. //
  195. // Synopsis: Standard DLL initialization entrypoint
  196. //
  197. //---------------------------------------------------------------
  198. EXTERN_C BOOL __cdecl
  199. LibMain(HINSTANCE hInst, ULONG ulReason, LPVOID pvReserved)
  200. {
  201. HRESULT hr;
  202. static DWORD dwCriticalSectionsInitialized = 0;
  203. switch (ulReason)
  204. {
  205. case DLL_PROCESS_ATTACH:
  206. //
  207. // Catch case of init crit sect failing.
  208. //
  209. __try {
  210. DisableThreadLibraryCalls(hInst);
  211. g_hInst = hInst;
  212. g_hActiveDs = GetModuleHandle(TEXT("activeds.dll"));
  213. InitializeCriticalSection(&g_TypeInfoCritSect);
  214. ++dwCriticalSectionsInitialized;
  215. //
  216. // If the following code is ever uncommented, then the
  217. // switch statement in the DLL_PROCESS_DETACH section
  218. // also needs to be updated to take this into account.
  219. //
  220. // Disabled to avoid linker warnings
  221. // InitializeCriticalSection(&g_DispTypeInfoCritSect);
  222. //
  223. //
  224. // for 3rd party extension
  225. //
  226. InitializeCriticalSection(&g_ExtCritSect);
  227. ++dwCriticalSectionsInitialized;
  228. //
  229. // Initialize the loadlibs critsect.
  230. //
  231. InitializeCriticalSection(&g_csLoadLibs);
  232. ++dwCriticalSectionsInitialized;
  233. #if DBG==1
  234. InitializeCriticalSection(&g_csDP);
  235. ++dwCriticalSectionsInitialized;
  236. #ifndef MSVC
  237. InitializeCriticalSection(&g_csOT);
  238. ++dwCriticalSectionsInitialized;
  239. InitializeCriticalSection(&g_csMem);
  240. ++dwCriticalSectionsInitialized;
  241. #endif
  242. #endif
  243. //
  244. // Load up localized strings.
  245. //
  246. LoadLocalizedStrings();
  247. gpClassHead = BuildClassesList();
  248. //
  249. // Build the global object class cache
  250. //
  251. hr = CObjNameCache::CreateClassCache(
  252. &pgPDCNameCache
  253. );
  254. if (FAILED(hr)) {
  255. return(FALSE);
  256. }
  257. //
  258. // create semaphore used to protect global data (DLL handles and
  259. // function pointers.
  260. //
  261. if ((FpnwLoadLibSemaphore = CreateSemaphore( NULL,1,1,NULL ))
  262. == NULL)
  263. {
  264. return FALSE ;
  265. }
  266. g_pRtlEncryptMemory = (FRTLENCRYPTMEMORY) LoadAdvapi32Function(
  267. STRINGIZE(RtlEncryptMemory));
  268. g_pRtlDecryptMemory = (FRTLDECRYPTMEMORY) LoadAdvapi32Function(
  269. STRINGIZE(RtlDecryptMemory));
  270. if( (NULL == g_pRtlEncryptMemory) || (NULL == g_pRtlDecryptMemory) )
  271. g_pRtlEncryptMemory = g_pRtlDecryptMemory = NULL;
  272. }
  273. __except (EXCEPTION_EXECUTE_HANDLER) {
  274. //
  275. // Critical failure
  276. //
  277. //
  278. // Delete the critical sections. Note this must occur in reverse order
  279. // to the order in which they were initialized. The fall through in
  280. // each case statement is intentional.
  281. //
  282. switch(dwCriticalSectionsInitialized)
  283. {
  284. #if DBG==1
  285. #ifndef MSVC
  286. case 6:
  287. DeleteCriticalSection(&g_csMem);
  288. case 5:
  289. DeleteCriticalSection(&g_csOT);
  290. #endif
  291. case 4:
  292. DeleteCriticalSection(&g_csDP);
  293. #endif
  294. case 3:
  295. DeleteCriticalSection(&g_csLoadLibs);
  296. case 2:
  297. //
  298. // Causes link warnings if enabled
  299. // DeleteCriticalSection(&g_DispTypeInfoCritSect);
  300. //
  301. DeleteCriticalSection(&g_ExtCritSect);
  302. case 1:
  303. DeleteCriticalSection(&g_TypeInfoCritSect);
  304. }
  305. //
  306. // Reset the counts of critical sections that we have initialized, just
  307. // in case LibMain(DLL_PROCESS_DETACH) does get called.
  308. //
  309. dwCriticalSectionsInitialized = 0;
  310. return FALSE;
  311. }
  312. break;
  313. case DLL_PROCESS_DETACH:
  314. //
  315. // Release semaphor if applicable.
  316. //
  317. if (FpnwLoadLibSemaphore) {
  318. CloseHandle(FpnwLoadLibSemaphore);
  319. FpnwLoadLibSemaphore = NULL;
  320. }
  321. //
  322. // Del the name cache - delte should handle NULL btw.
  323. //
  324. delete pgPDCNameCache;
  325. //
  326. // free global list of class entries for 3rd party ext
  327. //
  328. FreeClassesList(gpClassHead);
  329. //
  330. // Delete the critical sections. Note this must occur in reverse order
  331. // to the order in which they were initialized. The fall through in
  332. // each case statement is intentional.
  333. //
  334. switch(dwCriticalSectionsInitialized)
  335. {
  336. #if DBG==1
  337. #ifndef MSVC
  338. case 6:
  339. DeleteCriticalSection(&g_csMem);
  340. case 5:
  341. DeleteCriticalSection(&g_csOT);
  342. #endif
  343. case 4:
  344. DeleteCriticalSection(&g_csDP);
  345. #endif
  346. case 3:
  347. DeleteCriticalSection(&g_csLoadLibs);
  348. case 2:
  349. //
  350. // Causes link warnings if enabled
  351. // DeleteCriticalSection(&g_DispTypeInfoCritSect);
  352. //
  353. DeleteCriticalSection(&g_ExtCritSect);
  354. case 1:
  355. DeleteCriticalSection(&g_TypeInfoCritSect);
  356. }
  357. //
  358. // Free libs we may have loaded dynamically.
  359. //
  360. if (g_hDllNetapi32) {
  361. FreeLibrary((HMODULE) g_hDllNetapi32);
  362. g_hDllNetapi32 = NULL;
  363. }
  364. if (g_hDllAdvapi32) {
  365. FreeLibrary((HMODULE) g_hDllAdvapi32);
  366. }
  367. break;
  368. default:
  369. break;
  370. }
  371. return TRUE;
  372. }
  373. //+---------------------------------------------------------------------------
  374. //
  375. // Function: DllMain
  376. //
  377. // Synopsis: entry point for NT - post .546
  378. //
  379. //----------------------------------------------------------------------------
  380. BOOL
  381. DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  382. {
  383. return LibMain((HINSTANCE)hDll, dwReason, lpReserved);
  384. }
  385. //+------------------------------------------------------------------------
  386. //
  387. // Function: GetCachedClsidIndex
  388. //
  389. // Synopsis: Returns the index of the given CLSID in the cache, or
  390. // -1 if the CLSID is not present in the cache
  391. //
  392. // Arguments: [clsid]
  393. //
  394. // Returns: int
  395. //
  396. //-------------------------------------------------------------------------
  397. int
  398. GetCachedClsidIndex(REFCLSID clsid)
  399. {
  400. int i;
  401. CLSCACHE * pclscache;
  402. for (i = 0, pclscache = g_aclscache;
  403. i < ARRAY_SIZE(g_aclscache);
  404. i ++, pclscache++)
  405. {
  406. if (IsEqualCLSID(*pclscache->pclsid, clsid))
  407. return i;
  408. }
  409. return -1;
  410. }
  411. //+------------------------------------------------------------------------
  412. //
  413. // Function: GetCachedClassFactory
  414. //
  415. // Synopsis: Returns the cached class factory with the given index.
  416. // The pointer returned has been AddRef'd.
  417. //
  418. // Arguments: [iclsid]
  419. //
  420. // Returns: IClassFactory *
  421. //
  422. //-------------------------------------------------------------------------
  423. IClassFactory *
  424. GetCachedClassFactory(int iclsid)
  425. {
  426. IClassFactory * pCF;
  427. // Assert(iclsid >= 0);
  428. // Assert(iclsid < ARRAY_SIZE(g_aclscache));
  429. pCF = g_aclscache[iclsid].pCF;
  430. pCF->AddRef();
  431. return pCF;
  432. }
  433. //+------------------------------------------------------------------------
  434. //
  435. // Function: GetCachedClsid
  436. //
  437. // Synopsis: Returns the CLSID corresponding to the given index.
  438. // Normally, code should call GetCachedClassFactory to get
  439. // the class factory directly.
  440. //
  441. // Arguments: [iclsid] -- Clsid index
  442. // [pclsid] -- Matching clsid returned in *pclsid
  443. //
  444. //-------------------------------------------------------------------------
  445. void
  446. GetCachedClsid(int iclsid, CLSID * pclsid)
  447. {
  448. // Assert(iclsid >= 0);
  449. // Assert(iclsid < ARRAY_SIZE(g_aclscache));
  450. *pclsid = *g_aclscache[iclsid].pclsid;
  451. }