// genoid.c #include "oidtst.h" #define VOLUME_PATH L"\\\\.\\H:" #define VOLUME_DRIVE_LETTER_INDEX 4 #define FULL_PATH L"\\??\\H:\\1234567890123456" #define FULL_DRIVE_LETTER_INDEX 4 #define DEVICE_PREFIX_LEN 14 #define RELATIVE_OPEN int FsTestGenOid( IN HANDLE hFile, IN FILE_OBJECTID_BUFFER *ObjectIdBuffer ) { IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; Status = NtFsControlFile( hFile, // file handle NULL, // event NULL, // apc routine NULL, // apc context &IoStatusBlock, // iosb FSCTL_CREATE_OR_GET_OBJECT_ID, // FsControlCode &hFile, // input buffer sizeof(HANDLE), // input buffer length ObjectIdBuffer, // OutputBuffer for data from the FS sizeof(FILE_OBJECTID_BUFFER) ); // OutputBuffer Length if (Status == STATUS_SUCCESS) { printf( "\nOid for this file is:" ); FsTestHexDump( ObjectIdBuffer->ObjectId, 16 ); printf( "\nExtended info is:" ); FsTestHexDump( ObjectIdBuffer->ObjectId, 64 ); } return FsTestDecipherStatus( Status ); } int FsTestGetFileId( IN HANDLE hFile, IN PFILE_INTERNAL_INFORMATION FileId ) { IO_STATUS_BLOCK IoStatusBlock; NTSTATUS Status; Status = NtQueryInformationFile( hFile, // file handle &IoStatusBlock, // iosb FileId, sizeof( FILE_INTERNAL_INFORMATION ), FileInternalInformation ); if (Status == STATUS_SUCCESS) { printf( "\nFile id for this file is:" ); FsTestHexDump( (PCHAR)FileId, 8 ); } return FsTestDecipherStatus( Status ); } int FsTestGetName ( HANDLE File ) { NTSTATUS Status; IO_STATUS_BLOCK IoStatusBlock; PFILE_NAME_INFORMATION FileName; WCHAR buffer[100]; FileName = (PFILE_NAME_INFORMATION) buffer; Status = NtQueryInformationFile( File, &IoStatusBlock, FileName, sizeof( buffer ), FileNameInformation ); if (Status == STATUS_SUCCESS) { printf( "\nFilename is: %.*lS", FileName->FileNameLength/sizeof(WCHAR), FileName->FileName ); } return FsTestDecipherStatus( Status ); } DWORD FsTestOpenVolumeHandle ( PWCHAR DriveLetter, HANDLE *VolumeHandle ) { WCHAR Volume[] = VOLUME_PATH; DWORD Status = 0; // // Open the volume for relative opens. // RtlCopyMemory( &Volume[VOLUME_DRIVE_LETTER_INDEX], DriveLetter, sizeof(WCHAR) ); *VolumeHandle = CreateFileW( (PUSHORT) &Volume, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if (*VolumeHandle == INVALID_HANDLE_VALUE) { Status = GetLastError(); printf( "Unable to open %ws volume\n", &Volume ); printf( "Error from CreateFile", Status ); return Status; } return Status; } NTSTATUS FsTestOpenFileById ( IN HANDLE VolumeHandle, IN PUNICODE_STRING FileId, OUT HANDLE *File ) { NTSTATUS Status; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; InitializeObjectAttributes( &ObjectAttributes, FileId, 0, VolumeHandle, NULL ); Status = NtCreateFile( File, GENERIC_READ, &ObjectAttributes, &IoStatusBlock, NULL, 0, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, FILE_OVERWRITE, FILE_OPEN_BY_FILE_ID, NULL, 0 ); if (!NT_SUCCESS( Status )) { FsTestDecipherStatus( Status ); return Status; } return Status; } VOID FsTestGenerateFullName ( IN PWCHAR DriveLetter, IN PUNICODE_STRING FileId, OUT PUNICODE_STRING FullName ) { WCHAR FullPath[] = FULL_PATH; UNICODE_STRING DeviceName; ASSERT( FullName->MaximumLength >= (DEVICE_PREFIX_LEN + FileId->Length) ); RtlCopyMemory( &FullPath[FULL_DRIVE_LETTER_INDEX], DriveLetter, sizeof(WCHAR) ); DeviceName.Length = DeviceName.MaximumLength = DEVICE_PREFIX_LEN; DeviceName.Buffer = FullPath; RtlCopyUnicodeString( FullName, &DeviceName ); RtlAppendUnicodeStringToString( FullName, FileId ); } VOID _cdecl main( int argc, char *argv[] ) { HANDLE File; HANDLE VolumeHandle = NULL; FILE_OBJECTID_BUFFER ObjectIdBuffer; FILE_INTERNAL_INFORMATION FileId; OBJECT_ATTRIBUTES ObjectAttributes; IO_STATUS_BLOCK IoStatusBlock; UNICODE_STRING IdString; NTSTATUS Status; WCHAR DriveLetter; WCHAR FullNameBuffer [100]; UNICODE_STRING FullName; // // Get parameters // if (argc < 3) { printf("This program finds the object id of a file and generates one if necessary (ntfs only), then prints out the file name once that file is opened by the ids.\n\n"); printf("usage: %s drive filename\n", argv[0]); return; } File = CreateFile( argv[2], 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if ( File == INVALID_HANDLE_VALUE ) { printf( "Error opening file %s %x\n", argv[2], GetLastError() ); return; } FsTestGetName( File ); RtlZeroBytes( &FileId, sizeof( FileId ) ); FsTestGetFileId( File, &FileId ); RtlZeroBytes( &ObjectIdBuffer, sizeof( ObjectIdBuffer ) ); FsTestGenOid( File, &ObjectIdBuffer ); CloseHandle( File ); DriveLetter = *argv[1]; #ifdef RELATIVE_OPEN FsTestOpenVolumeHandle( &DriveLetter, &VolumeHandle ); if (VolumeHandle == INVALID_HANDLE_VALUE) { goto main_exit; } #endif RtlInitEmptyUnicodeString( &FullName, FullNameBuffer, sizeof( FullNameBuffer ) ); printf( "\nReopening file by file id....\n" ); IdString.Length = IdString.MaximumLength = sizeof( LARGE_INTEGER ); IdString.Buffer = (PWSTR) &FileId; #ifdef RELATIVE_OPEN Status = FsTestOpenFileById( VolumeHandle, &IdString , &File ); #else FsTestGenerateFullName( &DriveLetter, &IdString, &FullName ); Status = FsTestOpenFileById( VolumeHandle, &FullName , &File ); #endif if (!NT_SUCCESS( Status )) { goto main_exit; } FsTestGetName( File ); NtClose( File ); printf( "\nReopening file by object id....\n" ); IdString.Length = IdString.MaximumLength = 16 * sizeof( UCHAR ); IdString.Buffer = (PWSTR) &(ObjectIdBuffer.ObjectId); #ifdef RELATIVE_OPEN Status = FsTestOpenFileById( VolumeHandle, &IdString , &File ); #else FsTestGenerateFullName( &DriveLetter, &IdString, &FullName ); Status = FsTestOpenFileById( VolumeHandle, &FullName , &File ); #endif if (!NT_SUCCESS( Status )) { goto main_exit; } FsTestGetName( File ); NtClose( File ); main_exit: if (VolumeHandle != NULL) { CloseHandle( VolumeHandle ); } }