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.

264 lines
7.5 KiB

  1. #include <afxwin.h>
  2. #include "imagehlp.h"
  3. #include "iodll.h"
  4. //... PROTOTYPES
  5. static PIMAGE_NT_HEADERS MyRtlImageNtHeader(
  6. PVOID pBaseAddress);
  7. static BOOL MyUpdateDebugInfoFileEx(
  8. LPSTR ImageFileName,
  9. LPSTR SymbolPath,
  10. LPSTR DebugFilePath,
  11. PIMAGE_NT_HEADERS NtHeaders,
  12. DWORD OldCheckSum
  13. );
  14. //...........................................................................
  15. DWORD QuitA( DWORD err, LPCSTR, LPSTR )
  16. {
  17. return err;
  18. }
  19. DWORD FixCheckSum( LPCSTR ImageName, LPCSTR OrigFileName, LPCSTR SymbolPath)
  20. {
  21. HANDLE FileHandle;
  22. HANDLE MappingHandle;
  23. PIMAGE_NT_HEADERS NtHeaders;
  24. PVOID BaseAddress;
  25. ULONG CheckSum;
  26. ULONG FileLength;
  27. ULONG HeaderSum;
  28. ULONG OldCheckSum;
  29. DWORD iErr = ERROR_NO_ERROR;
  30. FileHandle = CreateFileA( ImageName,
  31. GENERIC_READ | GENERIC_WRITE,
  32. FILE_SHARE_READ,
  33. NULL,
  34. OPEN_EXISTING,
  35. 0,
  36. NULL);
  37. if ( FileHandle == INVALID_HANDLE_VALUE )
  38. {
  39. QuitA( 1, ImageName, NULL);
  40. }
  41. MappingHandle = CreateFileMapping( FileHandle,
  42. NULL,
  43. PAGE_READWRITE,
  44. 0,
  45. 0,
  46. NULL);
  47. if ( MappingHandle == NULL )
  48. {
  49. CloseHandle( FileHandle );
  50. QuitA( 22, ImageName, NULL);
  51. }
  52. else
  53. {
  54. BaseAddress = MapViewOfFile( MappingHandle,
  55. FILE_MAP_READ | FILE_MAP_WRITE,
  56. 0,
  57. 0,
  58. 0);
  59. CloseHandle( MappingHandle );
  60. if ( BaseAddress == NULL )
  61. {
  62. CloseHandle( FileHandle );
  63. QuitA( 23, ImageName, NULL);
  64. }
  65. else
  66. {
  67. //
  68. // Get the length of the file in bytes and compute the checksum.
  69. //
  70. FileLength = GetFileSize( FileHandle, NULL );
  71. //
  72. // Obtain a pointer to the header information.
  73. //
  74. NtHeaders = MyRtlImageNtHeader( BaseAddress);
  75. if ( NtHeaders == NULL )
  76. {
  77. CloseHandle( FileHandle );
  78. UnmapViewOfFile( BaseAddress );
  79. QuitA( 17, ImageName, NULL);
  80. }
  81. else
  82. {
  83. //
  84. // Recompute and reset the checksum of the modified file.
  85. //
  86. OldCheckSum = NtHeaders->OptionalHeader.CheckSum;
  87. (VOID) CheckSumMappedFile( BaseAddress,
  88. FileLength,
  89. &HeaderSum,
  90. &CheckSum);
  91. NtHeaders->OptionalHeader.CheckSum = CheckSum;
  92. if (SymbolPath && *SymbolPath)
  93. {
  94. TCHAR DebugFilePath[MAX_PATH];
  95. SetLastError(0);
  96. MyUpdateDebugInfoFileEx((LPSTR)OrigFileName,
  97. (LPSTR)SymbolPath,
  98. DebugFilePath,
  99. NtHeaders,
  100. OldCheckSum);
  101. iErr = GetLastError();
  102. switch(iErr)
  103. {
  104. case ERROR_INVALID_DATA:
  105. iErr = ERROR_IO_CHECKSUM_MISMATCH;
  106. break;
  107. case ERROR_FILE_NOT_FOUND:
  108. iErr = ERROR_IO_SYMBOLFILE_NOT_FOUND;
  109. break;
  110. case ERROR_NO_ERROR:
  111. break;
  112. default:
  113. iErr += LAST_ERROR;
  114. }
  115. }
  116. if ( ! FlushViewOfFile( BaseAddress, FileLength) )
  117. {
  118. QuitA( 24, ImageName, NULL);
  119. }
  120. if ( NtHeaders->OptionalHeader.CheckSum != OldCheckSum )
  121. {
  122. if ( ! TouchFileTimes( FileHandle, NULL) )
  123. {
  124. QuitA( 25, ImageName, NULL);
  125. }
  126. }
  127. UnmapViewOfFile( BaseAddress );
  128. CloseHandle( FileHandle );
  129. }
  130. }
  131. }
  132. return( iErr);
  133. }
  134. //.........................................................................
  135. static PIMAGE_NT_HEADERS MyRtlImageNtHeader( PVOID pBaseAddress)
  136. {
  137. IMAGE_DOS_HEADER *pDosHeader = (IMAGE_DOS_HEADER *)pBaseAddress;
  138. return( pDosHeader->e_magic == IMAGE_DOS_SIGNATURE
  139. ? (PIMAGE_NT_HEADERS)(((PBYTE)pBaseAddress) + pDosHeader->e_lfanew)
  140. : NULL);
  141. }
  142. BOOL
  143. MyUpdateDebugInfoFileEx(
  144. LPSTR ImageFileName,
  145. LPSTR SymbolPath,
  146. LPSTR DebugFilePath,
  147. PIMAGE_NT_HEADERS NtHeaders,
  148. DWORD OldCheckSum
  149. )
  150. {
  151. // UnSafe...
  152. HANDLE hDebugFile, hMappedFile;
  153. PVOID MappedAddress;
  154. PIMAGE_SEPARATE_DEBUG_HEADER DbgFileHeader;
  155. BOOL bRet;
  156. hDebugFile = FindDebugInfoFile(
  157. ImageFileName,
  158. SymbolPath,
  159. DebugFilePath
  160. );
  161. if ( hDebugFile == NULL ) {
  162. return FALSE;
  163. }
  164. CloseHandle(hDebugFile);
  165. hDebugFile = CreateFile( DebugFilePath,
  166. GENERIC_READ | GENERIC_WRITE,
  167. FILE_SHARE_DELETE | FILE_SHARE_READ
  168. | FILE_SHARE_WRITE,
  169. NULL,
  170. OPEN_EXISTING,
  171. 0,
  172. NULL
  173. );
  174. if ( hDebugFile == INVALID_HANDLE_VALUE ) {
  175. return FALSE;
  176. }
  177. hMappedFile = CreateFileMapping(
  178. hDebugFile,
  179. NULL,
  180. PAGE_READWRITE,
  181. 0,
  182. 0,
  183. NULL
  184. );
  185. if ( !hMappedFile ) {
  186. CloseHandle(hDebugFile);
  187. return FALSE;
  188. }
  189. MappedAddress = MapViewOfFile(hMappedFile,
  190. FILE_MAP_WRITE,
  191. 0,
  192. 0,
  193. 0
  194. );
  195. CloseHandle(hMappedFile);
  196. if ( !MappedAddress ) {
  197. CloseHandle(hDebugFile);
  198. return FALSE;
  199. }
  200. DbgFileHeader = (PIMAGE_SEPARATE_DEBUG_HEADER)MappedAddress;
  201. if (DbgFileHeader->ImageBase != NtHeaders->OptionalHeader.ImageBase ||
  202. DbgFileHeader->CheckSum != NtHeaders->OptionalHeader.CheckSum
  203. ) {
  204. if (OldCheckSum != DbgFileHeader->CheckSum) {
  205. DbgFileHeader->Flags |= IMAGE_SEPARATE_DEBUG_MISMATCH;
  206. SetLastError(ERROR_INVALID_DATA);
  207. } else {
  208. SetLastError(ERROR_SUCCESS);
  209. }
  210. DbgFileHeader->ImageBase = (DWORD) NtHeaders->OptionalHeader.ImageBase;
  211. DbgFileHeader->CheckSum = NtHeaders->OptionalHeader.CheckSum;
  212. DbgFileHeader->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
  213. bRet = TRUE;
  214. }
  215. else
  216. {
  217. bRet = FALSE;
  218. }
  219. if (bRet)
  220. TouchFileTimes(hDebugFile,NULL);
  221. UnmapViewOfFile(MappedAddress);
  222. CloseHandle(hDebugFile);
  223. return bRet;
  224. }