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.

397 lines
10 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1995.
  5. //
  6. // File: libmain.cxx
  7. //
  8. // Contents: LibMain for nds.dll
  9. //
  10. // Functions: LibMain, DllGetClassObject
  11. //
  12. // History: 25-Oct-94 KrishnaG Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "ldap.hxx"
  16. #pragma hdrstop
  17. HINSTANCE g_hInst = NULL;
  18. extern HMODULE g_hActiveDs;
  19. typedef DWORD (*PF_DllGetClassObject) (
  20. REFCLSID clsid,
  21. REFIID iid,
  22. LPVOID FAR* ppverved
  23. );
  24. //---------------------------------------------------------------------------
  25. // ADs debug print, mem leak and object tracking-related stuff
  26. //---------------------------------------------------------------------------
  27. DECLARE_INFOLEVEL(ADs)
  28. //+---------------------------------------------------------------------------
  29. //
  30. // Function: ShutDown
  31. //
  32. // Synopsis: Function to handle printing out heap debugging display
  33. //
  34. //----------------------------------------------------------------------------
  35. inline VOID ShutDown()
  36. {
  37. #if DBG==1
  38. #ifndef MSVC
  39. DUMP_TRACKING_INFO_DELETE();
  40. DeleteCriticalSection(&g_csOT);
  41. #endif // ifndef MSVC
  42. DeleteCriticalSection(&g_csDP);
  43. #endif
  44. }
  45. extern "C" DWORD heapInfoLevel;
  46. extern "C" DWORD OtInfoLevel;
  47. extern "C" DWORD ADsInfoLevel;
  48. extern CRITICAL_SECTION g_RootDSECritSect;
  49. extern CRITICAL_SECTION g_ExtCritSect;
  50. extern CRITICAL_SECTION g_TypeInfoCritSect;
  51. extern CRITICAL_SECTION g_DispTypeInfoCritSect;
  52. //+---------------------------------------------------------------------------
  53. //
  54. // Function: GetINIHeapInfoLevel
  55. //
  56. // Synopsis: Gets various infolevel values from win.ini
  57. //
  58. //----------------------------------------------------------------------------
  59. inline VOID GetINIHeapInfoLevel()
  60. {
  61. #if DBG==1
  62. const INT MAXINFOLEN=11;
  63. TCHAR awcs[MAXINFOLEN];
  64. #ifndef MSVC
  65. if (GetProfileString(TEXT("LDAP"),TEXT("heapInfoLevel"), TEXT("00000003"), awcs,MAXINFOLEN))
  66. heapInfoLevel = _tcstoul(awcs, NULL, 16);
  67. if (GetProfileString(TEXT("LDAP"),TEXT("Ot"), TEXT("00000003"), awcs, MAXINFOLEN))
  68. OtInfoLevel = _tcstoul(awcs, NULL, 16);
  69. #endif // MSVC
  70. if (GetProfileString(TEXT("LDAP"),TEXT("ADsInfoLevel"), TEXT("00000003"), awcs,MAXINFOLEN))
  71. ADsInfoLevel = _tcstoul(awcs, NULL, 16);
  72. #endif
  73. }
  74. // Globals
  75. ULONG g_ulObjCount = 0; // Number of objects alive in oleds.dll
  76. CLDAPProviderCF g_cfProvider;
  77. CLDAPNamespaceCF g_cfNamespace;
  78. CADSystemInfoCF g_cfADSystemInfo;
  79. CLDAPConnectionCF g_cfLDAPConnection;
  80. CUmiLDAPQueryCF g_cfLDAPUmiQuery;
  81. CNameTranslateCF g_cfNameTranslate;
  82. //+------------------------------------------------------------------------
  83. //
  84. // oleds class factories
  85. //
  86. //-------------------------------------------------------------------------
  87. struct CLSCACHE
  88. {
  89. const CLSID * pclsid;
  90. IClassFactory * pCF;
  91. };
  92. CLSCACHE g_aclscache[] =
  93. {
  94. &CLSID_LDAPProvider, &g_cfProvider,
  95. &CLSID_LDAPNamespace, &g_cfNamespace,
  96. &CLSID_NameTranslate, &g_cfNameTranslate,
  97. &CLSID_ADSystemInfo, &g_cfADSystemInfo,
  98. &CLSID_LDAPConnectionObject, &g_cfLDAPConnection,
  99. &CLSID_UmiLDAPQueryObject, &g_cfLDAPUmiQuery
  100. };
  101. extern PCLASS_ENTRY gpClassHead;
  102. //+---------------------------------------------------------------
  103. //
  104. // Function: DllGetClassObject
  105. //
  106. // Synopsis: Standard DLL entrypoint for locating class factories
  107. //
  108. //----------------------------------------------------------------
  109. STDAPI
  110. DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID FAR* ppv)
  111. {
  112. HRESULT hr = E_NOINTERFACE;
  113. size_t i;
  114. HKEY hKey = NULL;
  115. HINSTANCE hDll = NULL ;
  116. if (ppv)
  117. *ppv = NULL;
  118. for (i = 0; i < ARRAY_SIZE(g_aclscache); i++)
  119. {
  120. if (IsEqualCLSID(clsid, *g_aclscache[i].pclsid))
  121. {
  122. hr = g_aclscache[i].pCF->QueryInterface(iid, ppv);
  123. RRETURN(hr);
  124. }
  125. }
  126. //
  127. // This workaround is for the special case where an old version of ADSI
  128. // is installed in the system. Installing that will overwrite the registry
  129. // with the old setting for pathcracker. The pathcracker object used to live
  130. // on adsldp.
  131. // The following code redirects the call to the DllGetClassObject in
  132. // activeds if the Pathname object is being requested. It also fixes the
  133. // registry to point to the correct DLL.
  134. //
  135. if (IsEqualCLSID(clsid, CLSID_Pathname)) {
  136. PF_DllGetClassObject pfDllGetClassObject= NULL ;
  137. WCHAR szPathDescriptor[] = L"ADs Pathname Object";
  138. WCHAR szDllName[] = L"activeds.dll";
  139. DWORD WinError;
  140. if (!(hDll = LoadLibrary(szDllName))) {
  141. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  142. }
  143. if (!(pfDllGetClassObject = (PF_DllGetClassObject)GetProcAddress(hDll, "DllGetClassObject"))) {
  144. BAIL_ON_FAILURE(hr = HRESULT_FROM_WIN32(GetLastError()));
  145. }
  146. hr = (*pfDllGetClassObject)(clsid,
  147. iid,
  148. ppv);
  149. BAIL_ON_FAILURE(hr);
  150. //
  151. // Setting the general description
  152. // Even if any of the operations below fails, we'll just bail with the
  153. // hr from DllGetClassObject.
  154. //
  155. WinError = RegOpenKeyEx(HKEY_CLASSES_ROOT,
  156. L"CLSID\\{080d0d78-f421-11d0-a36e-00c04fb950dc}",
  157. NULL,
  158. KEY_ALL_ACCESS,
  159. &hKey);
  160. if (WinError != ERROR_SUCCESS) {
  161. goto error;
  162. }
  163. WinError = RegSetValueEx(hKey,
  164. NULL,
  165. 0,
  166. REG_SZ,
  167. (BYTE *)szPathDescriptor,
  168. (wcslen(szPathDescriptor)+1) * sizeof(WCHAR));
  169. if (WinError != ERROR_SUCCESS) {
  170. goto error;
  171. }
  172. RegCloseKey(hKey);
  173. hKey = NULL;
  174. //
  175. // Setting the inprocserver
  176. //
  177. WinError = RegOpenKeyEx(HKEY_CLASSES_ROOT,
  178. L"CLSID\\{080d0d78-f421-11d0-a36e-00c04fb950dc}\\InprocServer32",
  179. NULL,
  180. KEY_ALL_ACCESS,
  181. &hKey);
  182. if (WinError != ERROR_SUCCESS) {
  183. goto error;
  184. }
  185. WinError = RegSetValueEx(hKey,
  186. NULL,
  187. 0,
  188. REG_SZ,
  189. (BYTE *)szDllName,
  190. (wcslen(szDllName)+1) * sizeof(WCHAR));
  191. if (WinError != ERROR_SUCCESS) {
  192. goto error;
  193. }
  194. }
  195. //
  196. // Add Debugging Code to indicate that the oleds.DllGetClassObject has been called with an unknown CLSID.
  197. //
  198. error:
  199. if (hDll) {
  200. FreeLibrary(hDll);
  201. }
  202. if (hKey) {
  203. RegCloseKey(hKey);
  204. }
  205. return hr;
  206. }
  207. //+---------------------------------------------------------------
  208. //
  209. // Function: DllCanUnloadNow
  210. //
  211. // Synopsis: Standard DLL entrypoint to determine if DLL can be unloaded
  212. //
  213. //---------------------------------------------------------------
  214. STDAPI
  215. DllCanUnloadNow(void)
  216. {
  217. HRESULT hr;
  218. hr = S_FALSE;
  219. //
  220. // Both the ldap and utils\cdispmgr count need to be 0
  221. //
  222. if (AggregatorDllCanUnload() && DllReadyToUnload()) {
  223. hr = S_OK;
  224. }
  225. return hr;
  226. }
  227. //+---------------------------------------------------------------
  228. //
  229. // Function: LibMain
  230. //
  231. // Synopsis: Standard DLL initialization entrypoint
  232. //
  233. //---------------------------------------------------------------
  234. EXTERN_C BOOL __cdecl
  235. LibMain(HINSTANCE hInst, ULONG ulReason, LPVOID pvReserved)
  236. {
  237. HRESULT hr;
  238. switch (ulReason)
  239. {
  240. case DLL_PROCESS_ATTACH:
  241. //
  242. // In try to catch possibily of init crit sects failing.
  243. //
  244. __try {
  245. DisableThreadLibraryCalls(hInst);
  246. g_hInst = hInst;
  247. g_hActiveDs = GetModuleHandle(TEXT("activeds.dll"));
  248. // Maybe we should check the handle.
  249. #if DBG==1
  250. #ifndef MSVC
  251. InitializeCriticalSection(&g_csOT);
  252. InitializeCriticalSection(&g_csMem);
  253. #endif
  254. InitializeCriticalSection(&g_csDP);
  255. #endif
  256. InitializeCriticalSection(&g_RootDSECritSect);
  257. InitializeCriticalSection(&g_ExtCritSect);
  258. InitializeCriticalSection(&g_TypeInfoCritSect);
  259. InitializeCriticalSection(&g_DispTypeInfoCritSect);
  260. InitializeCriticalSection(&g_csLoadLibsCritSect);
  261. }
  262. __except (EXCEPTION_EXECUTE_HANDLER) {
  263. //
  264. // Something went wrong
  265. //
  266. return FALSE;
  267. }
  268. break;
  269. case DLL_PROCESS_DETACH:
  270. //
  271. // free global list of class entries for 3rd party ext
  272. //
  273. if (gpClassHead) {
  274. FreeClassesList(gpClassHead);
  275. }
  276. if (gpszStickyServerName) {
  277. FreeADsStr(gpszStickyServerName);
  278. gpszStickyServerName = NULL;
  279. }
  280. if (gpszStickyDomainName) {
  281. FreeADsStr(gpszStickyDomainName);
  282. gpszStickyDomainName = NULL;
  283. }
  284. FreeServerType();
  285. //
  286. // Good idea to delete all the critical sections
  287. //
  288. #if DBG==1
  289. #ifndef MSVC
  290. DeleteCriticalSection(&g_csOT);
  291. DeleteCriticalSection(&g_csMem);
  292. #endif
  293. DeleteCriticalSection(&g_csDP);
  294. #endif
  295. DeleteCriticalSection(&g_RootDSECritSect);
  296. DeleteCriticalSection(&g_ExtCritSect);
  297. DeleteCriticalSection(&g_TypeInfoCritSect);
  298. DeleteCriticalSection(&g_DispTypeInfoCritSect);
  299. DeleteCriticalSection(&g_csLoadLibsCritSect);
  300. //
  301. // Should be ok to free the dynamically loaded libs.
  302. //
  303. if (g_hDllNtdsapi) {
  304. FreeLibrary((HMODULE) g_hDllNtdsapi);
  305. g_hDllNtdsapi = NULL;
  306. }
  307. if (g_hDllSecur32) {
  308. FreeLibrary((HMODULE) g_hDllSecur32);
  309. }
  310. break;
  311. default:
  312. break;
  313. }
  314. return TRUE;
  315. }
  316. //+---------------------------------------------------------------------------
  317. //
  318. // Function: DllMain
  319. //
  320. // Synopsis: entry point for NT - post .546
  321. //
  322. //----------------------------------------------------------------------------
  323. BOOL
  324. DllMain(HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
  325. {
  326. return LibMain((HINSTANCE)hDll, dwReason, lpReserved);
  327. }