Created
December 16, 2011 18:54
-
-
Save malkia/1487388 to your computer and use it in GitHub Desktop.
Win32: Reading directory in one kernel call
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Not sure whether it's faster than FindFirstFile, etc. - but it does it in one kernel call | |
#include <windows.h> | |
#include <stdio.h> | |
// to compile: | |
// cl fileinfo.c setargv.obj | |
void fileinfo(const char*name); | |
int main( int argc, const char* argv[] ) | |
{ | |
int i; | |
if( argc == 1 ) | |
printf( "fileinfo: Dumps GetFileInformationByHandleEx Information\n" ); | |
for( i=1; i<argc; i++ ) { | |
fileinfo(argv[i]); | |
printf("\n"); | |
} | |
return 0; | |
} | |
void fileinfo(const char*name) | |
{ | |
int i, j; | |
HANDLE h = CreateFileA( | |
name, | |
GENERIC_READ, | |
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, | |
NULL, | |
OPEN_EXISTING, | |
FILE_FLAG_BACKUP_SEMANTICS, | |
NULL | |
); | |
if( h == INVALID_HANDLE_VALUE ) { | |
fprintf( stderr, "%s: error hr=%p\n", name, GetLastError() ); | |
return; | |
} | |
for( i=0; i<256; i++ ) | |
{ | |
static __declspec(align(8)) unsigned char buffer1[64*1024*1024]; | |
static __declspec(align(8)) unsigned char buffer2[64*1024*1024]; | |
if(!GetFileInformationByHandleEx(h, (FILE_INFO_BY_HANDLE_CLASS)i, buffer1, sizeof(buffer1)) ) | |
continue; | |
memset(&buffer1, 0xBA, sizeof(buffer1)); | |
memset(&buffer2, 0xFD, sizeof(buffer2)); | |
if(!GetFileInformationByHandleEx(h, (FILE_INFO_BY_HANDLE_CLASS)i, buffer1, sizeof(buffer1)) | |
|| !GetFileInformationByHandleEx(h, (FILE_INFO_BY_HANDLE_CLASS)i, buffer2, sizeof(buffer2))) | |
continue; | |
for( j=0; j<sizeof(buffer1); j++ ) | |
{ | |
if( buffer1[j] == buffer2[j] ) | |
continue; | |
if( buffer1[j] == 0xBA && buffer2[j] == 0xFD ) | |
break; | |
printf( "%s: info %p differs at %p\n", name, i, j ); | |
break; | |
} | |
switch( i ) { | |
case FileBasicInfo: { | |
PFILE_BASIC_INFO info = (PFILE_BASIC_INFO)buffer1; | |
printf( "%s: FILE_BASIC_INFO (%d)\n", name, i ); | |
printf( "%s: CreationTime = %I64u\n", name, info->CreationTime.QuadPart ); | |
printf( "%s: LastAccessTime = %I64u\n", name, info->LastAccessTime.QuadPart ); | |
printf( "%s: LastWriteTime = %I64u\n", name, info->LastWriteTime.QuadPart ); | |
printf( "%s: ChangeTime = %I64u\n", name, info->ChangeTime.QuadPart ); | |
printf( "%s: FileAttributes = 0x%p\n", name, info->FileAttributes ); | |
} break; | |
case FileStandardInfo: { | |
PFILE_STANDARD_INFO info = (PFILE_STANDARD_INFO)buffer1; | |
printf( "%s: FILE_STANDARD_INFO (%d)\n", name, i ); | |
printf( "%s: AllocationSize = %I64u\n", name, info->AllocationSize.QuadPart ); | |
printf( "%s: EndOfFile = %I64u\n", name, info->EndOfFile.QuadPart ); | |
printf( "%s: NumberOfLinks = %d\n", name, info->NumberOfLinks ); | |
printf( "%s: DeletePending = %d\n", name, info->DeletePending ); | |
printf( "%s: Directory = %d\n", name, info->Directory ); | |
} break; | |
case FileNameInfo: { | |
PFILE_NAME_INFO info = (PFILE_NAME_INFO)buffer1; | |
printf( "%s: FILE_NAME_INFO (%d)\n", name, i ); | |
printf( "%s: FileNameLength = %d\n", name, info->FileNameLength ); | |
printf( "%s: FileName = %*.*S\n", name, info->FileNameLength/2, info->FileNameLength/2, info->FileName ); // UNICODE, hence /2 | |
} break; | |
case FileStreamInfo: { | |
int entryIndex = 0; | |
PFILE_STREAM_INFO info = (PFILE_STREAM_INFO)buffer1; | |
printf( "%s: FILE_STREAM_INFO (%d)\n", name, i ); | |
for( ;; ) { | |
printf( "%s: Stream = %d\n", name, entryIndex ); | |
printf( "%s: NextEntryOffset = 0x%p\n", name, info->NextEntryOffset ); | |
printf( "%s: StreamNameLength = %d\n", name, info->StreamNameLength ); | |
printf( "%s: StreamSize = %I64u\n", name, info->StreamSize.QuadPart ); | |
printf( "%s: StreamAllocationSize = %I64u\n", name, info->StreamAllocationSize.QuadPart ); | |
printf( "%s: StreamName = %*.*S\n", name, info->StreamNameLength/2, info->StreamNameLength/2, info->StreamName ); // UNICODE, hence /2 | |
if( !info->NextEntryOffset ) | |
break; | |
entryIndex ++; | |
info = (PFILE_STREAM_INFO)( (char*)info + info->NextEntryOffset ); | |
}; | |
} break; | |
case FileCompressionInfo: { | |
PFILE_COMPRESSION_INFO info = (PFILE_COMPRESSION_INFO)buffer1; | |
printf( "%s: FILE_COMPRESSION_INFO (%d)\n", name, i ); | |
printf( "%s: CompressedFileSize = %I64u\n", name, info->CompressedFileSize.QuadPart ); | |
printf( "%s: CompressionFormat = %d\n", name, info->CompressionFormat); | |
printf( "%s: CompressionUnitShift = %d\n", name, info->CompressionUnitShift); | |
printf( "%s: ChunkShift = %d\n", name, info->ChunkShift); | |
printf( "%s: ClusterShift = %d\n", name, info->ClusterShift); | |
printf( "%s: Reserved[3] = %d %d %d\n", name, info->Reserved[0],info->Reserved[1],info->Reserved[2]); | |
} break; | |
case FileAttributeTagInfo: { | |
PFILE_ATTRIBUTE_TAG_INFO info = (PFILE_ATTRIBUTE_TAG_INFO)buffer1; | |
printf( "%s: FILE_ATTRIBUTE_TAG_INFO (%d)\n", name, i ); | |
printf( "%s: FileAttributes = 0x%p\n", name, info->FileAttributes); | |
printf( "%s: ReparseTag = 0x%p\n", name, info->ReparseTag); | |
} break; | |
case FileIdBothDirectoryInfo: | |
case FileIdBothDirectoryRestartInfo: { | |
int entryIndex = 0; | |
PFILE_ID_BOTH_DIR_INFO info = (PFILE_ID_BOTH_DIR_INFO)buffer1; | |
printf( "%s: FILE_ID_BOTH_DIR_INFO (%d) size=%p\n", name, i, j ); | |
for( ;; ) { | |
printf( "%s: Entry = 0x%p %d 0x%p\n", name, (char*)info - (char*)buffer1, entryIndex, (char*)info - (char*)buffer1 + sizeof(FILE_ID_BOTH_DIR_INFO)*2 ); | |
printf( "%s: NextEntryOffset = 0x%p\n", name, info->NextEntryOffset ); | |
printf( "%s: FileIndex = %d\n", name, info->FileIndex ); | |
printf( "%s: CreationTime = %I64u\n", name, info->CreationTime.QuadPart ); | |
printf( "%s: LastAccessTime = %I64u\n", name, info->LastAccessTime.QuadPart ); | |
printf( "%s: LastWriteTime = %I64u\n", name, info->LastWriteTime.QuadPart ); | |
printf( "%s: ChangeTime = %I64u\n", name, info->ChangeTime.QuadPart ); | |
printf( "%s: EndOfFile = %I64u\n", name, info->EndOfFile.QuadPart ); | |
printf( "%s: AllocationSize = %I64u\n", name, info->AllocationSize.QuadPart ); | |
printf( "%s: FileAttributes = 0x%p\n", name, info->FileAttributes); | |
printf( "%s: FileNameLength = %d\n", name, info->FileNameLength ); | |
printf( "%s: EaSize = %d\n", name, info->EaSize ); | |
printf( "%s: ShortNameLength = %d\n", name, info->ShortNameLength ); | |
printf( "%s: ShortName = %*.*S\n", name, info->ShortNameLength/2, info->ShortNameLength/2, info->ShortName ); | |
printf( "%s: FileId = %I64u\n", name, info->FileId ); | |
printf( "%s: FileName = %*.*S\n", name, info->FileNameLength/2, info->FileNameLength/2, info->FileName ); // UNICODE, hence /2 | |
if( !info->NextEntryOffset ) | |
break; | |
entryIndex++; | |
info = (PFILE_ID_BOTH_DIR_INFO)( (char*)info + info->NextEntryOffset ); | |
} | |
} break; | |
default: { | |
printf( "%s: UKNOWN_FILE_INFO (%d) sized %d bytes\n", name, i, j ); | |
} break; | |
} | |
} | |
CloseHandle(h); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment