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.

413 lines
10 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 void (__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. void 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. s_pfnGetSysWinDir(psz, cch);
  136. else
  137. GetWindowsDirectory(psz, cch);
  138. }
  139. void SHGetManifest(PTSTR pszManifest, int cch)
  140. {
  141. NT5_GetSystemWindowsDirectory(pszManifest, cch);
  142. // Tack WindowsShell.Manifest
  143. StrCat(pszManifest, TEXT("\\WindowsShell.Manifest"));
  144. }
  145. BOOL SHFusionInitializeID(PTSTR pszPath, int id)
  146. {
  147. TCHAR szPath[MAX_PATH];
  148. ACTCTX act = {0};
  149. if (pszPath == NULL)
  150. {
  151. SHGetManifest(szPath, ARRAYSIZE(szPath));
  152. pszPath = szPath;
  153. }
  154. else
  155. {
  156. act.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID;
  157. act.lpResourceName = MAKEINTRESOURCE(id);
  158. }
  159. if (g_hActCtx == INVALID_HANDLE_VALUE)
  160. {
  161. act.cbSize = sizeof(act);
  162. act.lpSource = pszPath;
  163. g_hActCtx = NT5_CreateActCtx(&act);
  164. }
  165. #ifndef NOCOMCTL32
  166. DelayLoadCC();
  167. #endif
  168. return g_hActCtx != INVALID_HANDLE_VALUE;
  169. }
  170. BOOL SHFusionInitialize(PTSTR pszPath)
  171. {
  172. return SHFusionInitializeID(pszPath, 123);
  173. }
  174. BOOL SHFusionInitializeFromModuleID(HMODULE hMod, int id)
  175. {
  176. TCHAR szPath[MAX_PATH];
  177. GetModuleFileName(hMod, szPath, ARRAYSIZE(szPath));
  178. return SHFusionInitializeID(szPath, id);
  179. }
  180. BOOL SHFusionInitializeFromModule(HMODULE hMod)
  181. {
  182. TCHAR szPath[MAX_PATH];
  183. GetModuleFileName(hMod, szPath, ARRAYSIZE(szPath));
  184. return SHFusionInitialize(szPath);
  185. }
  186. void SHFusionUninitialize()
  187. {
  188. if (g_hActCtx != INVALID_HANDLE_VALUE)
  189. {
  190. NT5_ReleaseActCtx(g_hActCtx);
  191. g_hActCtx = INVALID_HANDLE_VALUE;
  192. }
  193. }
  194. HMODULE SHFusionLoadLibrary(LPCTSTR lpLibFileName)
  195. {
  196. HMODULE hmod;
  197. ENTERCONTEXT(NULL)
  198. hmod = LoadLibrary(lpLibFileName);
  199. LEAVECONTEXT
  200. return hmod;
  201. }
  202. HWND SHFusionCreateWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName, DWORD dwStyle,
  203. int x, int y, int nWidth, int nHeight, HWND hWndParent,
  204. HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  205. {
  206. HWND hwnd;
  207. ENTERCONTEXT(NULL)
  208. hwnd = CreateWindow(lpClassName, lpWindowName, dwStyle,
  209. x, y, nWidth, nHeight, hWndParent,
  210. hMenu, hInstance, lpParam);
  211. LEAVECONTEXT
  212. return hwnd;
  213. }
  214. HWND SHFusionCreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
  215. DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent,
  216. HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  217. {
  218. HWND hwnd;
  219. ENTERCONTEXT(NULL)
  220. hwnd = CreateWindowEx(dwExStyle, lpClassName, lpWindowName,
  221. dwStyle, x, y, nWidth, nHeight, hWndParent,
  222. hMenu, hInstance, lpParam);
  223. LEAVECONTEXT
  224. return hwnd;
  225. }
  226. HWND SHNoFusionCreateWindowEx(DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
  227. DWORD dwStyle, int x, int y, int nWidth, int nHeight, HWND hWndParent,
  228. HMENU hMenu, HINSTANCE hInstance, LPVOID lpParam)
  229. {
  230. // DO NOT ACTIVATE A MANIFEST.
  231. HWND hwnd = CreateWindowEx(dwExStyle, lpClassName, lpWindowName,
  232. dwStyle, x, y, nWidth, nHeight, hWndParent,
  233. hMenu, hInstance, lpParam);
  234. return hwnd;
  235. }
  236. HWND SHFusionCreateDialogIndirect(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate,
  237. HWND hWndParent, DLGPROC lpDialogFunc)
  238. {
  239. HWND hwnd;
  240. ENTERCONTEXT(NULL)
  241. hwnd = CreateDialogIndirect(hInstance, lpTemplate, hWndParent, lpDialogFunc);
  242. LEAVECONTEXT
  243. return hwnd;
  244. }
  245. HWND SHFusionCreateDialogParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent, DLGPROC lpDialogFunc, LPARAM dwInitParam)
  246. {
  247. HWND hwnd;
  248. ENTERCONTEXT(NULL)
  249. hwnd = CreateDialogParam(hInstance, lpTemplateName, hWndParent, lpDialogFunc, dwInitParam);
  250. LEAVECONTEXT
  251. return hwnd;
  252. }
  253. HWND SHFusionCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent,
  254. DLGPROC lpDialogFunc, LPARAM lParamInit)
  255. {
  256. HWND hwnd;
  257. ENTERCONTEXT(NULL)
  258. hwnd = CreateDialogIndirectParam(hInstance, lpTemplate, hWndParent,
  259. lpDialogFunc, lParamInit);
  260. LEAVECONTEXT
  261. return hwnd;
  262. }
  263. HWND SHNoFusionCreateDialogIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE lpTemplate, HWND hWndParent,
  264. DLGPROC lpDialogFunc, LPARAM lParamInit)
  265. {
  266. HWND hwnd;
  267. hwnd = CreateDialogIndirectParam(hInstance, lpTemplate, hWndParent,
  268. lpDialogFunc, lParamInit);
  269. return hwnd;
  270. }
  271. INT_PTR SHFusionDialogBoxIndirectParam(HINSTANCE hInstance, LPCDLGTEMPLATE hDialogTemplate, HWND hWndParent,
  272. DLGPROC lpDialogFunc, LPARAM dwInitParam)
  273. {
  274. INT_PTR i;
  275. ENTERCONTEXT(0)
  276. i = DialogBoxIndirectParam(hInstance, hDialogTemplate, hWndParent,
  277. lpDialogFunc, dwInitParam);
  278. LEAVECONTEXT
  279. return i;
  280. }
  281. INT_PTR SHFusionDialogBoxParam(HINSTANCE hInstance, LPCTSTR lpTemplateName, HWND hWndParent,
  282. DLGPROC lpDialogFunc, LPARAM dwInitParam)
  283. {
  284. INT_PTR i;
  285. ENTERCONTEXT(0)
  286. i = DialogBoxParam(hInstance, lpTemplateName, hWndParent,
  287. lpDialogFunc, dwInitParam);
  288. LEAVECONTEXT
  289. return i;
  290. }
  291. ATOM SHFusionRegisterClass(CONST WNDCLASS *lpWndClass)
  292. {
  293. ATOM a;
  294. ENTERCONTEXT(0)
  295. a = RegisterClass(lpWndClass);
  296. LEAVECONTEXT
  297. return a;
  298. }
  299. ATOM SHFusionRegisterClassEx(CONST WNDCLASSEX *lpwcx)
  300. {
  301. ATOM a;
  302. ENTERCONTEXT(0)
  303. a = RegisterClassEx(lpwcx);
  304. LEAVECONTEXT
  305. return a;
  306. }
  307. BOOL SHFusionGetClassInfo(HINSTANCE hInstance, LPCTSTR lpClassName, LPWNDCLASS lpWndClass)
  308. {
  309. BOOL f;
  310. ENTERCONTEXT(FALSE)
  311. f = GetClassInfo(hInstance, lpClassName, lpWndClass);
  312. LEAVECONTEXT
  313. return f;
  314. }
  315. BOOL SHFusionGetClassInfoEx(HINSTANCE hinst, LPCTSTR lpszClass, LPWNDCLASSEX lpwcx)
  316. {
  317. BOOL f;
  318. ENTERCONTEXT(FALSE)
  319. f = GetClassInfoEx(hinst, lpszClass, lpwcx);
  320. LEAVECONTEXT
  321. return f;
  322. }
  323. STDAPI SHSquirtManifest(HINSTANCE hInst, UINT uIdManifest, LPTSTR pszPath)
  324. {
  325. HRESULT hr = E_FAIL;
  326. char szManifest[2048]; // Comctl32 has a long manifest.
  327. if (LoadStringA(hInst, uIdManifest, szManifest, ARRAYSIZE(szManifest)))
  328. {
  329. HANDLE hFile;
  330. SetFileAttributes(pszPath, FILE_ATTRIBUTE_NORMAL);
  331. hFile = CreateFile(pszPath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY, NULL);
  332. if (hFile != INVALID_HANDLE_VALUE)
  333. {
  334. DWORD dw = lstrlenA(szManifest) * sizeof(char);
  335. if (WriteFile(hFile, szManifest, dw, &dw, NULL))
  336. {
  337. hr = S_OK;
  338. }
  339. else
  340. {
  341. hr = HRESULT_FROM_WIN32(GetLastError());
  342. }
  343. CloseHandle(hFile);
  344. }
  345. }
  346. return hr;
  347. }