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.

476 lines
12 KiB

  1. #include "stock.h"
  2. #pragma hdrstop
  3. #define SHFUSION_IMPL
  4. #include "shfusion.h"
  5. #include "delaycc.h"
  6. #ifdef FUSION_DOWNLEVEL
  7. #include <w95wraps.h>
  8. #endif
  9. typedef BOOL (__stdcall *PFNACTCTX)(HANDLE, ULONG_PTR *);
  10. typedef BOOL (__stdcall *PFNDEACTCTX)(DWORD, ULONG_PTR );
  11. typedef HANDLE (__stdcall *PFNCREATECTX)(ACTCTX*);
  12. typedef void (__stdcall *PFNRELCTX)(HANDLE);
  13. typedef UINT (__stdcall *PFNGSWD)(PTSTR psz, int cch);
  14. HMODULE g_hmodKernel = NULL;
  15. static PFNACTCTX s_pfnAct = (PFNACTCTX)-1;
  16. static PFNDEACTCTX s_pfnDeact = (PFNDEACTCTX)-1;
  17. static PFNCREATECTX s_pfnCreateact = (PFNCREATECTX)-1;
  18. static PFNRELCTX s_pfnReleaseact = (PFNRELCTX)-1;
  19. static PFNGSWD s_pfnGetSysWinDir = (PFNGSWD)-1;
  20. HANDLE NT5_CreateActCtx(ACTCTX* p)
  21. {
  22. if (s_pfnCreateact == (PFNCREATECTX)-1)
  23. {
  24. g_hmodKernel = GetModuleHandle(TEXT("Kernel32"));
  25. if (g_hmodKernel)
  26. {
  27. #ifdef _UNICODE
  28. s_pfnCreateact = (PFNCREATECTX)GetProcAddress(g_hmodKernel, "CreateActCtxW");
  29. #else
  30. s_pfnCreateact = (PFNCREATECTX)GetProcAddress(g_hmodKernel, "CreateActCtxA");
  31. #endif // _UNICODE
  32. }
  33. else
  34. s_pfnCreateact = NULL;
  35. }
  36. if (s_pfnCreateact)
  37. return s_pfnCreateact(p);
  38. return NULL;
  39. }
  40. void NT5_ReleaseActCtx(HANDLE h)
  41. {
  42. if (s_pfnReleaseact == (PFNRELCTX)-1)
  43. {
  44. g_hmodKernel = GetModuleHandle(TEXT("Kernel32"));
  45. if (g_hmodKernel)
  46. {
  47. s_pfnReleaseact = (PFNRELCTX)GetProcAddress(g_hmodKernel, "ReleaseActCtx");
  48. }
  49. else
  50. s_pfnReleaseact = NULL;
  51. }
  52. if (s_pfnReleaseact)
  53. s_pfnReleaseact(h);
  54. }
  55. BOOL NT5_ActivateActCtx(HANDLE h, ULONG_PTR* p)
  56. {
  57. if (s_pfnAct == (PFNACTCTX)-1)
  58. {
  59. g_hmodKernel = GetModuleHandle(TEXT("Kernel32"));
  60. if (g_hmodKernel)
  61. {
  62. s_pfnAct = (PFNACTCTX)GetProcAddress(g_hmodKernel, "ActivateActCtx");
  63. }
  64. else
  65. {
  66. s_pfnAct = NULL;
  67. }
  68. }
  69. *p = 0;
  70. if (s_pfnAct)
  71. {
  72. return s_pfnAct(h, p);
  73. }
  74. return TRUE;
  75. }
  76. BOOL NT5_DeactivateActCtx(ULONG_PTR p)
  77. {
  78. if (s_pfnDeact == (PFNDEACTCTX)-1)
  79. {
  80. g_hmodKernel = GetModuleHandle(TEXT("Kernel32"));
  81. if (g_hmodKernel)
  82. {
  83. s_pfnDeact = (PFNDEACTCTX)GetProcAddress(g_hmodKernel, "DeactivateActCtx");
  84. }
  85. else
  86. s_pfnDeact = NULL;
  87. }
  88. if (s_pfnDeact)
  89. return s_pfnDeact(0, p);
  90. return TRUE;
  91. }
  92. BOOL SHActivateContext(ULONG_PTR* pulCookie)
  93. {
  94. *pulCookie = 0;
  95. if (g_hActCtx != INVALID_HANDLE_VALUE)
  96. {
  97. return NT5_ActivateActCtx(g_hActCtx, pulCookie);
  98. }
  99. // Default to success in activation for down level.
  100. return TRUE;
  101. }
  102. void SHDeactivateContext(ULONG_PTR ulCookie)
  103. {
  104. if (ulCookie != 0)
  105. {
  106. NT5_DeactivateActCtx(ulCookie);
  107. }
  108. }
  109. #define ENTERCONTEXT(fail) \
  110. ULONG_PTR ulCookie = 0;\
  111. if (!SHActivateContext(&ulCookie)) \
  112. return fail;\
  113. __try {
  114. #define LEAVECONTEXT \
  115. } __finally {SHDeactivateContext(ulCookie);}
  116. EXTERN_C HINSTANCE g_hinst;
  117. HANDLE g_hActCtx = INVALID_HANDLE_VALUE;
  118. UINT NT5_GetSystemWindowsDirectory(PTSTR psz, int cch)
  119. {
  120. if (s_pfnGetSysWinDir == (PFNGSWD)-1)
  121. {
  122. g_hmodKernel = GetModuleHandle(TEXT("Kernel32"));
  123. if (g_hmodKernel)
  124. {
  125. #ifdef _UNICODE
  126. s_pfnGetSysWinDir = (PFNGSWD)GetProcAddress(g_hmodKernel, "GetSystemWindowsDirectoryW");
  127. #else
  128. s_pfnGetSysWinDir = (PFNGSWD)GetProcAddress(g_hmodKernel, "GetSystemWindowsDirectoryA");
  129. #endif // _UNICODE
  130. }
  131. else
  132. s_pfnGetSysWinDir = NULL;
  133. }
  134. if (s_pfnGetSysWinDir)
  135. return s_pfnGetSysWinDir(psz, cch);
  136. else
  137. return GetWindowsDirectory(psz, cch);
  138. }
  139. void SHGetManifest(PTSTR pszManifest, int cch)
  140. {
  141. int cchWindir = NT5_GetSystemWindowsDirectory(pszManifest, cch);
  142. // We want to use StrCatBuff but we cannot assume that the caller
  143. // is using shlwapi so we do it manually. Note that it's okay to use
  144. // lstrcpynW even though Win9x doesn't support it, because Win9x doesn't
  145. // support manifests anyway!
  146. if (cch > cchWindir)
  147. {
  148. lstrcpyn(pszManifest + cchWindir, TEXT("\\WindowsShell.Manifest"),
  149. cch - cchWindir);
  150. }
  151. }
  152. void VerifyComctl32Loaded()
  153. {
  154. #ifndef NOCOMCTL32
  155. DelayLoadCC();
  156. #endif
  157. }
  158. BOOL SHFusionInitializeIDCC(PTSTR pszPath, int id, BOOL fLoadCC)
  159. {
  160. TCHAR szPath[MAX_PATH];
  161. ACTCTX act = {0};
  162. if (pszPath == NULL)
  163. {
  164. SHGetManifest(szPath, ARRAYSIZE(szPath));
  165. pszPath = szPath;
  166. }
  167. else
  168. {
  169. act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
  170. act.lpResourceName = MAKEINTRESOURCE(id);
  171. }
  172. if (g_hActCtx == INVALID_HANDLE_VALUE)
  173. {
  174. act.cbSize = sizeof(act);
  175. act.lpSource = pszPath;
  176. g_hActCtx = NT5_CreateActCtx(&act);
  177. }
  178. #ifndef NOCOMCTL32
  179. if (fLoadCC)
  180. DelayLoadCC();
  181. #endif
  182. return g_hActCtx != INVALID_HANDLE_VALUE;
  183. }
  184. BOOL SHFusionInitializeID(PTSTR pszPath, int id)
  185. {
  186. return SHFusionInitializeIDCC(pszPath, id, TRUE);
  187. }
  188. BOOL SHFusionInitialize(PTSTR pszPath)
  189. {
  190. return SHFusionInitializeID(pszPath, 123);
  191. }
  192. BOOL SHFusionInitializeFromModuleID(HMODULE hMod, int id)
  193. {
  194. TCHAR szPath[MAX_PATH];
  195. GetModuleFileName(hMod, szPath, ARRAYSIZE(szPath));
  196. return SHFusionInitializeIDCC(szPath, id, TRUE);
  197. }
  198. BOOL SHFusionInitializeFromModuleIDCC(HMODULE hMod, int id, BOOL fLoadCC)
  199. {
  200. TCHAR szPath[MAX_PATH];
  201. GetModuleFileName(hMod, szPath, ARRAYSIZE(szPath));
  202. return SHFusionInitializeIDCC(szPath, id, fLoadCC);
  203. }
  204. BOOL __stdcall SHFusionInitializeFromModuleIDNoCC(HMODULE hMod, int id)
  205. {
  206. TCHAR szPath[MAX_PATH];
  207. GetModuleFileName(hMod, szPath, ARRAYSIZE(szPath));
  208. return SHFusionInitializeIDCC(szPath, id, FALSE);
  209. }
  210. BOOL SHFusionInitializeFromModule(HMODULE hMod)
  211. {
  212. TCHAR szPath[MAX_PATH];
  213. GetModuleFileName(hMod, szPath, ARRAYSIZE(szPath));
  214. return SHFusionInitialize(szPath);
  215. }
  216. void SHFusionUninitialize()
  217. {
  218. if (g_hActCtx != INVALID_HANDLE_VALUE)
  219. {
  220. NT5_ReleaseActCtx(g_hActCtx);
  221. g_hActCtx = INVALID_HANDLE_VALUE;
  222. }
  223. }
  224. HMODULE SHFusionLoadLibrary(LPCTSTR lpLibFileName)
  225. {
  226. HMODULE hmod;
  227. ENTERCONTEXT(NULL)
  228. hmod = LoadLibrary(lpLibFileName);
  229. LEAVECONTEXT
  230. return hmod;
  231. }
  232. HWND SHFusionCreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle,
  233. int x, int y, int nWidth, int nHeight, HWND hWndParent,
  234. HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  235. {
  236. HWND hwnd;
  237. ENTERCONTEXT(NULL)
  238. VerifyComctl32Loaded();
  239. hwnd = CreateWindow(lpClassName, lpWindowName, dwStyle,
  240. x, y, nWidth, nHeight, hWndParent,
  241. hMenu, hInstance, lpParam);
  242. LEAVECONTEXT
  243. return hwnd;
  244. }
  245. HWND SHFusionCreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
  246. DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent,
  247. HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  248. {
  249. HWND hwnd;
  250. ENTERCONTEXT(NULL)
  251. VerifyComctl32Loaded();
  252. hwnd = CreateWindowEx(dwExStyle, lpClassName, lpWindowName,
  253. dwStyle, x, y, nWidth, nHeight, hWndParent,
  254. hMenu, hInstance, lpParam);
  255. LEAVECONTEXT
  256. return hwnd;
  257. }
  258. HWND SHNoFusionCreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
  259. DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent,
  260. HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  261. {
  262. // DO NOT ACTIVATE A MANIFEST.
  263. HWND hwnd;
  264. VerifyComctl32Loaded();
  265. hwnd = CreateWindowEx(dwExStyle, lpClassName, lpWindowName,
  266. dwStyle, x, y, nWidth, nHeight, hWndParent,
  267. hMenu, hInstance, lpParam);
  268. return hwnd;
  269. }
  270. HWND SHFusionCreateDialogIndirect(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate,
  271. HWND hWndParent, DLGPROC lpDialogFunc)
  272. {
  273. HWND hwnd;
  274. ENTERCONTEXT(NULL)
  275. VerifyComctl32Loaded();
  276. hwnd = CreateDialogIndirect(hInstance, lpTemplate, hWndParent, lpDialogFunc);
  277. LEAVECONTEXT
  278. return hwnd;
  279. }
  280. HWND SHFusionCreateDialogParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
  281. {
  282. HWND hwnd;
  283. ENTERCONTEXT(NULL)
  284. VerifyComctl32Loaded();
  285. hwnd = CreateDialogParam(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
  286. LEAVECONTEXT
  287. return hwnd;
  288. }
  289. HWND SHFusionCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent,
  290. DLGPROC lpDialogFunc, LPARAM lParamInit)
  291. {
  292. HWND hwnd;
  293. ENTERCONTEXT(NULL)
  294. VerifyComctl32Loaded();
  295. hwnd = CreateDialogIndirectParam(hInstance, lpTemplate, hWndParent,
  296. lpDialogFunc, lParamInit);
  297. LEAVECONTEXT
  298. return hwnd;
  299. }
  300. HWND SHNoFusionCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent,
  301. DLGPROC lpDialogFunc, LPARAM lParamInit)
  302. {
  303. HWND hwnd;
  304. VerifyComctl32Loaded();
  305. hwnd = CreateDialogIndirectParam(hInstance, lpTemplate, hWndParent,
  306. lpDialogFunc, lParamInit);
  307. return hwnd;
  308. }
  309. INT_PTR SHFusionDialogBoxIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE hDialogTemplate, HWND hWndParent,
  310. DLGPROC lpDialogFunc, LPARAM dwInitParam)
  311. {
  312. INT_PTR i;
  313. ENTERCONTEXT(0)
  314. VerifyComctl32Loaded();
  315. i = DialogBoxIndirectParam(hInstance, hDialogTemplate, hWndParent,
  316. lpDialogFunc, dwInitParam);
  317. LEAVECONTEXT
  318. return i;
  319. }
  320. INT_PTR SHFusionDialogBoxParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent,
  321. DLGPROC lpDialogFunc, LPARAM dwInitParam)
  322. {
  323. INT_PTR i;
  324. ENTERCONTEXT(0)
  325. VerifyComctl32Loaded();
  326. i = DialogBoxParam(hInstance, lpTemplateName, hWndParent,
  327. lpDialogFunc, dwInitParam);
  328. LEAVECONTEXT
  329. return i;
  330. }
  331. ATOM SHFusionRegisterClass(CONST WNDCLASS *lpWndClass)
  332. {
  333. ATOM a;
  334. ENTERCONTEXT(0)
  335. a = RegisterClass(lpWndClass);
  336. LEAVECONTEXT
  337. return a;
  338. }
  339. ATOM SHFusionRegisterClassEx(CONST WNDCLASSEX *lpwcx)
  340. {
  341. ATOM a;
  342. ENTERCONTEXT(0)
  343. a = RegisterClassEx(lpwcx);
  344. LEAVECONTEXT
  345. return a;
  346. }
  347. BOOL SHFusionGetClassInfo(HINSTANCE hInstance, LPCTSTR lpClassName, LPWNDCLASS lpWndClass)
  348. {
  349. BOOL f;
  350. ENTERCONTEXT(FALSE)
  351. f = GetClassInfo(hInstance, lpClassName, lpWndClass);
  352. LEAVECONTEXT
  353. return f;
  354. }
  355. BOOL SHFusionGetClassInfoEx(HINSTANCE hinst, LPCTSTR lpszClass, LPWNDCLASSEX lpwcx)
  356. {
  357. BOOL f;
  358. ENTERCONTEXT(FALSE)
  359. f = GetClassInfoEx(hinst, lpszClass, lpwcx);
  360. LEAVECONTEXT
  361. return f;
  362. }
  363. STDAPI SHSquirtManifest(HINSTANCE hInst, UINT uIdManifest, LPTSTR pszPath)
  364. {
  365. HRESULT hr = E_FAIL;
  366. char szManifest[2048]; // Comctl32 has a long manifest.
  367. if (LoadStringA(hInst, uIdManifest, szManifest, ARRAYSIZE(szManifest)))
  368. {
  369. HANDLE hFile;
  370. SetFileAttributes(pszPath, FILE_ATTRIBUTE_NORMAL);
  371. hFile = CreateFile(pszPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY, NULL);
  372. if (hFile != INVALID_HANDLE_VALUE)
  373. {
  374. DWORD dw = lstrlenA(szManifest) * sizeof(char);
  375. if (WriteFile(hFile, szManifest, dw, &dw, NULL))
  376. {
  377. hr = S_OK;
  378. }
  379. else
  380. {
  381. hr = HRESULT_FROM_WIN32(GetLastError());
  382. }
  383. CloseHandle(hFile);
  384. }
  385. }
  386. return hr;
  387. }