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.
303 lines
8.3 KiB
303 lines
8.3 KiB
// 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 );
|
|
}
|
|
}
|