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.

183 lines
4.9 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. RecopyExeFromCD.cpp
  5. Abstract:
  6. This shim waits for CloseHandle to be called on the appropriate .exe file.
  7. Once this call has been made, CopyFile is called to recopy the executable
  8. due to truncation of the file during install.
  9. History:
  10. 12/08/1999 a-jamd Created
  11. --*/
  12. #include "precomp.h"
  13. IMPLEMENT_SHIM_BEGIN(RecopyExeFromCD)
  14. #include "ShimHookMacro.h"
  15. APIHOOK_ENUM_BEGIN
  16. APIHOOK_ENUM_ENTRY(CreateFileA)
  17. APIHOOK_ENUM_ENTRY(CloseHandle)
  18. APIHOOK_ENUM_END
  19. // The following variables are used to keep track of the file handle,
  20. // the source path and the destination path.
  21. HANDLE g_hInterestingHandle = NULL;
  22. CString * g_wszSourcePath = NULL;
  23. CString * g_wszDestinationPath = NULL;
  24. BOOL g_bInCopyFile = FALSE;
  25. // The following array specifies what the valid names of executables to
  26. // be recopied are. Add to these lists when new apps requiring this shim are
  27. // found.
  28. WCHAR *g_rgszExes[] = {
  29. L"eaw.exe",
  30. L"GK3.EXE",
  31. };
  32. #define N_RECOPY_EXE (sizeof(g_rgszExes) / sizeof(g_rgszExes[0]))
  33. /*++
  34. This stub function breaks into CreateFileA and checks to see if the file in
  35. use is a known .exe file. If it is, APIHook_CreateFileA determines if
  36. lpFileName is the source path or the destination and saves it. When the
  37. file is the destination, the handle returned by CreateFile is also saved
  38. for my check in CloseHandle.
  39. --*/
  40. HANDLE
  41. APIHOOK(CreateFileA)(
  42. LPSTR lpFileName,
  43. DWORD dwDesiredAccess,
  44. DWORD dwShareMode,
  45. LPSECURITY_ATTRIBUTES lpSecurityAttributes,
  46. DWORD dwCreationDisposition,
  47. DWORD dwFlagsAndAttributes,
  48. HANDLE hTemplateFile
  49. )
  50. {
  51. HANDLE hRet = ORIGINAL_API(CreateFileA)(
  52. lpFileName,
  53. dwDesiredAccess,
  54. dwShareMode,
  55. lpSecurityAttributes,
  56. dwCreationDisposition,
  57. dwFlagsAndAttributes,
  58. hTemplateFile);
  59. if (hRet != INVALID_HANDLE_VALUE)
  60. {
  61. CString csFilePartOnly;
  62. CString csFileName(lpFileName);
  63. csFileName.GetFullPathNameW();
  64. csFileName.GetLastPathComponent(csFilePartOnly);
  65. // Should be d:\ or somesuch
  66. CString csDir;
  67. csFileName.Mid(0, 3, csDir);
  68. UINT uiDriveType = GetDriveTypeW(csDir);
  69. for (int i = 0; i < N_RECOPY_EXE; ++i)
  70. {
  71. const WCHAR * lpszRecopy = g_rgszExes[i];
  72. // Find out if one of the known .exe files is the file in use
  73. if (csFilePartOnly.CompareNoCase(lpszRecopy) == 0)
  74. {
  75. if (uiDriveType != DRIVE_CDROM)
  76. {
  77. // Known .exe file was found in the filename, and it wasn't on the CDRom.
  78. // There is also a valid handle.
  79. g_hInterestingHandle = hRet;
  80. g_wszDestinationPath = new CString(csFileName);
  81. break;
  82. }
  83. else
  84. {
  85. // Known .exe was found in the filename, and the drive is a CDRom.
  86. // This is the path to the source and must be stored for later.
  87. g_wszSourcePath = new CString(csFileName);
  88. break;
  89. }
  90. }
  91. }
  92. }
  93. return hRet;
  94. }
  95. /*++
  96. This stub function breaks into CloseHandle and checks to see if the handle in
  97. use is the handle to a known .exe. If it is, APIHook_CloseHandle calls
  98. CopyFile and copies the known .exe from the CDRom to the destination.
  99. --*/
  100. BOOL
  101. APIHOOK(CloseHandle)(HANDLE hObject)
  102. {
  103. BOOL bRet;
  104. bRet = ORIGINAL_API(CloseHandle)(hObject);
  105. // Find out if g_hInterestingHandle is being closed
  106. if ((hObject == g_hInterestingHandle) &&
  107. g_wszSourcePath &&
  108. g_wszDestinationPath &&
  109. (g_bInCopyFile == FALSE) )
  110. {
  111. // CopyFileA calls CloseHandle, so we must maintain the recursive state
  112. // to fix a recursion problem
  113. g_bInCopyFile = TRUE;
  114. // Correct Handle
  115. // Call CopyFile and recopy the known .exe file from the CDRom to the
  116. // destination
  117. CopyFileW( g_wszSourcePath->Get(), g_wszDestinationPath->Get(), FALSE );
  118. LOGN( eDbgLevelWarning, "[CloseHandle] Copied %S from CD to %S", g_wszSourcePath->Get(), g_wszDestinationPath->Get());
  119. // Since copying from the CDRom, and attributes are carried over, the
  120. // file attributes must be set
  121. SetFileAttributesW( g_wszDestinationPath->Get(), FILE_ATTRIBUTE_NORMAL );
  122. g_bInCopyFile = FALSE;
  123. g_hInterestingHandle = NULL;
  124. return bRet;
  125. }
  126. return bRet;
  127. }
  128. /*++
  129. Register hooked functions
  130. --*/
  131. HOOK_BEGIN
  132. APIHOOK_ENTRY(KERNEL32.DLL, CreateFileA)
  133. APIHOOK_ENTRY(KERNEL32.DLL, CloseHandle)
  134. HOOK_END
  135. IMPLEMENT_SHIM_END