Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2620 lines
80 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. CorrectFilePaths.cpp
  5. Abstract:
  6. This APIHooks CreateProcess and attempts to convert paths from Win9x locations to Win2000
  7. locations. For example "C:\WINNT\WRITE.EXE" will be converted to C:\WINNT\SYSTEM32\WRITE.EXE"
  8. Notes:
  9. This APIHook emulates Windows 9x.
  10. Created:
  11. 12/15/1999 robkenny
  12. Modified:
  13. 03/14/2000 robkenny Now uses ClassCFP instead of global routines.
  14. 03/31/2000 robkenny ShellExecuteEx now handle lpDirectory path as well.
  15. 05/18/2000 a-sesk GetCommandLineA and GetCommandLineW convert cmd line args to short path.
  16. 06/20/2000 robkenny Added SetFileAttributes()
  17. 06/22/2000 robkenny Reordered enum list and DECLARE_APIHOOK list to match each other.
  18. --SERIOUS CHANGE--
  19. 10/30/2000 robkenny Added path specific fixes.
  20. Command lines now have the EXE path removed and corrected
  21. separately from the remainder of the command line.
  22. 11/13/2000 a-alexsm Added SetArguments & SetIconLocation hooks
  23. 11/13/2000 robkenny Changed CorrectPath to always return a valid string
  24. by returning the original string. Must call CorrectFree
  25. to properly release the memory.
  26. 12/14/2000 prashkud Added hooks for _lopen and _lcreat
  27. 03/10/2001 robkenny Do not convert any paths until *after* all shims have been loaded.
  28. 03/15/2001 robkenny Converted to CString
  29. --*/
  30. #include "precomp.h"
  31. #include "ClassCFP.h"
  32. IMPLEMENT_SHIM_BEGIN(CorrectFilePaths)
  33. #include "ShimHookMacro.h"
  34. APIHOOK_ENUM_BEGIN
  35. APIHOOK_ENUM_ENTRY(CreateProcessA)
  36. APIHOOK_ENUM_ENTRY(CreateProcessW)
  37. APIHOOK_ENUM_ENTRY(WinExec)
  38. APIHOOK_ENUM_ENTRY(ShellExecuteA)
  39. APIHOOK_ENUM_ENTRY(ShellExecuteW)
  40. APIHOOK_ENUM_ENTRY(ShellExecuteExA)
  41. APIHOOK_ENUM_ENTRY(ShellExecuteExW)
  42. APIHOOK_ENUM_ENTRY(GetCommandLineA)
  43. APIHOOK_ENUM_ENTRY(GetCommandLineW)
  44. APIHOOK_ENUM_ENTRY(GetPrivateProfileIntA)
  45. APIHOOK_ENUM_ENTRY(GetPrivateProfileIntW)
  46. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionA)
  47. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionW)
  48. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionNamesA)
  49. APIHOOK_ENUM_ENTRY(GetPrivateProfileSectionNamesW)
  50. APIHOOK_ENUM_ENTRY(GetPrivateProfileStringA)
  51. APIHOOK_ENUM_ENTRY(GetPrivateProfileStringW)
  52. APIHOOK_ENUM_ENTRY(GetPrivateProfileStructA)
  53. APIHOOK_ENUM_ENTRY(GetPrivateProfileStructW)
  54. APIHOOK_ENUM_ENTRY(WritePrivateProfileSectionA)
  55. APIHOOK_ENUM_ENTRY(WritePrivateProfileSectionW)
  56. APIHOOK_ENUM_ENTRY(WritePrivateProfileStringA)
  57. APIHOOK_ENUM_ENTRY(WritePrivateProfileStringW)
  58. APIHOOK_ENUM_ENTRY(WritePrivateProfileStructA)
  59. APIHOOK_ENUM_ENTRY(WritePrivateProfileStructW)
  60. APIHOOK_ENUM_ENTRY(CopyFileA)
  61. APIHOOK_ENUM_ENTRY(CopyFileW)
  62. APIHOOK_ENUM_ENTRY(CopyFileExA)
  63. APIHOOK_ENUM_ENTRY(CopyFileExW)
  64. APIHOOK_ENUM_ENTRY(CreateDirectoryA)
  65. APIHOOK_ENUM_ENTRY(CreateDirectoryW)
  66. APIHOOK_ENUM_ENTRY(CreateDirectoryExA)
  67. APIHOOK_ENUM_ENTRY(CreateDirectoryExW)
  68. APIHOOK_ENUM_ENTRY(CreateFileA)
  69. APIHOOK_ENUM_ENTRY(CreateFileW)
  70. APIHOOK_ENUM_ENTRY(DeleteFileA)
  71. APIHOOK_ENUM_ENTRY(DeleteFileW)
  72. APIHOOK_ENUM_ENTRY(FindFirstFileA)
  73. APIHOOK_ENUM_ENTRY(FindFirstFileW)
  74. APIHOOK_ENUM_ENTRY(FindFirstFileExA)
  75. APIHOOK_ENUM_ENTRY(FindFirstFileExW)
  76. APIHOOK_ENUM_ENTRY(GetBinaryTypeA)
  77. APIHOOK_ENUM_ENTRY(GetBinaryTypeW)
  78. APIHOOK_ENUM_ENTRY(GetFileAttributesA)
  79. APIHOOK_ENUM_ENTRY(GetFileAttributesW)
  80. APIHOOK_ENUM_ENTRY(GetFileAttributesExA)
  81. APIHOOK_ENUM_ENTRY(GetFileAttributesExW)
  82. APIHOOK_ENUM_ENTRY(SetFileAttributesA)
  83. APIHOOK_ENUM_ENTRY(SetFileAttributesW)
  84. APIHOOK_ENUM_ENTRY(MoveFileA)
  85. APIHOOK_ENUM_ENTRY(MoveFileW)
  86. APIHOOK_ENUM_ENTRY(MoveFileExA)
  87. APIHOOK_ENUM_ENTRY(MoveFileExW)
  88. APIHOOK_ENUM_ENTRY(MoveFileWithProgressA)
  89. APIHOOK_ENUM_ENTRY(MoveFileWithProgressW)
  90. APIHOOK_ENUM_ENTRY(RemoveDirectoryA)
  91. APIHOOK_ENUM_ENTRY(RemoveDirectoryW)
  92. APIHOOK_ENUM_ENTRY(SetCurrentDirectoryA)
  93. APIHOOK_ENUM_ENTRY(SetCurrentDirectoryW)
  94. APIHOOK_ENUM_ENTRY(OpenFile)
  95. APIHOOK_ENUM_ENTRY(RegSetValueA)
  96. APIHOOK_ENUM_ENTRY(RegSetValueW)
  97. APIHOOK_ENUM_ENTRY(RegSetValueExA)
  98. APIHOOK_ENUM_ENTRY(RegSetValueExW)
  99. APIHOOK_ENUM_ENTRY(_lopen)
  100. APIHOOK_ENUM_ENTRY(_lcreat)
  101. APIHOOK_ENUM_ENTRY_COMSERVER(SHELL32)
  102. APIHOOK_ENUM_ENTRY(LoadImageA)
  103. APIHOOK_ENUM_END
  104. // This is a private define (shlapip.h) that can mess up ShellExecuteEx
  105. #ifndef SEE_MASK_FILEANDURL
  106. #define SEE_MASK_FILEANDURL 0x00400000
  107. #endif
  108. /*++
  109. CorrectFree: free lpMalloc if it is different from lpOrig
  110. --*/
  111. inline void CorrectFree(char * lpMalloc, const char * lpOrig)
  112. {
  113. if (lpMalloc != lpOrig)
  114. {
  115. free(lpMalloc);
  116. }
  117. }
  118. inline void CorrectFree(WCHAR * lpMalloc, const WCHAR * lpOrig)
  119. {
  120. if (lpMalloc != lpOrig)
  121. {
  122. free(lpMalloc);
  123. }
  124. }
  125. /*++
  126. Our path changing class.
  127. Note: This is a pointer to the base class.
  128. Note: g_PathCorrector *MUST* remain NULL until after SHIM_STATIC_DLLS_INITIALIZED
  129. --*/
  130. CorrectPathChangesBase * g_PathCorrector = NULL;
  131. CorrectPathChangesBase * g_AllocatedPathCorrector = NULL;
  132. /*++
  133. Values that can be modified by the command line
  134. --*/
  135. enum PathCorrectorEnum
  136. {
  137. ePathCorrectorBase,
  138. ePathCorrectorUser,
  139. ePathCorrectorAllUser,
  140. };
  141. BOOL g_bCreateProcessRoutines = TRUE;
  142. BOOL g_bGetCommandLineRoutines = FALSE;
  143. BOOL g_bRegSetValueRoutines = FALSE;
  144. BOOL g_bFileRoutines = TRUE;
  145. BOOL g_bProfileRoutines = TRUE;
  146. BOOL g_bShellLinkRoutines = TRUE;
  147. BOOL g_bW9xPath = FALSE;
  148. BOOL g_bLoadImage = FALSE;
  149. PathCorrectorEnum g_pathcorrectorType = ePathCorrectorAllUser;
  150. int g_nExtraPathCorrections = 0;
  151. CString * g_ExtraPathCorrections;
  152. /*++
  153. Parse the command line.
  154. --*/
  155. BOOL ParseCommandLine(const char * commandLine)
  156. {
  157. // Force the default values
  158. g_bCreateProcessRoutines = TRUE;
  159. g_bGetCommandLineRoutines = FALSE;
  160. g_bRegSetValueRoutines = FALSE;
  161. g_bFileRoutines = TRUE;
  162. g_bProfileRoutines = TRUE;
  163. g_bShellLinkRoutines = TRUE;
  164. g_bW9xPath = FALSE;
  165. g_bLoadImage = FALSE;
  166. g_pathcorrectorType = ePathCorrectorAllUser;
  167. g_nExtraPathCorrections = 0;
  168. g_ExtraPathCorrections = NULL;
  169. // Search the beginning of the command line for these switches
  170. //
  171. // Switch Default Meaning
  172. //================ ======= =========================================================
  173. // -a Y Force shortcuts to All Users
  174. // -c N Do not shim Create process routines
  175. // -f N Do not shim File routines
  176. // -p N Do not shim GetPrivateProfile routines
  177. // -s N Do not shim IShellLink routines
  178. // -b N Bare: Use the base corrector (has no built-in path changes)
  179. // -u N User: Built-in paths correct to <username>/Start Menu and <username>/Desktop
  180. // +GetCommandLine N shim GetCommandLine routines
  181. // +RegSetValue N shim the RegSetValue and RegSetValueEx routines
  182. // +Win9xPath N Apply Win9x *path* specific fixes (does not apply to command lines)
  183. // -Profiles N Do not force shortcuts to All Users
  184. // +LoadBitmap N shim the LoadBitmapA routine
  185. //
  186. CSTRING_TRY
  187. {
  188. CString csCl(commandLine);
  189. CStringParser csParser(csCl, L" ");
  190. int argc = csParser.GetCount();
  191. if (csParser.GetCount() == 0)
  192. {
  193. return TRUE; // Not an error
  194. }
  195. // allocate for worst case
  196. g_ExtraPathCorrections = new CString[argc];
  197. if (!g_ExtraPathCorrections)
  198. {
  199. return FALSE; // Failure
  200. }
  201. g_nExtraPathCorrections = 0;
  202. for (int i = 0; i < argc; ++i)
  203. {
  204. CString & csArg = csParser[i];
  205. DPFN( eDbgLevelSpew, "Argv[%d] == (%S)\n", i, csArg.Get());
  206. if (csArg == L"-a")
  207. {
  208. g_pathcorrectorType = ePathCorrectorAllUser;
  209. }
  210. else if (csArg == L"-b")
  211. {
  212. g_pathcorrectorType = ePathCorrectorBase;
  213. }
  214. else if (csArg == L"-u" || csArg == L"-Profiles")
  215. {
  216. g_pathcorrectorType = ePathCorrectorUser;
  217. }
  218. else if (csArg == L"-c")
  219. {
  220. g_bCreateProcessRoutines = FALSE;
  221. }
  222. else if (csArg == L"-f")
  223. {
  224. g_bFileRoutines = FALSE;
  225. }
  226. else if (csArg == L"-p")
  227. {
  228. g_bProfileRoutines = FALSE;
  229. }
  230. else if (csArg == L"-s")
  231. {
  232. g_bShellLinkRoutines = FALSE;
  233. }
  234. else if (csArg == L"+GetCommandLine")
  235. {
  236. DPFN( eDbgLevelInfo, "Command line routines will be shimmed\n");
  237. g_bGetCommandLineRoutines = TRUE;
  238. }
  239. else if (csArg == L"+RegSetValue")
  240. {
  241. DPFN( eDbgLevelInfo, "RegSetValue routines will be shimmed\n");
  242. g_bRegSetValueRoutines = TRUE;
  243. }
  244. else if (csArg == L"+Win9xPath")
  245. {
  246. DPFN( eDbgLevelInfo, "Win9x Path corrections will be applied\n");
  247. g_bW9xPath = TRUE;
  248. }
  249. else if (csArg == L"+LoadImage")
  250. {
  251. DPFN( eDbgLevelInfo, "LoadImageA will be shimmed\n");
  252. g_bLoadImage = TRUE;
  253. }
  254. else
  255. {
  256. g_ExtraPathCorrections[g_nExtraPathCorrections] = csArg;
  257. g_nExtraPathCorrections += 1;
  258. }
  259. }
  260. #if DBG
  261. // Dump out the new path correction values.
  262. {
  263. const char *lpszPathCorrectorType = "Unknown";
  264. if (g_pathcorrectorType == ePathCorrectorBase)
  265. {
  266. lpszPathCorrectorType = "ePathCorrectorBase";
  267. }
  268. else if (g_pathcorrectorType == ePathCorrectorUser)
  269. {
  270. lpszPathCorrectorType = "ePathCorrectorUser";
  271. }
  272. else if (g_pathcorrectorType == ePathCorrectorAllUser)
  273. {
  274. lpszPathCorrectorType = "ePathCorrectorAllUser";
  275. }
  276. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim CreateProcessRoutines = %d\n", g_bCreateProcessRoutines);
  277. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim GetCommandLineRoutines = %d\n", g_bGetCommandLineRoutines);
  278. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim RegSetValueRoutines = %d\n", g_bRegSetValueRoutines);
  279. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim FileRoutines = %d\n", g_bFileRoutines);
  280. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim ProfileRoutines = %d\n", g_bProfileRoutines);
  281. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim ShellLinkRoutines = %d\n", g_bShellLinkRoutines);
  282. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim LoadImageA = %d\n", g_bLoadImage);
  283. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim W9xPath = %d\n", g_bW9xPath);
  284. DPFN( eDbgLevelInfo, "[ParseCommandLine] Shim Path Corrector Type = %s\n", lpszPathCorrectorType);
  285. for (int i = 0; i < g_nExtraPathCorrections; ++i)
  286. {
  287. DPFN( eDbgLevelInfo, "[ParseCommandLine] Extra Path Change(%S)\n", g_ExtraPathCorrections[i].Get());
  288. }
  289. }
  290. #endif
  291. }
  292. CSTRING_CATCH
  293. {
  294. return FALSE;
  295. }
  296. return TRUE;
  297. }
  298. /*++
  299. Create the appropriate g_PathCorrector
  300. Return TRUE if we were successful in creating and initializing.
  301. Note: We create g_AllocatedPathCorrector because g_PathCorrector must remain NULL until SHIM_STATIC_DLLS_INITIALIZED
  302. --*/
  303. BOOL InitPathcorrectorClass()
  304. {
  305. switch (g_pathcorrectorType)
  306. {
  307. case ePathCorrectorBase:
  308. g_AllocatedPathCorrector = new CorrectPathChangesBase;
  309. break;
  310. case ePathCorrectorUser:
  311. g_AllocatedPathCorrector = new CorrectPathChangesUser;
  312. break;
  313. case ePathCorrectorAllUser:
  314. default:
  315. g_AllocatedPathCorrector = new CorrectPathChangesAllUser;
  316. break;
  317. };
  318. if (g_AllocatedPathCorrector)
  319. {
  320. return g_AllocatedPathCorrector->ClassInit();
  321. }
  322. return FALSE;
  323. }
  324. /*++
  325. Add all the path corrections to the path corrector.
  326. Call after SHIM_STATIC_DLLS_INITIALIZED
  327. --*/
  328. void InitializePathCorrections()
  329. {
  330. if (g_PathCorrector)
  331. {
  332. g_PathCorrector->InitializeCorrectPathChanges();
  333. if (g_ExtraPathCorrections && g_nExtraPathCorrections)
  334. {
  335. // Add the command line to this Path Corrector
  336. for (int i = 0; i < g_nExtraPathCorrections; ++i)
  337. {
  338. g_PathCorrector->AddFromToPairW(g_ExtraPathCorrections[i]);
  339. }
  340. delete [] g_ExtraPathCorrections;
  341. g_ExtraPathCorrections = NULL;
  342. g_nExtraPathCorrections = 0;
  343. }
  344. }
  345. }
  346. /*++
  347. Return a pointer to the PathCorrecting object
  348. --*/
  349. inline CorrectPathChangesBase * GetPathcorrecter()
  350. {
  351. return g_PathCorrector;
  352. }
  353. inline void DebugSpew(const WCHAR * uncorrect, const WCHAR * correct, const char * debugMsg)
  354. {
  355. if (correct && uncorrect && _wcsicmp(correct, uncorrect) != 0)
  356. {
  357. LOGN( eDbgLevelError, "%s corrected path:\n %S\n %S\n",
  358. debugMsg, uncorrect, correct);
  359. }
  360. else // Massive Spew:
  361. {
  362. DPFN( eDbgLevelSpew, "%s unchanged %S\n", debugMsg, uncorrect);
  363. }
  364. }
  365. inline void DebugSpew(const char * uncorrect, const char * correct, const char * debugMsg)
  366. {
  367. if (correct && uncorrect && _stricmp(correct, uncorrect) != 0)
  368. {
  369. LOGN( eDbgLevelError, "%s corrected path:\n %s\n %s\n",
  370. debugMsg, uncorrect, correct);
  371. }
  372. else // Massive Spew:
  373. {
  374. DPFN( eDbgLevelSpew, "%s unchanged %s\n", debugMsg, uncorrect);
  375. }
  376. }
  377. /*++
  378. Given a string, correct the path.
  379. bMassagePath determines of path specific fixes are applied
  380. (should be FALSE for command lines)
  381. --*/
  382. WCHAR * CorrectorCorrectPath(CorrectPathChangesBase * pathCorrector, const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath)
  383. {
  384. if (uncorrect == NULL)
  385. return NULL;
  386. if (!pathCorrector)
  387. return (WCHAR *)uncorrect;
  388. const WCHAR * W9xCorrectedPath = uncorrect;
  389. // Check and see if we need to perform the special Win9x path massaging
  390. if (bMassagePath)
  391. {
  392. W9xCorrectedPath = W9xPathMassageW(uncorrect);
  393. }
  394. WCHAR * strCorrectFile = pathCorrector->CorrectPathAllocW(W9xCorrectedPath);
  395. // If the allocation failed, return the original string.
  396. // This should allow the shim routines to pass along the orignal
  397. // values to the hooked APIs, which if they fail, will have the
  398. // proper error codes.
  399. if (!strCorrectFile)
  400. {
  401. strCorrectFile = (WCHAR *)uncorrect;
  402. }
  403. else if (debugMsg)
  404. {
  405. DebugSpew(uncorrect, strCorrectFile, debugMsg);
  406. }
  407. if (W9xCorrectedPath != uncorrect)
  408. free((WCHAR *)W9xCorrectedPath);
  409. return strCorrectFile;
  410. }
  411. WCHAR * CorrectPath(const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath)
  412. {
  413. WCHAR * wstrCorrectFile = const_cast<WCHAR *>(uncorrect);
  414. CSTRING_TRY
  415. {
  416. CorrectPathChangesBase * pathCorrector = GetPathcorrecter();
  417. wstrCorrectFile = CorrectorCorrectPath(pathCorrector, uncorrect, debugMsg, bMassagePath);
  418. }
  419. CSTRING_CATCH
  420. {
  421. // Fall through
  422. }
  423. return wstrCorrectFile;
  424. }
  425. /*++
  426. Given a string, correct the path.
  427. bMassagePath determines of path specific fixes are applied
  428. (should be FALSE for command lines)
  429. --*/
  430. char * CorrectPath(const char * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath)
  431. {
  432. char * strCorrectFile = const_cast<char *>(uncorrect);
  433. CSTRING_TRY
  434. {
  435. CString csUncorrect(uncorrect);
  436. WCHAR * wstrCorrectFile = CorrectPath(csUncorrect, NULL, bMassagePath);
  437. // Don't assign to strCorrectFile unless we successfully allocate the memory.
  438. char * lpszChar = ToAnsi(wstrCorrectFile);
  439. if (lpszChar)
  440. {
  441. strCorrectFile = lpszChar;
  442. }
  443. CorrectFree(wstrCorrectFile, csUncorrect);
  444. }
  445. CSTRING_CATCH
  446. {
  447. // Fall through
  448. }
  449. if (debugMsg)
  450. {
  451. DebugSpew(uncorrect, strCorrectFile, debugMsg);
  452. }
  453. return strCorrectFile;
  454. }
  455. DWORD APIHOOK(GetFileAttributesA)(
  456. LPCSTR lpFileName // name of file or directory
  457. )
  458. {
  459. char * strCorrect = CorrectPath(lpFileName, "GetFileAttributesA");
  460. DWORD returnValue = ORIGINAL_API(GetFileAttributesA)(strCorrect);
  461. CorrectFree(strCorrect, lpFileName);
  462. return returnValue;
  463. }
  464. DWORD APIHOOK(GetFileAttributesW)(
  465. LPCWSTR lpFileName // name of file or directory
  466. )
  467. {
  468. WCHAR * strCorrect = CorrectPath(lpFileName, "GetFileAttributesW");
  469. DWORD returnValue = ORIGINAL_API(GetFileAttributesW)(strCorrect);
  470. CorrectFree(strCorrect, lpFileName);
  471. return returnValue;
  472. }
  473. BOOL APIHOOK(SetFileAttributesA)(
  474. LPCSTR lpFileName, // file name
  475. DWORD dwFileAttributes // attributes
  476. )
  477. {
  478. char * strCorrect = CorrectPath(lpFileName, "SetFileAttributesA");
  479. DWORD returnValue = ORIGINAL_API(SetFileAttributesA)(strCorrect, dwFileAttributes);
  480. CorrectFree(strCorrect, lpFileName);
  481. return returnValue;
  482. }
  483. DWORD APIHOOK(SetFileAttributesW)(
  484. LPCWSTR lpFileName, // file name
  485. DWORD dwFileAttributes // attributes
  486. )
  487. {
  488. WCHAR * strCorrect = CorrectPath(lpFileName, "SetFileAttributesW");
  489. DWORD returnValue = ORIGINAL_API(SetFileAttributesW)(strCorrect, dwFileAttributes);
  490. CorrectFree(strCorrect, lpFileName);
  491. return returnValue;
  492. }
  493. BOOL APIHOOK(GetFileAttributesExA)(
  494. LPCSTR lpFileName, // file or directory name
  495. GET_FILEEX_INFO_LEVELS fInfoLevelId, // attribute
  496. LPVOID lpFileInformation // attribute information
  497. )
  498. {
  499. char * strCorrect = CorrectPath(lpFileName, "GetFileAttributesExA");
  500. BOOL returnValue = ORIGINAL_API(GetFileAttributesExA)(strCorrect, fInfoLevelId, lpFileInformation);
  501. CorrectFree(strCorrect, lpFileName);
  502. return returnValue;
  503. }
  504. BOOL APIHOOK(GetFileAttributesExW)(
  505. LPCWSTR lpFileName, // file or directory name
  506. GET_FILEEX_INFO_LEVELS fInfoLevelId, // attribute
  507. LPVOID lpFileInformation // attribute information
  508. )
  509. {
  510. WCHAR * strCorrect = CorrectPath(lpFileName, "GetFileAttributesExW");
  511. BOOL returnValue = ORIGINAL_API(GetFileAttributesExW)(strCorrect, fInfoLevelId, lpFileInformation);
  512. CorrectFree(strCorrect, lpFileName);
  513. return returnValue;
  514. }
  515. /*++
  516. Convert Win9x paths to WinNT paths for CreateProcessA
  517. --*/
  518. BOOL APIHOOK(CreateProcessA)(
  519. LPCSTR lpApplicationName,
  520. LPSTR lpCommandLine,
  521. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  522. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  523. BOOL bInheritHandles,
  524. DWORD dwCreationFlags,
  525. LPVOID lpEnvironment,
  526. LPCSTR lpCurrentDirectory,
  527. LPSTARTUPINFOA lpStartupInfo,
  528. LPPROCESS_INFORMATION lpProcessInformation)
  529. {
  530. // Application name and command line that is passed to CreateProcess
  531. // Will either point to lpApplicationName or strCorrectApplicationName
  532. // Will either point to lpCommandLine or strCorrectCommandLine
  533. const char * pstrCorrectApplicationName = lpApplicationName;
  534. char * pstrCorrectCommandLine = lpCommandLine;
  535. if (lpApplicationName != NULL)
  536. {
  537. // Get a buffer containing the application name with the corrected path
  538. pstrCorrectApplicationName = CorrectPath(lpApplicationName, "CreateProcessA ApplicationName:");
  539. }
  540. if (lpCommandLine != NULL)
  541. {
  542. // Get a buffer containing the command line with the corrected path
  543. pstrCorrectCommandLine = CorrectPath(lpCommandLine, "CreateProcessA CommandLine:", FALSE);
  544. }
  545. DPFN( eDbgLevelInfo, "CreateProcessA Application(%s) CommandLine(%s)\n", pstrCorrectApplicationName, pstrCorrectCommandLine);
  546. BOOL returnValue = ORIGINAL_API(CreateProcessA)(pstrCorrectApplicationName,
  547. pstrCorrectCommandLine,
  548. lpProcessAttributes,
  549. lpThreadAttributes,
  550. bInheritHandles,
  551. dwCreationFlags,
  552. lpEnvironment,
  553. lpCurrentDirectory,
  554. lpStartupInfo,
  555. lpProcessInformation);
  556. CorrectFree(const_cast<char*>(pstrCorrectApplicationName), lpApplicationName);
  557. CorrectFree(pstrCorrectCommandLine, lpCommandLine);
  558. return returnValue;
  559. }
  560. /*++
  561. Convert Win9x paths to WinNT paths for CreateProcessW
  562. --*/
  563. BOOL APIHOOK(CreateProcessW)(
  564. LPCWSTR lpApplicationName,
  565. LPWSTR lpCommandLine,
  566. LPSECURITY_ATTRIBUTES lpProcessAttributes,
  567. LPSECURITY_ATTRIBUTES lpThreadAttributes,
  568. BOOL bInheritHandles,
  569. DWORD dwCreationFlags,
  570. LPVOID lpEnvironment,
  571. LPCWSTR lpCurrentDirectory,
  572. LPSTARTUPINFOW lpStartupInfo,
  573. LPPROCESS_INFORMATION lpProcessInformation)
  574. {
  575. // Application name and command line that is passed to CreateProcess
  576. // Will either point to lpApplicationName or strCorrectApplicationName
  577. // Will either point to lpCommandLine or strCorrectCommandLine
  578. const WCHAR * pstrCorrectApplicationName = lpApplicationName;
  579. WCHAR * pstrCorrectCommandLine = lpCommandLine;
  580. if (lpApplicationName != NULL)
  581. {
  582. // Get a buffer containing the application name with the corrected path
  583. pstrCorrectApplicationName = CorrectPath(lpApplicationName, "CreateProcessW ApplicationName:");
  584. }
  585. if (lpCommandLine != NULL)
  586. {
  587. // Get a buffer containing the command line with the corrected path
  588. pstrCorrectCommandLine = CorrectPath(lpCommandLine, "CreateProcessW CommandLine:", FALSE);
  589. }
  590. DPFN( eDbgLevelInfo, "CreateProcessW Application(%S) CommandLine(%S)\n", pstrCorrectApplicationName, pstrCorrectCommandLine);
  591. BOOL returnValue = ORIGINAL_API(CreateProcessW)(pstrCorrectApplicationName,
  592. pstrCorrectCommandLine,
  593. lpProcessAttributes,
  594. lpThreadAttributes,
  595. bInheritHandles,
  596. dwCreationFlags,
  597. lpEnvironment,
  598. lpCurrentDirectory,
  599. lpStartupInfo,
  600. lpProcessInformation);
  601. CorrectFree(const_cast<WCHAR *>(pstrCorrectApplicationName), lpApplicationName);
  602. CorrectFree(pstrCorrectCommandLine, lpCommandLine);
  603. return returnValue;
  604. }
  605. /*++
  606. Convert Win9x paths to WinNT paths for WinExec
  607. --*/
  608. UINT APIHOOK(WinExec)(LPCSTR lpCmdLine, UINT uCmdShow)
  609. {
  610. // Get a buffer containing the command line with the corrected path
  611. char * strCorrect = CorrectPath(lpCmdLine, "WinExec", FALSE);
  612. UINT returnValue = ORIGINAL_API(WinExec)(strCorrect, uCmdShow);
  613. CorrectFree(strCorrect, lpCmdLine);
  614. return returnValue;
  615. }
  616. /*++
  617. Convert Win9x paths to WinNT paths for ShellExecuteA
  618. --*/
  619. HINSTANCE APIHOOK(ShellExecuteA)(
  620. HWND hwnd,
  621. LPCSTR lpVerb,
  622. LPCSTR lpFile,
  623. LPCSTR lpParameters,
  624. LPCSTR lpDirectory,
  625. INT nShowCmd
  626. )
  627. {
  628. HINSTANCE returnValue = (HINSTANCE)SE_ERR_OOM;
  629. // Since this command is executed by the shell, it may contain %env% variables,
  630. // expand them before calling correctpath.
  631. CSTRING_TRY
  632. {
  633. CString csExpandFile(lpFile);
  634. csExpandFile.ExpandEnvironmentStringsW();
  635. returnValue = ORIGINAL_API(ShellExecuteA)(hwnd, lpVerb, csExpandFile.GetAnsi(), lpParameters, lpDirectory, nShowCmd);
  636. }
  637. CSTRING_CATCH
  638. {
  639. // Error expanding the string, just pass the value thru.
  640. returnValue = ORIGINAL_API(ShellExecuteA)(hwnd, lpVerb, lpFile, lpParameters, lpDirectory, nShowCmd);
  641. }
  642. return returnValue;
  643. }
  644. /*++
  645. Convert Win9x paths to WinNT paths for ShellExecuteW
  646. --*/
  647. HINSTANCE APIHOOK(ShellExecuteW)(
  648. HWND hwnd,
  649. LPCWSTR lpVerb,
  650. LPCWSTR lpFile,
  651. LPCWSTR lpParameters,
  652. LPCWSTR lpDirectory,
  653. INT nShowCmd
  654. )
  655. {
  656. HINSTANCE returnValue = (HINSTANCE)SE_ERR_OOM;
  657. // Since this command is executed by the shell, it may contain %env% variables,
  658. // expand them before calling correctpath.
  659. CSTRING_TRY
  660. {
  661. CString csExpandFile(lpFile);
  662. csExpandFile.ExpandEnvironmentStringsW();
  663. returnValue = ORIGINAL_API(ShellExecuteW)(hwnd, lpVerb, csExpandFile, lpParameters, lpDirectory, nShowCmd);
  664. }
  665. CSTRING_CATCH
  666. {
  667. // Error expanding the string, just pass the value thru.
  668. returnValue = ORIGINAL_API(ShellExecuteW)(hwnd, lpVerb, lpFile, lpParameters, lpDirectory, nShowCmd);
  669. }
  670. return returnValue;
  671. }
  672. /*++
  673. Convert Win9x paths to WinNT paths for ShellExecuteExA
  674. --*/
  675. BOOL APIHOOK(ShellExecuteExA)(
  676. LPSHELLEXECUTEINFOA lpExecInfo
  677. )
  678. {
  679. // Check for this magical internal flag that tells the system
  680. // that lpExecInfo->lpFile is actually a file and URL combined with
  681. // a 0 byte seperator, (file\0url\0)
  682. // Since this is internal only, we should not be receiving bad paths.
  683. if (lpExecInfo->fMask & SEE_MASK_FILEANDURL)
  684. {
  685. return ORIGINAL_API(ShellExecuteExA)(lpExecInfo);
  686. }
  687. const char * lpFile = lpExecInfo->lpFile;
  688. const char * lpDirectory = lpExecInfo->lpDirectory;
  689. char * strFileCorrect;
  690. char * strDirCorrect;
  691. // Check to see if app is expecting %env% substitution
  692. if (lpExecInfo->fMask & SEE_MASK_DOENVSUBST )
  693. {
  694. CSTRING_TRY
  695. {
  696. CString csExpandedFile(lpFile);
  697. CString csExpandedDir(lpDirectory);
  698. csExpandedFile.ExpandEnvironmentStringsW();
  699. csExpandedDir.ExpandEnvironmentStringsW();
  700. strFileCorrect = CorrectPath(csExpandedFile.GetAnsi(), "ShellExecuteExA");
  701. strDirCorrect = CorrectPath(csExpandedDir.GetAnsi(), "ShellExecuteExA");
  702. }
  703. CSTRING_CATCH
  704. {
  705. // Failed to expand the env values, pass all values untouched.
  706. return ORIGINAL_API(ShellExecuteExA)(lpExecInfo);
  707. }
  708. }
  709. else
  710. {
  711. strFileCorrect = CorrectPath(lpFile, "ShellExecuteExA");
  712. strDirCorrect = CorrectPath(lpDirectory, "ShellExecuteExA");
  713. }
  714. // Save the original fileName
  715. lpExecInfo->lpFile = strFileCorrect;
  716. lpExecInfo->lpDirectory = strDirCorrect;
  717. BOOL returnValue = ORIGINAL_API(ShellExecuteExA)(lpExecInfo);
  718. lpExecInfo->lpFile = lpFile;
  719. lpExecInfo->lpDirectory = lpDirectory;
  720. CorrectFree(strFileCorrect, lpFile);
  721. CorrectFree(strDirCorrect, lpDirectory);
  722. return returnValue;
  723. }
  724. /*++
  725. Convert Win9x paths to WinNT paths for ShellExecuteExW
  726. --*/
  727. BOOL APIHOOK(ShellExecuteExW)(
  728. LPSHELLEXECUTEINFOW lpExecInfo
  729. )
  730. {
  731. // Check for this magical *internal* flag that tells the system
  732. // that lpExecInfo->lpFile is actually a file and URL combined with
  733. // a 0 byte seperator, (file\0url\0)
  734. // Since this is internal only, we should not be receiving bad paths.
  735. if (lpExecInfo->fMask & SEE_MASK_FILEANDURL)
  736. {
  737. return ORIGINAL_API(ShellExecuteExW)(lpExecInfo);
  738. }
  739. const WCHAR * lpFile = lpExecInfo->lpFile;
  740. const WCHAR * lpDirectory = lpExecInfo->lpDirectory;
  741. WCHAR * strFileCorrect;
  742. WCHAR * strDirCorrect;
  743. // Check to see if app is expecting %env% substitution
  744. if (lpExecInfo->fMask & SEE_MASK_DOENVSUBST )
  745. {
  746. CSTRING_TRY
  747. {
  748. CString csExpandedFile(lpFile);
  749. CString csExpandedDir(lpDirectory);
  750. csExpandedFile.ExpandEnvironmentStringsW();
  751. csExpandedDir.ExpandEnvironmentStringsW();
  752. strFileCorrect = CorrectPath(csExpandedFile, "ShellExecuteExW");
  753. strDirCorrect = CorrectPath(csExpandedDir, "ShellExecuteExW");
  754. }
  755. CSTRING_CATCH
  756. {
  757. // Failed to expand the env values, pass all values untouched.
  758. return ORIGINAL_API(ShellExecuteExW)(lpExecInfo);
  759. }
  760. }
  761. else
  762. {
  763. strFileCorrect = CorrectPath(lpFile, "ShellExecuteExW");
  764. strDirCorrect = CorrectPath(lpDirectory, "ShellExecuteExW");
  765. }
  766. // Save the original fileName
  767. lpExecInfo->lpFile = strFileCorrect;
  768. lpExecInfo->lpDirectory = strDirCorrect;
  769. BOOL returnValue = ORIGINAL_API(ShellExecuteExW)(lpExecInfo);
  770. lpExecInfo->lpFile = lpFile;
  771. lpExecInfo->lpDirectory = lpDirectory;
  772. CorrectFree(strFileCorrect, lpFile);
  773. CorrectFree(strDirCorrect, lpDirectory);
  774. return returnValue;
  775. }
  776. /*++
  777. Convert long command line paths to short paths for GetCommandLineW
  778. --*/
  779. LPCWSTR APIHOOK(GetCommandLineW)()
  780. {
  781. static LPCWSTR wstrCorrectCommandLine = NULL;
  782. if (wstrCorrectCommandLine == NULL)
  783. {
  784. LPCWSTR wstrCommandLine = ORIGINAL_API(GetCommandLineW)();
  785. wstrCorrectCommandLine = CorrectPath(wstrCommandLine, "GetCommandLineW", FALSE);
  786. }
  787. return wstrCorrectCommandLine;
  788. }
  789. /*++
  790. Convert long command line paths to short paths for GetCommandLineA
  791. --*/
  792. LPCSTR APIHOOK(GetCommandLineA)()
  793. {
  794. static LPCSTR strCorrectCommandLine = NULL;
  795. if (strCorrectCommandLine == NULL)
  796. {
  797. LPCSTR strCommandLine = ORIGINAL_API(GetCommandLineA)();
  798. strCorrectCommandLine = CorrectPath(strCommandLine, "GetCommandLineA", FALSE);
  799. }
  800. return strCorrectCommandLine;
  801. }
  802. /*++
  803. The PrivateProfile routines treat filenames differently than pathnames.
  804. If we have Win9xPath corrections enabled, it is possible to "fix" a path
  805. from .\example.ini to example.ini. Unfortunately the PrivateProfile routines
  806. look for example.ini in %windir%
  807. If we have a path that contains path seperators, we must ensure that
  808. the resulting string also contains path separators.
  809. --*/
  810. char * ProfileCorrectPath(const char * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath)
  811. {
  812. char * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
  813. if (bMassagePath && uncorrect != strCorrect)
  814. {
  815. char * returnString = NULL;
  816. CSTRING_TRY
  817. {
  818. CString csUncorrect(uncorrect);
  819. if (csUncorrect.FindOneOf(L"\\/") >= 0)
  820. {
  821. // Found some path separators in the original string, check the corrected string.
  822. // If the corrected string does not have any path separators,
  823. // then the path was corrected from .\example.ini to example.ini
  824. CString csCorrect(strCorrect);
  825. if (csCorrect.FindOneOf(L"\\/") < 0)
  826. {
  827. // No path seperators, make this a CWD relative path
  828. csCorrect.Insert(0, L".\\");
  829. returnString = csCorrect.ReleaseAnsi();
  830. }
  831. }
  832. }
  833. CSTRING_CATCH
  834. {
  835. // Some CString error occured, make sure returnString is NULL
  836. if (returnString != NULL)
  837. {
  838. free(returnString);
  839. }
  840. returnString = NULL;
  841. }
  842. if (returnString)
  843. {
  844. CorrectFree(strCorrect, uncorrect);
  845. strCorrect = returnString;
  846. }
  847. }
  848. if (debugMsg)
  849. {
  850. DebugSpew(uncorrect, strCorrect, debugMsg);
  851. }
  852. return strCorrect;
  853. }
  854. /*++
  855. The PrivateProfile routines treat filenames differently than pathnames.
  856. If we have Win9xPath corrections enabled, it is possible to "fix" a path
  857. from .\example.ini to example.ini. Unfortunately the PrivateProfile routines
  858. look for example.ini in %windir%
  859. If we have a path that contains path seperators, we must ensure that
  860. the resulting string also contains path separators.
  861. --*/
  862. WCHAR * ProfileCorrectPath(const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath)
  863. {
  864. WCHAR * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
  865. if (bMassagePath && uncorrect != strCorrect)
  866. {
  867. WCHAR * returnString = NULL;
  868. CSTRING_TRY
  869. {
  870. CString csUncorrect(uncorrect);
  871. if (csUncorrect.FindOneOf(L"\\/") >= 0)
  872. {
  873. // Found some path separators in the original string, check the corrected string.
  874. // If the corrected string does not have any path separators,
  875. // then the path was corrected from .\example.ini to example.ini
  876. CString csCorrect(strCorrect);
  877. if (csCorrect.FindOneOf(L"\\/") < 0)
  878. {
  879. // No path seperators, make this a CWD relative path
  880. csCorrect.Insert(0, L".\\");
  881. // Manually copy the buffer
  882. size_t nBytes = (csCorrect.GetLength() + 1) * sizeof(WCHAR);
  883. returnString = (WCHAR*) malloc(nBytes);
  884. if (returnString)
  885. {
  886. memcpy(returnString, csCorrect.Get(), nBytes);
  887. }
  888. }
  889. }
  890. }
  891. CSTRING_CATCH
  892. {
  893. // Some CString error occured, make sure returnString is NULL
  894. if (returnString != NULL)
  895. {
  896. free(returnString);
  897. }
  898. returnString = NULL;
  899. }
  900. if (returnString)
  901. {
  902. CorrectFree(strCorrect, uncorrect);
  903. strCorrect = returnString;
  904. }
  905. }
  906. if (debugMsg)
  907. {
  908. DebugSpew(uncorrect, strCorrect, debugMsg);
  909. }
  910. return strCorrect;
  911. }
  912. /*++
  913. Convert Win9x paths to WinNT paths for GetPrivateProfileIntA
  914. --*/
  915. UINT APIHOOK(GetPrivateProfileIntA)(
  916. LPCSTR lpAppName, // section name
  917. LPCSTR lpKeyName, // key name
  918. INT nDefault, // return value if key name not found
  919. LPCSTR lpFileName // initialization file name
  920. )
  921. {
  922. char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileIntA");
  923. UINT returnValue = ORIGINAL_API(GetPrivateProfileIntA)(lpAppName, lpKeyName, nDefault, strCorrect);
  924. CorrectFree(strCorrect, lpFileName);
  925. return returnValue;
  926. }
  927. /*++
  928. Convert Win9x paths to WinNT paths for GetPrivateProfileIntW
  929. --*/
  930. UINT APIHOOK(GetPrivateProfileIntW)(
  931. LPCWSTR lpAppName, // section name
  932. LPCWSTR lpKeyName, // key name
  933. INT nDefault, // return value if key name not found
  934. LPCWSTR lpFileName // initialization file name
  935. )
  936. {
  937. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileIntW");
  938. UINT returnValue = ORIGINAL_API(GetPrivateProfileIntW)(lpAppName, lpKeyName, nDefault, strCorrect);
  939. CorrectFree(strCorrect, lpFileName);
  940. return returnValue;
  941. }
  942. /*++
  943. Convert Win9x paths to WinNT paths for GetPrivateProfileSectionA
  944. --*/
  945. DWORD APIHOOK(GetPrivateProfileSectionA)(
  946. LPCSTR lpAppName, // section name
  947. LPSTR lpReturnedString, // return buffer
  948. DWORD nSize, // size of return buffer
  949. LPCSTR lpFileName // initialization file name
  950. )
  951. {
  952. char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionA");
  953. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionA)(lpAppName, lpReturnedString, nSize, strCorrect);
  954. CorrectFree(strCorrect, lpFileName);
  955. return returnValue;
  956. }
  957. /*++
  958. Convert Win9x paths to WinNT paths for GetPrivateProfileSectionW
  959. --*/
  960. DWORD APIHOOK(GetPrivateProfileSectionW)(
  961. LPCWSTR lpAppName, // section name
  962. LPWSTR lpReturnedString, // return buffer
  963. DWORD nSize, // size of return buffer
  964. LPCWSTR lpFileName // initialization file name
  965. )
  966. {
  967. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionW");
  968. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionW)(lpAppName, lpReturnedString, nSize, strCorrect);
  969. CorrectFree(strCorrect, lpFileName);
  970. return returnValue;
  971. }
  972. /*++
  973. Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesA
  974. --*/
  975. DWORD APIHOOK(GetPrivateProfileSectionNamesA)(
  976. LPSTR lpszReturnBuffer, // return buffer
  977. DWORD nSize, // size of return buffer
  978. LPCSTR lpFileName // initialization file name
  979. )
  980. {
  981. char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionNamesA");
  982. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionNamesA)(lpszReturnBuffer, nSize, strCorrect);
  983. CorrectFree(strCorrect, lpFileName);
  984. return returnValue;
  985. }
  986. /*++
  987. Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesW
  988. --*/
  989. DWORD APIHOOK(GetPrivateProfileSectionNamesW)(
  990. LPWSTR lpszReturnBuffer, // return buffer
  991. DWORD nSize, // size of return buffer
  992. LPCWSTR lpFileName // initialization file name
  993. )
  994. {
  995. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileSectionNamesW");
  996. DWORD returnValue = ORIGINAL_API(GetPrivateProfileSectionNamesW)(lpszReturnBuffer, nSize, strCorrect);
  997. CorrectFree(strCorrect, lpFileName);
  998. return returnValue;
  999. }
  1000. /*++
  1001. Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesA
  1002. --*/
  1003. DWORD APIHOOK(GetPrivateProfileStringA)(
  1004. LPCSTR lpAppName, // section name
  1005. LPCSTR lpKeyName, // key name
  1006. LPCSTR lpDefault, // default string
  1007. LPSTR lpReturnedString, // destination buffer
  1008. DWORD nSize, // size of destination buffer
  1009. LPCSTR lpFileName // initialization file name
  1010. )
  1011. {
  1012. char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStringA");
  1013. DWORD returnValue = ORIGINAL_API(GetPrivateProfileStringA)(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, strCorrect);
  1014. CorrectFree(strCorrect, lpFileName);
  1015. return returnValue;
  1016. }
  1017. /*++
  1018. Convert Win9x paths to WinNT paths for GetPrivateProfileSectionNamesA
  1019. --*/
  1020. DWORD APIHOOK(GetPrivateProfileStringW)(
  1021. LPCWSTR lpAppName, // section name
  1022. LPCWSTR lpKeyName, // key name
  1023. LPCWSTR lpDefault, // default string
  1024. LPWSTR lpReturnedString, // destination buffer
  1025. DWORD nSize, // size of destination buffer
  1026. LPCWSTR lpFileName // initialization file name
  1027. )
  1028. {
  1029. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStringW");
  1030. DWORD returnValue = ORIGINAL_API(GetPrivateProfileStringW)(lpAppName, lpKeyName, lpDefault, lpReturnedString, nSize, strCorrect);
  1031. CorrectFree(strCorrect, lpFileName);
  1032. return returnValue;
  1033. }
  1034. /*++
  1035. Convert Win9x paths to WinNT paths for GetPrivateProfileStructA
  1036. --*/
  1037. BOOL APIHOOK(GetPrivateProfileStructA)(
  1038. LPCSTR lpszSection, // section name
  1039. LPCSTR lpszKey, // key name
  1040. LPVOID lpStruct, // return buffer
  1041. UINT uSizeStruct, // size of return buffer
  1042. LPCSTR lpFileName // initialization file name
  1043. )
  1044. {
  1045. char * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStructA");
  1046. BOOL returnValue = ORIGINAL_API(GetPrivateProfileStructA)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
  1047. CorrectFree(strCorrect, lpFileName);
  1048. return returnValue;
  1049. }
  1050. /*++
  1051. Convert Win9x paths to WinNT paths for GetPrivateProfileStructW
  1052. --*/
  1053. BOOL APIHOOK(GetPrivateProfileStructW)(
  1054. LPCWSTR lpszSection, // section name
  1055. LPCWSTR lpszKey, // key name
  1056. LPVOID lpStruct, // return buffer
  1057. UINT uSizeStruct, // size of return buffer
  1058. LPCWSTR lpFileName // initialization file name
  1059. )
  1060. {
  1061. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "GetPrivateProfileStructW");
  1062. BOOL returnValue = ORIGINAL_API(GetPrivateProfileStructW)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
  1063. CorrectFree(strCorrect, lpFileName);
  1064. return returnValue;
  1065. }
  1066. /*++
  1067. Convert Win9x paths to WinNT paths for GetPrivateProfileStructA
  1068. --*/
  1069. BOOL APIHOOK(WritePrivateProfileSectionA)(
  1070. LPCSTR lpAppName, // section name
  1071. LPCSTR lpString, // data
  1072. LPCSTR lpFileName // file name
  1073. )
  1074. {
  1075. char * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileSectionA");
  1076. BOOL returnValue = ORIGINAL_API(WritePrivateProfileSectionA)(lpAppName, lpString, strCorrect);
  1077. CorrectFree(strCorrect, lpFileName);
  1078. return returnValue;
  1079. }
  1080. /*++
  1081. Convert Win9x paths to WinNT paths for WritePrivateProfileSectionW
  1082. --*/
  1083. BOOL APIHOOK(WritePrivateProfileSectionW)(
  1084. LPCWSTR lpAppName, // section name
  1085. LPCWSTR lpString, // data
  1086. LPCWSTR lpFileName // file name
  1087. )
  1088. {
  1089. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileSectionW");
  1090. BOOL returnValue = ORIGINAL_API(WritePrivateProfileSectionW)(lpAppName, lpString, strCorrect);
  1091. CorrectFree(strCorrect, lpFileName);
  1092. return returnValue;
  1093. }
  1094. /*++
  1095. Convert Win9x paths to WinNT paths for WritePrivateProfileStringA
  1096. --*/
  1097. BOOL APIHOOK(WritePrivateProfileStringA)(
  1098. LPCSTR lpAppName, // section name
  1099. LPCSTR lpKeyName, // key name
  1100. LPCSTR lpString, // string to add
  1101. LPCSTR lpFileName // initialization file
  1102. )
  1103. {
  1104. char * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStringA");
  1105. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStringA)(lpAppName, lpKeyName, lpString, strCorrect);
  1106. CorrectFree(strCorrect, lpFileName);
  1107. return returnValue;
  1108. }
  1109. /*++
  1110. Convert Win9x paths to WinNT paths for WritePrivateProfileStringW
  1111. --*/
  1112. BOOL APIHOOK(WritePrivateProfileStringW)(
  1113. LPCWSTR lpAppName, // section name
  1114. LPCWSTR lpKeyName, // key name
  1115. LPCWSTR lpString, // string to add
  1116. LPCWSTR lpFileName // initialization file
  1117. )
  1118. {
  1119. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStringW");
  1120. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStringW)(lpAppName, lpKeyName, lpString, strCorrect);
  1121. CorrectFree(strCorrect, lpFileName);
  1122. return returnValue;
  1123. }
  1124. /*++
  1125. Convert Win9x paths to WinNT paths for WritePrivateProfileStructA
  1126. --*/
  1127. BOOL APIHOOK(WritePrivateProfileStructA)(
  1128. LPCSTR lpszSection, // section name
  1129. LPCSTR lpszKey, // key name
  1130. LPVOID lpStruct, // data buffer
  1131. UINT uSizeStruct, // size of data buffer
  1132. LPCSTR lpFileName // initialization file
  1133. )
  1134. {
  1135. char * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStructA");
  1136. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStructA)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
  1137. CorrectFree(strCorrect, lpFileName);
  1138. return returnValue;
  1139. }
  1140. /*++
  1141. Convert Win9x paths to WinNT paths for WritePrivateProfileStructW
  1142. --*/
  1143. BOOL APIHOOK(WritePrivateProfileStructW)(
  1144. LPCWSTR lpszSection, // section name
  1145. LPCWSTR lpszKey, // key name
  1146. LPVOID lpStruct, // data buffer
  1147. UINT uSizeStruct, // size of data buffer
  1148. LPCWSTR lpFileName // initialization file
  1149. )
  1150. {
  1151. WCHAR * strCorrect = ProfileCorrectPath(lpFileName, "WritePrivateProfileStructW");
  1152. BOOL returnValue = ORIGINAL_API(WritePrivateProfileStructW)(lpszSection, lpszKey, lpStruct, uSizeStruct, strCorrect);
  1153. CorrectFree(strCorrect, lpFileName);
  1154. return returnValue;
  1155. }
  1156. /*++
  1157. Convert Win9x paths to WinNT paths for IShellLinkA::SetArguments
  1158. --*/
  1159. HRESULT COMHOOK(IShellLinkA, SetArguments)( PVOID pThis, LPCSTR pszArgs )
  1160. {
  1161. HRESULT hrReturn = E_FAIL;
  1162. char * strCorrect = CorrectPath(pszArgs, "IShellLinkA::SetArguments", FALSE);
  1163. _pfn_IShellLinkA_SetArguments pfnOld = ORIGINAL_COM(IShellLinkA, SetArguments, pThis);
  1164. if (pfnOld)
  1165. hrReturn = (*pfnOld)( pThis, strCorrect );
  1166. CorrectFree(strCorrect, pszArgs);
  1167. return hrReturn;
  1168. }
  1169. /*++
  1170. Convert Win9x paths to WinNT paths for IShellLinkW::SetArguments
  1171. --*/
  1172. HRESULT COMHOOK(IShellLinkW, SetArguments)( PVOID pThis, LPCWSTR pszArgs )
  1173. {
  1174. HRESULT hrReturn = E_FAIL;
  1175. WCHAR * strCorrect = CorrectPath(pszArgs, "IShellLinkA::SetArguments", FALSE);
  1176. _pfn_IShellLinkW_SetArguments pfnOld = ORIGINAL_COM(IShellLinkW, SetArguments, pThis);
  1177. if(pfnOld)
  1178. hrReturn = (*pfnOld)( pThis, strCorrect );
  1179. CorrectFree(strCorrect, pszArgs);
  1180. return hrReturn;
  1181. }
  1182. /*++
  1183. Convert Win9x paths to WinNT paths for IShellLinkA::SetIconLocation
  1184. --*/
  1185. HRESULT COMHOOK(IShellLinkA, SetIconLocation)(PVOID pThis, LPCSTR pszIconLocation, int nIcon )
  1186. {
  1187. HRESULT hrReturn = E_FAIL;
  1188. char * strCorrect = CorrectPath(pszIconLocation, "IShellLinkA::SetIconLocation");
  1189. _pfn_IShellLinkA_SetIconLocation pfnOld = ORIGINAL_COM(IShellLinkA, SetIconLocation, pThis);
  1190. if (pfnOld)
  1191. hrReturn = (*pfnOld)( pThis, strCorrect, nIcon );
  1192. CorrectFree(strCorrect, pszIconLocation);
  1193. return hrReturn;
  1194. }
  1195. /*++
  1196. Convert Win9x paths to WinNT paths for IShellLinkW::SetIconLocation
  1197. --*/
  1198. HRESULT COMHOOK(IShellLinkW, SetIconLocation)(PVOID pThis, LPCWSTR pszIconLocation, int nIcon )
  1199. {
  1200. HRESULT hrReturn = E_FAIL;
  1201. WCHAR * strCorrect = CorrectPath(pszIconLocation, "IShellLinkW::SetIconLocation");
  1202. _pfn_IShellLinkW_SetIconLocation pfnOld = ORIGINAL_COM(IShellLinkW, SetIconLocation, pThis);
  1203. if(pfnOld)
  1204. hrReturn = (*pfnOld)( pThis, strCorrect, nIcon );
  1205. CorrectFree(strCorrect, pszIconLocation);
  1206. return hrReturn;
  1207. }
  1208. /*++
  1209. Convert Win9x paths to WinNT paths for IShellLinkA::SetPath
  1210. --*/
  1211. HRESULT COMHOOK(IShellLinkA, SetPath)(PVOID pThis,
  1212. LPCSTR pszFile )
  1213. {
  1214. HRESULT hrReturn = E_FAIL;
  1215. char * strCorrect = CorrectPath(pszFile, "IShellLinkA::SetPath");
  1216. _pfn_IShellLinkA_SetPath pfnOld = ORIGINAL_COM(IShellLinkA, SetPath, pThis);
  1217. if (pfnOld)
  1218. hrReturn = (*pfnOld)( pThis, strCorrect );
  1219. CorrectFree(strCorrect, pszFile);
  1220. return hrReturn;
  1221. }
  1222. /*++
  1223. Convert Win9x paths to WinNT paths for IShellLinkW::SetPath
  1224. --*/
  1225. HRESULT COMHOOK(IShellLinkW, SetPath)(PVOID pThis,
  1226. LPCWSTR pszFile )
  1227. {
  1228. HRESULT hrReturn = E_FAIL;
  1229. WCHAR * strCorrect = CorrectPath(pszFile, "IShellLinkW::SetPath");
  1230. _pfn_IShellLinkW_SetPath pfnOld = ORIGINAL_COM(IShellLinkW, SetPath, pThis);
  1231. if (pfnOld)
  1232. hrReturn = (*pfnOld)( pThis, strCorrect );
  1233. CorrectFree(strCorrect, pszFile);
  1234. return hrReturn;
  1235. }
  1236. /*++
  1237. Convert Win9x paths to WinNT paths for IPersistFile::Save
  1238. --*/
  1239. HRESULT COMHOOK(IPersistFile, Save)(PVOID pThis,
  1240. LPCOLESTR pszFileName,
  1241. BOOL fRemember)
  1242. {
  1243. HRESULT hrReturn = E_FAIL;
  1244. WCHAR * strCorrect = CorrectPath(pszFileName, "IPersistFile_Save");
  1245. _pfn_IPersistFile_Save pfnOld = ORIGINAL_COM(IPersistFile, Save, pThis);
  1246. if (pfnOld)
  1247. hrReturn = (*pfnOld)( pThis, strCorrect, fRemember );
  1248. CorrectFree(strCorrect, pszFileName);
  1249. return hrReturn;
  1250. }
  1251. BOOL APIHOOK(CopyFileA)(
  1252. LPCSTR lpExistingFileName, // name of an existing file
  1253. LPCSTR lpNewFileName, // name of new file
  1254. BOOL bFailIfExists // operation if file exists
  1255. )
  1256. {
  1257. char * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileA");
  1258. char * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileA");
  1259. BOOL returnValue = ORIGINAL_API(CopyFileA)(strExistingCorrect, strNewCorrect, bFailIfExists);
  1260. CorrectFree(strExistingCorrect, lpExistingFileName);
  1261. CorrectFree(strNewCorrect, lpNewFileName);
  1262. return returnValue;
  1263. }
  1264. BOOL APIHOOK(CopyFileW)(
  1265. LPCWSTR lpExistingFileName, // name of an existing file
  1266. LPCWSTR lpNewFileName, // name of new file
  1267. BOOL bFailIfExists // operation if file exists
  1268. )
  1269. {
  1270. WCHAR * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileW");
  1271. WCHAR * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileW");
  1272. BOOL returnValue = ORIGINAL_API(CopyFileW)(strExistingCorrect, strNewCorrect, bFailIfExists);
  1273. CorrectFree(strExistingCorrect, lpExistingFileName);
  1274. CorrectFree(strNewCorrect, lpNewFileName);
  1275. return returnValue;
  1276. }
  1277. BOOL APIHOOK(CopyFileExA)(
  1278. LPCSTR lpExistingFileName, // name of existing file
  1279. LPCSTR lpNewFileName, // name of new file
  1280. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1281. LPVOID lpData, // callback parameter
  1282. LPBOOL pbCancel, // cancel status
  1283. DWORD dwCopyFlags // copy options
  1284. )
  1285. {
  1286. char * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileExA");
  1287. char * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileExA");
  1288. BOOL returnValue = ORIGINAL_API(CopyFileExA)(strExistingCorrect, strNewCorrect, lpProgressRoutine, lpData, pbCancel, dwCopyFlags);
  1289. CorrectFree(strExistingCorrect, lpExistingFileName);
  1290. CorrectFree(strNewCorrect, lpNewFileName);
  1291. return returnValue;
  1292. }
  1293. BOOL APIHOOK(CopyFileExW)(
  1294. LPCWSTR lpExistingFileName, // name of existing file
  1295. LPCWSTR lpNewFileName, // name of new file
  1296. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1297. LPVOID lpData, // callback parameter
  1298. LPBOOL pbCancel, // cancel status
  1299. DWORD dwCopyFlags // copy options
  1300. )
  1301. {
  1302. WCHAR * strExistingCorrect = CorrectPath(lpExistingFileName, "CopyFileExW");
  1303. WCHAR * strNewCorrect = CorrectPath(lpNewFileName, "CopyFileExW");
  1304. BOOL returnValue = ORIGINAL_API(CopyFileExW)(strExistingCorrect, strNewCorrect, lpProgressRoutine, lpData, pbCancel, dwCopyFlags);
  1305. CorrectFree(strExistingCorrect, lpExistingFileName);
  1306. CorrectFree(strNewCorrect, lpNewFileName);
  1307. return returnValue;
  1308. }
  1309. BOOL APIHOOK(CreateDirectoryA)(
  1310. LPCSTR lpPathName, // directory name
  1311. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1312. )
  1313. {
  1314. char * strCorrect = CorrectPath(lpPathName, "CreateDirectoryA");
  1315. BOOL returnValue = ORIGINAL_API(CreateDirectoryA)(strCorrect, lpSecurityAttributes);
  1316. CorrectFree(strCorrect, lpPathName);
  1317. return returnValue;
  1318. }
  1319. BOOL APIHOOK(CreateDirectoryW)(
  1320. LPCWSTR lpPathName, // directory name
  1321. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1322. )
  1323. {
  1324. WCHAR * strCorrect = CorrectPath(lpPathName, "CreateDirectoryW");
  1325. BOOL returnValue = ORIGINAL_API(CreateDirectoryW)(strCorrect, lpSecurityAttributes);
  1326. CorrectFree(strCorrect, lpPathName);
  1327. return returnValue;
  1328. }
  1329. BOOL APIHOOK(CreateDirectoryExA)(
  1330. LPCSTR lpTemplateDirectory, // template directory
  1331. LPCSTR lpNewDirectory, // directory name
  1332. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1333. )
  1334. {
  1335. char * strTemplateCorrect = CorrectPath(lpTemplateDirectory, "CreateDirectoryExA");
  1336. char * strNewCorrect = CorrectPath(lpNewDirectory, "CreateDirectoryExA");
  1337. BOOL returnValue = ORIGINAL_API(CreateDirectoryExA)(strTemplateCorrect, strNewCorrect, lpSecurityAttributes);
  1338. CorrectFree(strTemplateCorrect, lpTemplateDirectory);
  1339. CorrectFree(strNewCorrect, lpNewDirectory);
  1340. return returnValue;
  1341. }
  1342. BOOL APIHOOK(CreateDirectoryExW)(
  1343. LPCWSTR lpTemplateDirectory, // template directory
  1344. LPCWSTR lpNewDirectory, // directory name
  1345. LPSECURITY_ATTRIBUTES lpSecurityAttributes // SD
  1346. )
  1347. {
  1348. WCHAR * strTemplateCorrect = CorrectPath(lpTemplateDirectory, "CreateDirectoryExW");
  1349. WCHAR * strNewCorrect = CorrectPath(lpNewDirectory, "CreateDirectoryExW");
  1350. BOOL returnValue = ORIGINAL_API(CreateDirectoryExW)(strTemplateCorrect, strNewCorrect, lpSecurityAttributes);
  1351. CorrectFree(strTemplateCorrect, lpTemplateDirectory);
  1352. CorrectFree(strNewCorrect, lpNewDirectory);
  1353. return returnValue;
  1354. }
  1355. HANDLE APIHOOK(CreateFileA)(
  1356. LPCSTR lpFileName, // file name
  1357. DWORD dwDesiredAccess, // access mode
  1358. DWORD dwShareMode, // share mode
  1359. LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  1360. DWORD dwCreationDisposition, // how to create
  1361. DWORD dwFlagsAndAttributes, // file attributes
  1362. HANDLE hTemplateFile // handle to template file
  1363. )
  1364. {
  1365. char * strCorrect = CorrectPath(lpFileName, "CreateFileA");
  1366. HANDLE returnValue = ORIGINAL_API(CreateFileA)(strCorrect,
  1367. dwDesiredAccess,
  1368. dwShareMode,
  1369. lpSecurityAttributes,
  1370. dwCreationDisposition,
  1371. dwFlagsAndAttributes,
  1372. hTemplateFile);
  1373. CorrectFree(strCorrect, lpFileName);
  1374. return returnValue;
  1375. }
  1376. HANDLE APIHOOK(CreateFileW)(
  1377. LPCWSTR lpFileName, // file name
  1378. DWORD dwDesiredAccess, // access mode
  1379. DWORD dwShareMode, // share mode
  1380. LPSECURITY_ATTRIBUTES lpSecurityAttributes, // SD
  1381. DWORD dwCreationDisposition, // how to create
  1382. DWORD dwFlagsAndAttributes, // file attributes
  1383. HANDLE hTemplateFile // handle to template file
  1384. )
  1385. {
  1386. WCHAR * strCorrect = CorrectPath(lpFileName, "CreateFileW");
  1387. HANDLE returnValue = ORIGINAL_API(CreateFileW)(
  1388. strCorrect,
  1389. dwDesiredAccess,
  1390. dwShareMode,
  1391. lpSecurityAttributes,
  1392. dwCreationDisposition,
  1393. dwFlagsAndAttributes,
  1394. hTemplateFile);
  1395. CorrectFree(strCorrect, lpFileName);
  1396. return returnValue;
  1397. }
  1398. BOOL APIHOOK(DeleteFileA)(
  1399. LPCSTR lpFileName // file name
  1400. )
  1401. {
  1402. char * strCorrect = CorrectPath(lpFileName, "DeleteFileA");
  1403. BOOL returnValue = ORIGINAL_API(DeleteFileA)(strCorrect);
  1404. CorrectFree(strCorrect, lpFileName);
  1405. return returnValue;
  1406. }
  1407. BOOL APIHOOK(DeleteFileW)(
  1408. LPCWSTR lpFileName // file name
  1409. )
  1410. {
  1411. WCHAR * strCorrect = CorrectPath(lpFileName, "DeleteFileW");
  1412. BOOL returnValue = ORIGINAL_API(DeleteFileW)(strCorrect);
  1413. CorrectFree(strCorrect, lpFileName);
  1414. return returnValue;
  1415. }
  1416. /*++
  1417. Win9xPath corrections will strip a trailing . from the end of a search string.
  1418. As a path, the . is not significant, but as a wildcard it is important--the
  1419. difference between finding files without an extension and finding all files
  1420. in the directory.
  1421. --*/
  1422. char * FindFirstFileCorrectPath(const char * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath)
  1423. {
  1424. char * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
  1425. if (bMassagePath && uncorrect != strCorrect)
  1426. {
  1427. char * returnString = NULL;
  1428. CSTRING_TRY
  1429. {
  1430. CString csUncorrect(uncorrect);
  1431. CString csCorrect(strCorrect);
  1432. CString csUncorrectLast;
  1433. CString csCorrectLast;
  1434. csUncorrect.GetLastPathComponent(csUncorrectLast);
  1435. csCorrect.GetLastPathComponent(csCorrectLast);
  1436. if (csUncorrectLast.Compare(L"*.") == 0 && csCorrectLast.Compare(L"*") == 0)
  1437. {
  1438. csCorrectLast += L".";
  1439. returnString = csCorrectLast.ReleaseAnsi();
  1440. }
  1441. }
  1442. CSTRING_CATCH
  1443. {
  1444. // Some CString error occured, make sure returnString is NULL
  1445. if (returnString != NULL)
  1446. {
  1447. free(returnString);
  1448. }
  1449. returnString = NULL;
  1450. }
  1451. if (returnString)
  1452. {
  1453. CorrectFree(strCorrect, uncorrect);
  1454. strCorrect = returnString;
  1455. }
  1456. }
  1457. if (debugMsg)
  1458. {
  1459. DebugSpew(uncorrect, strCorrect, debugMsg);
  1460. }
  1461. return strCorrect;
  1462. }
  1463. /*++
  1464. Win9xPath corrections will strip a trailing . from the end of a search string.
  1465. As a path, the . is not significant, but as a wildcard it is important--the
  1466. difference between finding files without an extension and finding all files
  1467. in the directory.
  1468. --*/
  1469. WCHAR * FindFirstFileCorrectPath(const WCHAR * uncorrect, const char * debugMsg, BOOL bMassagePath = g_bW9xPath)
  1470. {
  1471. WCHAR * strCorrect = CorrectPath(uncorrect, NULL, bMassagePath);
  1472. if (bMassagePath && uncorrect != strCorrect)
  1473. {
  1474. WCHAR * returnString = NULL;
  1475. CSTRING_TRY
  1476. {
  1477. CString csUncorrect(uncorrect);
  1478. CString csCorrect(strCorrect);
  1479. CString csUncorrectLast;
  1480. CString csCorrectLast;
  1481. csUncorrect.GetLastPathComponent(csUncorrectLast);
  1482. csCorrect.GetLastPathComponent(csCorrectLast);
  1483. if (csUncorrectLast.Compare(L"*.") == 0 && csCorrectLast.Compare(L"*") == 0)
  1484. {
  1485. csCorrectLast += L".";
  1486. // Manually copy the buffer
  1487. size_t nBytes = (csCorrectLast.GetLength() + 1) * sizeof(WCHAR);
  1488. returnString = (WCHAR*) malloc(nBytes);
  1489. if (returnString)
  1490. {
  1491. memcpy(returnString, csCorrectLast.Get(), nBytes);
  1492. }
  1493. }
  1494. }
  1495. CSTRING_CATCH
  1496. {
  1497. // Some CString error occured, make sure returnString is NULL
  1498. if (returnString != NULL)
  1499. {
  1500. free(returnString);
  1501. }
  1502. returnString = NULL;
  1503. }
  1504. if (returnString)
  1505. {
  1506. CorrectFree(strCorrect, uncorrect);
  1507. strCorrect = returnString;
  1508. }
  1509. }
  1510. if (debugMsg)
  1511. {
  1512. DebugSpew(uncorrect, strCorrect, debugMsg);
  1513. }
  1514. return strCorrect;
  1515. }
  1516. HANDLE APIHOOK(FindFirstFileA)(
  1517. LPCSTR lpFileName, // file name
  1518. LPWIN32_FIND_DATAA lpFindFileData // data buffer
  1519. )
  1520. {
  1521. char * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileA");
  1522. HANDLE returnValue = ORIGINAL_API(FindFirstFileA)(strCorrect, lpFindFileData);
  1523. CorrectFree(strCorrect, lpFileName);
  1524. return returnValue;
  1525. }
  1526. HANDLE APIHOOK(FindFirstFileW)(
  1527. LPCWSTR lpFileName, // file name
  1528. LPWIN32_FIND_DATAW lpFindFileData // data buffer
  1529. )
  1530. {
  1531. WCHAR * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileW");
  1532. HANDLE returnValue = ORIGINAL_API(FindFirstFileW)(strCorrect, lpFindFileData);
  1533. CorrectFree(strCorrect, lpFileName);
  1534. return returnValue;
  1535. }
  1536. HANDLE APIHOOK(FindFirstFileExA)(
  1537. LPCSTR lpFileName, // file name
  1538. FINDEX_INFO_LEVELS fInfoLevelId, // information level
  1539. LPVOID lpFindFileData, // information buffer
  1540. FINDEX_SEARCH_OPS fSearchOp, // filtering type
  1541. LPVOID lpSearchFilter, // search criteria
  1542. DWORD dwAdditionalFlags // additional search control
  1543. )
  1544. {
  1545. char * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileExA");
  1546. HANDLE returnValue = ORIGINAL_API(FindFirstFileExA)(
  1547. strCorrect,
  1548. fInfoLevelId,
  1549. lpFindFileData,
  1550. fSearchOp,
  1551. lpSearchFilter,
  1552. dwAdditionalFlags);
  1553. CorrectFree(strCorrect, lpFileName);
  1554. return returnValue;
  1555. }
  1556. HANDLE APIHOOK(FindFirstFileExW)(
  1557. LPCWSTR lpFileName, // file name
  1558. FINDEX_INFO_LEVELS fInfoLevelId, // information level
  1559. LPVOID lpFindFileData, // information buffer
  1560. FINDEX_SEARCH_OPS fSearchOp, // filtering type
  1561. LPVOID lpSearchFilter, // search criteria
  1562. DWORD dwAdditionalFlags // additional search control
  1563. )
  1564. {
  1565. WCHAR * strCorrect = FindFirstFileCorrectPath(lpFileName, "FindFirstFileExW");
  1566. HANDLE returnValue = ORIGINAL_API(FindFirstFileExW)(
  1567. strCorrect,
  1568. fInfoLevelId,
  1569. lpFindFileData,
  1570. fSearchOp,
  1571. lpSearchFilter,
  1572. dwAdditionalFlags);
  1573. CorrectFree(strCorrect, lpFileName);
  1574. return returnValue;
  1575. }
  1576. BOOL APIHOOK(GetBinaryTypeA)(
  1577. LPCSTR lpApplicationName, // full file path
  1578. LPDWORD lpBinaryType // binary type information
  1579. )
  1580. {
  1581. char * strCorrect = CorrectPath(lpApplicationName, "GetBinaryTypeA");
  1582. BOOL returnValue = ORIGINAL_API(GetBinaryTypeA)(strCorrect, lpBinaryType);
  1583. CorrectFree(strCorrect, lpApplicationName);
  1584. return returnValue;
  1585. }
  1586. BOOL APIHOOK(GetBinaryTypeW)(
  1587. LPCWSTR lpApplicationName, // full file path
  1588. LPDWORD lpBinaryType // binary type information
  1589. )
  1590. {
  1591. WCHAR * strCorrect = CorrectPath(lpApplicationName, "GetBinaryTypeW");
  1592. BOOL returnValue = ORIGINAL_API(GetBinaryTypeW)(strCorrect, lpBinaryType);
  1593. CorrectFree(strCorrect, lpApplicationName);
  1594. return returnValue;
  1595. }
  1596. BOOL APIHOOK(MoveFileA)(
  1597. LPCSTR lpExistingFileName, // file name
  1598. LPCSTR lpNewFileName // new file name
  1599. )
  1600. {
  1601. char * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileA");
  1602. char * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileA");
  1603. BOOL returnValue = ORIGINAL_API(MoveFileA)(strCorrectExisting, strCorrectNew);
  1604. CorrectFree(strCorrectExisting, lpExistingFileName);
  1605. CorrectFree(strCorrectNew, lpNewFileName);
  1606. return returnValue;
  1607. }
  1608. BOOL APIHOOK(MoveFileW)(
  1609. LPCWSTR lpExistingFileName, // file name
  1610. LPCWSTR lpNewFileName // new file name
  1611. )
  1612. {
  1613. WCHAR * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileW");
  1614. WCHAR * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileW");
  1615. BOOL returnValue = ORIGINAL_API(MoveFileW)(strCorrectExisting, strCorrectNew);
  1616. CorrectFree(strCorrectExisting, lpExistingFileName);
  1617. CorrectFree(strCorrectNew, lpNewFileName);
  1618. return returnValue;
  1619. }
  1620. BOOL APIHOOK(MoveFileExA)(
  1621. LPCSTR lpExistingFileName, // file name
  1622. LPCSTR lpNewFileName, // new file name
  1623. DWORD dwFlags // move options
  1624. )
  1625. {
  1626. char * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileExA");
  1627. char * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileExA");
  1628. BOOL returnValue = ORIGINAL_API(MoveFileExA)(strCorrectExisting, strCorrectNew, dwFlags);
  1629. CorrectFree(strCorrectExisting, lpExistingFileName);
  1630. CorrectFree(strCorrectNew, lpNewFileName);
  1631. return returnValue;
  1632. }
  1633. BOOL APIHOOK(MoveFileExW)(
  1634. LPCWSTR lpExistingFileName, // file name
  1635. LPCWSTR lpNewFileName, // new file name
  1636. DWORD dwFlags // move options
  1637. )
  1638. {
  1639. WCHAR * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileExW");
  1640. WCHAR * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileExW");
  1641. BOOL returnValue = ORIGINAL_API(MoveFileExW)(strCorrectExisting, strCorrectNew, dwFlags);
  1642. CorrectFree(strCorrectExisting, lpExistingFileName);
  1643. CorrectFree(strCorrectNew, lpNewFileName);
  1644. return returnValue;
  1645. }
  1646. BOOL APIHOOK(MoveFileWithProgressA)(
  1647. LPCSTR lpExistingFileName, // file name
  1648. LPCSTR lpNewFileName, // new file name
  1649. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1650. LPVOID lpData, // parameter for callback
  1651. DWORD dwFlags // move options
  1652. )
  1653. {
  1654. char * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileWithProgressA");
  1655. char * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileWithProgressA");
  1656. BOOL returnValue = ORIGINAL_API(MoveFileWithProgressA)(strCorrectExisting, strCorrectNew, lpProgressRoutine, lpData, dwFlags);
  1657. CorrectFree(strCorrectExisting, lpExistingFileName);
  1658. CorrectFree(strCorrectNew, lpNewFileName);
  1659. return returnValue;
  1660. }
  1661. BOOL APIHOOK(MoveFileWithProgressW)(
  1662. LPCWSTR lpExistingFileName, // file name
  1663. LPCWSTR lpNewFileName, // new file name
  1664. LPPROGRESS_ROUTINE lpProgressRoutine, // callback function
  1665. LPVOID lpData, // parameter for callback
  1666. DWORD dwFlags // move options
  1667. )
  1668. {
  1669. WCHAR * strCorrectExisting = CorrectPath(lpExistingFileName, "MoveFileW");
  1670. WCHAR * strCorrectNew = CorrectPath(lpNewFileName, "MoveFileW");
  1671. BOOL returnValue = ORIGINAL_API(MoveFileWithProgressW)(strCorrectExisting, strCorrectNew, lpProgressRoutine, lpData, dwFlags);
  1672. CorrectFree(strCorrectExisting, lpExistingFileName);
  1673. CorrectFree(strCorrectNew, lpNewFileName);
  1674. return returnValue;
  1675. }
  1676. BOOL APIHOOK(RemoveDirectoryA)(
  1677. LPCSTR lpPathName // directory name
  1678. )
  1679. {
  1680. char * strCorrect = CorrectPath(lpPathName, "RemoveDirectoryA");
  1681. BOOL returnValue = ORIGINAL_API(RemoveDirectoryA)(strCorrect);
  1682. CorrectFree(strCorrect, lpPathName);
  1683. return returnValue;
  1684. }
  1685. BOOL APIHOOK(RemoveDirectoryW)(
  1686. LPCWSTR lpPathName // directory name
  1687. )
  1688. {
  1689. WCHAR * strCorrect = CorrectPath(lpPathName, "RemoveDirectoryW");
  1690. BOOL returnValue = ORIGINAL_API(RemoveDirectoryW)(strCorrect);
  1691. CorrectFree(strCorrect, lpPathName);
  1692. return returnValue;
  1693. }
  1694. BOOL APIHOOK(SetCurrentDirectoryA)(
  1695. LPCSTR lpPathName // new directory name
  1696. )
  1697. {
  1698. char * strCorrect = CorrectPath(lpPathName, "SetCurrentDirectoryA");
  1699. BOOL returnValue = ORIGINAL_API(SetCurrentDirectoryA)(strCorrect);
  1700. CorrectFree(strCorrect, lpPathName);
  1701. return returnValue;
  1702. }
  1703. BOOL APIHOOK(SetCurrentDirectoryW)(
  1704. LPCWSTR lpPathName // new directory name
  1705. )
  1706. {
  1707. WCHAR * strCorrect = CorrectPath(lpPathName, "SetCurrentDirectoryW");
  1708. BOOL returnValue = ORIGINAL_API(SetCurrentDirectoryW)(strCorrect);
  1709. CorrectFree(strCorrect, lpPathName);
  1710. return returnValue;
  1711. }
  1712. HFILE APIHOOK(OpenFile)(
  1713. LPCSTR lpFileName, // file name
  1714. LPOFSTRUCT lpReOpenBuff, // file information
  1715. UINT uStyle // action and attributes
  1716. )
  1717. {
  1718. char * strCorrect = CorrectPath(lpFileName, "OpenFile");
  1719. HFILE returnValue = ORIGINAL_API(OpenFile)(strCorrect, lpReOpenBuff, uStyle);
  1720. CorrectFree(strCorrect, lpFileName);
  1721. return returnValue;
  1722. }
  1723. LONG APIHOOK(RegSetValueA)(
  1724. HKEY hKey, // handle to key
  1725. LPCSTR lpSubKey, // subkey name
  1726. DWORD dwType, // information type
  1727. LPCSTR lpData, // value data
  1728. DWORD cbData // size of value data
  1729. )
  1730. {
  1731. char * strCorrect = CorrectPath(lpData, "RegSetValueA", FALSE);
  1732. // Data key is length of string *not* including null byte.
  1733. if (strCorrect)
  1734. {
  1735. cbData = strlen(strCorrect);
  1736. }
  1737. LONG returnValue = ORIGINAL_API(RegSetValueA)(hKey, lpSubKey, dwType, strCorrect, cbData);
  1738. CorrectFree(strCorrect, lpData);
  1739. return returnValue;
  1740. }
  1741. LONG APIHOOK(RegSetValueW)(
  1742. HKEY hKey, // handle to key
  1743. LPCWSTR lpSubKey, // subkey name
  1744. DWORD dwType, // information type
  1745. LPCWSTR lpData, // value data
  1746. DWORD cbData // size of value data
  1747. )
  1748. {
  1749. WCHAR * strCorrect = CorrectPath(lpData, "RegSetValueW", FALSE);
  1750. // Data key is length of string *not* including null byte.
  1751. if (strCorrect)
  1752. cbData = wcslen(strCorrect);
  1753. LONG returnValue = ORIGINAL_API(RegSetValueW)(hKey, lpSubKey, dwType, strCorrect, cbData);
  1754. CorrectFree(strCorrect, lpData);
  1755. return returnValue;
  1756. }
  1757. LONG APIHOOK(RegSetValueExA)(
  1758. HKEY hKey, // handle to key
  1759. LPCSTR lpValueName, // value name
  1760. DWORD Reserved, // reserved
  1761. DWORD dwType, // value type
  1762. CONST BYTE *lpData, // value data
  1763. DWORD cbData // size of value data
  1764. )
  1765. {
  1766. if (dwType == REG_SZ)
  1767. {
  1768. char * strCorrect = CorrectPath((const char *)lpData, "RegSetValueExA", FALSE);
  1769. // Data key is length of string *including* null byte.
  1770. if (strCorrect)
  1771. {
  1772. cbData = strlen(strCorrect) + 1;
  1773. }
  1774. LONG returnValue = ORIGINAL_API(RegSetValueExA)(
  1775. hKey, // handle to key
  1776. lpValueName, // value name
  1777. Reserved, // reserved
  1778. dwType, // value type
  1779. (CONST BYTE *)strCorrect, // value data
  1780. cbData);
  1781. CorrectFree(strCorrect, (const char *)lpData);
  1782. return returnValue;
  1783. }
  1784. else
  1785. {
  1786. // Pass data on through
  1787. LONG returnValue = ORIGINAL_API(RegSetValueExA)(
  1788. hKey, // handle to key
  1789. lpValueName, // value name
  1790. Reserved, // reserved
  1791. dwType, // value type
  1792. lpData, // value data
  1793. cbData);
  1794. return returnValue;
  1795. }
  1796. }
  1797. LONG APIHOOK(RegSetValueExW)(
  1798. HKEY hKey, // handle to key
  1799. LPCWSTR lpValueName, // value name
  1800. DWORD Reserved, // reserved
  1801. DWORD dwType, // value type
  1802. CONST BYTE *lpData, // value data
  1803. DWORD cbData // size of value data
  1804. )
  1805. {
  1806. if (dwType == REG_SZ)
  1807. {
  1808. WCHAR * strCorrect = CorrectPath((const WCHAR*)lpData, "RegSetValueExW", FALSE);
  1809. // Data key is length of string *including* null byte.
  1810. if (strCorrect)
  1811. {
  1812. cbData = wcslen(strCorrect) + 1;
  1813. }
  1814. LONG returnValue = ORIGINAL_API(RegSetValueExW)(
  1815. hKey, // handle to key
  1816. lpValueName, // value name
  1817. Reserved, // reserved
  1818. dwType, // value type
  1819. (CONST BYTE *)strCorrect, // value data
  1820. cbData);
  1821. CorrectFree(strCorrect, (const WCHAR *)lpData);
  1822. return returnValue;
  1823. }
  1824. else
  1825. {
  1826. // Pass data on through
  1827. LONG returnValue = ORIGINAL_API(RegSetValueExW)(
  1828. hKey, // handle to key
  1829. lpValueName, // value name
  1830. Reserved, // reserved
  1831. dwType, // value type
  1832. lpData, // value data
  1833. cbData);
  1834. return returnValue;
  1835. }
  1836. }
  1837. HFILE APIHOOK(_lopen)(
  1838. LPCSTR lpPathName,
  1839. int iReadWrite
  1840. )
  1841. {
  1842. char * strCorrect = CorrectPath(lpPathName, "lopen");
  1843. HFILE returnValue = ORIGINAL_API(_lopen)(strCorrect, iReadWrite);
  1844. CorrectFree(strCorrect, lpPathName);
  1845. return returnValue;
  1846. }
  1847. HFILE APIHOOK(_lcreat)(
  1848. LPCSTR lpPathName,
  1849. int iAttribute
  1850. )
  1851. {
  1852. char * strCorrect = CorrectPath(lpPathName, "lcreat");
  1853. HFILE returnValue = ORIGINAL_API(_lcreat)(strCorrect, iAttribute);
  1854. CorrectFree(strCorrect, lpPathName);
  1855. return returnValue;
  1856. }
  1857. HANDLE
  1858. APIHOOK(LoadImageA)(
  1859. HINSTANCE hinst, // handle to instance
  1860. LPCSTR lpszName, // name or identifier of the image
  1861. UINT uType, // image type
  1862. int cxDesired, // desired width
  1863. int cyDesired, // desired height
  1864. UINT fuLoad // load options
  1865. )
  1866. {
  1867. HANDLE returnValue = NULL;
  1868. // Another one of those incredibly overloaded API's:
  1869. // lpszName is not always a path
  1870. if ((uType == IMAGE_BITMAP) &&
  1871. (fuLoad & LR_LOADFROMFILE) &&
  1872. !IsBadStringPtrA(lpszName, 1))
  1873. {
  1874. char * strCorrect = CorrectPath(lpszName, "LoadImageA");
  1875. returnValue = ORIGINAL_API(LoadImageA)(hinst, strCorrect, uType, cxDesired, cyDesired, fuLoad);
  1876. CorrectFree(strCorrect, lpszName);
  1877. }
  1878. else
  1879. {
  1880. returnValue = ORIGINAL_API(LoadImageA)(hinst, lpszName, uType, cxDesired, cyDesired, fuLoad);
  1881. }
  1882. return returnValue;
  1883. }
  1884. IMPLEMENT_COMSERVER_HOOK(SHELL32)
  1885. BOOL
  1886. NOTIFY_FUNCTION(
  1887. DWORD fdwReason
  1888. )
  1889. {
  1890. BOOL bSuccess = TRUE;
  1891. if (fdwReason == DLL_PROCESS_ATTACH)
  1892. {
  1893. bSuccess = ParseCommandLine(COMMAND_LINE);
  1894. if (bSuccess)
  1895. {
  1896. // Create g_AllocatedPathCorrector
  1897. return InitPathcorrectorClass();
  1898. }
  1899. }
  1900. else if (fdwReason == SHIM_STATIC_DLLS_INITIALIZED)
  1901. {
  1902. // It is now safe for us to do our work
  1903. g_PathCorrector = g_AllocatedPathCorrector;
  1904. InitializePathCorrections();
  1905. }
  1906. return bSuccess;
  1907. }
  1908. /*++
  1909. Register hooked functions
  1910. --*/
  1911. HOOK_BEGIN
  1912. CALL_NOTIFY_FUNCTION
  1913. if (g_bCreateProcessRoutines)
  1914. {
  1915. APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessA)
  1916. APIHOOK_ENTRY(KERNEL32.DLL, CreateProcessW)
  1917. APIHOOK_ENTRY(KERNEL32.DLL, WinExec)
  1918. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteA)
  1919. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteW)
  1920. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteExA)
  1921. APIHOOK_ENTRY(SHELL32.DLL, ShellExecuteExW)
  1922. }
  1923. if (g_bGetCommandLineRoutines)
  1924. {
  1925. APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineA)
  1926. APIHOOK_ENTRY(KERNEL32.DLL, GetCommandLineW)
  1927. }
  1928. if (g_bProfileRoutines)
  1929. {
  1930. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileIntA)
  1931. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileIntW)
  1932. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionA)
  1933. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionW)
  1934. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionNamesA)
  1935. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileSectionNamesW)
  1936. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStringA)
  1937. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStringW)
  1938. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStructA)
  1939. APIHOOK_ENTRY(KERNEL32.DLL, GetPrivateProfileStructW)
  1940. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileSectionA)
  1941. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileSectionW)
  1942. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStringA)
  1943. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStringW)
  1944. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStructA)
  1945. APIHOOK_ENTRY(KERNEL32.DLL, WritePrivateProfileStructW)
  1946. }
  1947. if (g_bFileRoutines)
  1948. {
  1949. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileA)
  1950. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileW)
  1951. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExA)
  1952. APIHOOK_ENTRY(KERNEL32.DLL, CopyFileExW)
  1953. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryA)
  1954. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryW)
  1955. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExA)
  1956. APIHOOK_ENTRY(KERNEL32.DLL, CreateDirectoryExW)
  1957. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileA)
  1958. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileW)
  1959. APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileA)
  1960. APIHOOK_ENTRY(KERNEL32.DLL, DeleteFileW)
  1961. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileA)
  1962. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileW)
  1963. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileExA)
  1964. APIHOOK_ENTRY(KERNEL32.DLL, FindFirstFileExW)
  1965. APIHOOK_ENTRY(KERNEL32.DLL, GetBinaryTypeA)
  1966. APIHOOK_ENTRY(KERNEL32.DLL, GetBinaryTypeW)
  1967. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesA)
  1968. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesW)
  1969. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesExA)
  1970. APIHOOK_ENTRY(KERNEL32.DLL, GetFileAttributesExW)
  1971. APIHOOK_ENTRY(KERNEL32.DLL, SetFileAttributesA)
  1972. APIHOOK_ENTRY(KERNEL32.DLL, SetFileAttributesW)
  1973. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileA)
  1974. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileW)
  1975. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExA)
  1976. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileExW)
  1977. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressA)
  1978. APIHOOK_ENTRY(KERNEL32.DLL, MoveFileWithProgressW)
  1979. APIHOOK_ENTRY(KERNEL32.DLL, RemoveDirectoryA)
  1980. APIHOOK_ENTRY(KERNEL32.DLL, RemoveDirectoryW)
  1981. APIHOOK_ENTRY(KERNEL32.DLL, SetCurrentDirectoryA)
  1982. APIHOOK_ENTRY(KERNEL32.DLL, SetCurrentDirectoryW)
  1983. APIHOOK_ENTRY(KERNEL32.DLL, OpenFile)
  1984. // 16 bit compatibility file routines
  1985. APIHOOK_ENTRY(KERNEL32.DLL, _lopen)
  1986. APIHOOK_ENTRY(KERNEL32.DLL, _lcreat)
  1987. }
  1988. if (g_bRegSetValueRoutines)
  1989. {
  1990. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueA)
  1991. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueW)
  1992. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExA)
  1993. APIHOOK_ENTRY(ADVAPI32.DLL, RegSetValueExW)
  1994. }
  1995. if (g_bShellLinkRoutines)
  1996. {
  1997. APIHOOK_ENTRY_COMSERVER(SHELL32)
  1998. COMHOOK_ENTRY(ShellLink, IShellLinkA, SetPath, 20)
  1999. COMHOOK_ENTRY(ShellLink, IShellLinkW, SetPath, 20)
  2000. COMHOOK_ENTRY(ShellLink, IShellLinkA, SetArguments, 11)
  2001. COMHOOK_ENTRY(ShellLink, IShellLinkW, SetArguments, 11)
  2002. COMHOOK_ENTRY(ShellLink, IShellLinkA, SetIconLocation, 17)
  2003. COMHOOK_ENTRY(ShellLink, IShellLinkW, SetIconLocation, 17)
  2004. COMHOOK_ENTRY(ShellLink, IPersistFile, Save, 6)
  2005. }
  2006. if (g_bLoadImage)
  2007. {
  2008. APIHOOK_ENTRY(USER32.DLL, LoadImageA)
  2009. }
  2010. HOOK_END
  2011. IMPLEMENT_SHIM_END