windows-nt/Source/XPSP1/NT/sdktools/emptydirs/scanlib/utils.c
2020-09-26 16:20:57 +08:00

298 lines
6.9 KiB
C

#include "precomp.h"
#pragma hdrstop
DWORD
pOpenAndMapFile (
IN PVOID FileName,
IN BOOL NameIsUnicode,
IN DWORD DesiredAccess,
OUT PHANDLE FileHandle,
OUT PLARGE_INTEGER Size,
OUT PHANDLE MappingHandle,
OUT PVOID *MappedBase
)
{
BOOL ok;
DWORD error;
LARGE_INTEGER Zero;
*MappingHandle = NULL;
*MappedBase = NULL;
if ( NameIsUnicode ) {
*FileHandle = CreateFile(
FileName,
DesiredAccess,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
} else {
*FileHandle = CreateFileA(
FileName,
DesiredAccess,
0,
NULL,
OPEN_EXISTING,
0,
NULL
);
}
if ( *FileHandle == INVALID_HANDLE_VALUE ) {
error = GetLastError( );
goto cleanup;
}
Zero.QuadPart = 0;
ok = SetFilePointerEx( *FileHandle, Zero, Size, FILE_END );
if ( !ok ) {
error = GetLastError( );
goto cleanup;
}
if ( Size->QuadPart == 0 ) {
error = NO_ERROR;
goto cleanup;
}
*MappingHandle = CreateFileMapping(
*FileHandle,
NULL,
(DesiredAccess == GENERIC_READ) ? PAGE_READONLY : PAGE_READWRITE,
Size->HighPart,
Size->LowPart,
NULL
);
if ( *MappingHandle == NULL ) {
error = GetLastError( );
goto cleanup;
}
*MappedBase = MapViewOfFile(
*MappingHandle,
(DesiredAccess == GENERIC_READ) ? FILE_MAP_READ : (FILE_MAP_READ | FILE_MAP_WRITE),
0,
0,
Size->LowPart
);
if ( *MappedBase == NULL ) {
error = GetLastError( );
goto cleanup;
}
return NO_ERROR;
cleanup:
if ( *MappedBase != NULL ) {
UnmapViewOfFile( *MappedBase );
*MappedBase = NULL;
}
if ( *MappingHandle != NULL ) {
CloseHandle( *MappingHandle );
*MappingHandle = NULL;
}
if ( *FileHandle != INVALID_HANDLE_VALUE ) {
CloseHandle( *FileHandle );
*FileHandle = INVALID_HANDLE_VALUE;
}
return error;
}
DWORD
OpenAndMapFile (
IN PWCH FileName,
IN DWORD DesiredAccess,
OUT PHANDLE FileHandle,
OUT PLARGE_INTEGER Size,
OUT PHANDLE MappingHandle,
OUT PVOID *MappedBase
)
{
return pOpenAndMapFile(
FileName,
TRUE,
DesiredAccess,
FileHandle,
Size,
MappingHandle,
MappedBase
);
}
DWORD
OpenAndMapFileA (
IN PSZ FileName,
IN DWORD DesiredAccess,
OUT PHANDLE FileHandle,
OUT PLARGE_INTEGER Size,
OUT PHANDLE MappingHandle,
OUT PVOID *MappedBase
)
{
return pOpenAndMapFile(
FileName,
FALSE,
DesiredAccess,
FileHandle,
Size,
MappingHandle,
MappedBase
);
}
VOID
CloseMappedFile (
IN HANDLE FileHandle,
IN HANDLE MappingHandle,
IN PVOID MappedBase
)
{
if ( FileHandle != INVALID_HANDLE_VALUE ) {
if ( MappedBase != NULL ) {
UnmapViewOfFile( MappedBase );
}
if ( MappingHandle != NULL ) {
CloseHandle( MappingHandle );
}
CloseHandle( FileHandle );
}
return;
}
DWORD
DataLooksBinary (
IN PVOID MappedBase,
IN DWORD FileSize,
OUT PUCHAR BinaryData OPTIONAL,
OUT PDWORD BinaryDataOffset OPTIONAL
)
{
DWORD nBytes;
DWORD nBinary;
DWORD offset;
DWORD i;
PUCHAR p;
UCHAR c;
DWORD previousBinary;
BOOL anyBinaryFound;
if ( IsTextUnicode( MappedBase, FileSize < 512 ? FileSize : 512, NULL ) ) {
return SCAN_FILETYPE_UNICODE_TEXT;
}
anyBinaryFound = FALSE;
for ( offset = 0;
offset < FileSize;
offset += nBytes ) {
previousBinary = MAXULONG;
nBinary = 0;
nBytes = 512;
if ( offset + nBytes > FileSize ) {
nBytes = FileSize - offset;
}
for ( i = 0, p = (PUCHAR)MappedBase + offset;
i < nBytes;
i++, p++ ) {
c = *p;
switch ( c ) {
case '\a': // ignore all BELL for this test
case '\b': // BS
case '\f': // FF
case '\n': // LF
case '\r': // CR
case '\t': // tab
case '\v': // VT
case 0x1A: // ^Z
break;
default:
if ( (c < ' ') || (c > '~') ) { // worry about DBCS?
nBinary++;
if ( previousBinary == MAXULONG ) {
if ( ARGUMENT_PRESENT(BinaryData) ) {
*BinaryData = c;
}
if ( ARGUMENT_PRESENT(BinaryDataOffset) ) {
*BinaryDataOffset = offset + i;
}
previousBinary = c;
}
}
break;
}
}
if ( nBinary != 0 ) {
anyBinaryFound = TRUE;
if ( nBinary > (nBytes / 5) ) {
return SCAN_FILETYPE_BINARY;
}
}
}
if ( anyBinaryFound ) {
return SCAN_FILETYPE_MAYBE_BINARY;
}
return SCAN_FILETYPE_TEXT;
} // DataLooksBinary
DWORD
FileLooksBinary (
PWCH DirectoryName,
PWCH FileName,
OUT PUCHAR BinaryData OPTIONAL,
OUT PDWORD BinaryDataOffset OPTIONAL
)
{
DWORD error;
LARGE_INTEGER size;
HANDLE fileHandle;
HANDLE mappingHandle;
PVOID mappedBase;
WCHAR fullName[MAX_PATH+1];
DWORD i;
wcscpy( fullName, DirectoryName );
wcscat( fullName, L"\\" );
wcscat( fullName, FileName );
error = OpenAndMapFile (
fullName,
GENERIC_READ,
&fileHandle,
&size,
&mappingHandle,
&mappedBase
);
if ( error != NO_ERROR ) {
return SCAN_FILETYPE_TEXT;
}
if ( size.QuadPart == 0 ) {
return SCAN_FILETYPE_TEXT;
}
i = DataLooksBinary(
mappedBase,
size.HighPart == 0 ? size.LowPart : MAXULONG,
BinaryData,
BinaryDataOffset
);
CloseMappedFile( fileHandle, mappingHandle, mappedBase );
return i;
}