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.

256 lines
5.9 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. modules.c
  5. Abstract:
  6. Implements .
  7. Author:
  8. Calin Negreanu (calinn) 20-Jan-1999
  9. Revision History:
  10. <alias> <date> <comments>
  11. --*/
  12. #include "modules.h"
  13. PBYTE
  14. ShMapFileIntoMemory (
  15. IN PCTSTR FileName,
  16. OUT PHANDLE FileHandle,
  17. OUT PHANDLE MapHandle
  18. )
  19. {
  20. PBYTE fileImage = NULL;
  21. //first thing. Try to open the file, read-only
  22. *FileHandle = CreateFile (
  23. FileName,
  24. GENERIC_READ,
  25. FILE_SHARE_READ,
  26. NULL,
  27. OPEN_EXISTING,
  28. FILE_ATTRIBUTE_NORMAL,
  29. NULL
  30. );
  31. if (*FileHandle == INVALID_HANDLE_VALUE) {
  32. return NULL;
  33. }
  34. //now try to create a mapping object, read-only
  35. *MapHandle = CreateFileMapping (*FileHandle, NULL, PAGE_READONLY, 0, 0, NULL);
  36. if (*MapHandle == NULL) {
  37. return NULL;
  38. }
  39. //one more thing to do: map view of file
  40. fileImage = MapViewOfFile (*MapHandle, FILE_MAP_READ, 0, 0, 0);
  41. return fileImage;
  42. }
  43. BOOL
  44. ShUnmapFile (
  45. IN PBYTE FileImage,
  46. IN HANDLE MapHandle,
  47. IN HANDLE FileHandle
  48. )
  49. {
  50. BOOL result = TRUE;
  51. //if FileImage is a valid pointer then try to unmap file
  52. if (FileImage != NULL) {
  53. if (UnmapViewOfFile (FileImage) == 0) {
  54. result = FALSE;
  55. }
  56. }
  57. //if mapping object is valid then try to delete it
  58. if (MapHandle != NULL) {
  59. if (CloseHandle (MapHandle) == 0) {
  60. result = FALSE;
  61. }
  62. }
  63. //if file handle is valid then try to close the file
  64. if (FileHandle != INVALID_HANDLE_VALUE) {
  65. if (CloseHandle (FileHandle) == 0) {
  66. result = FALSE;
  67. }
  68. }
  69. return result;
  70. }
  71. #define MT_UNKNOWN_MODULE 0
  72. #define MT_DOS_MODULE 1
  73. #define MT_W16_MODULE 2
  74. #define MT_W32_MODULE 3
  75. DWORD
  76. ShGetModuleType (
  77. IN PBYTE MappedImage
  78. )
  79. {
  80. DWORD result;
  81. PIMAGE_DOS_HEADER dh;
  82. PDWORD sign;
  83. PWORD signNE;
  84. dh = (PIMAGE_DOS_HEADER) MappedImage;
  85. if (dh->e_magic != IMAGE_DOS_SIGNATURE) {
  86. result = MT_UNKNOWN_MODULE;
  87. } else {
  88. result = MT_DOS_MODULE;
  89. sign = (PDWORD)(MappedImage + dh->e_lfanew);
  90. if (*sign == IMAGE_NT_SIGNATURE) {
  91. result = MT_W32_MODULE;
  92. }
  93. signNE = (PWORD)sign;
  94. if (*signNE == IMAGE_OS2_SIGNATURE) {
  95. result = MT_W16_MODULE;
  96. }
  97. }
  98. return result;
  99. }
  100. PIMAGE_NT_HEADERS
  101. pShGetImageNtHeader (
  102. IN PVOID Base
  103. )
  104. {
  105. PIMAGE_NT_HEADERS NtHeaders;
  106. if (Base != NULL && Base != (PVOID)-1) {
  107. if (((PIMAGE_DOS_HEADER)Base)->e_magic == IMAGE_DOS_SIGNATURE) {
  108. NtHeaders = (PIMAGE_NT_HEADERS)((PCHAR)Base + ((PIMAGE_DOS_HEADER)Base)->e_lfanew);
  109. if (NtHeaders->Signature == IMAGE_NT_SIGNATURE) {
  110. return NtHeaders;
  111. }
  112. }
  113. }
  114. return NULL;
  115. }
  116. ULONG
  117. ShGetPECheckSum (
  118. IN PBYTE MappedImage
  119. )
  120. {
  121. PIMAGE_NT_HEADERS NtHeaders;
  122. ULONG result = 0;
  123. if (ShGetModuleType (MappedImage) != MT_W32_MODULE) {
  124. return 0;
  125. }
  126. NtHeaders = pShGetImageNtHeader(MappedImage);
  127. if (NtHeaders) {
  128. if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
  129. result = ((PIMAGE_NT_HEADERS32)NtHeaders)->OptionalHeader.CheckSum;
  130. } else
  131. if (NtHeaders->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
  132. result = ((PIMAGE_NT_HEADERS64)NtHeaders)->OptionalHeader.CheckSum;
  133. }
  134. }
  135. return result;
  136. }
  137. UINT
  138. ShGetCheckSum (
  139. IN ULONG ImageSize,
  140. IN PBYTE MappedImage
  141. )
  142. {
  143. INT i,size = 4096;
  144. DWORD startAddr = 512;
  145. UINT checkSum = 0;
  146. if (ImageSize < (ULONG)size) {
  147. //
  148. // File size is less than 4096. We set the start address to 0 and set the size for the checksum
  149. // to the actual file size.
  150. //
  151. startAddr = 0;
  152. size = ImageSize;
  153. }
  154. else
  155. if (startAddr + size > ImageSize) {
  156. //
  157. // File size is too small. We set the start address so that size of checksum can be 4096 bytes
  158. //
  159. startAddr = ImageSize - size;
  160. }
  161. if (size <= 3) {
  162. //
  163. // we need at least 3 bytes to be able to do something here.
  164. //
  165. return 0;
  166. }
  167. MappedImage = MappedImage + startAddr;
  168. for (i = 0; i<(size - 3); i+=4) {
  169. checkSum += *((PDWORD) (MappedImage + i));
  170. checkSum = _rotr (checkSum, 1);
  171. }
  172. return checkSum;
  173. }
  174. PTSTR
  175. ShGet16ModuleDescription (
  176. IN PBYTE MappedImage
  177. )
  178. {
  179. CHAR a_result [512]; // we know for sure that this one cannot be larger (size is a byte)
  180. PTSTR result = NULL;
  181. PIMAGE_DOS_HEADER dosHeader;
  182. PIMAGE_OS2_HEADER neHeader;
  183. PBYTE size;
  184. #ifdef UNICODE
  185. WCHAR w_result [512];
  186. INT converted;
  187. #endif
  188. if (ShGetModuleType (MappedImage) != MT_W16_MODULE) {
  189. return NULL;
  190. }
  191. dosHeader = (PIMAGE_DOS_HEADER) MappedImage;
  192. neHeader = (PIMAGE_OS2_HEADER) (MappedImage + dosHeader->e_lfanew);
  193. size = (PBYTE) (MappedImage + neHeader->ne_nrestab);
  194. if (*size == 0) {
  195. return NULL;
  196. }
  197. CopyMemory (a_result, MappedImage + neHeader->ne_nrestab + 1, *size);
  198. a_result [*size] = 0;
  199. #ifdef UNICODE
  200. converted = MultiByteToWideChar (
  201. CP_ACP,
  202. 0,
  203. a_result,
  204. *size,
  205. w_result,
  206. 512
  207. );
  208. if (!converted) {
  209. return NULL;
  210. }
  211. w_result [*size] = 0;
  212. result = HeapAlloc (GetProcessHeap (), 0, (converted + 1) * sizeof (WCHAR));
  213. lstrcpyW (result, w_result);
  214. #else
  215. result = HeapAlloc (GetProcessHeap (), 0, (*size + 1) * sizeof (CHAR));
  216. lstrcpyA (result, a_result);
  217. #endif
  218. return result;
  219. }