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.

577 lines
12 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: libmain.cxx
  7. //
  8. // Contents: LibMain for ADs.dll
  9. //
  10. // Functions: LibMain, DllGetClassObject
  11. //
  12. // History: 25-Oct-94 KrishnaG Created.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "winnt.hxx"
  16. #pragma hdrstop
  17. LPCWSTR lpszTopLevel = L"SOFTWARE\\Microsoft\\ADs\\Providers\\WinNT";
  18. LPCWSTR lpszExtensions = L"Extensions";
  19. PCLASS_ENTRY gpClassHead = NULL;
  20. PCLASS_ENTRY
  21. BuildClassesList()
  22. {
  23. HKEY hTopLevelKey = NULL;
  24. HKEY hExtensionKey = NULL;
  25. HKEY hExtensionRootKey = NULL;
  26. HKEY hClassKey = NULL;
  27. DWORD dwIndex = 0;
  28. WCHAR lpszClassName[MAX_PATH];
  29. DWORD dwchClassName = 0;
  30. PCLASS_ENTRY pClassHead = NULL;
  31. PCLASS_ENTRY pClassEntry = NULL;
  32. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  33. lpszTopLevel,
  34. 0,
  35. KEY_READ,
  36. &hTopLevelKey
  37. ) != ERROR_SUCCESS)
  38. {
  39. goto CleanupAndExit;
  40. }
  41. if (RegOpenKeyEx(hTopLevelKey,
  42. lpszExtensions,
  43. 0,
  44. KEY_READ,
  45. &hExtensionRootKey
  46. ) != ERROR_SUCCESS)
  47. {
  48. goto CleanupAndExit;
  49. }
  50. memset(lpszClassName, 0, sizeof(lpszClassName));
  51. dwchClassName = sizeof(lpszClassName)/sizeof(WCHAR);
  52. while(RegEnumKeyEx(hExtensionRootKey,
  53. dwIndex,
  54. lpszClassName,
  55. &dwchClassName,
  56. NULL,
  57. NULL,
  58. NULL,
  59. NULL
  60. ) == ERROR_SUCCESS)
  61. {
  62. //
  63. // Read namespace
  64. //
  65. if (RegOpenKeyEx(hExtensionRootKey,
  66. lpszClassName,
  67. 0,
  68. KEY_READ,
  69. &hClassKey
  70. ) != ERROR_SUCCESS){
  71. goto CleanupAndExit;
  72. }
  73. pClassEntry = BuildClassEntry(
  74. lpszClassName,
  75. hClassKey
  76. );
  77. if (pClassEntry) {
  78. pClassEntry->pNext = pClassHead;
  79. pClassHead = pClassEntry;
  80. }
  81. if (hClassKey) {
  82. CloseHandle(hClassKey);
  83. }
  84. memset(lpszClassName, 0, sizeof(lpszClassName));
  85. dwchClassName = sizeof(lpszClassName)/sizeof(WCHAR);
  86. dwIndex++;
  87. }
  88. CleanupAndExit:
  89. if (hExtensionRootKey) {
  90. RegCloseKey(hExtensionRootKey);
  91. }
  92. if (hTopLevelKey) {
  93. RegCloseKey(hTopLevelKey);
  94. }
  95. return(pClassHead);
  96. }
  97. VOID
  98. FreeClassesList(
  99. PCLASS_ENTRY pClassHead
  100. )
  101. {
  102. PCLASS_ENTRY pDelete;
  103. while (pClassHead) {
  104. pDelete = pClassHead;
  105. pClassHead = pClassHead->pNext;
  106. FreeClassEntry(pDelete);
  107. }
  108. return;
  109. }
  110. PCLASS_ENTRY
  111. BuildClassEntry(
  112. LPWSTR lpszClassName,
  113. HKEY hClassKey
  114. )
  115. {
  116. HKEY hTopLevelKey = NULL;
  117. HKEY hExtensionKey = NULL;
  118. DWORD dwIndex = 0;
  119. DWORD dwchExtensionCLSID = 0;
  120. WCHAR lpszExtensionCLSID[MAX_PATH];
  121. PCLASS_ENTRY pClassEntry = NULL;
  122. PEXTENSION_ENTRY pExtensionHead = NULL;
  123. PEXTENSION_ENTRY pExtensionEntry = NULL;
  124. pClassEntry = (PCLASS_ENTRY)AllocADsMem(sizeof(CLASS_ENTRY));
  125. if (!pClassEntry) {
  126. goto CleanupAndExit;
  127. }
  128. wcscpy(pClassEntry->szClassName, lpszClassName);
  129. memset(lpszExtensionCLSID, 0, sizeof(lpszExtensionCLSID));
  130. dwchExtensionCLSID = sizeof(lpszExtensionCLSID)/sizeof(WCHAR);
  131. while(RegEnumKeyEx(hClassKey,
  132. dwIndex,
  133. lpszExtensionCLSID,
  134. &dwchExtensionCLSID,
  135. NULL,
  136. NULL,
  137. NULL,
  138. NULL
  139. ) == ERROR_SUCCESS)
  140. {
  141. //
  142. // Read namespace
  143. //
  144. if (RegOpenKeyEx(hClassKey,
  145. lpszExtensionCLSID,
  146. 0,
  147. KEY_READ,
  148. &hExtensionKey
  149. ) != ERROR_SUCCESS){
  150. goto CleanupAndExit;
  151. }
  152. //
  153. // Read the Interfaces that this Extension supports
  154. //
  155. pExtensionEntry = BuildExtensionEntry(
  156. lpszExtensionCLSID,
  157. hExtensionKey
  158. );
  159. if (pExtensionEntry) {
  160. wcscpy(pExtensionEntry->szExtensionCLSID, lpszExtensionCLSID);
  161. pExtensionEntry->pNext = pExtensionHead;
  162. pExtensionHead = pExtensionEntry;
  163. }
  164. if (hExtensionKey) {
  165. CloseHandle(hExtensionKey);
  166. }
  167. memset(lpszExtensionCLSID, 0, sizeof(lpszExtensionCLSID));
  168. dwchExtensionCLSID = sizeof(lpszExtensionCLSID)/sizeof(WCHAR);
  169. dwIndex++;
  170. }
  171. pClassEntry->pExtensionHead = pExtensionHead;
  172. CleanupAndExit:
  173. return(pClassEntry);
  174. }
  175. PEXTENSION_ENTRY
  176. BuildExtensionEntry(
  177. LPWSTR lpszExtensionCLSID,
  178. HKEY hExtensionKey
  179. )
  180. {
  181. PEXTENSION_ENTRY pExtensionEntry = NULL;
  182. PINTERFACE_ENTRY pInterfaceEntry = NULL;
  183. PINTERFACE_ENTRY pInterfaceHead = NULL;
  184. WCHAR lpszInterfaces[MAX_PATH];
  185. DWORD dwchInterfaces = 0;
  186. LPWSTR psz = NULL;
  187. WCHAR Interface[MAX_PATH];
  188. HRESULT hr = S_OK;
  189. pExtensionEntry = (PEXTENSION_ENTRY)AllocADsMem(sizeof(EXTENSION_ENTRY));
  190. if (!pExtensionEntry) {
  191. goto CleanupAndExit;
  192. }
  193. memset(lpszInterfaces, 0, sizeof(lpszInterfaces));
  194. dwchInterfaces = sizeof(lpszInterfaces);
  195. RegQueryValueEx(
  196. hExtensionKey,
  197. L"Interfaces",
  198. NULL,
  199. NULL,
  200. (LPBYTE) lpszInterfaces,
  201. &dwchInterfaces
  202. );
  203. psz = lpszInterfaces;
  204. while (psz && *psz) {
  205. wcscpy(Interface, psz);
  206. // skip (length) + 1
  207. // lstrlen returns length sans '\0'
  208. pInterfaceEntry = (PINTERFACE_ENTRY)AllocADsMem(sizeof(INTERFACE_ENTRY));
  209. if (pInterfaceEntry) {
  210. wcscpy(pInterfaceEntry->szInterfaceIID, Interface);
  211. hr = IIDFromString(Interface, &(pInterfaceEntry->iid));
  212. pInterfaceEntry->pNext = pInterfaceHead;
  213. pInterfaceHead = pInterfaceEntry;
  214. }
  215. psz = psz + lstrlen(psz) + 1;
  216. }
  217. wcscpy(pExtensionEntry->szExtensionCLSID, lpszExtensionCLSID);
  218. hr = CLSIDFromString(lpszExtensionCLSID, &(pExtensionEntry->ExtCLSID));
  219. pExtensionEntry->pIID = pInterfaceHead;
  220. CleanupAndExit:
  221. return(pExtensionEntry);
  222. }
  223. void
  224. FreeInterfaceEntry(
  225. PINTERFACE_ENTRY pInterfaceEntry
  226. )
  227. {
  228. if (pInterfaceEntry) {
  229. FreeADsMem(pInterfaceEntry);
  230. }
  231. }
  232. void
  233. FreeExtensionEntry(
  234. PEXTENSION_ENTRY pExtensionEntry
  235. )
  236. {
  237. PINTERFACE_ENTRY pInterfaceEntry = NULL;
  238. PINTERFACE_ENTRY pTemp = NULL;
  239. if (pExtensionEntry) {
  240. pInterfaceEntry = pExtensionEntry->pIID;
  241. while (pInterfaceEntry) {
  242. pTemp = pInterfaceEntry->pNext;
  243. if (pInterfaceEntry) {
  244. FreeInterfaceEntry(pInterfaceEntry);
  245. }
  246. pInterfaceEntry = pTemp;
  247. }
  248. //
  249. // Now unload the Extension Object
  250. //
  251. if (pExtensionEntry->pUnknown) {
  252. //
  253. // Call non-delegating Release to release ref. count on innner
  254. // object (for pUnkown) -> inner object self destroy
  255. //
  256. (pExtensionEntry->pUnknown)->Release();
  257. }
  258. FreeADsMem(pExtensionEntry);
  259. }
  260. return;
  261. }
  262. void
  263. FreeClassEntry(
  264. PCLASS_ENTRY pClassEntry
  265. )
  266. {
  267. PEXTENSION_ENTRY pExtensionEntry = NULL;
  268. PEXTENSION_ENTRY pTemp = NULL;
  269. if (pClassEntry) {
  270. pExtensionEntry = pClassEntry->pExtensionHead;
  271. while (pExtensionEntry) {
  272. pTemp = pExtensionEntry->pNext;
  273. if (pExtensionEntry) {
  274. FreeExtensionEntry(pExtensionEntry);
  275. }
  276. pExtensionEntry = pTemp;
  277. }
  278. FreeADsMem(pClassEntry);
  279. }
  280. return;
  281. }
  282. PINTERFACE_ENTRY
  283. MakeCopyofInterfaceEntry(
  284. PINTERFACE_ENTRY pInterfaceEntry
  285. )
  286. {
  287. PINTERFACE_ENTRY pNewInterfaceEntry = NULL;
  288. pNewInterfaceEntry = (PINTERFACE_ENTRY)AllocADsMem(sizeof(INTERFACE_ENTRY));
  289. if (pNewInterfaceEntry) {
  290. wcscpy(pNewInterfaceEntry->szInterfaceIID, pInterfaceEntry->szInterfaceIID);
  291. memcpy(&(pNewInterfaceEntry->iid), &(pInterfaceEntry->iid), sizeof(GUID));
  292. }
  293. return(pNewInterfaceEntry);
  294. }
  295. PEXTENSION_ENTRY
  296. MakeCopyofExtensionEntry(
  297. PEXTENSION_ENTRY pExtensionEntry
  298. )
  299. {
  300. PEXTENSION_ENTRY pNewExtensionEntry = NULL;
  301. PINTERFACE_ENTRY pInterfaceEntry = NULL;
  302. PINTERFACE_ENTRY pNewInterfaceEntry = NULL;
  303. PINTERFACE_ENTRY pNewInterfaceHead = NULL;
  304. pInterfaceEntry = pExtensionEntry->pIID;
  305. while (pInterfaceEntry) {
  306. pNewInterfaceEntry = MakeCopyofInterfaceEntry(pInterfaceEntry);
  307. if (pNewInterfaceEntry) {
  308. pNewInterfaceEntry->pNext = pNewInterfaceHead;
  309. pNewInterfaceHead = pNewInterfaceEntry;
  310. }
  311. pInterfaceEntry = pInterfaceEntry->pNext;
  312. }
  313. pNewExtensionEntry = (PEXTENSION_ENTRY)AllocADsMem(sizeof(EXTENSION_ENTRY));
  314. if (pNewExtensionEntry) {
  315. wcscpy(
  316. pNewExtensionEntry->szExtensionCLSID,
  317. pExtensionEntry->szExtensionCLSID
  318. );
  319. memcpy(
  320. &(pNewExtensionEntry->ExtCLSID),
  321. &(pExtensionEntry->ExtCLSID),
  322. sizeof(GUID)
  323. );
  324. pNewExtensionEntry->pIID = pNewInterfaceHead;
  325. //
  326. // Initialize fields we won't know the values of until an instacne of
  327. // the extension is created and aggregated (loaded).
  328. //
  329. pNewExtensionEntry->pUnknown=NULL;
  330. pNewExtensionEntry->pPrivDisp=NULL;
  331. pNewExtensionEntry->pADsExt=NULL;
  332. pNewExtensionEntry->fDisp=FALSE;
  333. pNewExtensionEntry->dwExtensionID = (DWORD) -1; //invalid dwExtensionID
  334. //
  335. // let class entry handle pNext
  336. //
  337. }
  338. return(pNewExtensionEntry);
  339. }
  340. PCLASS_ENTRY
  341. MakeCopyofClassEntry(
  342. PCLASS_ENTRY pClassEntry
  343. )
  344. {
  345. PCLASS_ENTRY pNewClassEntry = NULL;
  346. PEXTENSION_ENTRY pExtensionEntry = NULL;
  347. PEXTENSION_ENTRY pNewExtensionEntry = NULL;
  348. PEXTENSION_ENTRY pNewExtensionHead = NULL;
  349. pExtensionEntry = pClassEntry->pExtensionHead;
  350. while (pExtensionEntry) {
  351. pNewExtensionEntry = MakeCopyofExtensionEntry(pExtensionEntry);
  352. if (pNewExtensionEntry) {
  353. pNewExtensionEntry->pNext = pNewExtensionHead;
  354. pNewExtensionHead = pNewExtensionEntry;
  355. }
  356. pExtensionEntry = pExtensionEntry->pNext;
  357. }
  358. pNewClassEntry = (PCLASS_ENTRY)AllocADsMem(sizeof(CLASS_ENTRY));
  359. if (pNewClassEntry) {
  360. wcscpy(pNewClassEntry->szClassName, pClassEntry->szClassName);
  361. pNewClassEntry->pExtensionHead = pNewExtensionHead;
  362. }
  363. return(pNewClassEntry);
  364. }
  365. CRITICAL_SECTION g_ExtCritSect;
  366. #define ENTER_EXTENSION_CRITSECT() EnterCriticalSection(&g_ExtCritSect)
  367. #define LEAVE_EXTENSION_CRITSECT() LeaveCriticalSection(&g_ExtCritSect)
  368. HRESULT
  369. ADSIGetExtensionList(
  370. LPWSTR pszClassName,
  371. PCLASS_ENTRY * ppClassEntry
  372. )
  373. {
  374. PCLASS_ENTRY pTempClassEntry = NULL;
  375. PCLASS_ENTRY pClassEntry = NULL;
  376. ENTER_EXTENSION_CRITSECT();
  377. pTempClassEntry = gpClassHead;
  378. while (pTempClassEntry) {
  379. if (!_wcsicmp(pTempClassEntry->szClassName, pszClassName)) {
  380. //
  381. // Make a copy of this entire extension and
  382. // hand it over to the calling entity.
  383. //
  384. pClassEntry = MakeCopyofClassEntry(pTempClassEntry);
  385. *ppClassEntry = pClassEntry;
  386. LEAVE_EXTENSION_CRITSECT();
  387. RRETURN(S_OK);
  388. }
  389. pTempClassEntry = pTempClassEntry->pNext;
  390. }
  391. *ppClassEntry = NULL;
  392. LEAVE_EXTENSION_CRITSECT();
  393. RRETURN(S_OK);
  394. }