windows-nt/Source/XPSP1/NT/base/fs/ntfs/fu/objectid.c
2020-09-26 16:20:57 +08:00

564 lines
12 KiB
C

/*++
Copyright (c) 2000 Microsoft Corporation
Module Name:
objectid.c
Abstract:
This file contains code for commands that affect object ids.
Author:
Wesley Witt [wesw] 1-March-2000
Revision History:
--*/
#include <precomp.h>
INT
ObjectIdHelp(
IN INT argc,
IN PWSTR argv[]
)
{
DisplayMsg( MSG_USAGE_OBJECTID );
return EXIT_CODE_SUCCESS;
}
VOID
PrintObjectId(
PFILE_OBJECTID_BUFFER lpOutBuffer
)
{
INT Index;
DisplayMsg( MSG_OBJECTID_TEXT );
for ( Index = 0 ; Index < 16 ; Index++ ) {
wprintf( L"%02x", lpOutBuffer->ObjectId[Index] );
}
wprintf( L"\n" );
DisplayMsg( MSG_BIRTHVOLID_TEXT );
for ( Index = 0 ; Index < 16 ; Index++ ) {
wprintf( L"%02x", lpOutBuffer->BirthVolumeId[Index] );
}
wprintf( L"\n" );
DisplayMsg( MSG_BIRTHOBJECTID_TEXT );
for ( Index = 0 ; Index < 16 ; Index++ ) {
wprintf( L"%02x", lpOutBuffer->BirthObjectId[Index] );
}
wprintf( L"\n" );
DisplayMsg( MSG_DOMAINID_TEXT );
for ( Index = 0 ; Index < 16 ; Index++ ) {
wprintf( L"%02x", lpOutBuffer->DomainId[Index] );
}
wprintf( L"\n" );
}
UCHAR
GetNibbleValue(
IN OUT PCWSTR *String
)
{
UCHAR v;
WCHAR c;
c = *(*String)++;
c = (UCHAR) toupper( c );
if (isdigit( c )) {
v = c - L'0';
} else if (isalpha( c ) && c <= L'F') {
v = c - L'A' + 10;
} else {
(*String)--;
return 0;
}
return v;
}
UCHAR
GetByteValue(
IN OUT PCWSTR *String
)
{
UCHAR v = GetNibbleValue( String );
v *= 16;
v += GetNibbleValue( String );
return v;
}
BOOL
ConvertStringToHexData(
IN PCWSTR Arg,
OUT PUCHAR Buffer
)
{
int i;
for (i = 0; i < 16; i++) {
Buffer[i] = GetByteValue( &Arg );
}
return *Arg == L'\0';
}
INT
SetObjectId(
IN INT argc,
IN PWSTR argv[]
)
/*++
Routine Description:
This routine sets the objectID for the file specified.
Arguments:
argc - The argument count.
argv - Array of Strings of the form :
' fscutl setoid <oid=val> <bvid=val> <boid=val> <did=val> <pathname>'.
Return Value:
None
--*/
{
PWSTR Filename = NULL;
HANDLE FileHandle = INVALID_HANDLE_VALUE;
PFILE_OBJECTID_BUFFER lpInBuffer = NULL;
BOOL Status;
DWORD nInBufferSize;
DWORD BytesReturned;
INT ExitCode = EXIT_CODE_SUCCESS;
try {
if (argc != 5) {
DisplayMsg( MSG_USAGE_SETOBJECTID );
if (argc != 0) {
ExitCode = EXIT_CODE_FAILURE;
}
leave;
}
Filename = GetFullPath( argv[4] );
if (!Filename) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
if (!IsVolumeLocalNTFS( Filename[0] )) {
DisplayMsg( MSG_NTFS_REQUIRED );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
nInBufferSize = sizeof(FILE_OBJECTID_BUFFER);
lpInBuffer = (PFILE_OBJECTID_BUFFER) malloc ( nInBufferSize );
if (lpInBuffer == NULL) {
DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
//
// Convert the input strings into the correct data
//
if (!ConvertStringToHexData( argv[0], lpInBuffer->ObjectId)
|| !ConvertStringToHexData( argv[1], lpInBuffer->BirthVolumeId)
|| !ConvertStringToHexData( argv[2], lpInBuffer->BirthObjectId)
|| !ConvertStringToHexData( argv[3], lpInBuffer->DomainId)) {
DisplayMsg( MSG_USAGE_SETOBJECTID );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
EnablePrivilege( SE_RESTORE_NAME );
FileHandle = CreateFile(
Filename,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS,
NULL
);
if (FileHandle == INVALID_HANDLE_VALUE) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
Status = DeviceIoControl(
FileHandle,
FSCTL_SET_OBJECT_ID,
(LPVOID) lpInBuffer,
nInBufferSize,
NULL,
0,
&BytesReturned,
(LPOVERLAPPED)NULL
);
if (!Status) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
} finally {
if (FileHandle != INVALID_HANDLE_VALUE) {
CloseHandle( FileHandle );
}
free(lpInBuffer);
free( Filename );
}
return ExitCode;
}
INT
GetObjectId(
IN INT argc,
IN PWSTR argv[]
)
/*++
Routine Description:
This routine gets the objectID associated with the file specified.
Arguments:
argc - The argument count.
argv - Array of Strings of the form :
' fscutl getoid <pathname> '.
Return Value:
None
--*/
{
HANDLE FileHandle = INVALID_HANDLE_VALUE;
PWSTR Filename = NULL;
PFILE_OBJECTID_BUFFER lpOutBuffer = NULL;
BOOL Status;
DWORD nOutBufferSize;
DWORD BytesReturned;
INT ExitCode = EXIT_CODE_SUCCESS;
try {
if (argc != 1) {
DisplayMsg( MSG_USAGE_GETOBJECTID );
if (argc != 0) {
ExitCode = EXIT_CODE_FAILURE;
}
leave;
}
Filename = GetFullPath( argv[0] );
if (!Filename) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
if (!IsVolumeNTFS( Filename )) {
DisplayMsg( MSG_NTFS_REQUIRED );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
nOutBufferSize = sizeof(FILE_OBJECTID_BUFFER);
lpOutBuffer = (PFILE_OBJECTID_BUFFER) malloc ( nOutBufferSize );
if (lpOutBuffer == NULL) {
DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
FileHandle = CreateFile(
Filename,
GENERIC_READ,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (FileHandle == INVALID_HANDLE_VALUE) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
Status = DeviceIoControl(
FileHandle,
FSCTL_GET_OBJECT_ID,
NULL,
0,
(LPVOID) lpOutBuffer,
nOutBufferSize,
&BytesReturned,
(LPOVERLAPPED)NULL
);
if (!Status) {
if (GetLastError( ) == ERROR_FILE_NOT_FOUND) {
DisplayMsg( MSG_NO_OBJECT_ID );
} else {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
}
leave;
}
PrintObjectId( lpOutBuffer );
} finally {
if (FileHandle != INVALID_HANDLE_VALUE) {
CloseHandle( FileHandle );
}
free(lpOutBuffer);
free( Filename );
}
return ExitCode;
}
INT
CreateOrGetObjectId(
IN INT argc,
IN PWSTR argv[]
)
/*++
Routine Description:
This routine gets the objectID for the file, if it exists, else
creates an objectID and returns it.
Arguments:
argc - The argument count.
argv - Array of Strings of the form :
' fscutl crgetoid <pathname>'.
Return Value:
None
--*/
{
PWSTR Filename = NULL;
HANDLE FileHandle = INVALID_HANDLE_VALUE;
PFILE_OBJECTID_BUFFER lpOutBuffer = NULL;
BOOL Status;
DWORD nOutBufferSize;
DWORD BytesReturned;
INT ExitCode = EXIT_CODE_SUCCESS;
try {
if (argc != 1) {
DisplayMsg( MSG_USAGE_CREATEOBJECTID );
if (argc != 0) {
ExitCode = EXIT_CODE_FAILURE;
}
leave;
}
Filename = GetFullPath( argv[0] );
if (!Filename) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
if (!IsVolumeLocalNTFS( Filename[0] )) {
DisplayMsg( MSG_NTFS_REQUIRED );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
nOutBufferSize = sizeof(FILE_OBJECTID_BUFFER);
lpOutBuffer = (PFILE_OBJECTID_BUFFER) malloc ( nOutBufferSize );
if (lpOutBuffer == NULL) {
DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
FileHandle = CreateFile(
Filename,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (FileHandle == INVALID_HANDLE_VALUE) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
Status = DeviceIoControl(
FileHandle,
FSCTL_CREATE_OR_GET_OBJECT_ID,
NULL,
0,
(LPVOID) lpOutBuffer,
nOutBufferSize,
&BytesReturned,
(LPOVERLAPPED)NULL
);
if (!Status) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
PrintObjectId( lpOutBuffer );
} finally {
if (FileHandle != INVALID_HANDLE_VALUE) {
CloseHandle( FileHandle );
}
if (lpOutBuffer) {
free(lpOutBuffer);
}
if (Filename) {
free( Filename );
}
}
return ExitCode;
}
INT
DeleteObjectId(
IN INT argc,
IN PWSTR argv[]
)
/*++
Routine Description:
This routine deletes the objectID associated with the file
specified.
Arguments:
argc - The argument count.
argv - Array of Strings of the form :
' fscutl deloid <pathname>'.
Return Value:
None
--*/
{
HANDLE FileHandle = INVALID_HANDLE_VALUE;
PWSTR Filename = NULL;
BOOL Status;
DWORD BytesReturned;
INT ExitCode = EXIT_CODE_SUCCESS;
try {
if (argc != 1) {
DisplayMsg( MSG_USAGE_DELETEOBJECTID );
if (argc != 0) {
ExitCode = EXIT_CODE_FAILURE;}
leave;
}
Filename = GetFullPath( argv[0] );
if (!Filename) {
DisplayError();
if (argc != 0) {
ExitCode = EXIT_CODE_FAILURE;
}
leave;
}
if (!IsVolumeLocalNTFS( Filename[0] )) {
DisplayMsg( MSG_NTFS_REQUIRED );
ExitCode = EXIT_CODE_FAILURE;
leave;
}
FileHandle = CreateFile(
Filename,
GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (FileHandle == INVALID_HANDLE_VALUE) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
Status = DeviceIoControl(
FileHandle,
FSCTL_DELETE_OBJECT_ID,
NULL,
0,
NULL,
0,
&BytesReturned,
(LPOVERLAPPED)NULL
);
if (!Status) {
DisplayError();
ExitCode = EXIT_CODE_FAILURE;
leave;
}
} finally {
if (FileHandle != INVALID_HANDLE_VALUE) {
CloseHandle( FileHandle );
}
free( Filename );
}
return ExitCode;
}