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.

652 lines
16 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. fusion.c
  5. Abstract:
  6. Wrappers and functions for fusionizing SetupAPI
  7. without effecting 3rd party DLL's
  8. and without dll-load overhead
  9. Author:
  10. Jamie Hunter (JamieHun) 12/4/2000
  11. Revision History:
  12. Jamie Hunter (JamieHun) Apr-28-2002
  13. Security code review
  14. --*/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. #undef CreateWindow
  18. #undef CreateWindowEx
  19. #undef CreateDialogParam
  20. #undef CreateDialogIndirectParam
  21. #undef DialogBoxParam
  22. #undef DialogBoxIndirectParam
  23. #undef MessageBox
  24. #undef CreatePropertySheetPage
  25. #undef DestroyPropertySheetPage
  26. #undef PropertySheet
  27. #undef ImageList_Create
  28. #undef ImageList_Destroy
  29. #undef ImageList_GetImageCount
  30. #undef ImageList_SetImageCount
  31. #undef ImageList_Add
  32. #undef ImageList_ReplaceIcon
  33. #undef ImageList_SetBkColor
  34. #undef ImageList_GetBkColor
  35. #undef ImageList_SetOverlayImage
  36. #include <shfusion.h>
  37. static CRITICAL_SECTION spFusionInitCritSec;
  38. static BOOL spInitFusionCritSec = FALSE;
  39. static BOOL spFusionDoneInit = FALSE;
  40. BOOL spFusionInitialize()
  41. /*++
  42. Routine Description:
  43. Called on DllLoad
  44. do minimum possible
  45. Arguments:
  46. none
  47. Return Value:
  48. TRUE successful initialization
  49. --*/
  50. {
  51. try {
  52. InitializeCriticalSection(&spFusionInitCritSec);
  53. spInitFusionCritSec = TRUE;
  54. } except (EXCEPTION_EXECUTE_HANDLER) {
  55. //
  56. // spInitFusionCritSec remains FALSE
  57. //
  58. }
  59. return spInitFusionCritSec;
  60. }
  61. VOID
  62. spFusionInitLong()
  63. /*++
  64. Routine Description:
  65. Called by internal stub to do real initialization
  66. Arguments:
  67. none
  68. Return Value:
  69. none
  70. --*/
  71. {
  72. BOOL locked = FALSE;
  73. BOOL success = FALSE;
  74. INITCOMMONCONTROLSEX CommCtrl;
  75. if(!spInitFusionCritSec) {
  76. //
  77. // critical section not initialized
  78. // probably out of memory
  79. // bail
  80. //
  81. MYASSERT(spInitFusionCritSec);
  82. spFusionDoneInit = TRUE;
  83. return;
  84. }
  85. try {
  86. EnterCriticalSection(&spFusionInitCritSec);
  87. locked = TRUE;
  88. } except(EXCEPTION_EXECUTE_HANDLER) {
  89. }
  90. if(!locked) {
  91. //
  92. // wasn't able to grab lock - probably out of memory
  93. // bail
  94. //
  95. spFusionDoneInit = TRUE;
  96. return;
  97. }
  98. if(spFusionDoneInit) {
  99. //
  100. // by the time we grabbed critical section
  101. // initialization was done
  102. // bail
  103. //
  104. LeaveCriticalSection(&spFusionInitCritSec);
  105. return;
  106. }
  107. //
  108. // call shell's fusion enabler
  109. //
  110. success = SHFusionInitializeFromModuleID(MyDllModuleHandle,IDR_MANIFEST);
  111. MYASSERT(success);
  112. ZeroMemory(&CommCtrl,sizeof(CommCtrl));
  113. CommCtrl.dwSize = sizeof(CommCtrl);
  114. CommCtrl.dwICC = ICC_WIN95_CLASSES | ICC_LINK_CLASS;
  115. success = InitCommonControlsEx(&CommCtrl);
  116. MYASSERT(success);
  117. //
  118. // at this point, it's now safe for anyone else to assume initialization is done
  119. // even if we haven't released critical section
  120. //
  121. spFusionDoneInit = TRUE;
  122. LeaveCriticalSection(&spFusionInitCritSec);
  123. }
  124. __inline
  125. VOID
  126. spFusionCheckInit()
  127. /*++
  128. Routine Description:
  129. Calls spFusionInitLong iff needed
  130. Arguments:
  131. none
  132. Return Value:
  133. none
  134. --*/
  135. {
  136. if(!spFusionDoneInit) {
  137. //
  138. // either not initialized, or currently going through initialization
  139. //
  140. spFusionInitLong();
  141. }
  142. }
  143. BOOL spFusionUninitialize(BOOL Full)
  144. /*++
  145. Routine Description:
  146. Called at DLL exit (if DLL being unloaded but not process Exit)
  147. Arguments:
  148. none
  149. Return Value:
  150. TRUE successful cleanup
  151. --*/
  152. {
  153. //
  154. // cleanup anything initialized at spFusionInitialize
  155. //
  156. if(spInitFusionCritSec) {
  157. DeleteCriticalSection(&spFusionInitCritSec);
  158. spInitFusionCritSec = FALSE;
  159. }
  160. if(Full && spFusionDoneInit) {
  161. SHFusionUninitialize();
  162. }
  163. return TRUE;
  164. }
  165. //
  166. // generic functions for dealing with 3rd party DLL's
  167. // that might be fusionized
  168. //
  169. HANDLE
  170. spFusionContextFromModule(
  171. IN PCTSTR ModuleName
  172. )
  173. /*++
  174. Routine Description:
  175. Called to get a fusion context for specified module name
  176. given blah.dll look for
  177. 1) blah.dll.manifest in same directory as blah.dll
  178. 2) blah.dll with a fusion resource ID 123.
  179. If either of these provide a valid manifest, use it
  180. otherwise use app global manifest.
  181. Arguments:
  182. fully qualified name of module that'll later be passed into LoadLibrary
  183. Return Value:
  184. fusion context, or NULL to indicate app-global
  185. --*/
  186. {
  187. ACTCTX act = { 0 };
  188. HANDLE hContext;
  189. TCHAR ManifestName[MAX_PATH];
  190. PTSTR End;
  191. act.cbSize = sizeof(act);
  192. if(FAILED(StringCchCopy(ManifestName,MAX_PATH,ModuleName))) {
  193. goto deflt;
  194. }
  195. if(GetFileAttributes(ManifestName) == -1) {
  196. //
  197. // didn't find DLL?
  198. //
  199. goto deflt;
  200. }
  201. if(FAILED(StringCchCat(ManifestName,SIZECHARS(ManifestName),TEXT(".Manifest")))) {
  202. goto deflt;
  203. }
  204. if(GetFileAttributes(ManifestName) != -1) {
  205. //
  206. // found manifest
  207. //
  208. act.lpSource = ManifestName;
  209. act.dwFlags = 0;
  210. hContext = CreateActCtx(&act);
  211. if(hContext != INVALID_HANDLE_VALUE) {
  212. //
  213. // we created context based on manifest file
  214. //
  215. return hContext;
  216. }
  217. }
  218. deflt:
  219. //
  220. // if the dll has a manifest resource
  221. // then use that
  222. //
  223. act.lpSource = ModuleName;
  224. // act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
  225. // act.lpResourceName = MAKEINTRESOURCE(123);
  226. act.dwFlags = 0;
  227. hContext = CreateActCtx(&act);
  228. if(hContext != INVALID_HANDLE_VALUE) {
  229. //
  230. // we created context based on resource
  231. //
  232. return hContext;
  233. }
  234. //
  235. // if we couldn't find an alternative, use app-global
  236. //
  237. return NULL;
  238. }
  239. BOOL
  240. spFusionKillContext(
  241. IN HANDLE hContext
  242. )
  243. /*++
  244. Routine Description:
  245. Release a context previously obtained by
  246. spFusionContextFromModule
  247. Arguments:
  248. fusion context
  249. Return Value:
  250. TRUE (always)
  251. --*/
  252. {
  253. if(hContext) {
  254. ReleaseActCtx(hContext);
  255. }
  256. return TRUE;
  257. }
  258. BOOL
  259. spFusionEnterContext(
  260. IN HANDLE hContext,
  261. OUT PSPFUSIONINSTANCE pInst
  262. )
  263. /*++
  264. Routine Description:
  265. Enter into a manifest context
  266. status of call is saved into pInst
  267. so that return value does not need
  268. to be checked
  269. Arguments:
  270. hContext = fusion context
  271. pInst = structure to save the "push" information
  272. Return Value:
  273. TRUE if success, FALSE otherwise
  274. --*/
  275. {
  276. pInst->Acquired = ActivateActCtx(hContext,&pInst->Cookie);
  277. MYASSERT(pInst->Acquired);
  278. return pInst->Acquired;
  279. }
  280. BOOL
  281. spFusionLeaveContext(
  282. IN PSPFUSIONINSTANCE pInst
  283. )
  284. /*++
  285. Routine Description:
  286. If pInst indicates that spFusionEnterContext
  287. succeeded, leave same context
  288. Arguments:
  289. pInst = structure initialized by spFusionEnterContext
  290. Return Value:
  291. TRUE if spFusionEnterContext succeeded, FALSE otherwise
  292. --*/
  293. {
  294. if(pInst->Acquired) {
  295. pInst->Acquired = FALSE;
  296. DeactivateActCtx(0,pInst->Cookie);
  297. return TRUE;
  298. } else {
  299. return FALSE;
  300. }
  301. }
  302. HWND spFusionCreateWindow(
  303. LPCTSTR lpClassName, // registered class name
  304. LPCTSTR lpWindowName, // window name
  305. DWORD dwStyle, // window style
  306. int x, // horizontal position of window
  307. int y, // vertical position of window
  308. int nWidth, // window width
  309. int nHeight, // window height
  310. HWND hWndParent, // handle to parent or owner window
  311. HMENU hMenu, // menu handle or child identifier
  312. HINSTANCE hInstance, // handle to application instance
  313. LPVOID lpParam // window-creation data
  314. )
  315. {
  316. spFusionCheckInit();
  317. return SHFusionCreateWindow(lpClassName,
  318. lpWindowName,
  319. dwStyle,
  320. x,
  321. y,
  322. nWidth,
  323. nHeight,
  324. hWndParent,
  325. hMenu,
  326. hInstance,
  327. lpParam
  328. );
  329. }
  330. HWND spFusionCreateWindowEx(
  331. DWORD dwExStyle, // extended window style
  332. LPCTSTR lpClassName, // registered class name
  333. LPCTSTR lpWindowName, // window name
  334. DWORD dwStyle, // window style
  335. int x, // horizontal position of window
  336. int y, // vertical position of window
  337. int nWidth, // window width
  338. int nHeight, // window height
  339. HWND hWndParent, // handle to parent or owner window
  340. HMENU hMenu, // menu handle or child identifier
  341. HINSTANCE hInstance, // handle to application instance
  342. LPVOID lpParam // window-creation data
  343. )
  344. {
  345. spFusionCheckInit();
  346. return SHFusionCreateWindowEx(dwExStyle,
  347. lpClassName,
  348. lpWindowName,
  349. dwStyle,
  350. x,
  351. y,
  352. nWidth,
  353. nHeight,
  354. hWndParent,
  355. hMenu,
  356. hInstance,
  357. lpParam
  358. );
  359. }
  360. HWND spFusionCreateDialogParam(
  361. HINSTANCE hInstance, // handle to module
  362. LPCTSTR lpTemplateName, // dialog box template
  363. HWND hWndParent, // handle to owner window
  364. DLGPROC lpDialogFunc, // dialog box procedure
  365. LPARAM dwInitParam // initialization value
  366. )
  367. {
  368. spFusionCheckInit();
  369. return SHFusionCreateDialogParam(
  370. hInstance,
  371. lpTemplateName,
  372. hWndParent,
  373. lpDialogFunc,
  374. dwInitParam
  375. );
  376. }
  377. HWND spFusionCreateDialogIndirectParam(
  378. HINSTANCE hInstance, // handle to module
  379. LPCDLGTEMPLATE lpTemplate, // dialog box template
  380. HWND hWndParent, // handle to owner window
  381. DLGPROC lpDialogFunc, // dialog box procedure
  382. LPARAM lParamInit // initialization value
  383. )
  384. {
  385. spFusionCheckInit();
  386. return SHFusionCreateDialogIndirectParam(
  387. hInstance,
  388. lpTemplate,
  389. hWndParent,
  390. lpDialogFunc,
  391. lParamInit
  392. );
  393. }
  394. INT_PTR spFusionDialogBoxParam(
  395. HINSTANCE hInstance, // handle to module
  396. LPCTSTR lpTemplateName, // dialog box template
  397. HWND hWndParent, // handle to owner window
  398. DLGPROC lpDialogFunc, // dialog box procedure
  399. LPARAM dwInitParam // initialization value
  400. )
  401. {
  402. spFusionCheckInit();
  403. return SHFusionDialogBoxParam(
  404. hInstance,
  405. lpTemplateName,
  406. hWndParent,
  407. lpDialogFunc,
  408. dwInitParam
  409. );
  410. }
  411. INT_PTR spFusionDialogBoxIndirectParam(
  412. HINSTANCE hInstance, // handle to module
  413. LPCDLGTEMPLATE hDialogTemplate, // dialog box template
  414. HWND hWndParent, // handle to owner window
  415. DLGPROC lpDialogFunc, // dialog box procedure
  416. LPARAM dwInitParam // initialization value
  417. )
  418. {
  419. spFusionCheckInit();
  420. return SHFusionDialogBoxIndirectParam(
  421. hInstance,
  422. hDialogTemplate,
  423. hWndParent,
  424. lpDialogFunc,
  425. dwInitParam
  426. );
  427. }
  428. int spFusionMessageBox(
  429. IN HWND hWnd,
  430. IN LPCTSTR lpText,
  431. IN LPCTSTR lpCaption,
  432. IN UINT uType
  433. )
  434. {
  435. ULONG_PTR dwCookie;
  436. BOOL act;
  437. int iRes = 0;
  438. spFusionCheckInit();
  439. act = SHActivateContext(&dwCookie);
  440. try {
  441. iRes = MessageBoxW(
  442. hWnd,
  443. lpText,
  444. lpCaption,
  445. uType
  446. );
  447. } finally {
  448. if(act) {
  449. SHDeactivateContext(dwCookie);
  450. }
  451. }
  452. return iRes;
  453. }
  454. INT_PTR spFusionPropertySheet(
  455. LPCPROPSHEETHEADER pPropSheetHeader
  456. )
  457. {
  458. spFusionCheckInit();
  459. return PropertySheetW(pPropSheetHeader);
  460. }
  461. HPROPSHEETPAGE spFusionCreatePropertySheetPage(
  462. LPPROPSHEETPAGE pPropSheetPage
  463. )
  464. {
  465. spFusionCheckInit();
  466. MYASSERT(pPropSheetPage->dwFlags & PSP_USEFUSIONCONTEXT);
  467. MYASSERT(!pPropSheetPage->hActCtx);
  468. MYASSERT(pPropSheetPage->dwSize >= sizeof(PROPSHEETPAGE));
  469. return CreatePropertySheetPageW(pPropSheetPage);
  470. }
  471. BOOL spFusionDestroyPropertySheetPage(
  472. HPROPSHEETPAGE hPropSheetPage
  473. )
  474. {
  475. spFusionCheckInit();
  476. return DestroyPropertySheetPage(
  477. hPropSheetPage
  478. );
  479. }
  480. HIMAGELIST spFusionImageList_Create(int cx, int cy, UINT flags, int cInitial, int cGrow)
  481. {
  482. spFusionCheckInit();
  483. return ImageList_Create(
  484. cx,
  485. cy,
  486. flags,
  487. cInitial,
  488. cGrow
  489. );
  490. }
  491. BOOL spFusionImageList_Destroy(HIMAGELIST himl)
  492. {
  493. spFusionCheckInit();
  494. return ImageList_Destroy(
  495. himl
  496. );
  497. }
  498. int spFusionImageList_Add(HIMAGELIST himl, HBITMAP hbmImage, HBITMAP hbmMask)
  499. {
  500. spFusionCheckInit();
  501. return ImageList_Add(
  502. himl,
  503. hbmImage,
  504. hbmMask
  505. );
  506. }
  507. int spFusionImageList_ReplaceIcon(HIMAGELIST himl, int i, HICON hicon)
  508. {
  509. spFusionCheckInit();
  510. return ImageList_ReplaceIcon(
  511. himl,
  512. i,
  513. hicon
  514. );
  515. }
  516. COLORREF spFusionImageList_SetBkColor(HIMAGELIST himl, COLORREF clrBk)
  517. {
  518. spFusionCheckInit();
  519. return ImageList_SetBkColor(
  520. himl,
  521. clrBk
  522. );
  523. }
  524. BOOL spFusionImageList_SetOverlayImage(HIMAGELIST himl, int iImage, int iOverlay)
  525. {
  526. spFusionCheckInit();
  527. return ImageList_SetOverlayImage(
  528. himl,
  529. iImage,
  530. iOverlay
  531. );
  532. }
  533. BOOL spFusionGetOpenFileName(LPOPENFILENAME lpofn)
  534. {
  535. spFusionCheckInit();
  536. return GetOpenFileNameW(lpofn);
  537. }