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.

4234 lines
123 KiB

  1. /*++
  2. Copyright (c) Microsoft Corporation. All rights reserved.
  3. Module Name:
  4. FilePaths.cpp
  5. Abstract:
  6. This AppVerifier shim hooks the APIs that require
  7. the caller to provide a path to a file or directory
  8. and attempts to ensure that the path is not a hardcoded
  9. one.
  10. Notes:
  11. This is a general purpose shim.
  12. Created:
  13. 02/26/2001 clupu
  14. Modified:
  15. 07/24/2001 rparsons Added hooks for Nt* calls
  16. Added checks for apps that use environment variables
  17. 09/04/2001 rparsons Fixed a bug in the Massage functions where we would
  18. stop processing a fake path as soon as we found a hardcode
  19. path. Also, we now fix multiple fake paths in the same string.
  20. 10/17/2001 rparsons Fixed bug where we wouldn't always report a bad path.
  21. This was because the CString Find method is case sensitive,
  22. but the paths we were comparing were mixed in case. Now all
  23. paths are in lower case form prior to the comparison.
  24. 11/21/2001 rparsons Fixed Raid bug # 492674. FilePaths did not contain an implementation
  25. for SHFileOperation - apps that used this API would not get their
  26. paths corrected, thus failing.
  27. 11/29/2001 rparsons Fixed Raid bug # 497853. Removed the hooks for GetTempFileName as they
  28. were causing a false positive to be generated. Also added code that
  29. would handle cases where the user provides a path via a common dialog
  30. and we provide a fake path to be massaged later.
  31. 12/11/2001 rparsons Fixed Raid bug # 505599. Added hooks for all RegQueryValue* calls
  32. and NtQueryValueKey. The Nt hook allows us to catch paths for
  33. system components.
  34. 02/20/2002 rparsons Implemented strsafe functions.
  35. --*/
  36. #include "precomp.h"
  37. #include "rtlutils.h"
  38. IMPLEMENT_SHIM_BEGIN(FilePaths)
  39. #include "ShimHookMacro.h"
  40. #include "ShimCString.h"
  41. #include "veriflog.h"
  42. #include "ids.h"
  43. APIHOOK_ENUM_BEGIN
  44. APIHOOK_ENUM_ENTRY(GetCommandLineA)
  45. APIHOOK_ENUM_ENTRY(GetCommandLineW)
  46. APIHOOK_ENUM_ENTRY(GetTempPathA)
  47. APIHOOK_ENUM_ENTRY(GetTempPathW)
  48. APIHOOK_ENUM_ENTRY(GetOpenFileNameA)
  49. APIHOOK_ENUM_ENTRY(GetOpenFileNameW)
  50. APIHOOK_ENUM_ENTRY(GetSaveFileNameA)
  51. APIHOOK_ENUM_ENTRY(GetSaveFileNameW)
  52. APIHOOK_ENUM_ENTRY(GetModuleFileNameA)
  53. APIHOOK_ENUM_ENTRY(GetModuleFileNameW)
  54. APIHOOK_ENUM_ENTRY(GetModuleFileNameExA)
  55. APIHOOK_ENUM_ENTRY(GetModuleFileNameExW)
  56. APIHOOK_ENUM_ENTRY(GetCurrentDirectoryA)
  57. APIHOOK_ENUM_ENTRY(GetCurrentDirectoryW)
  58. APIHOOK_ENUM_ENTRY(GetSystemDirectoryA)
  59. APIHOOK_ENUM_ENTRY(GetSystemDirectoryW)
  60. APIHOOK_ENUM_ENTRY(GetSystemWindowsDirectoryA)
  61. APIHOOK_ENUM_ENTRY(GetSystemWindowsDirectoryW)
  62. APIHOOK_ENUM_ENTRY(GetWindowsDirectoryA)
  63. APIHOOK_ENUM_ENTRY(GetWindowsDirectoryW)
  64. APIHOOK_ENUM_ENTRY(SHGetFolderPathA)
  65. APIHOOK_ENUM_ENTRY(SHGetFolderPathW)
  66. APIHOOK_ENUM_ENTRY(SHGetSpecialFolderPathA)
  67. APIHOOK_ENUM_ENTRY(SHGetSpecialFolderPathW)
  68. APIHOOK_ENUM_ENTRY(SHGetPathFromIDListA)
  69. APIHOOK_ENUM_ENTRY(SHGetPathFromIDListW)
  70. APIHOOK_ENUM_ENTRY(CreateProcessA)
  71. APIHOOK_ENUM_ENTRY(CreateProcessW)
  72. APIHOOK_ENUM_ENTRY(WinExec)
  73. APIHOOK_ENUM_ENTRY(ShellExecuteA)
  74. APIHOOK_ENUM_ENTRY(ShellExecuteW)
  75. APIHOOK_ENUM_ENTRY(ShellExecuteExA)
  76. APIHOOK_ENUM_ENTRY(ShellExecuteExW)
  77. APIHOOK_ENUM_ENTRY(GetPrivateProfileIntA)
  78. APIHOOK_ENUM_ENTRY(GetPrivateProfileIntW)
  79. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionA)
  80. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionW)
  81. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionNamesA)
  82. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionNamesW)
  83. APIHOOK_ENUM_ENTRY(GetPrivateProfileStringA)
  84. APIHOOK_ENUM_ENTRY(GetPrivateProfileStringW)
  85. APIHOOK_ENUM_ENTRY(GetPrivateProfileStructA)
  86. APIHOOK_ENUM_ENTRY(GetPrivateProfileStructW)
  87. APIHOOK_ENUM_ENTRY(WritePrivateProfileSectionA)
  88. APIHOOK_ENUM_ENTRY(WritePrivateProfileSectionW)
  89. APIHOOK_ENUM_ENTRY(WritePrivateProfileStringA)
  90. APIHOOK_ENUM_ENTRY(WritePrivateProfileStringW)
  91. APIHOOK_ENUM_ENTRY(WritePrivateProfileStructA)
  92. APIHOOK_ENUM_ENTRY(WritePrivateProfileStructW)
  93. APIHOOK_ENUM_ENTRY(CopyFileA)
  94. APIHOOK_ENUM_ENTRY(CopyFileW)
  95. APIHOOK_ENUM_ENTRY(CopyFileExA)
  96. APIHOOK_ENUM_ENTRY(CopyFileExW)
  97. APIHOOK_ENUM_ENTRY(CreateDirectoryA)
  98. APIHOOK_ENUM_ENTRY(CreateDirectoryW)
  99. APIHOOK_ENUM_ENTRY(CreateDirectoryExA)
  100. APIHOOK_ENUM_ENTRY(CreateDirectoryExW)
  101. APIHOOK_ENUM_ENTRY(CreateFileA)
  102. APIHOOK_ENUM_ENTRY(CreateFileW)
  103. APIHOOK_ENUM_ENTRY(DeleteFileA)
  104. APIHOOK_ENUM_ENTRY(DeleteFileW)
  105. APIHOOK_ENUM_ENTRY(FindFirstFileA)
  106. APIHOOK_ENUM_ENTRY(FindFirstFileW)
  107. APIHOOK_ENUM_ENTRY(FindFirstFileExA)
  108. APIHOOK_ENUM_ENTRY(FindFirstFileExW)
  109. APIHOOK_ENUM_ENTRY(GetBinaryTypeA)
  110. APIHOOK_ENUM_ENTRY(GetBinaryTypeW)
  111. APIHOOK_ENUM_ENTRY(GetFileAttributesA)
  112. APIHOOK_ENUM_ENTRY(GetFileAttributesW)
  113. APIHOOK_ENUM_ENTRY(GetFileAttributesExA)
  114. APIHOOK_ENUM_ENTRY(GetFileAttributesExW)
  115. APIHOOK_ENUM_ENTRY(SetFileAttributesA)
  116. APIHOOK_ENUM_ENTRY(SetFileAttributesW)
  117. APIHOOK_ENUM_ENTRY(MoveFileA)
  118. APIHOOK_ENUM_ENTRY(MoveFileW)
  119. APIHOOK_ENUM_ENTRY(MoveFileExA)
  120. APIHOOK_ENUM_ENTRY(MoveFileExW)
  121. APIHOOK_ENUM_ENTRY(MoveFileWithProgressA)
  122. APIHOOK_ENUM_ENTRY(MoveFileWithProgressW)
  123. APIHOOK_ENUM_ENTRY(RemoveDirectoryA)
  124. APIHOOK_ENUM_ENTRY(RemoveDirectoryW)
  125. APIHOOK_ENUM_ENTRY(SetCurrentDirectoryA)
  126. APIHOOK_ENUM_ENTRY(SetCurrentDirectoryW)
  127. APIHOOK_ENUM_ENTRY(LoadLibraryA)
  128. APIHOOK_ENUM_ENTRY(LoadLibraryW)
  129. APIHOOK_ENUM_ENTRY(LoadLibraryExA)
  130. APIHOOK_ENUM_ENTRY(LoadLibraryExW)
  131. APIHOOK_ENUM_ENTRY(SearchPathA)
  132. APIHOOK_ENUM_ENTRY(SearchPathW)
  133. APIHOOK_ENUM_ENTRY(SHFileOperationA)
  134. APIHOOK_ENUM_ENTRY(SHFileOperationW)
  135. APIHOOK_ENUM_ENTRY(ExpandEnvironmentStringsA)
  136. APIHOOK_ENUM_ENTRY(ExpandEnvironmentStringsW)
  137. APIHOOK_ENUM_ENTRY(GetFileVersionInfoSizeA)
  138. APIHOOK_ENUM_ENTRY(GetFileVersionInfoSizeW)
  139. APIHOOK_ENUM_ENTRY(GetFileVersionInfoA)
  140. APIHOOK_ENUM_ENTRY(GetFileVersionInfoW)
  141. APIHOOK_ENUM_ENTRY(OpenFile)
  142. APIHOOK_ENUM_ENTRY(RegQueryValueA)
  143. APIHOOK_ENUM_ENTRY(RegQueryValueW)
  144. APIHOOK_ENUM_ENTRY(RegQueryValueExA)
  145. APIHOOK_ENUM_ENTRY(RegQueryValueExW)
  146. APIHOOK_ENUM_ENTRY(RegSetValueA)
  147. APIHOOK_ENUM_ENTRY(RegSetValueW)
  148. APIHOOK_ENUM_ENTRY(RegSetValueExA)
  149. APIHOOK_ENUM_ENTRY(RegSetValueExW)
  150. APIHOOK_ENUM_ENTRY(NtCreateFile)
  151. APIHOOK_ENUM_ENTRY(NtOpenFile)
  152. APIHOOK_ENUM_ENTRY(NtQueryAttributesFile)
  153. APIHOOK_ENUM_ENTRY(NtQueryFullAttributesFile)
  154. APIHOOK_ENUM_ENTRY(NtCreateProcessEx)
  155. APIHOOK_ENUM_ENTRY(_lopen)
  156. APIHOOK_ENUM_ENTRY(_lcreat)
  157. APIHOOK_ENUM_END
  158. //
  159. // verifier log entries
  160. //
  161. BEGIN_DEFINE_VERIFIER_LOG(FilePaths)
  162. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_GETTEMPPATH)
  163. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_WINDOWSPATH)
  164. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_SYSWINDOWSPATH)
  165. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_SYSTEMPATH)
  166. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_PERSONALPATH)
  167. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_COMMONPROGRAMS)
  168. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_COMMONSTARTMENU)
  169. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_PROGRAMS)
  170. VERIFIER_LOG_ENTRY(VLOG_HARDCODED_STARTMENU)
  171. END_DEFINE_VERIFIER_LOG(FilePaths)
  172. INIT_VERIFIER_LOG(FilePaths);
  173. // This is a private define (shlapip.h) that can mess up ShellExecuteEx
  174. #ifndef SEE_MASK_FILEANDURL
  175. #define SEE_MASK_FILEANDURL 0x00400000
  176. #endif
  177. #define MAX_HARDCODED_PATHS 4
  178. //
  179. // Linked-list for SHFileOperation
  180. //
  181. typedef struct FILELIST {
  182. struct FILELIST* pNext;
  183. UINT cchSize;
  184. LPWSTR pwszFilePath;
  185. } FILELIST, *PFILELIST;
  186. enum ListType {
  187. eFrom = 0,
  188. eTo
  189. };
  190. //
  191. // Head of the linked-lists for SHFileOperation
  192. //
  193. PFILELIST g_pFileListFromHead = NULL;
  194. PFILELIST g_pFileListToHead = NULL;
  195. //
  196. // Critical section to keep our linked list safe.
  197. //
  198. RTL_CRITICAL_SECTION g_csLinkedList;
  199. //
  200. // Fake command-line for GetCommandLine calls.
  201. //
  202. LPSTR g_pszCommandLineA;
  203. LPWSTR g_pwszCommandLineW;
  204. typedef struct _PATH_INFO {
  205. char szSimulatedPathA[256];
  206. WCHAR szSimulatedPathW[256];
  207. char szCorrectPathA[MAX_PATH];
  208. WCHAR szCorrectPathW[MAX_PATH];
  209. int nSimulatedPathLen;
  210. int nCorrectPathLen;
  211. char szHardCodedPathsA[MAX_HARDCODED_PATHS][MAX_PATH];
  212. WCHAR szHardCodedPathsW[MAX_HARDCODED_PATHS][MAX_PATH];
  213. DWORD dwIssueCode;
  214. } PATH_INFO, *PPATH_INFO;
  215. //
  216. // the following enum and the g_Paths initializers must be kept in parallel
  217. // Note: The paths must be in lower case for the comparison to work properly.
  218. //
  219. enum _PATH_NUM {
  220. PATH_TEMP = 0,
  221. PATH_WINDOWS,
  222. PATH_SYSTEM_WINDOWS,
  223. PATH_SYSTEM,
  224. PATH_PERSONAL,
  225. PATH_COMMON_PROGRAMS,
  226. PATH_COMMON_STARTMENU,
  227. PATH_PROGRAMS,
  228. PATH_STARTMENU
  229. };
  230. PATH_INFO g_Paths[] = {
  231. {
  232. "c:\\abc\\temppath\\123\\",
  233. L"c:\\abc\\temppath\\123\\",
  234. "",
  235. L"",
  236. 0,
  237. 0,
  238. {
  239. "\\temp\\",
  240. "",
  241. "",
  242. ""
  243. },
  244. {
  245. L"\\temp\\",
  246. L"",
  247. L"",
  248. L""
  249. },
  250. VLOG_HARDCODED_GETTEMPPATH
  251. },
  252. {
  253. "c:\\abc\\windowsdir\\123",
  254. L"c:\\abc\\windowsdir\\123",
  255. "",
  256. L"",
  257. 0,
  258. 0,
  259. {
  260. ":\\windows\\",
  261. ":\\winnt\\",
  262. "",
  263. ""
  264. },
  265. {
  266. L":\\windows\\",
  267. L":\\winnt\\",
  268. L"",
  269. L""
  270. },
  271. VLOG_HARDCODED_WINDOWSPATH
  272. },
  273. {
  274. "c:\\abc\\systemwindowsdir\\123",
  275. L"c:\\abc\\systemwindowsdir\\123",
  276. "",
  277. L"",
  278. 0,
  279. 0,
  280. {
  281. ":\\windows\\",
  282. ":\\winnt\\",
  283. "",
  284. ""
  285. },
  286. {
  287. L":\\windows\\",
  288. L":\\winnt\\",
  289. L"",
  290. L""
  291. },
  292. VLOG_HARDCODED_SYSWINDOWSPATH
  293. },
  294. {
  295. "c:\\abc\\systemdir\\123",
  296. L"c:\\abc\\systemdir\\123",
  297. "",
  298. L"",
  299. 0,
  300. 0,
  301. {
  302. "\\system\\",
  303. "\\system32\\",
  304. "",
  305. ""
  306. },
  307. {
  308. L"\\system\\",
  309. L"\\system32\\",
  310. L"",
  311. L""
  312. },
  313. VLOG_HARDCODED_SYSTEMPATH
  314. },
  315. {
  316. "c:\\abc\\personal\\123",
  317. L"c:\\abc\\personal\\123",
  318. "",
  319. L"",
  320. 0,
  321. 0,
  322. {
  323. "\\my documents\\",
  324. "",
  325. "",
  326. ""
  327. },
  328. {
  329. L"\\my documents\\",
  330. L"",
  331. L"",
  332. L""
  333. },
  334. VLOG_HARDCODED_PERSONALPATH
  335. },
  336. {
  337. "c:\\abc\\commonprograms\\123",
  338. L"c:\\abc\\commonprograms\\123",
  339. "",
  340. L"",
  341. 0,
  342. 0,
  343. {
  344. "\\all users\\start menu\\programs\\",
  345. "",
  346. "",
  347. ""
  348. },
  349. {
  350. L"\\all users\\start menu\\programs\\",
  351. L"",
  352. L"",
  353. L""
  354. },
  355. VLOG_HARDCODED_COMMONPROGRAMS
  356. },
  357. {
  358. "c:\\abc\\commonstartmenu\\123",
  359. L"c:\\abc\\commonstartmenu\\123",
  360. "",
  361. L"",
  362. 0,
  363. 0,
  364. {
  365. "\\all users\\start menu\\",
  366. "",
  367. "",
  368. ""
  369. },
  370. {
  371. L"\\all users\\start menu\\",
  372. L"",
  373. L"",
  374. L""
  375. },
  376. VLOG_HARDCODED_COMMONSTARTMENU
  377. },
  378. {
  379. "c:\\abc\\programs\\123",
  380. L"c:\\abc\\programs\\123",
  381. "",
  382. L"",
  383. 0,
  384. 0,
  385. {
  386. "\\start menu\\programs\\",
  387. "",
  388. "",
  389. ""
  390. },
  391. {
  392. L"\\start menu\\programs\\",
  393. L"",
  394. L"",
  395. L""
  396. },
  397. VLOG_HARDCODED_PROGRAMS
  398. },
  399. {
  400. "c:\\abc\\startmenu\\123",
  401. L"c:\\abc\\startmenu\\123",
  402. "",
  403. L"",
  404. 0,
  405. 0,
  406. {
  407. "\\start menu\\",
  408. "",
  409. "",
  410. ""
  411. },
  412. {
  413. L"\\start menu\\",
  414. L"",
  415. L"",
  416. L""
  417. },
  418. VLOG_HARDCODED_STARTMENU
  419. }
  420. };
  421. const int g_nPaths = sizeof(g_Paths)/sizeof(g_Paths[0]);
  422. static BOOL g_bPathsInited = FALSE;
  423. void
  424. InitFakeCommandLine(
  425. void
  426. )
  427. {
  428. int cchSize;
  429. int nPathIndex;
  430. BOOL fReplaced = FALSE;
  431. CString csCommandLine(GetCommandLineW());
  432. csCommandLine.MakeLower();
  433. //
  434. // Point them to the normal command-line at first.
  435. //
  436. g_pwszCommandLineW = GetCommandLineW();
  437. g_pszCommandLineA = GetCommandLineA();
  438. //
  439. // Replace real paths with simulated paths.
  440. //
  441. for (nPathIndex = 0; nPathIndex < g_nPaths; ++nPathIndex) {
  442. if (csCommandLine.Replace(g_Paths[nPathIndex].szCorrectPathW,
  443. g_Paths[nPathIndex].szSimulatedPathW)) {
  444. fReplaced = TRUE;
  445. }
  446. }
  447. if (fReplaced) {
  448. //
  449. // Allocate room on the heap and save the command line away.
  450. //
  451. cchSize = csCommandLine.GetLength();
  452. g_pwszCommandLineW = (LPWSTR)malloc(cchSize * sizeof(WCHAR));
  453. if (!g_pwszCommandLineW) {
  454. DPFN(eDbgLevelError, "[InitFakeCommandLine] No memory available");
  455. return;
  456. }
  457. g_pszCommandLineA = (LPSTR)malloc(cchSize);
  458. if (!g_pszCommandLineA) {
  459. DPFN(eDbgLevelError, "[InitFakeCommandLine] No memory available");
  460. free(g_pwszCommandLineW);
  461. return;
  462. }
  463. StringCchCopy(g_pwszCommandLineW, cchSize, csCommandLine.Get());
  464. StringCchCopyA(g_pszCommandLineA, cchSize, csCommandLine.GetAnsi());
  465. }
  466. }
  467. void
  468. InitPaths(
  469. void
  470. )
  471. {
  472. g_bPathsInited = TRUE;
  473. //
  474. // Convert paths to lower case as this is necessary when performing
  475. // the comparison.
  476. //
  477. CharLowerA(g_Paths[PATH_TEMP].szCorrectPathA);
  478. CharLowerW(g_Paths[PATH_TEMP].szCorrectPathW);
  479. CharLowerA(g_Paths[PATH_WINDOWS].szCorrectPathA);
  480. CharLowerW(g_Paths[PATH_WINDOWS].szCorrectPathW);
  481. CharLowerA(g_Paths[PATH_SYSTEM_WINDOWS].szCorrectPathA);
  482. CharLowerW(g_Paths[PATH_SYSTEM_WINDOWS].szCorrectPathW);
  483. CharLowerA(g_Paths[PATH_SYSTEM].szCorrectPathA);
  484. CharLowerW(g_Paths[PATH_SYSTEM].szCorrectPathW);
  485. SHGetFolderPathA(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_PERSONAL].szCorrectPathA);
  486. SHGetFolderPathW(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_PERSONAL].szCorrectPathW);
  487. g_Paths[PATH_PERSONAL].nCorrectPathLen = strlen(g_Paths[PATH_PERSONAL].szCorrectPathA);
  488. g_Paths[PATH_PERSONAL].nSimulatedPathLen = strlen(g_Paths[PATH_PERSONAL].szSimulatedPathA);
  489. CharLowerA(g_Paths[PATH_PERSONAL].szCorrectPathA);
  490. CharLowerW(g_Paths[PATH_PERSONAL].szCorrectPathW);
  491. SHGetFolderPathA(NULL, CSIDL_STARTMENU, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_STARTMENU].szCorrectPathA);
  492. SHGetFolderPathW(NULL, CSIDL_STARTMENU, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_STARTMENU].szCorrectPathW);
  493. g_Paths[PATH_STARTMENU].nCorrectPathLen = strlen(g_Paths[PATH_STARTMENU].szCorrectPathA);
  494. g_Paths[PATH_STARTMENU].nSimulatedPathLen = strlen(g_Paths[PATH_STARTMENU].szSimulatedPathA);
  495. CharLowerA(g_Paths[PATH_STARTMENU].szCorrectPathA);
  496. CharLowerW(g_Paths[PATH_STARTMENU].szCorrectPathW);
  497. SHGetFolderPathA(NULL, CSIDL_COMMON_STARTMENU, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_COMMON_STARTMENU].szCorrectPathA);
  498. SHGetFolderPathW(NULL, CSIDL_COMMON_STARTMENU, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_COMMON_STARTMENU].szCorrectPathW);
  499. g_Paths[PATH_COMMON_STARTMENU].nCorrectPathLen = strlen(g_Paths[PATH_COMMON_STARTMENU].szCorrectPathA);
  500. g_Paths[PATH_COMMON_STARTMENU].nSimulatedPathLen = strlen(g_Paths[PATH_COMMON_STARTMENU].szSimulatedPathA);
  501. CharLowerA(g_Paths[PATH_COMMON_STARTMENU].szCorrectPathA);
  502. CharLowerW(g_Paths[PATH_COMMON_STARTMENU].szCorrectPathW);
  503. SHGetFolderPathA(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_PROGRAMS].szCorrectPathA);
  504. SHGetFolderPathW(NULL, CSIDL_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_PROGRAMS].szCorrectPathW);
  505. g_Paths[PATH_PROGRAMS].nCorrectPathLen = strlen(g_Paths[PATH_PROGRAMS].szCorrectPathA);
  506. g_Paths[PATH_PROGRAMS].nSimulatedPathLen = strlen(g_Paths[PATH_PROGRAMS].szSimulatedPathA);
  507. CharLowerA(g_Paths[PATH_PROGRAMS].szCorrectPathA);
  508. CharLowerW(g_Paths[PATH_PROGRAMS].szCorrectPathW);
  509. SHGetFolderPathA(NULL, CSIDL_COMMON_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_COMMON_PROGRAMS].szCorrectPathA);
  510. SHGetFolderPathW(NULL, CSIDL_COMMON_PROGRAMS, NULL, SHGFP_TYPE_CURRENT, g_Paths[PATH_COMMON_PROGRAMS].szCorrectPathW);
  511. g_Paths[PATH_COMMON_PROGRAMS].nCorrectPathLen = strlen(g_Paths[PATH_COMMON_PROGRAMS].szCorrectPathA);
  512. g_Paths[PATH_COMMON_PROGRAMS].nSimulatedPathLen = strlen(g_Paths[PATH_COMMON_PROGRAMS].szSimulatedPathA);
  513. CharLowerA(g_Paths[PATH_COMMON_PROGRAMS].szCorrectPathA);
  514. CharLowerW(g_Paths[PATH_COMMON_PROGRAMS].szCorrectPathW);
  515. InitFakeCommandLine();
  516. }
  517. inline void
  518. FPFreeA(
  519. LPSTR lpMalloc,
  520. LPCSTR lpOrig
  521. )
  522. {
  523. if (lpMalloc != lpOrig) {
  524. free((LPVOID)lpMalloc);
  525. }
  526. }
  527. inline void
  528. FPFreeW(
  529. LPWSTR lpMalloc,
  530. LPCWSTR lpOrig
  531. )
  532. {
  533. if (lpMalloc != lpOrig) {
  534. free((LPVOID)lpMalloc);
  535. }
  536. }
  537. void
  538. MassageRealPathToFakePathW(
  539. LPWSTR pwszPath,
  540. DWORD cchBufferSize
  541. )
  542. {
  543. int nPathIndex;
  544. BOOL fReplaced = FALSE;
  545. if (!pwszPath || 0 == cchBufferSize) {
  546. return;
  547. }
  548. if (!g_bPathsInited) {
  549. InitPaths();
  550. }
  551. DPFN(eDbgLevelInfo, "[MassageRealPathToFakePath] '%ls'", pwszPath);
  552. CString csString(pwszPath);
  553. csString.MakeLower();
  554. //
  555. // Replace real paths with simulated paths.
  556. //
  557. for (nPathIndex = 0; nPathIndex < g_nPaths; ++nPathIndex) {
  558. if (csString.Replace(g_Paths[nPathIndex].szCorrectPathW,
  559. g_Paths[nPathIndex].szSimulatedPathW)) {
  560. fReplaced = TRUE;
  561. }
  562. }
  563. if (fReplaced) {
  564. //
  565. // Ensure that the buffer is large enough to contain the new path.
  566. //
  567. if (cchBufferSize < (DWORD)csString.GetLength()) {
  568. DPFN(eDbgLevelError,
  569. "[MassageRealPathToFakePath] Buffer is not large enough. Need %d have %lu",
  570. csString.GetLength(),
  571. cchBufferSize);
  572. return;
  573. } else {
  574. StringCchCopy(pwszPath, cchBufferSize, csString);
  575. }
  576. }
  577. }
  578. void
  579. MassageRealPathToFakePathA(
  580. LPSTR pszPath,
  581. DWORD cchBufferSize
  582. )
  583. {
  584. int nPathIndex;
  585. BOOL fReplaced = FALSE;
  586. if (!pszPath || 0 == cchBufferSize) {
  587. return;
  588. }
  589. if (!g_bPathsInited) {
  590. InitPaths();
  591. }
  592. DPFN(eDbgLevelInfo, "[MassageRealPathToFakePath] '%s'", pszPath);
  593. CString csString(pszPath);
  594. csString.MakeLower();
  595. //
  596. // Replace real paths with simulated paths.
  597. //
  598. for (nPathIndex = 0; nPathIndex < g_nPaths; ++nPathIndex) {
  599. if (csString.Replace(g_Paths[nPathIndex].szCorrectPathW,
  600. g_Paths[nPathIndex].szSimulatedPathW)) {
  601. fReplaced = TRUE;
  602. }
  603. }
  604. if (fReplaced) {
  605. //
  606. // Ensure that the buffer is large enough to contain the new path.
  607. //
  608. if (cchBufferSize < (DWORD)csString.GetLength()) {
  609. DPFN(eDbgLevelError,
  610. "[MassageRealPathToFakePath] Buffer is not large enough. Need %d have %lu",
  611. csString.GetLength(),
  612. cchBufferSize);
  613. return;
  614. } else {
  615. StringCchCopyA(pszPath, cchBufferSize, csString.GetAnsi());
  616. }
  617. }
  618. }
  619. LPWSTR
  620. MassageStringForPathW(
  621. LPCWSTR pwszString
  622. )
  623. {
  624. int nPosition;
  625. int nPathIndex, nHardcodedIndex;
  626. UINT nLen = 0;
  627. UINT cFakePaths = 0;
  628. LPWSTR pwszPath;
  629. LPWSTR pwszNew = NULL;
  630. CString csToken(L"");
  631. if (pwszString == NULL || *pwszString == 0) {
  632. return (LPWSTR)pwszString;
  633. }
  634. if (!g_bPathsInited) {
  635. InitPaths();
  636. }
  637. DPFN(eDbgLevelInfo, "[MassageStringForPathW] '%ls'", pwszString);
  638. //
  639. // Search the string for hardcoded paths first.
  640. //
  641. CString csString(pwszString);
  642. csString.MakeLower();
  643. for (nPathIndex = 0; nPathIndex < g_nPaths; ++nPathIndex) {
  644. for (nHardcodedIndex = 0; nHardcodedIndex < MAX_HARDCODED_PATHS; ++nHardcodedIndex) {
  645. pwszPath = g_Paths[nPathIndex].szHardCodedPathsW[nHardcodedIndex];
  646. if (!pwszPath[0]) {
  647. break;
  648. }
  649. nPosition = csString.Find(pwszPath);
  650. if (nPosition != -1) {
  651. VLOG(VLOG_LEVEL_ERROR,
  652. g_Paths[nPathIndex].dwIssueCode,
  653. "Hardcoded path found in path '%ls'.",
  654. pwszString);
  655. break;
  656. }
  657. nPosition = 0;
  658. }
  659. }
  660. //
  661. // Now search for the fake paths that we substituted ourselves.
  662. //
  663. CStringToken csTokenList(csString, L" ");
  664. while (csTokenList.GetToken(csToken)) {
  665. csToken.MakeLower();
  666. for (nPathIndex = 0, nPosition = 0; nPathIndex < g_nPaths; ++nPathIndex) {
  667. nPosition = csToken.Find(g_Paths[nPathIndex].szSimulatedPathW);
  668. if (nPosition != -1) {
  669. cFakePaths++;
  670. break;
  671. }
  672. nPosition = 0;
  673. }
  674. }
  675. //
  676. // See if the string contained any fake paths. If not, we're done here.
  677. //
  678. if (!cFakePaths) {
  679. return (LPWSTR)pwszString;
  680. }
  681. //
  682. // Our string has simulated paths; replace them.
  683. //
  684. for (nPathIndex = 0; nPathIndex < g_nPaths; ++nPathIndex) {
  685. csString.Replace(g_Paths[nPathIndex].szSimulatedPathW,
  686. g_Paths[nPathIndex].szCorrectPathW);
  687. }
  688. //
  689. // Allocate a string large enough to hold the corrected path and
  690. // give it back to the caller. They'll free it later.
  691. //
  692. nLen = MAX_PATH * cFakePaths;
  693. nLen += csString.GetLength();
  694. pwszNew = (LPWSTR)malloc((nLen + 1) * sizeof(WCHAR));
  695. if (!pwszNew) {
  696. DPFN(eDbgLevelError,
  697. "[MassageStringForPathW] Failed to allocate memory");
  698. return (LPWSTR)pwszString;
  699. }
  700. StringCchCopy(pwszNew, nLen + 1, csString);
  701. DPFN(eDbgLevelInfo,
  702. "[MassageStringForPathW] Replaced '%ls' with '%ls'",
  703. pwszString,
  704. pwszNew);
  705. return pwszNew;
  706. }
  707. LPSTR
  708. MassageStringForPathA(
  709. LPCSTR pszString
  710. )
  711. {
  712. int cchSize, nRetLen = 0;
  713. WCHAR wszTmp[MAX_PATH];
  714. LPWSTR pwszReturn = NULL;
  715. LPSTR pszNew = NULL;
  716. if (pszString == NULL || *pszString == 0) {
  717. return (LPSTR)pszString;
  718. }
  719. if (!g_bPathsInited) {
  720. InitPaths();
  721. }
  722. //
  723. // Convert from ANSI to Unicode so we can pass this on
  724. // to the Unicode version of the function.
  725. //
  726. cchSize = MultiByteToWideChar(CP_ACP,
  727. 0,
  728. pszString,
  729. -1,
  730. wszTmp,
  731. ARRAYSIZE(wszTmp));
  732. if (cchSize == 0) {
  733. DPFN(eDbgLevelError, "[MassageStringForPathA] Ansi -> Unicode failed");
  734. return (LPSTR)pszString;
  735. }
  736. pwszReturn = MassageStringForPathW(wszTmp);
  737. //
  738. // If the return is the same as the source, we're done.
  739. //
  740. if (!_wcsicmp(pwszReturn, wszTmp)) {
  741. return (LPSTR)pszString;
  742. }
  743. //
  744. // Allocate a buffer large enough to hold the return
  745. // and give it back to the caller as ANSI.
  746. //
  747. nRetLen = wcslen(pwszReturn) + 1;
  748. pszNew = (LPSTR)malloc(nRetLen);
  749. if (!pszNew) {
  750. DPFN(eDbgLevelError, "[MassageStringForPathA] No memory available");
  751. return (LPSTR)pszString;
  752. }
  753. cchSize = WideCharToMultiByte(CP_ACP,
  754. 0,
  755. pwszReturn,
  756. -1,
  757. pszNew,
  758. nRetLen,
  759. NULL,
  760. NULL);
  761. if (cchSize == 0) {
  762. DPFN(eDbgLevelError, "[MassageStringForPathA] Unicode -> Ansi failed");
  763. free(pszNew);
  764. return (LPSTR)pszString;
  765. }
  766. free(pwszReturn);
  767. return pszNew;
  768. }
  769. void
  770. MassageNtPath(
  771. IN POBJECT_ATTRIBUTES pObjectAttributes,
  772. OUT POBJECT_ATTRIBUTES pRetObjectAttributes
  773. )
  774. {
  775. NTSTATUS status;
  776. PUNICODE_STRING pstrObjectName = NULL;
  777. LPWSTR pwszString = NULL;
  778. RTL_UNICODE_STRING_BUFFER DosPathBuffer;
  779. UCHAR PathBuffer[MAX_PATH * 2];
  780. BOOL TranslationStatus = FALSE;
  781. //
  782. // Preserve the existing attributes.
  783. //
  784. InitializeObjectAttributes(pRetObjectAttributes,
  785. pObjectAttributes->ObjectName,
  786. pObjectAttributes->Attributes,
  787. pObjectAttributes->RootDirectory,
  788. pObjectAttributes->SecurityDescriptor);
  789. //
  790. // Ensure that we have a valid source path to work with.
  791. //
  792. if (!pObjectAttributes->ObjectName->Buffer) {
  793. return;
  794. }
  795. DPFN(eDbgLevelInfo,
  796. "[MassageNtPath] '%ls'",
  797. pObjectAttributes->ObjectName->Buffer);
  798. //
  799. // Convert from an NT path to a DOS path.
  800. //
  801. RtlInitUnicodeStringBuffer(&DosPathBuffer,
  802. PathBuffer,
  803. sizeof(PathBuffer));
  804. status = ShimAssignUnicodeStringBuffer(&DosPathBuffer,
  805. pObjectAttributes->ObjectName);
  806. if (!NT_SUCCESS(status)) {
  807. DPFN(eDbgLevelError,
  808. "[MassageNtPath] Failed to initialize DOS path buffer");
  809. return;
  810. }
  811. status = ShimNtPathNameToDosPathName(0, &DosPathBuffer, NULL, NULL);
  812. if (!NT_SUCCESS(status)) {
  813. DPFN(eDbgLevelError,
  814. "[MassageNtPath] Failed to convert NT '%ls' to DOS path",
  815. pObjectAttributes->ObjectName->Buffer);
  816. goto cleanup;
  817. }
  818. //
  819. // Now check for a hardcoded path.
  820. //
  821. pwszString = MassageStringForPathW(DosPathBuffer.String.Buffer);
  822. //
  823. // Convert from a DOS path to an NT path name.
  824. //
  825. pstrObjectName = (PUNICODE_STRING)RtlAllocateHeap(RtlProcessHeap(),
  826. HEAP_ZERO_MEMORY,
  827. sizeof(UNICODE_STRING));
  828. if (!pstrObjectName) {
  829. DPFN(eDbgLevelError, "[MassageNtPath] Failed to allocate memory");
  830. goto cleanup;
  831. }
  832. TranslationStatus = RtlDosPathNameToNtPathName_U(pwszString,
  833. pstrObjectName,
  834. NULL,
  835. NULL);
  836. if (!TranslationStatus) {
  837. DPFN(eDbgLevelError,
  838. "[MassageNtPath] Failed to convert DOS '%ls' to NT path",
  839. pwszString);
  840. goto cleanup;
  841. }
  842. //
  843. // Everything worked, so now we update the ObjectName and return it through
  844. // the structure.
  845. //
  846. pRetObjectAttributes->ObjectName = pstrObjectName;
  847. cleanup:
  848. FPFreeW(pwszString, DosPathBuffer.String.Buffer);
  849. RtlFreeUnicodeStringBuffer(&DosPathBuffer);
  850. }
  851. inline
  852. void
  853. FPNtFree(
  854. IN POBJECT_ATTRIBUTES pOriginal,
  855. IN POBJECT_ATTRIBUTES pAllocated
  856. )
  857. {
  858. RtlFreeUnicodeString(pAllocated->ObjectName);
  859. if (pOriginal->ObjectName != pAllocated->ObjectName) {
  860. RtlFreeHeap(RtlProcessHeap(), 0, pAllocated->ObjectName);
  861. }
  862. }
  863. LPSTR
  864. APIHOOK(GetCommandLineA)(
  865. void
  866. )
  867. {
  868. if (g_bPathsInited) {
  869. return g_pszCommandLineA;
  870. } else {
  871. return ORIGINAL_API(GetCommandLineA)();
  872. }
  873. }
  874. LPWSTR
  875. APIHOOK(GetCommandLineW)(
  876. void
  877. )
  878. {
  879. if (g_bPathsInited) {
  880. return g_pwszCommandLineW;
  881. } else {
  882. return ORIGINAL_API(GetCommandLineW)();
  883. }
  884. }
  885. DWORD
  886. APIHOOK(GetFileAttributesA)(
  887. LPCSTR lpFileName // name of file or directory
  888. )
  889. {
  890. LPSTR lpszString = MassageStringForPathA(lpFileName);
  891. DWORD returnValue = ORIGINAL_API(GetFileAttributesA)(lpszString);
  892. FPFreeA(lpszString, lpFileName);
  893. return returnValue;
  894. }
  895. DWORD
  896. APIHOOK(GetFileAttributesW)(
  897. LPCWSTR lpFileName // name of file or directory
  898. )
  899. {
  900. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  901. DWORD returnValue = ORIGINAL_API(GetFileAttributesW)(lpszString);
  902. FPFreeW(lpszString, lpFileName);
  903. return returnValue;
  904. }
  905. BOOL
  906. APIHOOK(SetFileAttributesA)(
  907. LPCSTR lpFileName, // file name
  908. DWORD dwFileAttributes // attributes
  909. )
  910. {
  911. LPSTR lpszString = MassageStringForPathA(lpFileName);
  912. DWORD returnValue = ORIGINAL_API(SetFileAttributesA)(lpszString, dwFileAttributes);
  913. FPFreeA(lpszString, lpFileName);
  914. return returnValue;
  915. }
  916. DWORD
  917. APIHOOK(SetFileAttributesW)(
  918. LPCWSTR lpFileName, // file name
  919. DWORD dwFileAttributes // attributes
  920. )
  921. {
  922. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  923. DWORD returnValue = ORIGINAL_API(SetFileAttributesW)(lpszString, dwFileAttributes);
  924. FPFreeW(lpszString, lpFileName);
  925. return returnValue;
  926. }
  927. BOOL
  928. APIHOOK(GetFileAttributesExA)(
  929. LPCSTR lpFileName, // file or directory name
  930. GET_FILEEX_INFO_LEVELS fInfoLevelId, // attribute
  931. LPVOID lpFileInformation // attribute information
  932. )
  933. {
  934. LPSTR lpszString = MassageStringForPathA(lpFileName);
  935. BOOL returnValue = ORIGINAL_API(GetFileAttributesExA)(lpszString,
  936. fInfoLevelId,
  937. lpFileInformation);
  938. FPFreeA(lpszString, lpFileName);
  939. return returnValue;
  940. }
  941. BOOL
  942. APIHOOK(GetFileAttributesExW)(
  943. LPCWSTR lpFileName, // file or directory name
  944. GET_FILEEX_INFO_LEVELS fInfoLevelId, // attribute
  945. LPVOID lpFileInformation // attribute information
  946. )
  947. {
  948. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  949. BOOL returnValue = ORIGINAL_API(GetFileAttributesExW)(lpszString,
  950. fInfoLevelId,
  951. lpFileInformation);
  952. FPFreeW(lpszString, lpFileName);
  953. return returnValue;
  954. }
  955. BOOL
  956. APIHOOK(CreateProcessA)(
  957. LPCSTR lpApplicationName,
  958. LPSTR lpCommandLine,
  959. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  960. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  961. BOOL bInheritHandles,
  962. DWORD dwCreationFlags,
  963. LPVOID lpEnvironment,
  964. LPCSTR lpCurrentDirectory,
  965. LPSTARTUPINFOA lpStartupInfo,
  966. LPPROCESS_INFORMATION lpProcessInformation
  967. )
  968. {
  969. LPSTR lpszStringAppName = MassageStringForPathA(lpApplicationName);
  970. LPSTR lpszStringCmdLine = MassageStringForPathA(lpCommandLine);
  971. BOOL returnValue = ORIGINAL_API(CreateProcessA)(lpszStringAppName,
  972. lpszStringCmdLine,
  973. lpProcessAttributes,
  974. lpThreadAttributes,
  975. bInheritHandles,
  976. dwCreationFlags,
  977. lpEnvironment,
  978. lpCurrentDirectory,
  979. lpStartupInfo,
  980. lpProcessInformation);
  981. FPFreeA(lpszStringAppName, lpApplicationName);
  982. FPFreeA(lpszStringCmdLine, lpCommandLine);
  983. return returnValue;
  984. }
  985. BOOL
  986. APIHOOK(CreateProcessW)(
  987. LPCWSTR lpApplicationName,
  988. LPWSTR lpCommandLine,
  989. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  990. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  991. BOOL bInheritHandles,
  992. DWORD dwCreationFlags,
  993. LPVOID lpEnvironment,
  994. LPCWSTR lpCurrentDirectory,
  995. LPSTARTUPINFOW lpStartupInfo,
  996. LPPROCESS_INFORMATION lpProcessInformation
  997. )
  998. {
  999. LPWSTR lpszStringAppName = MassageStringForPathW(lpApplicationName);
  1000. LPWSTR lpszStringCmdLine = MassageStringForPathW(lpCommandLine);
  1001. BOOL returnValue = ORIGINAL_API(CreateProcessW)(lpszStringAppName,
  1002. lpszStringCmdLine,
  1003. lpProcessAttributes,
  1004. lpThreadAttributes,
  1005. bInheritHandles,
  1006. dwCreationFlags,
  1007. lpEnvironment,
  1008. lpCurrentDirectory,
  1009. lpStartupInfo,
  1010. lpProcessInformation);
  1011. FPFreeW(lpszStringAppName, lpApplicationName);
  1012. FPFreeW(lpszStringCmdLine, lpCommandLine);
  1013. return returnValue;
  1014. }
  1015. UINT
  1016. APIHOOK(WinExec)(
  1017. LPCSTR lpCmdLine,
  1018. UINT uCmdShow
  1019. )
  1020. {
  1021. LPSTR lpszString = MassageStringForPathA(lpCmdLine);
  1022. UINT returnValue = ORIGINAL_API(WinExec)(lpszString, uCmdShow);
  1023. FPFreeA(lpszString, lpCmdLine);
  1024. return returnValue;
  1025. }
  1026. HINSTANCE
  1027. APIHOOK(ShellExecuteA)(
  1028. HWND hwnd,
  1029. LPCSTR lpVerb,
  1030. LPCSTR lpFile,
  1031. LPCSTR lpParameters,
  1032. LPCSTR lpDirectory,
  1033. INT nShowCmd
  1034. )
  1035. {
  1036. LPSTR lpszStringFile = MassageStringForPathA(lpFile);
  1037. LPSTR lpszStringDir = MassageStringForPathA(lpDirectory);
  1038. HINSTANCE returnValue = ORIGINAL_API(ShellExecuteA)(hwnd,
  1039. lpVerb,
  1040. lpszStringFile,
  1041. lpParameters,
  1042. lpszStringDir,
  1043. nShowCmd);
  1044. FPFreeA(lpszStringFile, lpFile);
  1045. FPFreeA(lpszStringDir, lpDirectory);
  1046. return returnValue;
  1047. }
  1048. /*++
  1049. Convert Win9x paths to WinNT paths for ShellExecuteW
  1050. --*/
  1051. HINSTANCE
  1052. APIHOOK(ShellExecuteW)(
  1053. HWND hwnd,
  1054. LPCWSTR lpVerb,
  1055. LPCWSTR lpFile,
  1056. LPCWSTR lpParameters,
  1057. LPCWSTR lpDirectory,
  1058. INT nShowCmd
  1059. )
  1060. {
  1061. LPWSTR lpszStringFile = MassageStringForPathW(lpFile);
  1062. LPWSTR lpszStringDir = MassageStringForPathW(lpDirectory);
  1063. HINSTANCE returnValue = ORIGINAL_API(ShellExecuteW)(hwnd,
  1064. lpVerb,
  1065. lpszStringFile,
  1066. lpParameters,
  1067. lpszStringDir,
  1068. nShowCmd);
  1069. FPFreeW(lpszStringFile, lpFile);
  1070. FPFreeW(lpszStringDir, lpDirectory);
  1071. return returnValue;
  1072. }
  1073. BOOL
  1074. APIHOOK(ShellExecuteExA)(
  1075. LPSHELLEXECUTEINFOA lpExecInfo
  1076. )
  1077. {
  1078. //
  1079. // Check for this magical *internal* flag that tells the system
  1080. // that lpExecInfo->lpFile is actually a file and URL combined with
  1081. // a 0 byte seperator, (file\0url\0)
  1082. // Since this is internal only, we should not be receiving bad paths.
  1083. //
  1084. if (lpExecInfo->fMask & SEE_MASK_FILEANDURL) {
  1085. return ORIGINAL_API(ShellExecuteExA)(lpExecInfo);
  1086. }
  1087. LPSTR lpszStringFile = MassageStringForPathA(lpExecInfo->lpFile);
  1088. LPSTR lpszStringDir = MassageStringForPathA(lpExecInfo->lpDirectory);
  1089. LPCSTR lpFileSave = lpExecInfo->lpFile;
  1090. LPCSTR lpDirSave = lpExecInfo->lpDirectory;
  1091. lpExecInfo->lpFile = lpszStringFile;
  1092. lpExecInfo->lpDirectory = lpszStringDir;
  1093. BOOL returnValue = ORIGINAL_API(ShellExecuteExA)(lpExecInfo);
  1094. lpExecInfo->lpFile = lpFileSave;
  1095. lpExecInfo->lpDirectory = lpDirSave;
  1096. FPFreeA(lpszStringFile, lpFileSave);
  1097. FPFreeA(lpszStringDir, lpDirSave);
  1098. return returnValue;
  1099. }
  1100. /*++
  1101. Convert Win9x paths to WinNT paths for ShellExecuteExW
  1102. --*/
  1103. BOOL
  1104. APIHOOK(ShellExecuteExW)(
  1105. LPSHELLEXECUTEINFOW lpExecInfo
  1106. )
  1107. {
  1108. //
  1109. // Check for this magical *internal* flag that tells the system
  1110. // that lpExecInfo->lpFile is actually a file and URL combined with
  1111. // a 0 byte seperator, (file\0url\0)
  1112. // Since this is internal only, we should not be receiving bad paths.
  1113. //
  1114. if (lpExecInfo->fMask & SEE_MASK_FILEANDURL) {
  1115. return ORIGINAL_API(ShellExecuteExW)(lpExecInfo);
  1116. }
  1117. LPWSTR lpszStringFile = MassageStringForPathW(lpExecInfo->lpFile);
  1118. LPWSTR lpszStringDir = MassageStringForPathW(lpExecInfo->lpDirectory);
  1119. LPCWSTR lpFileSave = lpExecInfo->lpFile;
  1120. LPCWSTR lpDirSave = lpExecInfo->lpDirectory;
  1121. lpExecInfo->lpFile = lpszStringFile;
  1122. lpExecInfo->lpDirectory = lpszStringDir;
  1123. BOOL returnValue = ORIGINAL_API(ShellExecuteExW)(lpExecInfo);
  1124. lpExecInfo->lpFile = lpFileSave;
  1125. lpExecInfo->lpDirectory = lpDirSave;
  1126. FPFreeW(lpszStringFile, lpFileSave);
  1127. FPFreeW(lpszStringDir, lpDirSave);
  1128. return returnValue;
  1129. }
  1130. UINT
  1131. APIHOOK(GetPrivateProfileIntA)(
  1132. LPCSTR lpAppName, // section name
  1133. LPCSTR lpKeyName, // key name
  1134. INT nDefault, // return value if key name not found
  1135. LPCSTR lpFileName // initialization file name
  1136. )
  1137. {
  1138. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1139. UINT returnValue = ORIGINAL_API(GetPrivateProfileIntA)(lpAppName,
  1140. lpKeyName,
  1141. nDefault,
  1142. lpszString);
  1143. FPFreeA(lpszString, lpFileName);
  1144. return returnValue;
  1145. }
  1146. UINT
  1147. APIHOOK(GetPrivateProfileIntW)(
  1148. LPCWSTR lpAppName, // section name
  1149. LPCWSTR lpKeyName, // key name
  1150. INT nDefault, // return value if key name not found
  1151. LPCWSTR lpFileName // initialization file name
  1152. )
  1153. {
  1154. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1155. UINT returnValue = ORIGINAL_API(GetPrivateProfileIntW)(lpAppName,
  1156. lpKeyName,
  1157. nDefault,
  1158. lpszString);
  1159. FPFreeW(lpszString, lpFileName);
  1160. return returnValue;
  1161. }
  1162. DWORD
  1163. APIHOOK(GetPrivateProfileSectionA)(
  1164. LPCSTR lpAppName, // section name
  1165. LPSTR lpReturnedString, // return buffer
  1166. DWORD nSize, // size of return buffer
  1167. LPCSTR lpFileName // initialization file name
  1168. )
  1169. {
  1170. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1171. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionA)(lpAppName,
  1172. lpReturnedString,
  1173. nSize,
  1174. lpszString);
  1175. FPFreeA(lpszString, lpFileName);
  1176. return returnValue;
  1177. }
  1178. DWORD
  1179. APIHOOK(GetPrivateProfileSectionW)(
  1180. LPCWSTR lpAppName, // section name
  1181. LPWSTR lpReturnedString, // return buffer
  1182. DWORD nSize, // size of return buffer
  1183. LPCWSTR lpFileName // initialization file name
  1184. )
  1185. {
  1186. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1187. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionW)(lpAppName,
  1188. lpReturnedString,
  1189. nSize,
  1190. lpszString);
  1191. FPFreeW(lpszString, lpFileName);
  1192. return returnValue;
  1193. }
  1194. DWORD
  1195. APIHOOK(GetPrivateProfileSectionNamesA)(
  1196. LPSTR lpszReturnBuffer, // return buffer
  1197. DWORD nSize, // size of return buffer
  1198. LPCSTR lpFileName // initialization file name
  1199. )
  1200. {
  1201. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1202. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionNamesA)(lpszReturnBuffer,
  1203. nSize,
  1204. lpszString);
  1205. FPFreeA(lpszString, lpFileName);
  1206. return returnValue;
  1207. }
  1208. DWORD
  1209. APIHOOK(GetPrivateProfileSectionNamesW)(
  1210. LPWSTR lpszReturnBuffer, // return buffer
  1211. DWORD nSize, // size of return buffer
  1212. LPCWSTR lpFileName // initialization file name
  1213. )
  1214. {
  1215. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1216. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionNamesW)(lpszReturnBuffer,
  1217. nSize,
  1218. lpszString);
  1219. FPFreeW(lpszString, lpFileName);
  1220. return returnValue;
  1221. }
  1222. DWORD
  1223. APIHOOK(GetPrivateProfileStringA)(
  1224. LPCSTR lpAppName, // section name
  1225. LPCSTR lpKeyName, // key name
  1226. LPCSTR lpDefault, // default string
  1227. LPSTR lpReturnedString, // destination buffer
  1228. DWORD nSize, // size of destination buffer
  1229. LPCSTR lpFileName // initialization file name
  1230. )
  1231. {
  1232. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1233. DWORD returnValue = ORIGINAL_API(GetPrivateProfileStringA)(lpAppName,
  1234. lpKeyName,
  1235. lpDefault,
  1236. lpReturnedString,
  1237. nSize,
  1238. lpszString);
  1239. FPFreeA(lpszString, lpFileName);
  1240. return returnValue;
  1241. }
  1242. DWORD
  1243. APIHOOK(GetPrivateProfileStringW)(
  1244. LPCWSTR lpAppName, // section name
  1245. LPCWSTR lpKeyName, // key name
  1246. LPCWSTR lpDefault, // default string
  1247. LPWSTR lpReturnedString, // destination buffer
  1248. DWORD nSize, // size of destination buffer
  1249. LPCWSTR lpFileName // initialization file name
  1250. )
  1251. {
  1252. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1253. DWORD returnValue = ORIGINAL_API(GetPrivateProfileStringW)(lpAppName,
  1254. lpKeyName,
  1255. lpDefault,
  1256. lpReturnedString,
  1257. nSize,
  1258. lpszString);
  1259. FPFreeW(lpszString, lpFileName);
  1260. return returnValue;
  1261. }
  1262. BOOL
  1263. APIHOOK(GetPrivateProfileStructA)(
  1264. LPCSTR lpszSection, // section name
  1265. LPCSTR lpszKey, // key name
  1266. LPVOID lpStruct, // return buffer
  1267. UINT uSizeStruct, // size of return buffer
  1268. LPCSTR lpFileName // initialization file name
  1269. )
  1270. {
  1271. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1272. BOOL returnValue = ORIGINAL_API(GetPrivateProfileStructA)(lpszSection,
  1273. lpszKey,
  1274. lpStruct,
  1275. uSizeStruct,
  1276. lpszString);
  1277. FPFreeA(lpszString, lpFileName);
  1278. return returnValue;
  1279. }
  1280. BOOL
  1281. APIHOOK(GetPrivateProfileStructW)(
  1282. LPCWSTR lpszSection, // section name
  1283. LPCWSTR lpszKey, // key name
  1284. LPVOID lpStruct, // return buffer
  1285. UINT uSizeStruct, // size of return buffer
  1286. LPCWSTR lpFileName // initialization file name
  1287. )
  1288. {
  1289. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1290. BOOL returnValue = ORIGINAL_API(GetPrivateProfileStructW)(lpszSection,
  1291. lpszKey,
  1292. lpStruct,
  1293. uSizeStruct,
  1294. lpszString);
  1295. FPFreeW(lpszString, lpFileName);
  1296. return returnValue;
  1297. }
  1298. BOOL
  1299. APIHOOK(WritePrivateProfileSectionA)(
  1300. LPCSTR lpAppName, // section name
  1301. LPCSTR lpString, // data
  1302. LPCSTR lpFileName // file name
  1303. )
  1304. {
  1305. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1306. BOOL returnValue = ORIGINAL_API(WritePrivateProfileSectionA)(lpAppName,
  1307. lpString,
  1308. lpszString);
  1309. FPFreeA(lpszString, lpFileName);
  1310. return returnValue;
  1311. }
  1312. BOOL
  1313. APIHOOK(WritePrivateProfileSectionW)(
  1314. LPCWSTR lpAppName, // section name
  1315. LPCWSTR lpString, // data
  1316. LPCWSTR lpFileName // file name
  1317. )
  1318. {
  1319. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1320. BOOL returnValue = ORIGINAL_API(WritePrivateProfileSectionW)(lpAppName,
  1321. lpString,
  1322. lpszString);
  1323. FPFreeW(lpszString, lpFileName);
  1324. return returnValue;
  1325. }
  1326. BOOL
  1327. APIHOOK(WritePrivateProfileStringA)(
  1328. LPCSTR lpAppName, // section name
  1329. LPCSTR lpKeyName, // key name
  1330. LPCSTR lpString, // string to add
  1331. LPCSTR lpFileName // initialization file
  1332. )
  1333. {
  1334. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1335. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStringA)(lpAppName,
  1336. lpKeyName,
  1337. lpString,
  1338. lpszString);
  1339. FPFreeA(lpszString, lpFileName);
  1340. return returnValue;
  1341. }
  1342. BOOL
  1343. APIHOOK(WritePrivateProfileStringW)(
  1344. LPCWSTR lpAppName, // section name
  1345. LPCWSTR lpKeyName, // key name
  1346. LPCWSTR lpString, // string to add
  1347. LPCWSTR lpFileName // initialization file
  1348. )
  1349. {
  1350. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1351. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStringW)(lpAppName,
  1352. lpKeyName,
  1353. lpString,
  1354. lpszString);
  1355. FPFreeW(lpszString, lpFileName);
  1356. return returnValue;
  1357. }
  1358. BOOL APIHOOK(WritePrivateProfileStructA)(
  1359. LPCSTR lpszSection, // section name
  1360. LPCSTR lpszKey, // key name
  1361. LPVOID lpStruct, // data buffer
  1362. UINT uSizeStruct, // size of data buffer
  1363. LPCSTR lpFileName // initialization file
  1364. )
  1365. {
  1366. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1367. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStructA)(lpszSection,
  1368. lpszKey,
  1369. lpStruct,
  1370. uSizeStruct,
  1371. lpszString);
  1372. FPFreeA(lpszString, lpFileName);
  1373. return returnValue;
  1374. }
  1375. BOOL
  1376. APIHOOK(WritePrivateProfileStructW)(
  1377. LPCWSTR lpszSection, // section name
  1378. LPCWSTR lpszKey, // key name
  1379. LPVOID lpStruct, // data buffer
  1380. UINT uSizeStruct, // size of data buffer
  1381. LPCWSTR lpFileName // initialization file
  1382. )
  1383. {
  1384. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1385. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStructW)(lpszSection,
  1386. lpszKey,
  1387. lpStruct,
  1388. uSizeStruct,
  1389. lpszString);
  1390. FPFreeW(lpszString, lpFileName);
  1391. return returnValue;
  1392. }
  1393. BOOL
  1394. APIHOOK(CopyFileA)(
  1395. LPCSTR lpExistingFileName, // name of an existing file
  1396. LPCSTR lpNewFileName, // name of new file
  1397. BOOL bFailIfExists // operation if file exists
  1398. )
  1399. {
  1400. LPSTR lpszStringExisting = MassageStringForPathA(lpExistingFileName);
  1401. LPSTR lpszStringNew = MassageStringForPathA(lpNewFileName);
  1402. BOOL returnValue = ORIGINAL_API(CopyFileA)(lpszStringExisting,
  1403. lpszStringNew,
  1404. bFailIfExists);
  1405. FPFreeA(lpszStringExisting, lpExistingFileName);
  1406. FPFreeA(lpszStringNew, lpNewFileName);
  1407. return returnValue;
  1408. }
  1409. BOOL
  1410. APIHOOK(CopyFileW)(
  1411. LPCWSTR lpExistingFileName, // name of an existing file
  1412. LPCWSTR lpNewFileName, // name of new file
  1413. BOOL bFailIfExists // operation if file exists
  1414. )
  1415. {
  1416. LPWSTR lpszStringExisting = MassageStringForPathW(lpExistingFileName);
  1417. LPWSTR lpszStringNew = MassageStringForPathW(lpNewFileName);
  1418. BOOL returnValue = ORIGINAL_API(CopyFileW)(lpszStringExisting,
  1419. lpszStringNew,
  1420. bFailIfExists);
  1421. FPFreeW(lpszStringExisting, lpExistingFileName);
  1422. FPFreeW(lpszStringNew, lpNewFileName);
  1423. return returnValue;
  1424. }
  1425. BOOL APIHOOK(CopyFileExA)(
  1426. LPCSTR lpExistingFileName, // name of existing file
  1427. LPCSTR lpNewFileName, // name of new file
  1428. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1429. LPVOID lpData, // callback parameter
  1430. LPBOOL pbCancel, // cancel status
  1431. DWORD dwCopyFlags // copy options
  1432. )
  1433. {
  1434. LPSTR lpszStringExisting = MassageStringForPathA(lpExistingFileName);
  1435. LPSTR lpszStringNew = MassageStringForPathA(lpNewFileName);
  1436. BOOL returnValue = ORIGINAL_API(CopyFileExA)(lpszStringExisting,
  1437. lpszStringNew,
  1438. lpProgressRoutine,
  1439. lpData,
  1440. pbCancel,
  1441. dwCopyFlags);
  1442. FPFreeA(lpszStringExisting, lpExistingFileName);
  1443. FPFreeA(lpszStringNew, lpNewFileName);
  1444. return returnValue;
  1445. }
  1446. BOOL
  1447. APIHOOK(CopyFileExW)(
  1448. LPCWSTR lpExistingFileName, // name of existing file
  1449. LPCWSTR lpNewFileName, // name of new file
  1450. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1451. LPVOID lpData, // callback parameter
  1452. LPBOOL pbCancel, // cancel status
  1453. DWORD dwCopyFlags // copy options
  1454. )
  1455. {
  1456. LPWSTR lpszStringExisting = MassageStringForPathW(lpExistingFileName);
  1457. LPWSTR lpszStringNew = MassageStringForPathW(lpNewFileName);
  1458. BOOL returnValue = ORIGINAL_API(CopyFileExW)(lpszStringExisting,
  1459. lpszStringNew,
  1460. lpProgressRoutine,
  1461. lpData,
  1462. pbCancel,
  1463. dwCopyFlags);
  1464. FPFreeW(lpszStringExisting, lpExistingFileName);
  1465. FPFreeW(lpszStringNew, lpNewFileName);
  1466. return returnValue;
  1467. }
  1468. BOOL
  1469. APIHOOK(CreateDirectoryA)(
  1470. LPCSTR lpPathName, // directory name
  1471. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1472. )
  1473. {
  1474. LPSTR lpszString = MassageStringForPathA(lpPathName);
  1475. BOOL returnValue = ORIGINAL_API(CreateDirectoryA)(lpszString, lpSecurityAttributes);
  1476. FPFreeA(lpszString, lpPathName);
  1477. return returnValue;
  1478. }
  1479. BOOL
  1480. APIHOOK(CreateDirectoryW)(
  1481. LPCWSTR lpPathName, // directory name
  1482. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1483. )
  1484. {
  1485. LPWSTR lpszString = MassageStringForPathW(lpPathName);
  1486. BOOL returnValue = ORIGINAL_API(CreateDirectoryW)(lpszString, lpSecurityAttributes);
  1487. FPFreeW(lpszString, lpPathName);
  1488. return returnValue;
  1489. }
  1490. BOOL
  1491. APIHOOK(CreateDirectoryExA)(
  1492. LPCSTR lpTemplateDirectory, // template directory
  1493. LPCSTR lpNewDirectory, // directory name
  1494. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1495. )
  1496. {
  1497. LPSTR lpszStringTemplate = MassageStringForPathA(lpTemplateDirectory);
  1498. LPSTR lpszStringNew = MassageStringForPathA(lpNewDirectory);
  1499. BOOL returnValue = ORIGINAL_API(CreateDirectoryExA)(lpszStringTemplate,
  1500. lpszStringNew,
  1501. lpSecurityAttributes);
  1502. FPFreeA(lpszStringTemplate, lpTemplateDirectory);
  1503. FPFreeA(lpszStringNew, lpNewDirectory);
  1504. return returnValue;
  1505. }
  1506. BOOL
  1507. APIHOOK(CreateDirectoryExW)(
  1508. LPCWSTR lpTemplateDirectory, // template directory
  1509. LPCWSTR lpNewDirectory, // directory name
  1510. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1511. )
  1512. {
  1513. LPWSTR lpszStringTemplate = MassageStringForPathW(lpTemplateDirectory);
  1514. LPWSTR lpszStringNew = MassageStringForPathW(lpNewDirectory);
  1515. BOOL returnValue = ORIGINAL_API(CreateDirectoryExW)(lpszStringTemplate,
  1516. lpszStringNew,
  1517. lpSecurityAttributes);
  1518. FPFreeW(lpszStringTemplate, lpTemplateDirectory);
  1519. FPFreeW(lpszStringNew, lpNewDirectory);
  1520. return returnValue;
  1521. }
  1522. HANDLE
  1523. APIHOOK(CreateFileA)(
  1524. LPCSTR lpFileName, // file name
  1525. DWORD dwDesiredAccess, // access mode
  1526. DWORD dwShareMode, // share mode
  1527. LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  1528. DWORD dwCreationDisposition, // how to create
  1529. DWORD dwFlagsAndAttributes, // file attributes
  1530. HANDLE hTemplateFile // handle to template file
  1531. )
  1532. {
  1533. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1534. HANDLE returnValue = ORIGINAL_API(CreateFileA)(lpszString,
  1535. dwDesiredAccess,
  1536. dwShareMode,
  1537. lpSecurityAttributes,
  1538. dwCreationDisposition,
  1539. dwFlagsAndAttributes,
  1540. hTemplateFile);
  1541. FPFreeA(lpszString, lpFileName);
  1542. return returnValue;
  1543. }
  1544. HANDLE
  1545. APIHOOK(CreateFileW)(
  1546. LPCWSTR lpFileName, // file name
  1547. DWORD dwDesiredAccess, // access mode
  1548. DWORD dwShareMode, // share mode
  1549. LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  1550. DWORD dwCreationDisposition, // how to create
  1551. DWORD dwFlagsAndAttributes, // file attributes
  1552. HANDLE hTemplateFile // handle to template file
  1553. )
  1554. {
  1555. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1556. HANDLE returnValue = ORIGINAL_API(CreateFileW)(lpszString,
  1557. dwDesiredAccess,
  1558. dwShareMode,
  1559. lpSecurityAttributes,
  1560. dwCreationDisposition,
  1561. dwFlagsAndAttributes,
  1562. hTemplateFile);
  1563. FPFreeW(lpszString, lpFileName);
  1564. return returnValue;
  1565. }
  1566. BOOL
  1567. APIHOOK(DeleteFileA)(
  1568. LPCSTR lpFileName // file name
  1569. )
  1570. {
  1571. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1572. BOOL returnValue = ORIGINAL_API(DeleteFileA)(lpszString);
  1573. FPFreeA(lpszString, lpFileName);
  1574. return returnValue;
  1575. }
  1576. BOOL
  1577. APIHOOK(DeleteFileW)(
  1578. LPCWSTR lpFileName // file name
  1579. )
  1580. {
  1581. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1582. BOOL returnValue = ORIGINAL_API(DeleteFileW)(lpszString);
  1583. FPFreeW(lpszString, lpFileName);
  1584. return returnValue;
  1585. }
  1586. HANDLE
  1587. APIHOOK(FindFirstFileA)(
  1588. LPCSTR lpFileName, // file name
  1589. LPWIN32_FIND_DATAA lpFindFileData // data buffer
  1590. )
  1591. {
  1592. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1593. HANDLE returnValue = ORIGINAL_API(FindFirstFileA)(lpszString, lpFindFileData);
  1594. FPFreeA(lpszString, lpFileName);
  1595. return returnValue;
  1596. }
  1597. HANDLE
  1598. APIHOOK(FindFirstFileW)(
  1599. LPCWSTR lpFileName, // file name
  1600. LPWIN32_FIND_DATAW lpFindFileData // data buffer
  1601. )
  1602. {
  1603. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1604. HANDLE returnValue = ORIGINAL_API(FindFirstFileW)(lpszString, lpFindFileData);
  1605. FPFreeW(lpszString, lpFileName);
  1606. return returnValue;
  1607. }
  1608. HANDLE
  1609. APIHOOK(FindFirstFileExA)(
  1610. LPCSTR lpFileName, // file name
  1611. FINDEX_INFO_LEVELS fInfoLevelId, // information level
  1612. LPVOID lpFindFileData, // information buffer
  1613. FINDEX_SEARCH_OPS fSearchOp, // filtering type
  1614. LPVOID lpSearchFilter, // search criteria
  1615. DWORD dwAdditionalFlags // additional search control
  1616. )
  1617. {
  1618. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1619. HANDLE returnValue = ORIGINAL_API(FindFirstFileExA)(lpszString,
  1620. fInfoLevelId,
  1621. lpFindFileData,
  1622. fSearchOp,
  1623. lpSearchFilter,
  1624. dwAdditionalFlags);
  1625. FPFreeA(lpszString, lpFileName);
  1626. return returnValue;
  1627. }
  1628. HANDLE
  1629. APIHOOK(FindFirstFileExW)(
  1630. LPCWSTR lpFileName, // file name
  1631. FINDEX_INFO_LEVELS fInfoLevelId, // information level
  1632. LPVOID lpFindFileData, // information buffer
  1633. FINDEX_SEARCH_OPS fSearchOp, // filtering type
  1634. LPVOID lpSearchFilter, // search criteria
  1635. DWORD dwAdditionalFlags // additional search control
  1636. )
  1637. {
  1638. LPWSTR lpszString = MassageStringForPathW(lpFileName);
  1639. HANDLE returnValue = ORIGINAL_API(FindFirstFileExW)(lpszString,
  1640. fInfoLevelId,
  1641. lpFindFileData,
  1642. fSearchOp,
  1643. lpSearchFilter,
  1644. dwAdditionalFlags);
  1645. FPFreeW(lpszString, lpFileName);
  1646. return returnValue;
  1647. }
  1648. BOOL
  1649. APIHOOK(GetBinaryTypeA)(
  1650. LPCSTR lpApplicationName, // full file path
  1651. LPDWORD lpBinaryType // binary type information
  1652. )
  1653. {
  1654. LPSTR lpszString = MassageStringForPathA(lpApplicationName);
  1655. BOOL returnValue = ORIGINAL_API(GetBinaryTypeA)(lpszString, lpBinaryType);
  1656. FPFreeA(lpszString, lpApplicationName);
  1657. return returnValue;
  1658. }
  1659. BOOL
  1660. APIHOOK(GetBinaryTypeW)(
  1661. LPCWSTR lpApplicationName, // full file path
  1662. LPDWORD lpBinaryType // binary type information
  1663. )
  1664. {
  1665. LPWSTR lpszString = MassageStringForPathW(lpApplicationName);
  1666. BOOL returnValue = ORIGINAL_API(GetBinaryTypeW)(lpszString, lpBinaryType);
  1667. FPFreeW(lpszString, lpApplicationName);
  1668. return returnValue;
  1669. }
  1670. BOOL
  1671. APIHOOK(MoveFileA)(
  1672. LPCSTR lpExistingFileName, // file name
  1673. LPCSTR lpNewFileName // new file name
  1674. )
  1675. {
  1676. LPSTR lpszStringExisting = MassageStringForPathA(lpExistingFileName);
  1677. LPSTR lpszStringNew = MassageStringForPathA(lpNewFileName);
  1678. BOOL returnValue = ORIGINAL_API(MoveFileA)(lpszStringExisting, lpszStringNew);
  1679. FPFreeA(lpszStringExisting, lpExistingFileName);
  1680. FPFreeA(lpszStringNew, lpNewFileName);
  1681. return returnValue;
  1682. }
  1683. BOOL
  1684. APIHOOK(MoveFileW)(
  1685. LPCWSTR lpExistingFileName, // file name
  1686. LPCWSTR lpNewFileName // new file name
  1687. )
  1688. {
  1689. LPWSTR lpszStringExisting = MassageStringForPathW(lpExistingFileName);
  1690. LPWSTR lpszStringNew = MassageStringForPathW(lpNewFileName);
  1691. BOOL returnValue = ORIGINAL_API(MoveFileW)(lpszStringExisting, lpszStringNew);
  1692. FPFreeW(lpszStringExisting, lpExistingFileName);
  1693. FPFreeW(lpszStringNew, lpNewFileName);
  1694. return returnValue;
  1695. }
  1696. BOOL
  1697. APIHOOK(MoveFileExA)(
  1698. LPCSTR lpExistingFileName, // file name
  1699. LPCSTR lpNewFileName, // new file name
  1700. DWORD dwFlags // move options
  1701. )
  1702. {
  1703. LPSTR lpszStringExisting = MassageStringForPathA(lpExistingFileName);
  1704. LPSTR lpszStringNew = MassageStringForPathA(lpNewFileName);
  1705. BOOL returnValue = ORIGINAL_API(MoveFileExA)(lpszStringExisting, lpszStringNew, dwFlags);
  1706. FPFreeA(lpszStringExisting, lpExistingFileName);
  1707. FPFreeA(lpszStringNew, lpNewFileName);
  1708. return returnValue;
  1709. }
  1710. BOOL
  1711. APIHOOK(MoveFileExW)(
  1712. LPCWSTR lpExistingFileName, // file name
  1713. LPCWSTR lpNewFileName, // new file name
  1714. DWORD dwFlags // move options
  1715. )
  1716. {
  1717. LPWSTR lpszStringExisting = MassageStringForPathW(lpExistingFileName);
  1718. LPWSTR lpszStringNew = MassageStringForPathW(lpNewFileName);
  1719. BOOL returnValue = ORIGINAL_API(MoveFileExW)(lpszStringExisting, lpszStringNew, dwFlags);
  1720. FPFreeW(lpszStringExisting, lpExistingFileName);
  1721. FPFreeW(lpszStringNew, lpNewFileName);
  1722. return returnValue;
  1723. }
  1724. BOOL
  1725. APIHOOK(MoveFileWithProgressA)(
  1726. LPCSTR lpExistingFileName, // file name
  1727. LPCSTR lpNewFileName, // new file name
  1728. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1729. LPVOID lpData, // parameter for callback
  1730. DWORD dwFlags // move options
  1731. )
  1732. {
  1733. LPSTR lpszStringExisting = MassageStringForPathA(lpExistingFileName);
  1734. LPSTR lpszStringNew = MassageStringForPathA(lpNewFileName);
  1735. BOOL returnValue = ORIGINAL_API(MoveFileWithProgressA)(lpszStringExisting,
  1736. lpszStringNew,
  1737. lpProgressRoutine,
  1738. lpData,
  1739. dwFlags);
  1740. FPFreeA(lpszStringExisting, lpExistingFileName);
  1741. FPFreeA(lpszStringNew, lpNewFileName);
  1742. return returnValue;
  1743. }
  1744. BOOL
  1745. APIHOOK(MoveFileWithProgressW)(
  1746. LPCWSTR lpExistingFileName, // file name
  1747. LPCWSTR lpNewFileName, // new file name
  1748. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1749. LPVOID lpData, // parameter for callback
  1750. DWORD dwFlags // move options
  1751. )
  1752. {
  1753. LPWSTR lpszStringExisting = MassageStringForPathW(lpExistingFileName);
  1754. LPWSTR lpszStringNew = MassageStringForPathW(lpNewFileName);
  1755. BOOL returnValue = ORIGINAL_API(MoveFileWithProgressW)(lpExistingFileName,
  1756. lpNewFileName,
  1757. lpProgressRoutine,
  1758. lpData,
  1759. dwFlags);
  1760. FPFreeW(lpszStringExisting, lpExistingFileName);
  1761. FPFreeW(lpszStringNew, lpNewFileName);
  1762. return returnValue;
  1763. }
  1764. BOOL
  1765. APIHOOK(RemoveDirectoryA)(
  1766. LPCSTR lpPathName // directory name
  1767. )
  1768. {
  1769. LPSTR lpszString = MassageStringForPathA(lpPathName);
  1770. BOOL returnValue = ORIGINAL_API(RemoveDirectoryA)(lpszString);
  1771. FPFreeA(lpszString, lpPathName);
  1772. return returnValue;
  1773. }
  1774. BOOL
  1775. APIHOOK(RemoveDirectoryW)(
  1776. LPCWSTR lpPathName // directory name
  1777. )
  1778. {
  1779. LPWSTR lpszString = MassageStringForPathW(lpPathName);
  1780. BOOL returnValue = ORIGINAL_API(RemoveDirectoryW)(lpszString);
  1781. FPFreeW(lpszString, lpPathName);
  1782. return returnValue;
  1783. }
  1784. BOOL
  1785. APIHOOK(SetCurrentDirectoryA)(
  1786. LPCSTR lpPathName // new directory name
  1787. )
  1788. {
  1789. LPSTR lpszString = MassageStringForPathA(lpPathName);
  1790. BOOL returnValue = ORIGINAL_API(SetCurrentDirectoryA)(lpszString);
  1791. FPFreeA(lpszString, lpPathName);
  1792. return returnValue;
  1793. }
  1794. BOOL
  1795. APIHOOK(SetCurrentDirectoryW)(
  1796. LPCWSTR lpPathName // new directory name
  1797. )
  1798. {
  1799. LPWSTR lpszString = MassageStringForPathW(lpPathName);
  1800. BOOL returnValue = ORIGINAL_API(SetCurrentDirectoryW)(lpszString);
  1801. FPFreeW(lpszString, lpPathName);
  1802. return returnValue;
  1803. }
  1804. HMODULE
  1805. APIHOOK(LoadLibraryA)(
  1806. LPCSTR lpPathName
  1807. )
  1808. {
  1809. LPSTR lpszString = MassageStringForPathA(lpPathName);
  1810. HMODULE returnValue = ORIGINAL_API(LoadLibraryA)(lpszString);
  1811. FPFreeA(lpszString, lpPathName);
  1812. return returnValue;
  1813. }
  1814. HMODULE
  1815. APIHOOK(LoadLibraryW)(
  1816. LPCWSTR lpPathName
  1817. )
  1818. {
  1819. LPWSTR lpszString = MassageStringForPathW(lpPathName);
  1820. HMODULE returnValue = ORIGINAL_API(LoadLibraryW)(lpszString);
  1821. FPFreeW(lpszString, lpPathName);
  1822. return returnValue;
  1823. }
  1824. HMODULE
  1825. APIHOOK(LoadLibraryExA)(
  1826. LPCSTR lpPathName,
  1827. HANDLE hFile,
  1828. DWORD dwFlags
  1829. )
  1830. {
  1831. LPSTR lpszString = MassageStringForPathA(lpPathName);
  1832. HMODULE returnValue = ORIGINAL_API(LoadLibraryExA)(lpszString, hFile, dwFlags);
  1833. FPFreeA(lpszString, lpPathName);
  1834. return returnValue;
  1835. }
  1836. HMODULE
  1837. APIHOOK(LoadLibraryExW)(
  1838. LPCWSTR lpPathName,
  1839. HANDLE hFile,
  1840. DWORD dwFlags
  1841. )
  1842. {
  1843. LPWSTR lpszString = MassageStringForPathW(lpPathName);
  1844. HMODULE returnValue = ORIGINAL_API(LoadLibraryExW)(lpszString, hFile, dwFlags);
  1845. FPFreeW(lpszString, lpPathName);
  1846. return returnValue;
  1847. }
  1848. HFILE
  1849. APIHOOK(OpenFile)(
  1850. LPCSTR lpFileName, // file name
  1851. LPOFSTRUCT lpReOpenBuff, // file information
  1852. UINT uStyle // action and attributes
  1853. )
  1854. {
  1855. LPSTR lpszString = MassageStringForPathA(lpFileName);
  1856. HFILE returnValue = ORIGINAL_API(OpenFile)(lpszString, lpReOpenBuff, uStyle);
  1857. MassageRealPathToFakePathA(lpReOpenBuff->szPathName, OFS_MAXPATHNAME);
  1858. FPFreeA(lpszString, lpFileName);
  1859. return returnValue;
  1860. }
  1861. LONG
  1862. APIHOOK(RegSetValueA)(
  1863. HKEY hKey, // handle to key
  1864. LPCSTR lpSubKey, // subkey name
  1865. DWORD dwType, // information type
  1866. LPCSTR lpData, // value data
  1867. DWORD cbData // size of value data
  1868. )
  1869. {
  1870. LPSTR lpszString = MassageStringForPathA(lpData);
  1871. //
  1872. // Data key is length of string *not* including null byte.
  1873. //
  1874. if (lpszString != NULL) {
  1875. cbData = strlen(lpszString);
  1876. }
  1877. LONG returnValue = ORIGINAL_API(RegSetValueA)(hKey,
  1878. lpSubKey,
  1879. dwType,
  1880. lpszString,
  1881. cbData);
  1882. FPFreeA(lpszString, lpData);
  1883. return returnValue;
  1884. }
  1885. LONG
  1886. APIHOOK(RegSetValueW)(
  1887. HKEY hKey, // handle to key
  1888. LPCWSTR lpSubKey, // subkey name
  1889. DWORD dwType, // information type
  1890. LPCWSTR lpData, // value data
  1891. DWORD cbData // size of value data
  1892. )
  1893. {
  1894. LPWSTR lpszString = MassageStringForPathW(lpData);
  1895. //
  1896. // Data key is length of string *not* including null byte.
  1897. //
  1898. if (lpszString) {
  1899. cbData = wcslen(lpszString) * sizeof(WCHAR);
  1900. }
  1901. LONG returnValue = ORIGINAL_API(RegSetValueW)(hKey,
  1902. lpSubKey,
  1903. dwType,
  1904. lpszString,
  1905. cbData);
  1906. FPFreeW(lpszString, lpData);
  1907. return returnValue;
  1908. }
  1909. LONG
  1910. APIHOOK(RegSetValueExA)(
  1911. HKEY hKey, // handle to key
  1912. LPCSTR lpValueName, // value name
  1913. DWORD Reserved, // reserved
  1914. DWORD dwType, // value type
  1915. CONST BYTE *lpData, // value data
  1916. DWORD cbData // size of value data
  1917. )
  1918. {
  1919. if (dwType == REG_SZ || dwType == REG_EXPAND_SZ) {
  1920. LPSTR lpszString = MassageStringForPathA((LPCSTR)lpData);
  1921. //
  1922. // Data key is length of string *not* including null byte.
  1923. //
  1924. if (lpszString) {
  1925. cbData = strlen(lpszString);
  1926. }
  1927. LONG returnValue = ORIGINAL_API(RegSetValueExA)(hKey,
  1928. lpValueName,
  1929. Reserved,
  1930. dwType,
  1931. (CONST BYTE*)lpszString,
  1932. cbData);
  1933. FPFreeA(lpszString, (LPCSTR)lpData);
  1934. return returnValue;
  1935. } else {
  1936. //
  1937. // Pass data on through.
  1938. //
  1939. LONG returnValue = ORIGINAL_API(RegSetValueExA)(hKey,
  1940. lpValueName,
  1941. Reserved,
  1942. dwType,
  1943. lpData,
  1944. cbData);
  1945. return returnValue;
  1946. }
  1947. }
  1948. LONG
  1949. APIHOOK(RegSetValueExW)(
  1950. HKEY hKey, // handle to key
  1951. LPCWSTR lpValueName, // value name
  1952. DWORD Reserved, // reserved
  1953. DWORD dwType, // value type
  1954. CONST BYTE *lpData, // value data
  1955. DWORD cbData // size of value data
  1956. )
  1957. {
  1958. if (dwType == REG_SZ || dwType == REG_EXPAND_SZ) {
  1959. LPWSTR lpszString = MassageStringForPathW((LPCWSTR)lpData);
  1960. //
  1961. // Data key is length of string *not* including null byte.
  1962. //
  1963. if (lpszString) {
  1964. cbData = (wcslen(lpszString) + 1) * sizeof(WCHAR);
  1965. }
  1966. LONG returnValue = ORIGINAL_API(RegSetValueExW)(hKey,
  1967. lpValueName,
  1968. Reserved,
  1969. dwType,
  1970. (CONST BYTE*)lpszString,
  1971. cbData);
  1972. FPFreeW(lpszString, (LPCWSTR)lpData);
  1973. return returnValue;
  1974. } else {
  1975. //
  1976. // Pass data on through.
  1977. //
  1978. LONG returnValue = ORIGINAL_API(RegSetValueExW)(hKey,
  1979. lpValueName,
  1980. Reserved,
  1981. dwType,
  1982. lpData,
  1983. cbData);
  1984. return returnValue;
  1985. }
  1986. }
  1987. LONG
  1988. APIHOOK(RegQueryValueA)(
  1989. HKEY hKey,
  1990. LPCSTR lpSubKey,
  1991. LPSTR lpValue,
  1992. PLONG lpcbValue
  1993. )
  1994. {
  1995. //
  1996. // Obtain the size of the buffer prior to the call.
  1997. // When the call is complete, lpcbValue will contain
  1998. // the size of the data stored in the buffer. We
  1999. // need the size of the buffer.
  2000. //
  2001. LONG cbValue = 0;
  2002. if (lpcbValue) {
  2003. cbValue = *lpcbValue;
  2004. }
  2005. LONG returnValue = ORIGINAL_API(RegQueryValueA)(hKey,
  2006. lpSubKey,
  2007. lpValue,
  2008. lpcbValue);
  2009. if (ERROR_SUCCESS == returnValue) {
  2010. MassageRealPathToFakePathA(lpValue, (DWORD)cbValue);
  2011. }
  2012. return returnValue;
  2013. }
  2014. LONG
  2015. APIHOOK(RegQueryValueW)(
  2016. HKEY hKey,
  2017. LPCWSTR lpSubKey,
  2018. LPWSTR lpValue,
  2019. PLONG lpcbValue
  2020. )
  2021. {
  2022. LONG cbValue = 0;
  2023. if (lpcbValue) {
  2024. cbValue = *lpcbValue;
  2025. }
  2026. LONG returnValue = ORIGINAL_API(RegQueryValueW)(hKey,
  2027. lpSubKey,
  2028. lpValue,
  2029. lpcbValue);
  2030. if (ERROR_SUCCESS == returnValue) {
  2031. MassageRealPathToFakePathW(lpValue, (DWORD)cbValue);
  2032. }
  2033. return returnValue;
  2034. }
  2035. LONG
  2036. APIHOOK(RegQueryValueExA)(
  2037. HKEY hKey,
  2038. LPCSTR lpValueName,
  2039. LPDWORD lpReserved,
  2040. LPDWORD lpType,
  2041. LPBYTE lpData,
  2042. LPDWORD lpcbData
  2043. )
  2044. {
  2045. DWORD cbData = 0;
  2046. DWORD dwType = 0;
  2047. if (lpcbData) {
  2048. cbData = *lpcbData;
  2049. }
  2050. if (!lpType) {
  2051. lpType = &dwType;
  2052. }
  2053. LONG returnValue = ORIGINAL_API(RegQueryValueExA)(hKey,
  2054. lpValueName,
  2055. lpReserved,
  2056. lpType,
  2057. lpData,
  2058. lpcbData);
  2059. if (ERROR_SUCCESS == returnValue) {
  2060. if (*lpType == REG_SZ || *lpType == REG_EXPAND_SZ) {
  2061. MassageRealPathToFakePathA((LPSTR)lpData, cbData);
  2062. }
  2063. }
  2064. return returnValue;
  2065. }
  2066. LONG
  2067. APIHOOK(RegQueryValueExW)(
  2068. HKEY hKey,
  2069. LPCWSTR lpValueName,
  2070. LPDWORD lpReserved,
  2071. LPDWORD lpType,
  2072. LPBYTE lpData,
  2073. LPDWORD lpcbData
  2074. )
  2075. {
  2076. DWORD cbData = 0;
  2077. DWORD dwType = 0;
  2078. if (lpcbData) {
  2079. cbData = *lpcbData;
  2080. }
  2081. if (!lpType) {
  2082. lpType = &dwType;
  2083. }
  2084. LONG returnValue = ORIGINAL_API(RegQueryValueExW)(hKey,
  2085. lpValueName,
  2086. lpReserved,
  2087. lpType,
  2088. lpData,
  2089. lpcbData);
  2090. if (ERROR_SUCCESS == returnValue) {
  2091. if (*lpType == REG_SZ || *lpType == REG_EXPAND_SZ) {
  2092. MassageRealPathToFakePathW((LPWSTR)lpData, cbData);
  2093. }
  2094. }
  2095. return returnValue;
  2096. }
  2097. HFILE
  2098. APIHOOK(_lopen)(
  2099. LPCSTR lpPathName,
  2100. int iReadWrite
  2101. )
  2102. {
  2103. LPSTR lpszString = MassageStringForPathA(lpPathName);
  2104. HFILE returnValue = ORIGINAL_API(_lopen)(lpszString, iReadWrite);
  2105. FPFreeA(lpszString, lpPathName);
  2106. return returnValue;
  2107. }
  2108. HFILE
  2109. APIHOOK(_lcreat)(
  2110. LPCSTR lpPathName,
  2111. int iAttribute
  2112. )
  2113. {
  2114. LPSTR lpszString = MassageStringForPathA(lpPathName);
  2115. HFILE returnValue = ORIGINAL_API(_lcreat)(lpszString, iAttribute);
  2116. FPFreeA(lpszString, lpPathName);
  2117. return returnValue;
  2118. }
  2119. DWORD
  2120. APIHOOK(SearchPathA)(
  2121. LPCSTR lpPath, // search path
  2122. LPCSTR lpFileName, // file name
  2123. LPCSTR lpExtension, // file extension
  2124. DWORD nBufferLength, // size of buffer
  2125. LPSTR lpBuffer, // found file name buffer
  2126. LPSTR *lpFilePart // file component
  2127. )
  2128. {
  2129. LPSTR lpszStringPath = MassageStringForPathA(lpPath);
  2130. LPSTR lpszStringFile = MassageStringForPathA(lpFileName);
  2131. DWORD returnValue = ORIGINAL_API(SearchPathA)(lpszStringPath,
  2132. lpszStringFile,
  2133. lpExtension,
  2134. nBufferLength,
  2135. lpBuffer,
  2136. lpFilePart);
  2137. FPFreeA(lpszStringPath, lpPath);
  2138. FPFreeA(lpszStringFile, lpFileName);
  2139. return returnValue;
  2140. }
  2141. DWORD
  2142. APIHOOK(SearchPathW)(
  2143. LPCWSTR lpPath, // search path
  2144. LPCWSTR lpFileName, // file name
  2145. LPCWSTR lpExtension, // file extension
  2146. DWORD nBufferLength, // size of buffer
  2147. LPWSTR lpBuffer, // found file name buffer
  2148. LPWSTR *lpFilePart // file component
  2149. )
  2150. {
  2151. LPWSTR lpszStringPath = MassageStringForPathW(lpPath);
  2152. LPWSTR lpszStringFile = MassageStringForPathW(lpFileName);
  2153. DWORD returnValue = ORIGINAL_API(SearchPathW)(lpszStringPath,
  2154. lpszStringFile,
  2155. lpExtension,
  2156. nBufferLength,
  2157. lpBuffer,
  2158. lpFilePart);
  2159. FPFreeW(lpszStringPath, lpPath);
  2160. FPFreeW(lpszStringFile, lpFileName);
  2161. return returnValue;
  2162. }
  2163. DWORD
  2164. APIHOOK(ExpandEnvironmentStringsA)(
  2165. LPCSTR lpSrc, // string with environment variables
  2166. LPSTR lpDst, // string with expanded strings
  2167. DWORD nSize // maximum characters in expanded string
  2168. )
  2169. {
  2170. DWORD returnValue = ORIGINAL_API(ExpandEnvironmentStringsA)(lpSrc,
  2171. lpDst,
  2172. nSize);
  2173. if (returnValue && (!(returnValue > nSize))) {
  2174. LPSTR lpszString = MassageStringForPathA(lpDst);
  2175. returnValue = ORIGINAL_API(ExpandEnvironmentStringsA)(lpszString,
  2176. lpDst,
  2177. nSize);
  2178. FPFreeA(lpszString, lpDst);
  2179. }
  2180. return returnValue;
  2181. }
  2182. DWORD
  2183. APIHOOK(ExpandEnvironmentStringsW)(
  2184. LPCWSTR lpSrc, // string with environment variables
  2185. LPWSTR lpDst, // string with expanded strings
  2186. DWORD nSize // maximum characters in expanded string
  2187. )
  2188. {
  2189. DWORD returnValue = ORIGINAL_API(ExpandEnvironmentStringsW)(lpSrc,
  2190. lpDst,
  2191. nSize);
  2192. if (returnValue && (!(returnValue > nSize))) {
  2193. LPWSTR lpszString = MassageStringForPathW(lpDst);
  2194. returnValue = ORIGINAL_API(ExpandEnvironmentStringsW)(lpszString,
  2195. lpDst,
  2196. nSize);
  2197. FPFreeW(lpszString, lpDst);
  2198. }
  2199. return returnValue;
  2200. }
  2201. DWORD
  2202. APIHOOK(GetFileVersionInfoSizeA)(
  2203. LPSTR lptstrFilename, // file name
  2204. LPDWORD lpdwHandle // set to zero
  2205. )
  2206. {
  2207. LPSTR lpszString = MassageStringForPathA(lptstrFilename);
  2208. DWORD returnValue = ORIGINAL_API(GetFileVersionInfoSizeA)(lpszString,
  2209. lpdwHandle);
  2210. FPFreeA(lpszString, lptstrFilename);
  2211. return returnValue;
  2212. }
  2213. DWORD
  2214. APIHOOK(GetFileVersionInfoSizeW)(
  2215. LPWSTR lptstrFilename, // file name
  2216. LPDWORD lpdwHandle // set to zero
  2217. )
  2218. {
  2219. LPWSTR lpszString = MassageStringForPathW(lptstrFilename);
  2220. DWORD returnValue = ORIGINAL_API(GetFileVersionInfoSizeW)(lpszString,
  2221. lpdwHandle);
  2222. FPFreeW(lpszString, lptstrFilename);
  2223. return returnValue;
  2224. }
  2225. BOOL
  2226. APIHOOK(GetFileVersionInfoA)(
  2227. LPSTR lptstrFilename, // file name
  2228. DWORD dwHandle, // ignored
  2229. DWORD dwLen, // size of buffer
  2230. LPVOID lpData // version information buffer
  2231. )
  2232. {
  2233. LPSTR lpszString = MassageStringForPathA(lptstrFilename);
  2234. BOOL returnValue = ORIGINAL_API(GetFileVersionInfoA)(lpszString,
  2235. dwHandle,
  2236. dwLen,
  2237. lpData);
  2238. FPFreeA(lpszString, lptstrFilename);
  2239. return returnValue;
  2240. }
  2241. BOOL
  2242. APIHOOK(GetFileVersionInfoW)(
  2243. LPWSTR lptstrFilename, // file name
  2244. DWORD dwHandle, // ignored
  2245. DWORD dwLen, // size of buffer
  2246. LPVOID lpData // version information buffer
  2247. )
  2248. {
  2249. LPWSTR lpszString = MassageStringForPathW(lptstrFilename);
  2250. BOOL returnValue = ORIGINAL_API(GetFileVersionInfoW)(lpszString,
  2251. dwHandle,
  2252. dwLen,
  2253. lpData);
  2254. FPFreeW(lpszString, lptstrFilename);
  2255. return returnValue;
  2256. }
  2257. BOOL
  2258. APIHOOK(GetOpenFileNameA)(
  2259. LPOPENFILENAMEA lpofn // initialization data
  2260. )
  2261. {
  2262. BOOL fReturn = FALSE;
  2263. fReturn = ORIGINAL_API(GetOpenFileNameA)(lpofn);
  2264. if (fReturn) {
  2265. MassageRealPathToFakePathA(lpofn->lpstrFile, lpofn->nMaxFile);
  2266. }
  2267. return fReturn;
  2268. }
  2269. BOOL
  2270. APIHOOK(GetOpenFileNameW)(
  2271. LPOPENFILENAMEW lpofn // initialization data
  2272. )
  2273. {
  2274. BOOL fReturn = ORIGINAL_API(GetOpenFileNameW)(lpofn);
  2275. if (fReturn) {
  2276. MassageRealPathToFakePathW(lpofn->lpstrFile, lpofn->nMaxFile);
  2277. }
  2278. return fReturn;
  2279. }
  2280. BOOL
  2281. APIHOOK(GetSaveFileNameA)(
  2282. LPOPENFILENAMEA lpofn // initialization data
  2283. )
  2284. {
  2285. BOOL fReturn = ORIGINAL_API(GetSaveFileNameA)(lpofn);
  2286. if (fReturn) {
  2287. MassageRealPathToFakePathA(lpofn->lpstrFile, lpofn->nMaxFile);
  2288. }
  2289. return fReturn;
  2290. }
  2291. BOOL
  2292. APIHOOK(GetSaveFileNameW)(
  2293. LPOPENFILENAMEW lpofn // initialization data
  2294. )
  2295. {
  2296. BOOL fReturn = ORIGINAL_API(GetSaveFileNameW)(lpofn);
  2297. if (fReturn) {
  2298. MassageRealPathToFakePathW(lpofn->lpstrFile, lpofn->nMaxFile);
  2299. }
  2300. return fReturn;
  2301. }
  2302. DWORD
  2303. APIHOOK(GetModuleFileNameA)(
  2304. HMODULE hModule, // handle to module
  2305. LPSTR lpFilename, // path buffer
  2306. DWORD nSize // size of buffer
  2307. )
  2308. {
  2309. DWORD dwReturn = ORIGINAL_API(GetModuleFileNameA)(hModule,
  2310. lpFilename,
  2311. nSize);
  2312. if (dwReturn) {
  2313. MassageRealPathToFakePathA(lpFilename, nSize);
  2314. }
  2315. return dwReturn;
  2316. }
  2317. DWORD
  2318. APIHOOK(GetModuleFileNameW)(
  2319. HMODULE hModule, // handle to module
  2320. LPWSTR lpFilename, // path buffer
  2321. DWORD nSize // size of buffer
  2322. )
  2323. {
  2324. DWORD dwReturn = ORIGINAL_API(GetModuleFileNameW)(hModule,
  2325. lpFilename,
  2326. nSize);
  2327. if (dwReturn) {
  2328. MassageRealPathToFakePathW(lpFilename, nSize);
  2329. }
  2330. return dwReturn;
  2331. }
  2332. DWORD
  2333. APIHOOK(GetModuleFileNameExA)(
  2334. HANDLE hProcess, // handle to process
  2335. HMODULE hModule, // handle to module
  2336. LPSTR lpFilename, // path buffer
  2337. DWORD nSize // size of buffer
  2338. )
  2339. {
  2340. DWORD dwReturn = ORIGINAL_API(GetModuleFileNameExA)(hProcess,
  2341. hModule,
  2342. lpFilename,
  2343. nSize);
  2344. if (dwReturn) {
  2345. MassageRealPathToFakePathA(lpFilename, nSize);
  2346. }
  2347. return dwReturn;
  2348. }
  2349. DWORD
  2350. APIHOOK(GetModuleFileNameExW)(
  2351. HANDLE hProcess, // handle to process
  2352. HMODULE hModule, // handle to module
  2353. LPWSTR lpFilename, // path buffer
  2354. DWORD nSize // size of buffer
  2355. )
  2356. {
  2357. DWORD dwReturn = ORIGINAL_API(GetModuleFileNameExW)(hProcess,
  2358. hModule,
  2359. lpFilename,
  2360. nSize);
  2361. if (dwReturn) {
  2362. MassageRealPathToFakePathW(lpFilename, nSize);
  2363. }
  2364. return dwReturn;
  2365. }
  2366. DWORD
  2367. APIHOOK(GetCurrentDirectoryA)(
  2368. DWORD nBufferLength, // size of directory buffer
  2369. LPSTR lpBuffer // directory buffer
  2370. )
  2371. {
  2372. DWORD dwReturn = ORIGINAL_API(GetCurrentDirectoryA)(nBufferLength,
  2373. lpBuffer);
  2374. if (dwReturn) {
  2375. MassageRealPathToFakePathA(lpBuffer, nBufferLength);
  2376. }
  2377. return dwReturn;
  2378. }
  2379. DWORD
  2380. APIHOOK(GetCurrentDirectoryW)(
  2381. DWORD nBufferLength, // size of directory buffer
  2382. LPWSTR lpBuffer // directory buffer
  2383. )
  2384. {
  2385. DWORD dwReturn = ORIGINAL_API(GetCurrentDirectoryW)(nBufferLength,
  2386. lpBuffer);
  2387. if (dwReturn) {
  2388. MassageRealPathToFakePathW(lpBuffer, nBufferLength);
  2389. }
  2390. return dwReturn;
  2391. }
  2392. /*++
  2393. Add a corrected path to the linked list.
  2394. --*/
  2395. BOOL
  2396. AddCorrectedPath(
  2397. LPCWSTR pwszCorrectedPath,
  2398. ListType eType
  2399. )
  2400. {
  2401. int nLen = 0;
  2402. PFILELIST pFile = NULL;
  2403. LPWSTR pwszFilePath = NULL;
  2404. pFile = (PFILELIST)malloc(sizeof(FILELIST));
  2405. if (!pFile) {
  2406. DPFN(eDbgLevelError, "[AddCorrectedPath] No memory for new node!");
  2407. return FALSE;
  2408. }
  2409. //
  2410. // We allocate the memory here to make it easier to keep track of.
  2411. // When we release the memory at the end, we can release all of it
  2412. // from one place.
  2413. //
  2414. nLen = lstrlenW(pwszCorrectedPath) + 1;
  2415. pwszFilePath = (LPWSTR)malloc(nLen * sizeof(WCHAR));
  2416. if (!pwszFilePath) {
  2417. DPFN(eDbgLevelError, "[AddCorrectedPath] No memory for wide path!");
  2418. return FALSE;
  2419. }
  2420. StringCchCopy(pwszFilePath, nLen, pwszCorrectedPath);
  2421. pFile->cchSize = nLen;
  2422. pFile->pwszFilePath = pwszFilePath;
  2423. //
  2424. // Determine which list we should add this node to.
  2425. //
  2426. if (eType == eFrom) {
  2427. pFile->pNext = g_pFileListFromHead;
  2428. g_pFileListFromHead = pFile;
  2429. } else {
  2430. pFile->pNext = g_pFileListToHead;
  2431. g_pFileListToHead = pFile;
  2432. }
  2433. return TRUE;
  2434. }
  2435. /*++
  2436. Build a list of strings separated by NULLs with two NULLs at the end.
  2437. --*/
  2438. LPWSTR
  2439. BuildStringList(
  2440. ListType eListType
  2441. )
  2442. {
  2443. UINT uMemSize = 0;
  2444. PFILELIST pFile = NULL;
  2445. PFILELIST pHead = NULL;
  2446. LPWSTR pwszReturn = NULL;
  2447. LPWSTR pwszNextString = NULL;
  2448. //
  2449. // Determine which list we're working with.
  2450. //
  2451. switch (eListType) {
  2452. case eFrom:
  2453. pHead = pFile = g_pFileListFromHead;
  2454. break;
  2455. case eTo:
  2456. pHead = pFile = g_pFileListToHead;
  2457. break;
  2458. default:
  2459. break;
  2460. }
  2461. //
  2462. // Walk the list and determine how large of a block we'll need to allocate.
  2463. //
  2464. while (pFile) {
  2465. uMemSize += pFile->cchSize;
  2466. pFile = pFile->pNext;
  2467. }
  2468. if (!uMemSize) {
  2469. DPFN(eDbgLevelError, "[BuildStringList] List is empty!");
  2470. return NULL;
  2471. }
  2472. //
  2473. // Allocate a block large enough to hold the strings with a NULL at the end.
  2474. //
  2475. pwszReturn = (LPWSTR)malloc(++uMemSize * sizeof(WCHAR));
  2476. if (!pwszReturn) {
  2477. DPFN(eDbgLevelError, "[BuildStringList] No memory for string!");
  2478. return NULL;
  2479. }
  2480. //
  2481. // Walk the linked list and build the list of Unicode strings.
  2482. //
  2483. pwszNextString = pwszReturn;
  2484. *pwszNextString = '\0';
  2485. while (pHead) {
  2486. wcsncpy(pwszNextString, pHead->pwszFilePath, pHead->cchSize);
  2487. pwszNextString += pHead->cchSize;
  2488. pHead = pHead->pNext;
  2489. }
  2490. *pwszNextString++ = '\0';
  2491. return pwszReturn;
  2492. }
  2493. /*++
  2494. Release memory that was allocated while processing SHFileOperation.
  2495. --*/
  2496. void
  2497. ReleaseMemAllocations(
  2498. LPWSTR pwszFinalPath,
  2499. ListType eListType
  2500. )
  2501. {
  2502. PFILELIST pHead = NULL;
  2503. PFILELIST pTemp = NULL;
  2504. switch (eListType) {
  2505. case eFrom:
  2506. pHead = g_pFileListFromHead;
  2507. break;
  2508. case eTo:
  2509. pHead = g_pFileListToHead;
  2510. break;
  2511. default:
  2512. break;
  2513. }
  2514. //
  2515. // Free the paths first, then the nodes next.
  2516. //
  2517. while (pHead) {
  2518. if (pHead->pwszFilePath) {
  2519. free(pHead->pwszFilePath);
  2520. }
  2521. pTemp = pHead;
  2522. pHead = pHead->pNext;
  2523. free(pTemp);
  2524. }
  2525. if (pwszFinalPath) {
  2526. free(pwszFinalPath);
  2527. }
  2528. }
  2529. /*++
  2530. Build a linked list of corrected paths.
  2531. --*/
  2532. BOOL
  2533. BuildLinkedList(
  2534. LPCWSTR pwszOriginalPath,
  2535. ListType eListType
  2536. )
  2537. {
  2538. UINT uSize = 0;
  2539. LPWSTR pwszReturnPath = NULL;
  2540. if (pwszOriginalPath) {
  2541. while (TRUE) {
  2542. pwszReturnPath = MassageStringForPathW(pwszOriginalPath);
  2543. //
  2544. // Add this corrected path to our list.
  2545. //
  2546. if (!AddCorrectedPath(pwszReturnPath, eListType)) {
  2547. DPFN(eDbgLevelError,
  2548. "[BuildLinkedList] Failed to add wide path to linked list");
  2549. return FALSE;
  2550. }
  2551. FPFreeW(pwszReturnPath, pwszOriginalPath);
  2552. uSize = lstrlenW(pwszOriginalPath) + 1;
  2553. pwszOriginalPath += uSize;
  2554. if (*pwszOriginalPath == '\0') {
  2555. break;
  2556. }
  2557. }
  2558. }
  2559. return TRUE;
  2560. }
  2561. BOOL
  2562. ConvertStringsToUnicode(
  2563. LPWSTR* pwszBuffer,
  2564. LPSHFILEOPSTRUCTA lpFileOp,
  2565. LPSHFILEOPSTRUCTW lpOutFileOp
  2566. )
  2567. {
  2568. UINT cchSize = 0;
  2569. UINT cchWideSize = 0;
  2570. UINT cchTotalSize = 0;
  2571. UINT cchSizeTitle = 0;
  2572. LPCSTR pszAnsi = NULL;
  2573. LPWSTR pwszTemp = NULL;
  2574. //
  2575. // Determine how large of a buffer we need to allocate.
  2576. //
  2577. if (lpFileOp->pFrom) {
  2578. pszAnsi = lpFileOp->pFrom;
  2579. do {
  2580. cchSize = lstrlenA(pszAnsi) + 1;
  2581. cchTotalSize += cchSize;
  2582. pszAnsi += cchSize;
  2583. } while (cchSize != 1);
  2584. }
  2585. if (lpFileOp->pTo) {
  2586. pszAnsi = lpFileOp->pTo;
  2587. do {
  2588. cchSize = lstrlenA(pszAnsi) + 1;
  2589. cchTotalSize += cchSize;
  2590. pszAnsi += cchSize;
  2591. } while (cchSize != 1);
  2592. }
  2593. if (lpFileOp->lpszProgressTitle) {
  2594. cchSizeTitle = lstrlenA(lpFileOp->lpszProgressTitle) + 1;
  2595. cchTotalSize += cchSizeTitle;
  2596. }
  2597. if (cchTotalSize != 0) {
  2598. pwszTemp = *pwszBuffer = (LPWSTR)malloc(cchTotalSize * sizeof(WCHAR));
  2599. if (!*pwszBuffer) {
  2600. DPFN(eDbgLevelError,
  2601. "[ConvertStringsToUnicode] No memory for buffer");
  2602. return FALSE;
  2603. }
  2604. }
  2605. //
  2606. // Perform the ANSI to Unicode conversion.
  2607. //
  2608. if (lpFileOp->pFrom) {
  2609. lpOutFileOp->pFrom = pwszTemp;
  2610. pszAnsi = lpFileOp->pFrom;
  2611. do {
  2612. cchSize = lstrlenA(pszAnsi) + 1;
  2613. cchWideSize = MultiByteToWideChar(
  2614. CP_ACP,
  2615. 0,
  2616. pszAnsi,
  2617. cchSize,
  2618. pwszTemp,
  2619. cchSize);
  2620. pszAnsi += cchSize;
  2621. pwszTemp += cchWideSize;
  2622. } while (cchSize != 1);
  2623. } else {
  2624. lpOutFileOp->pFrom = NULL;
  2625. }
  2626. if (lpFileOp->pTo) {
  2627. lpOutFileOp->pTo = pwszTemp;
  2628. pszAnsi = lpFileOp->pTo;
  2629. do {
  2630. cchSize = lstrlenA(pszAnsi) + 1;
  2631. cchWideSize = MultiByteToWideChar(
  2632. CP_ACP,
  2633. 0,
  2634. pszAnsi,
  2635. cchSize,
  2636. pwszTemp,
  2637. cchSize);
  2638. pszAnsi += cchSize;
  2639. pwszTemp += cchWideSize;
  2640. } while (cchSize != 1);
  2641. } else {
  2642. lpOutFileOp->pTo = NULL;
  2643. }
  2644. if (lpFileOp->lpszProgressTitle) {
  2645. lpOutFileOp->lpszProgressTitle = pwszTemp;
  2646. MultiByteToWideChar(
  2647. CP_ACP,
  2648. 0,
  2649. lpFileOp->lpszProgressTitle,
  2650. cchSizeTitle,
  2651. pwszTemp,
  2652. cchSizeTitle);
  2653. } else {
  2654. lpOutFileOp->lpszProgressTitle = NULL;
  2655. }
  2656. return TRUE;
  2657. }
  2658. int
  2659. APIHOOK(SHFileOperationW)(
  2660. LPSHFILEOPSTRUCTW lpFileOp
  2661. )
  2662. {
  2663. int nReturn = 0;
  2664. LPCWSTR pwszOriginalFrom = NULL;
  2665. LPCWSTR pwszOriginalTo = NULL;
  2666. LPWSTR pwszFinalFrom = NULL;
  2667. LPWSTR pwszFinalTo = NULL;
  2668. pwszOriginalFrom = lpFileOp->pFrom;
  2669. pwszOriginalTo = lpFileOp->pTo;
  2670. RtlEnterCriticalSection(&g_csLinkedList);
  2671. //
  2672. // Build a linked list of the 'from' paths first,
  2673. // and then process to 'to' paths.
  2674. //
  2675. if (!BuildLinkedList(pwszOriginalFrom, eFrom)) {
  2676. DPFN(eDbgLevelError,
  2677. "[SHFileOperationW] Failed to add 'from' path to linked list");
  2678. goto exit;
  2679. }
  2680. if (!BuildLinkedList(pwszOriginalTo, eTo)) {
  2681. DPFN(eDbgLevelError,
  2682. "[SHFileOperationW] Failed to add 'to' path to linked list");
  2683. goto exit;
  2684. }
  2685. //
  2686. // All paths have been massaged - build a list of NULL
  2687. // separated strings with a double NULL at the end.
  2688. //
  2689. pwszFinalFrom = BuildStringList(eFrom);
  2690. if (!pwszFinalFrom) {
  2691. DPFN(eDbgLevelError, "[SHFileOperationW] Failed to build 'from' list");
  2692. goto exit;
  2693. }
  2694. pwszFinalTo = BuildStringList(eTo);
  2695. if (!pwszFinalTo) {
  2696. DPFN(eDbgLevelError, "[SHFileOperationW] Failed to build 'to' list");
  2697. goto exit;
  2698. }
  2699. //
  2700. // Package the strings back into the struct, call the original API
  2701. // to get the results, and then free any memory we've allocated.
  2702. //
  2703. lpFileOp->pFrom = pwszFinalFrom;
  2704. lpFileOp->pTo = pwszFinalTo;
  2705. exit:
  2706. RtlLeaveCriticalSection(&g_csLinkedList);
  2707. nReturn = ORIGINAL_API(SHFileOperationW)(lpFileOp);
  2708. ReleaseMemAllocations(pwszFinalFrom, eFrom);
  2709. ReleaseMemAllocations(pwszFinalTo, eTo);
  2710. g_pFileListFromHead = NULL;
  2711. g_pFileListToHead = NULL;
  2712. return nReturn;
  2713. }
  2714. int
  2715. APIHOOK(SHFileOperationA)(
  2716. LPSHFILEOPSTRUCTA lpFileOp
  2717. )
  2718. {
  2719. int nReturn = 0;
  2720. LPWSTR pwszBuffer = NULL;
  2721. SHFILEOPSTRUCTW shfileop;
  2722. memcpy(&shfileop, lpFileOp, sizeof(SHFILEOPSTRUCTW));
  2723. if (!ConvertStringsToUnicode(&pwszBuffer, lpFileOp, &shfileop)) {
  2724. DPFN(eDbgLevelError,
  2725. "[SHFileOperationA] Failed to convert strings");
  2726. goto exit;
  2727. }
  2728. nReturn = APIHOOK(SHFileOperationW)(&shfileop);
  2729. //
  2730. // Link up the two members that could have changed.
  2731. //
  2732. lpFileOp->fAnyOperationsAborted = shfileop.fAnyOperationsAborted;
  2733. lpFileOp->hNameMappings = shfileop.hNameMappings;
  2734. if (pwszBuffer) {
  2735. free(pwszBuffer);
  2736. }
  2737. return nReturn;
  2738. exit:
  2739. return ORIGINAL_API(SHFileOperationA)(lpFileOp);
  2740. }
  2741. NTSTATUS
  2742. APIHOOK(NtCreateFile)(
  2743. PHANDLE FileHandle,
  2744. ACCESS_MASK DesiredAccess,
  2745. POBJECT_ATTRIBUTES ObjectAttributes,
  2746. PIO_STATUS_BLOCK IoStatusBlock,
  2747. PLARGE_INTEGER AllocationSize,
  2748. ULONG FileAttributes,
  2749. ULONG ShareAccess,
  2750. ULONG CreateDisposition,
  2751. ULONG CreateOptions,
  2752. PVOID EaBuffer,
  2753. ULONG EaLength
  2754. )
  2755. {
  2756. OBJECT_ATTRIBUTES NewObjectAttributes;
  2757. MassageNtPath(ObjectAttributes, &NewObjectAttributes);
  2758. NTSTATUS status = ORIGINAL_API(NtCreateFile)(FileHandle,
  2759. DesiredAccess,
  2760. &NewObjectAttributes,
  2761. IoStatusBlock,
  2762. AllocationSize,
  2763. FileAttributes,
  2764. ShareAccess,
  2765. CreateDisposition,
  2766. CreateOptions,
  2767. EaBuffer,
  2768. EaLength);
  2769. FPNtFree(ObjectAttributes, &NewObjectAttributes);
  2770. return status;
  2771. }
  2772. NTSTATUS
  2773. APIHOOK(NtOpenFile)(
  2774. PHANDLE FileHandle,
  2775. ACCESS_MASK DesiredAccess,
  2776. POBJECT_ATTRIBUTES ObjectAttributes,
  2777. PIO_STATUS_BLOCK IoStatusBlock,
  2778. ULONG ShareAccess,
  2779. ULONG OpenOptions
  2780. )
  2781. {
  2782. OBJECT_ATTRIBUTES NewObjectAttributes;
  2783. MassageNtPath(ObjectAttributes, &NewObjectAttributes);
  2784. NTSTATUS status = ORIGINAL_API(NtOpenFile)(FileHandle,
  2785. DesiredAccess,
  2786. &NewObjectAttributes,
  2787. IoStatusBlock,
  2788. ShareAccess,
  2789. OpenOptions);
  2790. FPNtFree(ObjectAttributes, &NewObjectAttributes);
  2791. return status;
  2792. }
  2793. NTSTATUS
  2794. APIHOOK(NtQueryAttributesFile)(
  2795. POBJECT_ATTRIBUTES ObjectAttributes,
  2796. PFILE_BASIC_INFORMATION FileInformation
  2797. )
  2798. {
  2799. OBJECT_ATTRIBUTES NewObjectAttributes;
  2800. MassageNtPath(ObjectAttributes, &NewObjectAttributes);
  2801. NTSTATUS status = ORIGINAL_API(NtQueryAttributesFile)(&NewObjectAttributes,
  2802. FileInformation);
  2803. FPNtFree(ObjectAttributes, &NewObjectAttributes);
  2804. return status;
  2805. }
  2806. NTSTATUS
  2807. APIHOOK(NtQueryFullAttributesFile)(
  2808. POBJECT_ATTRIBUTES ObjectAttributes,
  2809. PFILE_NETWORK_OPEN_INFORMATION FileInformation
  2810. )
  2811. {
  2812. OBJECT_ATTRIBUTES NewObjectAttributes;
  2813. MassageNtPath(ObjectAttributes, &NewObjectAttributes);
  2814. NTSTATUS status = ORIGINAL_API(NtQueryFullAttributesFile)(&NewObjectAttributes,
  2815. FileInformation);
  2816. FPNtFree(ObjectAttributes, &NewObjectAttributes);
  2817. return status;
  2818. }
  2819. NTSTATUS
  2820. APIHOOK(NtCreateProcessEx)(
  2821. PHANDLE ProcessHandle,
  2822. ACCESS_MASK DesiredAccess,
  2823. POBJECT_ATTRIBUTES ObjectAttributes,
  2824. HANDLE ParentProcess,
  2825. ULONG Flags,
  2826. HANDLE SectionHandle,
  2827. HANDLE DebugPort,
  2828. HANDLE ExceptionPort,
  2829. ULONG JobMemberLevel
  2830. )
  2831. {
  2832. OBJECT_ATTRIBUTES NewObjectAttributes;
  2833. MassageNtPath(ObjectAttributes, &NewObjectAttributes);
  2834. NTSTATUS status = ORIGINAL_API(NtCreateProcessEx)(ProcessHandle,
  2835. DesiredAccess,
  2836. &NewObjectAttributes,
  2837. ParentProcess,
  2838. Flags,
  2839. SectionHandle,
  2840. DebugPort,
  2841. ExceptionPort,
  2842. JobMemberLevel);
  2843. FPNtFree(ObjectAttributes, &NewObjectAttributes);
  2844. return status;
  2845. }
  2846. UINT
  2847. GetSimulatedPathA(
  2848. LPSTR lpBuffer,
  2849. UINT unSize,
  2850. int nWhich
  2851. )
  2852. {
  2853. if (!g_bPathsInited) {
  2854. InitPaths();
  2855. }
  2856. if (unSize > (DWORD)g_Paths[nWhich].nSimulatedPathLen) {
  2857. StringCchCopyA(lpBuffer, unSize, g_Paths[nWhich].szSimulatedPathA);
  2858. return g_Paths[nWhich].nSimulatedPathLen;
  2859. } else {
  2860. return g_Paths[nWhich].nSimulatedPathLen + 1;
  2861. }
  2862. }
  2863. UINT
  2864. GetSimulatedPathW(
  2865. LPWSTR lpBuffer,
  2866. UINT unSize,
  2867. int nWhich
  2868. )
  2869. {
  2870. if (!g_bPathsInited) {
  2871. InitPaths();
  2872. }
  2873. if (unSize > (DWORD)g_Paths[nWhich].nSimulatedPathLen) {
  2874. StringCchCopy(lpBuffer, unSize, g_Paths[nWhich].szSimulatedPathW);
  2875. return g_Paths[nWhich].nSimulatedPathLen;
  2876. } else {
  2877. return g_Paths[nWhich].nSimulatedPathLen + 1;
  2878. }
  2879. }
  2880. DWORD
  2881. APIHOOK(GetTempPathA)(
  2882. DWORD nBufferLength,
  2883. LPSTR lpBuffer
  2884. )
  2885. {
  2886. return GetSimulatedPathA(lpBuffer, nBufferLength, PATH_TEMP);
  2887. }
  2888. DWORD
  2889. APIHOOK(GetTempPathW)(
  2890. DWORD nBufferLength,
  2891. LPWSTR lpBuffer
  2892. )
  2893. {
  2894. return GetSimulatedPathW(lpBuffer, nBufferLength, PATH_TEMP);
  2895. }
  2896. UINT
  2897. APIHOOK(GetWindowsDirectoryA)(
  2898. LPSTR lpBuffer,
  2899. UINT unSize
  2900. )
  2901. {
  2902. return GetSimulatedPathA(lpBuffer, unSize, PATH_WINDOWS);
  2903. }
  2904. UINT
  2905. APIHOOK(GetWindowsDirectoryW)(
  2906. LPWSTR lpBuffer,
  2907. UINT unSize
  2908. )
  2909. {
  2910. return GetSimulatedPathW(lpBuffer, unSize, PATH_WINDOWS);
  2911. }
  2912. UINT
  2913. APIHOOK(GetSystemWindowsDirectoryA)(
  2914. LPSTR lpBuffer,
  2915. UINT unSize
  2916. )
  2917. {
  2918. return GetSimulatedPathA(lpBuffer, unSize, PATH_SYSTEM_WINDOWS);
  2919. }
  2920. UINT
  2921. APIHOOK(GetSystemWindowsDirectoryW)(
  2922. LPWSTR lpBuffer,
  2923. UINT unSize
  2924. )
  2925. {
  2926. return GetSimulatedPathW(lpBuffer, unSize, PATH_SYSTEM_WINDOWS);
  2927. }
  2928. UINT
  2929. APIHOOK(GetSystemDirectoryA)(
  2930. LPSTR lpBuffer,
  2931. UINT unSize
  2932. )
  2933. {
  2934. return GetSimulatedPathA(lpBuffer, unSize, PATH_SYSTEM);
  2935. }
  2936. UINT
  2937. APIHOOK(GetSystemDirectoryW)(
  2938. LPWSTR lpBuffer,
  2939. UINT unSize
  2940. )
  2941. {
  2942. return GetSimulatedPathW(lpBuffer, unSize, PATH_SYSTEM);
  2943. }
  2944. BOOL
  2945. APIHOOK(SHGetSpecialFolderPathA)(
  2946. HWND hwndOwner,
  2947. LPSTR lpszPath,
  2948. int nFolder,
  2949. BOOL fCreate
  2950. )
  2951. {
  2952. if (!g_bPathsInited) {
  2953. InitPaths();
  2954. }
  2955. switch (nFolder) {
  2956. case CSIDL_PERSONAL:
  2957. StringCchCopyA(lpszPath, MAX_PATH, g_Paths[PATH_PERSONAL].szSimulatedPathA);
  2958. return TRUE;
  2959. break;
  2960. case CSIDL_SYSTEM:
  2961. StringCchCopyA(lpszPath, MAX_PATH, g_Paths[PATH_SYSTEM].szSimulatedPathA);
  2962. return TRUE;
  2963. break;
  2964. case CSIDL_WINDOWS:
  2965. StringCchCopyA(lpszPath, MAX_PATH, g_Paths[PATH_WINDOWS].szSimulatedPathA);
  2966. return TRUE;
  2967. break;
  2968. case CSIDL_PROGRAMS:
  2969. StringCchCopyA(lpszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathA);
  2970. return TRUE;
  2971. break;
  2972. case CSIDL_STARTMENU:
  2973. StringCchCopyA(lpszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathA);
  2974. return TRUE;
  2975. break;
  2976. case CSIDL_COMMON_PROGRAMS:
  2977. StringCchCopyA(lpszPath, MAX_PATH, g_Paths[PATH_COMMON_PROGRAMS].szSimulatedPathA);
  2978. return TRUE;
  2979. break;
  2980. case CSIDL_COMMON_STARTMENU:
  2981. StringCchCopyA(lpszPath, MAX_PATH, g_Paths[PATH_COMMON_STARTMENU].szSimulatedPathA);
  2982. return TRUE;
  2983. break;
  2984. }
  2985. //
  2986. // the others we aren't nabbing
  2987. //
  2988. return ORIGINAL_API(SHGetSpecialFolderPathA)(hwndOwner, lpszPath, nFolder, fCreate);
  2989. }
  2990. BOOL
  2991. APIHOOK(SHGetSpecialFolderPathW)(
  2992. HWND hwndOwner,
  2993. LPWSTR lpszPath,
  2994. int nFolder,
  2995. BOOL fCreate
  2996. )
  2997. {
  2998. if (!g_bPathsInited) {
  2999. InitPaths();
  3000. }
  3001. switch (nFolder) {
  3002. case CSIDL_PERSONAL:
  3003. StringCchCopy(lpszPath, MAX_PATH, g_Paths[PATH_PERSONAL].szSimulatedPathW);
  3004. return TRUE;
  3005. break;
  3006. case CSIDL_SYSTEM:
  3007. StringCchCopy(lpszPath, MAX_PATH, g_Paths[PATH_SYSTEM].szSimulatedPathW);
  3008. return TRUE;
  3009. break;
  3010. case CSIDL_WINDOWS:
  3011. StringCchCopy(lpszPath, MAX_PATH, g_Paths[PATH_WINDOWS].szSimulatedPathW);
  3012. return TRUE;
  3013. break;
  3014. case CSIDL_PROGRAMS:
  3015. StringCchCopy(lpszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathW);
  3016. return TRUE;
  3017. break;
  3018. case CSIDL_STARTMENU:
  3019. StringCchCopy(lpszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathW);
  3020. return TRUE;
  3021. break;
  3022. case CSIDL_COMMON_PROGRAMS:
  3023. StringCchCopy(lpszPath, MAX_PATH, g_Paths[PATH_COMMON_PROGRAMS].szSimulatedPathW);
  3024. return TRUE;
  3025. break;
  3026. case CSIDL_COMMON_STARTMENU:
  3027. StringCchCopy(lpszPath, MAX_PATH, g_Paths[PATH_COMMON_STARTMENU].szSimulatedPathW);
  3028. return TRUE;
  3029. break;
  3030. }
  3031. //
  3032. // the others we aren't nabbing
  3033. //
  3034. return ORIGINAL_API(SHGetSpecialFolderPathW)(hwndOwner, lpszPath, nFolder, fCreate);
  3035. }
  3036. HRESULT
  3037. APIHOOK(SHGetFolderPathA)(
  3038. HWND hwndOwner,
  3039. int nFolder,
  3040. HANDLE hToken,
  3041. DWORD dwFlags,
  3042. LPSTR pszPath
  3043. )
  3044. {
  3045. if (!g_bPathsInited) {
  3046. InitPaths();
  3047. }
  3048. switch (nFolder) {
  3049. case CSIDL_PERSONAL:
  3050. StringCchCopyA(pszPath, MAX_PATH, g_Paths[PATH_PERSONAL].szSimulatedPathA);
  3051. return S_OK;
  3052. break;
  3053. case CSIDL_SYSTEM:
  3054. StringCchCopyA(pszPath, MAX_PATH, g_Paths[PATH_SYSTEM].szSimulatedPathA);
  3055. return S_OK;
  3056. break;
  3057. case CSIDL_WINDOWS:
  3058. StringCchCopyA(pszPath, MAX_PATH, g_Paths[PATH_WINDOWS].szSimulatedPathA);
  3059. return S_OK;
  3060. break;
  3061. case CSIDL_PROGRAMS:
  3062. StringCchCopyA(pszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathA);
  3063. return S_OK;
  3064. break;
  3065. case CSIDL_STARTMENU:
  3066. StringCchCopyA(pszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathA);
  3067. return S_OK;
  3068. break;
  3069. case CSIDL_COMMON_PROGRAMS:
  3070. StringCchCopyA(pszPath, MAX_PATH, g_Paths[PATH_COMMON_PROGRAMS].szSimulatedPathA);
  3071. return S_OK;
  3072. break;
  3073. case CSIDL_COMMON_STARTMENU:
  3074. StringCchCopyA(pszPath, MAX_PATH, g_Paths[PATH_COMMON_STARTMENU].szSimulatedPathA);
  3075. return S_OK;
  3076. break;
  3077. }
  3078. //
  3079. // the others we aren't nabbing
  3080. //
  3081. return ORIGINAL_API(SHGetFolderPathA)(hwndOwner, nFolder, hToken, dwFlags, pszPath);
  3082. }
  3083. HRESULT
  3084. APIHOOK(SHGetFolderPathW)(
  3085. HWND hwndOwner,
  3086. int nFolder,
  3087. HANDLE hToken,
  3088. DWORD dwFlags,
  3089. LPWSTR pszPath
  3090. )
  3091. {
  3092. if (!g_bPathsInited) {
  3093. InitPaths();
  3094. }
  3095. switch (nFolder) {
  3096. case CSIDL_PERSONAL:
  3097. StringCchCopy(pszPath, MAX_PATH, g_Paths[PATH_PERSONAL].szSimulatedPathW);
  3098. return S_OK;
  3099. break;
  3100. case CSIDL_SYSTEM:
  3101. StringCchCopy(pszPath, MAX_PATH, g_Paths[PATH_SYSTEM].szSimulatedPathW);
  3102. return S_OK;
  3103. break;
  3104. case CSIDL_WINDOWS:
  3105. StringCchCopy(pszPath, MAX_PATH, g_Paths[PATH_WINDOWS].szSimulatedPathW);
  3106. return S_OK;
  3107. break;
  3108. case CSIDL_PROGRAMS:
  3109. StringCchCopy(pszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathW);
  3110. return S_OK;
  3111. break;
  3112. case CSIDL_STARTMENU:
  3113. StringCchCopy(pszPath, MAX_PATH, g_Paths[PATH_PROGRAMS].szSimulatedPathW);
  3114. return S_OK;
  3115. break;
  3116. case CSIDL_COMMON_PROGRAMS:
  3117. StringCchCopy(pszPath, MAX_PATH, g_Paths[PATH_COMMON_PROGRAMS].szSimulatedPathW);
  3118. return S_OK;
  3119. break;
  3120. case CSIDL_COMMON_STARTMENU:
  3121. StringCchCopy(pszPath, MAX_PATH, g_Paths[PATH_COMMON_STARTMENU].szSimulatedPathW);
  3122. return S_OK;
  3123. break;
  3124. }
  3125. //
  3126. // the others we aren't nabbing
  3127. //
  3128. return ORIGINAL_API(SHGetFolderPathW)(hwndOwner, nFolder, hToken, dwFlags, pszPath);
  3129. }
  3130. BOOL
  3131. APIHOOK(SHGetPathFromIDListA)(
  3132. LPCITEMIDLIST pidl,
  3133. LPSTR pszPath
  3134. )
  3135. {
  3136. if (!g_bPathsInited) {
  3137. InitPaths();
  3138. }
  3139. BOOL fReturn = ORIGINAL_API(SHGetPathFromIDListA)(pidl, pszPath);
  3140. if (fReturn) {
  3141. MassageRealPathToFakePathA(pszPath, MAX_PATH);
  3142. }
  3143. return fReturn;
  3144. }
  3145. BOOL
  3146. APIHOOK(SHGetPathFromIDListW)(
  3147. LPCITEMIDLIST pidl,
  3148. LPWSTR pszPath
  3149. )
  3150. {
  3151. if (!g_bPathsInited) {
  3152. InitPaths();
  3153. }
  3154. BOOL fReturn = ORIGINAL_API(SHGetPathFromIDListW)(pidl, pszPath);
  3155. if (fReturn) {
  3156. MassageRealPathToFakePathW(pszPath, MAX_PATH);
  3157. }
  3158. return fReturn;
  3159. }
  3160. SHIM_INFO_BEGIN()
  3161. SHIM_INFO_DESCRIPTION(AVS_FILEPATHS_DESC)
  3162. SHIM_INFO_FRIENDLY_NAME(AVS_FILEPATHS_FRIENDLY)
  3163. SHIM_INFO_FLAGS(AVRF_FLAG_RUN_ALONE | AVRF_FLAG_EXTERNAL_ONLY)
  3164. SHIM_INFO_GROUPS(0)
  3165. SHIM_INFO_VERSION(1, 6)
  3166. SHIM_INFO_INCLUDE_EXCLUDE("E:ole32.dll oleaut32.dll")
  3167. SHIM_INFO_END()
  3168. BOOL
  3169. NOTIFY_FUNCTION(
  3170. DWORD fdwReason
  3171. )
  3172. {
  3173. if (fdwReason == DLL_PROCESS_ATTACH) {
  3174. UINT cchSize;
  3175. DWORD cchReturned;
  3176. //
  3177. // Initialize a critical section to keep our linked list safe.
  3178. //
  3179. RtlInitializeCriticalSection(&g_csLinkedList);
  3180. cchReturned = GetTempPathA(MAX_PATH, g_Paths[PATH_TEMP].szCorrectPathA);
  3181. if (cchReturned > sizeof(g_Paths[PATH_TEMP].szCorrectPathA) || cchReturned == 0) {
  3182. goto exit;
  3183. }
  3184. cchReturned = GetTempPathW(MAX_PATH, g_Paths[PATH_TEMP].szCorrectPathW);
  3185. if (cchReturned > ARRAYSIZE(g_Paths[PATH_TEMP].szCorrectPathW) || cchReturned == 0) {
  3186. goto exit;
  3187. }
  3188. g_Paths[PATH_TEMP].nCorrectPathLen = strlen(g_Paths[PATH_TEMP].szCorrectPathA);
  3189. g_Paths[PATH_TEMP].nSimulatedPathLen = strlen(g_Paths[PATH_TEMP].szSimulatedPathA);
  3190. cchSize = GetWindowsDirectoryA(g_Paths[PATH_WINDOWS].szCorrectPathA, MAX_PATH);
  3191. if (cchSize > sizeof(g_Paths[PATH_WINDOWS].szCorrectPathA) || cchSize == 0) {
  3192. goto exit;
  3193. }
  3194. cchSize = GetWindowsDirectoryW(g_Paths[PATH_WINDOWS].szCorrectPathW, MAX_PATH);
  3195. if (cchSize > ARRAYSIZE(g_Paths[PATH_WINDOWS].szCorrectPathW) || cchSize == 0) {
  3196. goto exit;
  3197. }
  3198. g_Paths[PATH_WINDOWS].nCorrectPathLen = strlen(g_Paths[PATH_WINDOWS].szCorrectPathA);
  3199. g_Paths[PATH_WINDOWS].nSimulatedPathLen = strlen(g_Paths[PATH_WINDOWS].szSimulatedPathA);
  3200. cchSize = GetSystemWindowsDirectoryA(g_Paths[PATH_SYSTEM_WINDOWS].szCorrectPathA, MAX_PATH);
  3201. if (cchSize > sizeof(g_Paths[PATH_SYSTEM_WINDOWS].szCorrectPathA) || cchSize == 0) {
  3202. goto exit;
  3203. }
  3204. cchSize = GetSystemWindowsDirectoryW(g_Paths[PATH_SYSTEM_WINDOWS].szCorrectPathW, MAX_PATH);
  3205. if (cchSize > ARRAYSIZE(g_Paths[PATH_SYSTEM_WINDOWS].szCorrectPathW) || cchSize == 0) {
  3206. goto exit;
  3207. }
  3208. g_Paths[PATH_SYSTEM_WINDOWS].nCorrectPathLen = strlen(g_Paths[PATH_SYSTEM_WINDOWS].szCorrectPathA);
  3209. g_Paths[PATH_SYSTEM_WINDOWS].nSimulatedPathLen = strlen(g_Paths[PATH_SYSTEM_WINDOWS].szSimulatedPathA);
  3210. cchSize = GetSystemDirectoryA(g_Paths[PATH_SYSTEM].szCorrectPathA, MAX_PATH);
  3211. if (cchSize > sizeof(g_Paths[PATH_SYSTEM].szCorrectPathA) || cchSize == 0) {
  3212. goto exit;
  3213. }
  3214. cchSize = GetSystemDirectoryW(g_Paths[PATH_SYSTEM].szCorrectPathW, MAX_PATH);
  3215. if (cchSize > ARRAYSIZE(g_Paths[PATH_SYSTEM].szCorrectPathW) || cchSize == 0) {
  3216. goto exit;
  3217. }
  3218. g_Paths[PATH_SYSTEM].nCorrectPathLen = strlen(g_Paths[PATH_SYSTEM].szCorrectPathA);
  3219. g_Paths[PATH_SYSTEM].nSimulatedPathLen = strlen(g_Paths[PATH_SYSTEM].szSimulatedPathA);
  3220. //
  3221. // Catch apps that use ExpandEnvironmentStrings.
  3222. //
  3223. SetEnvironmentVariableW(L"TEMP", g_Paths[PATH_TEMP].szSimulatedPathW);
  3224. SetEnvironmentVariableW(L"TMP", g_Paths[PATH_TEMP].szSimulatedPathW);
  3225. SetEnvironmentVariableW(L"windir", g_Paths[PATH_WINDOWS].szSimulatedPathW);
  3226. }
  3227. return TRUE;
  3228. exit:
  3229. DPFN(eDbgLevelError,
  3230. "[NOTIFY_FUNCTION] 0x%08X Failed to initialize",
  3231. GetLastError());
  3232. return FALSE;
  3233. }
  3234. /*++
  3235. Register hooked functions
  3236. --*/
  3237. HOOK_BEGIN
  3238. CALL_NOTIFY_FUNCTION
  3239. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_GETTEMPPATH,
  3240. AVS_HARDCODED_GETTEMPPATH,
  3241. AVS_HARDCODED_GETTEMPPATH_R,
  3242. AVS_HARDCODED_GETTEMPPATH_URL)
  3243. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_WINDOWSPATH,
  3244. AVS_HARDCODED_WINDOWSPATH,
  3245. AVS_HARDCODED_WINDOWSPATH_R,
  3246. AVS_HARDCODED_WINDOWSPATH_URL)
  3247. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_SYSWINDOWSPATH,
  3248. AVS_HARDCODED_SYSWINDOWSPATH,
  3249. AVS_HARDCODED_SYSWINDOWSPATH_R,
  3250. AVS_HARDCODED_SYSWINDOWSPATH_URL)
  3251. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_SYSTEMPATH,
  3252. AVS_HARDCODED_SYSTEMPATH,
  3253. AVS_HARDCODED_SYSTEMPATH_R,
  3254. AVS_HARDCODED_SYSTEMPATH_URL)
  3255. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_PERSONALPATH,
  3256. AVS_HARDCODED_PERSONALPATH,
  3257. AVS_HARDCODED_PERSONALPATH_R,
  3258. AVS_HARDCODED_PERSONALPATH_URL)
  3259. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_COMMONPROGRAMS,
  3260. AVS_HARDCODED_COMMONPROGRAMS,
  3261. AVS_HARDCODED_COMMONPROGRAMS_R,
  3262. AVS_HARDCODED_COMMONPROGRAMS_URL)
  3263. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_COMMONSTARTMENU,
  3264. AVS_HARDCODED_COMMONSTARTMENU,
  3265. AVS_HARDCODED_COMMONSTARTMENU_R,
  3266. AVS_HARDCODED_COMMONSTARTMENU_URL)
  3267. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_PROGRAMS,
  3268. AVS_HARDCODED_PROGRAMS,
  3269. AVS_HARDCODED_PROGRAMS_R,
  3270. AVS_HARDCODED_PROGRAMS_URL)
  3271. DUMP_VERIFIER_LOG_ENTRY(VLOG_HARDCODED_STARTMENU,
  3272. AVS_HARDCODED_STARTMENU,
  3273. AVS_HARDCODED_STARTMENU_R,
  3274. AVS_HARDCODED_STARTMENU_URL)
  3275. APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA)
  3276. APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineW)
  3277. APIHOOK_ENTRY(KERNEL32.DLL, GetTempPathA)
  3278. APIHOOK_ENTRY(KERNEL32.DLL, GetTempPathW)
  3279. APIHOOK_ENTRY(KERNEL32.DLL, GetSystemDirectoryA)
  3280. APIHOOK_ENTRY(KERNEL32.DLL, GetSystemDirectoryW)
  3281. APIHOOK_ENTRY(KERNEL32.DLL, GetSystemWindowsDirectoryA)
  3282. APIHOOK_ENTRY(KERNEL32.DLL, GetSystemWindowsDirectoryW)
  3283. APIHOOK_ENTRY(KERNEL32.DLL, GetWindowsDirectoryA)
  3284. APIHOOK_ENTRY(KERNEL32.DLL, GetWindowsDirectoryW)
  3285. APIHOOK_ENTRY(SHELL32.DLL, SHGetFolderPathA)
  3286. APIHOOK_ENTRY(SHELL32.DLL, SHGetFolderPathW)
  3287. APIHOOK_ENTRY(SHELL32.DLL, SHGetSpecialFolderPathA)
  3288. APIHOOK_ENTRY(SHELL32.DLL, SHGetSpecialFolderPathW)
  3289. APIHOOK_ENTRY(SHELL32.DLL, SHGetPathFromIDListA)
  3290. APIHOOK_ENTRY(SHELL32.DLL, SHGetPathFromIDListW)
  3291. APIHOOK_ENTRY(COMDLG32.DLL, GetOpenFileNameA)
  3292. APIHOOK_ENTRY(COMDLG32.DLL, GetOpenFileNameW)
  3293. APIHOOK_ENTRY(COMDLG32.DLL, GetSaveFileNameA)
  3294. APIHOOK_ENTRY(COMDLG32.DLL, GetSaveFileNameW)
  3295. APIHOOK_ENTRY(KERNEL32.DLL, GetModuleFileNameA)
  3296. APIHOOK_ENTRY(KERNEL32.DLL, GetModuleFileNameW)
  3297. APIHOOK_ENTRY(PSAPI.DLL, GetModuleFileNameExA)
  3298. APIHOOK_ENTRY(PSAPI.DLL, GetModuleFileNameExW)
  3299. APIHOOK_ENTRY(KERNEL32.DLL, GetCurrentDirectoryA)
  3300. APIHOOK_ENTRY(KERNEL32.DLL, GetCurrentDirectoryW)
  3301. APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA)
  3302. APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessW)
  3303. APIHOOK_ENTRY(KERNEL32.DLL, WinExec)
  3304. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteA)
  3305. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteW)
  3306. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteExA)
  3307. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteExW)
  3308. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileIntA)
  3309. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileIntW)
  3310. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionA)
  3311. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionW)
  3312. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionNamesA)
  3313. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionNamesW)
  3314. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStringA)
  3315. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStringW)
  3316. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStructA)
  3317. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStructW)
  3318. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileSectionA)
  3319. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileSectionW)
  3320. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStringA)
  3321. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStringW)
  3322. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStructA)
  3323. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStructW)
  3324. // g_bFileRoutines)
  3325. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileA)
  3326. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileW)
  3327. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExA)
  3328. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExW)
  3329. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryA)
  3330. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryW)
  3331. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExA)
  3332. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExW)
  3333. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileA)
  3334. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileW)
  3335. APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileA)
  3336. APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileW)
  3337. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileA)
  3338. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileW)
  3339. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileExA)
  3340. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileExW)
  3341. APIHOOK_ENTRY(KERNEL32.DLL, GetBinaryTypeA)
  3342. APIHOOK_ENTRY(KERNEL32.DLL, GetBinaryTypeW)
  3343. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesA)
  3344. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesW)
  3345. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesExA)
  3346. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesExW)
  3347. APIHOOK_ENTRY(KERNEL32.DLL, SetFileAttributesA)
  3348. APIHOOK_ENTRY(KERNEL32.DLL, SetFileAttributesW)
  3349. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileA)
  3350. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileW)
  3351. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExA)
  3352. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExW)
  3353. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressA)
  3354. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressW)
  3355. APIHOOK_ENTRY(KERNEL32.DLL, RemoveDirectoryA)
  3356. APIHOOK_ENTRY(KERNEL32.DLL, RemoveDirectoryW)
  3357. APIHOOK_ENTRY(KERNEL32.DLL, SetCurrentDirectoryA)
  3358. APIHOOK_ENTRY(KERNEL32.DLL, SetCurrentDirectoryW)
  3359. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryA)
  3360. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryW)
  3361. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryExA)
  3362. APIHOOK_ENTRY(KERNEL32.DLL, LoadLibraryExW)
  3363. APIHOOK_ENTRY(KERNEL32.DLL, SearchPathA)
  3364. APIHOOK_ENTRY(KERNEL32.DLL, SearchPathW)
  3365. APIHOOK_ENTRY(KERNEL32.DLL, ExpandEnvironmentStringsA)
  3366. APIHOOK_ENTRY(KERNEL32.DLL, ExpandEnvironmentStringsW)
  3367. APIHOOK_ENTRY(VERSION.DLL, GetFileVersionInfoSizeA)
  3368. APIHOOK_ENTRY(VERSION.DLL, GetFileVersionInfoSizeW)
  3369. APIHOOK_ENTRY(VERSION.DLL, GetFileVersionInfoA)
  3370. APIHOOK_ENTRY(VERSION.DLL, GetFileVersionInfoW)
  3371. APIHOOK_ENTRY(SHELL32.DLL, SHFileOperationA)
  3372. APIHOOK_ENTRY(SHELL32.DLL, SHFileOperationW)
  3373. APIHOOK_ENTRY(KERNEL32.DLL, OpenFile)
  3374. // 16 bit compatibility file routines
  3375. APIHOOK_ENTRY(KERNEL32.DLL, _lopen)
  3376. APIHOOK_ENTRY(KERNEL32.DLL, _lcreat)
  3377. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueA)
  3378. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueW)
  3379. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueExA)
  3380. APIHOOK_ENTRY(ADVAPI32.DLL, RegQueryValueExW)
  3381. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueA)
  3382. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueW)
  3383. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExA)
  3384. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExW)
  3385. APIHOOK_ENTRY(NTDLL.DLL, NtCreateFile)
  3386. APIHOOK_ENTRY(NTDLL.DLL, NtOpenFile)
  3387. APIHOOK_ENTRY(NTDLL.DLL, NtQueryAttributesFile)
  3388. APIHOOK_ENTRY(NTDLL.DLL, NtQueryFullAttributesFile)
  3389. APIHOOK_ENTRY(NTDLL.DLL, NtCreateProcessEx)
  3390. HOOK_END
  3391. IMPLEMENT_SHIM_END