Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4204 lines
118 KiB

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