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.

297 lines
6.9 KiB

  1. #include "precomp.h"
  2. #pragma hdrstop
  3. DWORD
  4. pOpenAndMapFile (
  5. IN PVOID FileName,
  6. IN BOOL NameIsUnicode,
  7. IN DWORD DesiredAccess,
  8. OUT PHANDLE FileHandle,
  9. OUT PLARGE_INTEGER Size,
  10. OUT PHANDLE MappingHandle,
  11. OUT PVOID *MappedBase
  12. )
  13. {
  14. BOOL ok;
  15. DWORD error;
  16. LARGE_INTEGER Zero;
  17. *MappingHandle = NULL;
  18. *MappedBase = NULL;
  19. if ( NameIsUnicode ) {
  20. *FileHandle = CreateFile(
  21. FileName,
  22. DesiredAccess,
  23. 0,
  24. NULL,
  25. OPEN_EXISTING,
  26. 0,
  27. NULL
  28. );
  29. } else {
  30. *FileHandle = CreateFileA(
  31. FileName,
  32. DesiredAccess,
  33. 0,
  34. NULL,
  35. OPEN_EXISTING,
  36. 0,
  37. NULL
  38. );
  39. }
  40. if ( *FileHandle == INVALID_HANDLE_VALUE ) {
  41. error = GetLastError( );
  42. goto cleanup;
  43. }
  44. Zero.QuadPart = 0;
  45. ok = SetFilePointerEx( *FileHandle, Zero, Size, FILE_END );
  46. if ( !ok ) {
  47. error = GetLastError( );
  48. goto cleanup;
  49. }
  50. if ( Size->QuadPart == 0 ) {
  51. error = NO_ERROR;
  52. goto cleanup;
  53. }
  54. *MappingHandle = CreateFileMapping(
  55. *FileHandle,
  56. NULL,
  57. (DesiredAccess == GENERIC_READ) ? PAGE_READONLY : PAGE_READWRITE,
  58. Size->HighPart,
  59. Size->LowPart,
  60. NULL
  61. );
  62. if ( *MappingHandle == NULL ) {
  63. error = GetLastError( );
  64. goto cleanup;
  65. }
  66. *MappedBase = MapViewOfFile(
  67. *MappingHandle,
  68. (DesiredAccess == GENERIC_READ) ? FILE_MAP_READ : (FILE_MAP_READ | FILE_MAP_WRITE),
  69. 0,
  70. 0,
  71. Size->LowPart
  72. );
  73. if ( *MappedBase == NULL ) {
  74. error = GetLastError( );
  75. goto cleanup;
  76. }
  77. return NO_ERROR;
  78. cleanup:
  79. if ( *MappedBase != NULL ) {
  80. UnmapViewOfFile( *MappedBase );
  81. *MappedBase = NULL;
  82. }
  83. if ( *MappingHandle != NULL ) {
  84. CloseHandle( *MappingHandle );
  85. *MappingHandle = NULL;
  86. }
  87. if ( *FileHandle != INVALID_HANDLE_VALUE ) {
  88. CloseHandle( *FileHandle );
  89. *FileHandle = INVALID_HANDLE_VALUE;
  90. }
  91. return error;
  92. }
  93. DWORD
  94. OpenAndMapFile (
  95. IN PWCH FileName,
  96. IN DWORD DesiredAccess,
  97. OUT PHANDLE FileHandle,
  98. OUT PLARGE_INTEGER Size,
  99. OUT PHANDLE MappingHandle,
  100. OUT PVOID *MappedBase
  101. )
  102. {
  103. return pOpenAndMapFile(
  104. FileName,
  105. TRUE,
  106. DesiredAccess,
  107. FileHandle,
  108. Size,
  109. MappingHandle,
  110. MappedBase
  111. );
  112. }
  113. DWORD
  114. OpenAndMapFileA (
  115. IN PSZ FileName,
  116. IN DWORD DesiredAccess,
  117. OUT PHANDLE FileHandle,
  118. OUT PLARGE_INTEGER Size,
  119. OUT PHANDLE MappingHandle,
  120. OUT PVOID *MappedBase
  121. )
  122. {
  123. return pOpenAndMapFile(
  124. FileName,
  125. FALSE,
  126. DesiredAccess,
  127. FileHandle,
  128. Size,
  129. MappingHandle,
  130. MappedBase
  131. );
  132. }
  133. VOID
  134. CloseMappedFile (
  135. IN HANDLE FileHandle,
  136. IN HANDLE MappingHandle,
  137. IN PVOID MappedBase
  138. )
  139. {
  140. if ( FileHandle != INVALID_HANDLE_VALUE ) {
  141. if ( MappedBase != NULL ) {
  142. UnmapViewOfFile( MappedBase );
  143. }
  144. if ( MappingHandle != NULL ) {
  145. CloseHandle( MappingHandle );
  146. }
  147. CloseHandle( FileHandle );
  148. }
  149. return;
  150. }
  151. DWORD
  152. DataLooksBinary (
  153. IN PVOID MappedBase,
  154. IN DWORD FileSize,
  155. OUT PUCHAR BinaryData OPTIONAL,
  156. OUT PDWORD BinaryDataOffset OPTIONAL
  157. )
  158. {
  159. DWORD nBytes;
  160. DWORD nBinary;
  161. DWORD offset;
  162. DWORD i;
  163. PUCHAR p;
  164. UCHAR c;
  165. DWORD previousBinary;
  166. BOOL anyBinaryFound;
  167. if ( IsTextUnicode( MappedBase, FileSize < 512 ? FileSize : 512, NULL ) ) {
  168. return SCAN_FILETYPE_UNICODE_TEXT;
  169. }
  170. anyBinaryFound = FALSE;
  171. for ( offset = 0;
  172. offset < FileSize;
  173. offset += nBytes ) {
  174. previousBinary = MAXULONG;
  175. nBinary = 0;
  176. nBytes = 512;
  177. if ( offset + nBytes > FileSize ) {
  178. nBytes = FileSize - offset;
  179. }
  180. for ( i = 0, p = (PUCHAR)MappedBase + offset;
  181. i < nBytes;
  182. i++, p++ ) {
  183. c = *p;
  184. switch ( c ) {
  185. case '\a': // ignore all BELL for this test
  186. case '\b': // BS
  187. case '\f': // FF
  188. case '\n': // LF
  189. case '\r': // CR
  190. case '\t': // tab
  191. case '\v': // VT
  192. case 0x1A: // ^Z
  193. break;
  194. default:
  195. if ( (c < ' ') || (c > '~') ) { // worry about DBCS?
  196. nBinary++;
  197. if ( previousBinary == MAXULONG ) {
  198. if ( ARGUMENT_PRESENT(BinaryData) ) {
  199. *BinaryData = c;
  200. }
  201. if ( ARGUMENT_PRESENT(BinaryDataOffset) ) {
  202. *BinaryDataOffset = offset + i;
  203. }
  204. previousBinary = c;
  205. }
  206. }
  207. break;
  208. }
  209. }
  210. if ( nBinary != 0 ) {
  211. anyBinaryFound = TRUE;
  212. if ( nBinary > (nBytes / 5) ) {
  213. return SCAN_FILETYPE_BINARY;
  214. }
  215. }
  216. }
  217. if ( anyBinaryFound ) {
  218. return SCAN_FILETYPE_MAYBE_BINARY;
  219. }
  220. return SCAN_FILETYPE_TEXT;
  221. } // DataLooksBinary
  222. DWORD
  223. FileLooksBinary (
  224. PWCH DirectoryName,
  225. PWCH FileName,
  226. OUT PUCHAR BinaryData OPTIONAL,
  227. OUT PDWORD BinaryDataOffset OPTIONAL
  228. )
  229. {
  230. DWORD error;
  231. LARGE_INTEGER size;
  232. HANDLE fileHandle;
  233. HANDLE mappingHandle;
  234. PVOID mappedBase;
  235. WCHAR fullName[MAX_PATH+1];
  236. DWORD i;
  237. wcscpy( fullName, DirectoryName );
  238. wcscat( fullName, L"\\" );
  239. wcscat( fullName, FileName );
  240. error = OpenAndMapFile (
  241. fullName,
  242. GENERIC_READ,
  243. &fileHandle,
  244. &size,
  245. &mappingHandle,
  246. &mappedBase
  247. );
  248. if ( error != NO_ERROR ) {
  249. return SCAN_FILETYPE_TEXT;
  250. }
  251. if ( size.QuadPart == 0 ) {
  252. return SCAN_FILETYPE_TEXT;
  253. }
  254. i = DataLooksBinary(
  255. mappedBase,
  256. size.HighPart == 0 ? size.LowPart : MAXULONG,
  257. BinaryData,
  258. BinaryDataOffset
  259. );
  260. CloseMappedFile( fileHandle, mappingHandle, mappedBase );
  261. return i;
  262. }