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.

627 lines
12 KiB

  1. /*
  2. * olepig.c - Module for indirect calling of OLE32.DLL functions.
  3. */
  4. /*
  5. OLE32.DLL should be redesigned and reimplemented so that it can
  6. be dynalinked to like a well-behaved DLL. OLE32.DLL is currently so slow and
  7. piggy that we are forced to delay loading it until absolutely necessary.
  8. */
  9. /* Headers
  10. **********/
  11. #include "project.h"
  12. #pragma hdrstop
  13. #include <ole2ver.h>
  14. /* Constants
  15. ************/
  16. #define OLE_PIG_MODULE TEXT("ole32.dll")
  17. /* Types
  18. ********/
  19. /* OLE APIs */
  20. typedef struct _olevtbl
  21. {
  22. DWORD (STDAPICALLTYPE *CoBuildVersion)(void);
  23. HRESULT (STDAPICALLTYPE *CoCreateInstance)(REFCLSID, PIUnknown, DWORD, REFIID, PVOID *);
  24. HRESULT (STDAPICALLTYPE *CoGetMalloc)(DWORD, PIMalloc *);
  25. HRESULT (STDAPICALLTYPE *CreateBindCtx)(DWORD, PIBindCtx *);
  26. HRESULT (STDAPICALLTYPE *CreateFileMoniker)(LPCOLESTR, PIMoniker *);
  27. HRESULT (STDAPICALLTYPE *OleInitialize)(PIMalloc);
  28. HRESULT (STDAPICALLTYPE *StgOpenStorage)(const OLECHAR *, PIStorage, DWORD, SNB, DWORD, PIStorage *);
  29. }
  30. OLEVTBL;
  31. DECLARE_STANDARD_TYPES(OLEVTBL);
  32. /* Module Variables
  33. *******************/
  34. /* OLE module handle */
  35. PRIVATE_DATA HANDLE MhmodOLE = NULL;
  36. /* pointer to vtable of OLE functions */
  37. PRIVATE_DATA POLEVTBL Mpolevtbl = NULL;
  38. /* TLS slot used to store OLE thread initialization state */
  39. PRIVATE_DATA DWORD MdwOLEInitSlot = TLS_OUT_OF_INDEXES;
  40. /***************************** Private Functions *****************************/
  41. /* Module Prototypes
  42. ********************/
  43. PRIVATE_CODE BOOL IsOLELoaded(void);
  44. PRIVATE_CODE BOOL LoadOLE(void);
  45. PRIVATE_CODE void UnloadOLE(void);
  46. PRIVATE_CODE BOOL InitializeOLE(void);
  47. PRIVATE_CODE BOOL GetOLEProc(LPSTR, PROC *);
  48. PRIVATE_CODE BOOL FillOLEVTable(void);
  49. #ifdef DEBUG
  50. PRIVATE_CODE BOOL IsValidPCOLEVTBL(PCOLEVTBL);
  51. PRIVATE_CODE BOOL OLELoadedStateOK(void);
  52. PRIVATE_CODE BOOL OLENotLoadedStateOK(void);
  53. PRIVATE_CODE BOOL OLEStateOk(void);
  54. #endif
  55. /*
  56. ** IsOLELoaded()
  57. **
  58. **
  59. **
  60. ** Arguments:
  61. **
  62. ** Returns:
  63. **
  64. ** Side Effects: none
  65. */
  66. PRIVATE_CODE BOOL IsOLELoaded(void)
  67. {
  68. ASSERT(OLEStateOk());
  69. return(MhmodOLE != NULL);
  70. }
  71. /*
  72. ** LoadOLE()
  73. **
  74. **
  75. **
  76. ** Arguments:
  77. **
  78. ** Returns:
  79. **
  80. ** Side Effects: none
  81. */
  82. PRIVATE_CODE BOOL LoadOLE(void)
  83. {
  84. BOOL bResult;
  85. if (IsOLELoaded())
  86. bResult = TRUE;
  87. else
  88. {
  89. bResult = FALSE;
  90. MhmodOLE = LoadLibrary(OLE_PIG_MODULE);
  91. if (MhmodOLE)
  92. {
  93. if (FillOLEVTable())
  94. {
  95. DWORD dwBuildVersion;
  96. dwBuildVersion = Mpolevtbl->CoBuildVersion();
  97. /* Require same major version and same or newer minor version. */
  98. if (HIWORD(dwBuildVersion) == rmm &&
  99. LOWORD(dwBuildVersion) >= rup)
  100. {
  101. bResult = TRUE;
  102. TRACE_OUT((TEXT("LoadOLE(): %s loaded. Oink oink!"),
  103. OLE_PIG_MODULE));
  104. }
  105. else
  106. WARNING_OUT((TEXT("LoadOLE(): Bad %s version %u.%u. This module was built with %s version %u.%u."),
  107. OLE_PIG_MODULE,
  108. (UINT)HIWORD(dwBuildVersion),
  109. (UINT)LOWORD(dwBuildVersion),
  110. OLE_PIG_MODULE,
  111. (UINT)rmm,
  112. (UINT)rup));
  113. }
  114. else
  115. WARNING_OUT((TEXT("LoadOLE(): FillOLEVTable() failed.")));
  116. }
  117. else
  118. WARNING_OUT((TEXT("LoadOLE(): LoadLibrary(%s) failed."),
  119. OLE_PIG_MODULE));
  120. if (! bResult)
  121. UnloadOLE();
  122. }
  123. if (bResult)
  124. {
  125. bResult = InitializeOLE();
  126. if (! bResult)
  127. WARNING_OUT((TEXT("LoadOLE(): %s loaded, but InitializeOLE() failed."),
  128. OLE_PIG_MODULE));
  129. }
  130. ASSERT(OLEStateOk());
  131. return(bResult);
  132. }
  133. /*
  134. ** UnloadOLE()
  135. **
  136. **
  137. **
  138. ** Arguments:
  139. **
  140. ** Returns:
  141. **
  142. ** Side Effects: none
  143. */
  144. PRIVATE_CODE void UnloadOLE(void)
  145. {
  146. if (Mpolevtbl)
  147. {
  148. FreeMemory(Mpolevtbl);
  149. Mpolevtbl = NULL;
  150. TRACE_OUT((TEXT("UnloadOLE(): Freed %s vtable."),
  151. OLE_PIG_MODULE));
  152. }
  153. if (MhmodOLE)
  154. {
  155. /* Don't call CoUninitialize() here. OLE32.DLL will. */
  156. FreeLibrary(MhmodOLE);
  157. MhmodOLE = NULL;
  158. TRACE_OUT((TEXT("UnloadOLE(): Freed %s."),
  159. OLE_PIG_MODULE));
  160. }
  161. ASSERT(OLENotLoadedStateOK());
  162. return;
  163. }
  164. /*
  165. ** InitializeOLE()
  166. **
  167. **
  168. **
  169. ** Arguments:
  170. **
  171. ** Returns:
  172. **
  173. ** Side Effects: none
  174. */
  175. PRIVATE_CODE BOOL InitializeOLE(void)
  176. {
  177. BOOL bResult;
  178. ASSERT(IsOLELoaded());
  179. ASSERT(MdwOLEInitSlot != TLS_OUT_OF_INDEXES);
  180. if (TlsGetValue(MdwOLEInitSlot))
  181. bResult = TRUE;
  182. else
  183. {
  184. HRESULT hr;
  185. hr = Mpolevtbl->OleInitialize(NULL);
  186. bResult = (SUCCEEDED(hr) ||
  187. hr == CO_E_ALREADYINITIALIZED);
  188. if (hr == CO_E_ALREADYINITIALIZED)
  189. WARNING_OUT((TEXT("InitializeOLE(): OLE already initialized for thread %lx. OleInitialize() returned %s."),
  190. GetCurrentThreadId(),
  191. GetHRESULTString(hr)));
  192. if (bResult)
  193. {
  194. EVAL(TlsSetValue(MdwOLEInitSlot, (PVOID)TRUE));
  195. TRACE_OUT((TEXT("InitializeOLE(): OLE initialized for thread %lx. Using apartment threading model."),
  196. GetCurrentThreadId()));
  197. }
  198. else
  199. WARNING_OUT((TEXT("InitializeOLE(): OleInitialize() failed for thread %lx, returning %s."),
  200. GetCurrentThreadId(),
  201. GetHRESULTString(hr)));
  202. }
  203. return(bResult);
  204. }
  205. /*
  206. ** GetOLEProc()
  207. **
  208. **
  209. **
  210. ** Arguments:
  211. **
  212. ** Returns:
  213. **
  214. ** Side Effects: none
  215. */
  216. PRIVATE_CODE BOOL GetOLEProc(LPSTR pcszProc, PROC *pfp)
  217. {
  218. //ASSERT(IS_VALID_STRING_PTR(pcszProc, CSTR));
  219. ASSERT(IS_VALID_WRITE_PTR(pfp, PROC));
  220. ASSERT(IS_VALID_HANDLE(MhmodOLE, MODULE));
  221. *pfp = GetProcAddress(MhmodOLE, pcszProc);
  222. if (*pfp)
  223. TRACE_OUT((TEXT("GetOLEProc(): Got address of %s!%s."),
  224. OLE_PIG_MODULE,
  225. pcszProc));
  226. else
  227. WARNING_OUT((TEXT("GetOLEProc(): Failed to get address of %s!%s."),
  228. OLE_PIG_MODULE,
  229. pcszProc));
  230. ASSERT(! *pfp ||
  231. IS_VALID_CODE_PTR(*pfp, PROC));
  232. return(*pfp != NULL);
  233. }
  234. /*
  235. ** FillOLEVTable()
  236. **
  237. **
  238. **
  239. ** Arguments:
  240. **
  241. ** Returns:
  242. **
  243. ** Side Effects: none
  244. */
  245. PRIVATE_CODE BOOL FillOLEVTable(void)
  246. {
  247. BOOL bResult;
  248. ASSERT(IS_VALID_HANDLE(MhmodOLE, MODULE));
  249. bResult = AllocateMemory(sizeof(*Mpolevtbl), &Mpolevtbl);
  250. if (bResult)
  251. {
  252. bResult = (GetOLEProc("CoBuildVersion", &(PROC)(Mpolevtbl->CoBuildVersion)) &&
  253. GetOLEProc("CoCreateInstance", &(PROC)(Mpolevtbl->CoCreateInstance)) &&
  254. GetOLEProc("CoGetMalloc", &(PROC)(Mpolevtbl->CoGetMalloc)) &&
  255. GetOLEProc("CreateBindCtx", &(PROC)(Mpolevtbl->CreateBindCtx)) &&
  256. GetOLEProc("CreateFileMoniker", &(PROC)(Mpolevtbl->CreateFileMoniker)) &&
  257. GetOLEProc("OleInitialize", &(PROC)(Mpolevtbl->OleInitialize)) &&
  258. GetOLEProc("StgOpenStorage", &(PROC)(Mpolevtbl->StgOpenStorage)));
  259. if (bResult)
  260. TRACE_OUT((TEXT("FillOLEVTable(): OLE vtable filled successfully.")));
  261. else
  262. {
  263. FreeMemory(Mpolevtbl);
  264. Mpolevtbl = NULL;
  265. WARNING_OUT((TEXT("FillOLEVTable(): Failed to fill OLE vtable.")));
  266. }
  267. }
  268. else
  269. WARNING_OUT((TEXT("FillOLEVTable(): Out of memory.")));
  270. ASSERT(! bResult ||
  271. OLELoadedStateOK());
  272. return(bResult);
  273. }
  274. #ifdef DEBUG
  275. /*
  276. ** IsValidPCOLEVTBL()
  277. **
  278. **
  279. **
  280. ** Arguments:
  281. **
  282. ** Returns:
  283. **
  284. ** Side Effects: none
  285. */
  286. PRIVATE_CODE BOOL IsValidPCOLEVTBL(PCOLEVTBL pcolevtbl)
  287. {
  288. return(IS_VALID_READ_PTR(pcolevtbl, PCOLEVTBL) &&
  289. IS_VALID_CODE_PTR(pcolevtbl->CoBuildVersion, CoBuildVersion) &&
  290. IS_VALID_CODE_PTR(pcolevtbl->CoCreateInstance, CoCreateInstance) &&
  291. IS_VALID_CODE_PTR(pcolevtbl->CoGetMalloc, CoGetMalloc) &&
  292. IS_VALID_CODE_PTR(pcolevtbl->CreateBindCtx, CreateBindCtx) &&
  293. IS_VALID_CODE_PTR(pcolevtbl->CreateFileMoniker, CreateFileMoniker) &&
  294. IS_VALID_CODE_PTR(pcolevtbl->OleInitialize, OleInitialize) &&
  295. IS_VALID_CODE_PTR(pcolevtbl->StgOpenStorage, StgOpenStorage));
  296. }
  297. /*
  298. ** OLELoadedStateOK()
  299. **
  300. **
  301. **
  302. ** Arguments:
  303. **
  304. ** Returns:
  305. **
  306. ** Side Effects: none
  307. */
  308. PRIVATE_CODE BOOL OLELoadedStateOK(void)
  309. {
  310. return(IS_VALID_HANDLE(MhmodOLE, MODULE) &&
  311. IS_VALID_STRUCT_PTR(Mpolevtbl, COLEVTBL));
  312. }
  313. /*
  314. ** OLENotLoadedStateOK()
  315. **
  316. **
  317. **
  318. ** Arguments:
  319. **
  320. ** Returns:
  321. **
  322. ** Side Effects: none
  323. */
  324. PRIVATE_CODE BOOL OLENotLoadedStateOK(void)
  325. {
  326. return(! MhmodOLE &&
  327. ! Mpolevtbl);
  328. }
  329. /*
  330. ** OLEStateOk()
  331. **
  332. **
  333. **
  334. ** Arguments:
  335. **
  336. ** Returns:
  337. **
  338. ** Side Effects: none
  339. */
  340. PRIVATE_CODE BOOL OLEStateOk(void)
  341. {
  342. return(OLELoadedStateOK() ||
  343. OLENotLoadedStateOK);
  344. }
  345. #endif
  346. /****************************** Public Functions *****************************/
  347. /*
  348. ** ProcessInitOLEPigModule()
  349. **
  350. **
  351. **
  352. ** Arguments:
  353. **
  354. ** Returns:
  355. **
  356. ** Side Effects: none
  357. */
  358. PUBLIC_CODE BOOL ProcessInitOLEPigModule(void)
  359. {
  360. BOOL bResult;
  361. ASSERT(MdwOLEInitSlot == TLS_OUT_OF_INDEXES);
  362. MdwOLEInitSlot = TlsAlloc();
  363. bResult = (MdwOLEInitSlot != TLS_OUT_OF_INDEXES);
  364. if (bResult)
  365. {
  366. EVAL(TlsSetValue(MdwOLEInitSlot, (PVOID)FALSE));
  367. TRACE_OUT((TEXT("ProcessInitOLEPigModule(): Using thread local storage slot %lu for OLE initialization state."),
  368. MdwOLEInitSlot));
  369. }
  370. else
  371. ERROR_OUT((TEXT("ProcessInitOLEPigModule(): TlsAlloc() failed to allocate thread local storage for OLE initialization state.")));
  372. return(bResult);
  373. }
  374. /*
  375. ** ProcessExitOLEPigModule()
  376. **
  377. **
  378. **
  379. ** Arguments:
  380. **
  381. ** Returns:
  382. **
  383. ** Side Effects: none
  384. */
  385. PUBLIC_CODE void ProcessExitOLEPigModule(void)
  386. {
  387. UnloadOLE();
  388. if (MdwOLEInitSlot != TLS_OUT_OF_INDEXES)
  389. {
  390. EVAL(TlsFree(MdwOLEInitSlot));
  391. MdwOLEInitSlot= TLS_OUT_OF_INDEXES;
  392. }
  393. return;
  394. }
  395. /*
  396. ** CoCreateInstance()
  397. **
  398. **
  399. **
  400. ** Arguments:
  401. **
  402. ** Returns:
  403. **
  404. ** Side Effects: none
  405. */
  406. HRESULT STDAPICALLTYPE CoCreateInstance(REFCLSID rclsid, PIUnknown piunkOuter,
  407. DWORD dwClsCtx, REFIID riid,
  408. PVOID *ppv)
  409. {
  410. HRESULT hr;
  411. if (LoadOLE())
  412. hr = Mpolevtbl->CoCreateInstance(rclsid, piunkOuter, dwClsCtx, riid, ppv);
  413. else
  414. hr = E_FAIL;
  415. return(hr);
  416. }
  417. /*
  418. ** CoGetMalloc()
  419. **
  420. **
  421. **
  422. ** Arguments:
  423. **
  424. ** Returns:
  425. **
  426. ** Side Effects: none
  427. */
  428. HRESULT STDAPICALLTYPE CoGetMalloc(DWORD dwMemContext, PIMalloc *ppimalloc)
  429. {
  430. HRESULT hr;
  431. if (LoadOLE())
  432. hr = Mpolevtbl->CoGetMalloc(dwMemContext, ppimalloc);
  433. else
  434. hr = E_FAIL;
  435. return(hr);
  436. }
  437. /*
  438. ** CreateBindCtx()
  439. **
  440. **
  441. **
  442. ** Arguments:
  443. **
  444. ** Returns:
  445. **
  446. ** Side Effects: none
  447. */
  448. HRESULT STDAPICALLTYPE CreateBindCtx(DWORD dwReserved, PIBindCtx *ppibindctx)
  449. {
  450. HRESULT hr;
  451. if (LoadOLE())
  452. hr = Mpolevtbl->CreateBindCtx(dwReserved, ppibindctx);
  453. else
  454. hr = E_FAIL;
  455. return(hr);
  456. }
  457. /*
  458. ** CreateFileMoniker()
  459. **
  460. **
  461. **
  462. ** Arguments:
  463. **
  464. ** Returns:
  465. **
  466. ** Side Effects: none
  467. */
  468. HRESULT STDAPICALLTYPE CreateFileMoniker(LPCOLESTR pwszPath, PIMoniker *ppimk)
  469. {
  470. HRESULT hr;
  471. if (LoadOLE())
  472. hr = Mpolevtbl->CreateFileMoniker(pwszPath, ppimk);
  473. else
  474. hr = E_FAIL;
  475. return(hr);
  476. }
  477. /*
  478. ** StgOpenStorage()
  479. **
  480. **
  481. **
  482. ** Arguments:
  483. **
  484. ** Returns:
  485. **
  486. ** Side Effects: none
  487. */
  488. HRESULT STDAPICALLTYPE StgOpenStorage(LPCOLESTR pwszName,
  489. PIStorage pistgPriority, DWORD dwMode,
  490. SNB snbExclude, DWORD dwReserved,
  491. PIStorage *ppistgOpen)
  492. {
  493. HRESULT hr;
  494. if (LoadOLE())
  495. hr = Mpolevtbl->StgOpenStorage(pwszName, pistgPriority, dwMode,
  496. snbExclude, dwReserved, ppistgOpen);
  497. else
  498. hr = E_FAIL;
  499. return(hr);
  500. }