338 lines
7.9 KiB
C
338 lines
7.9 KiB
C
|
/*++
|
||
|
|
||
|
Copyright (c) 2000 Microsoft Corporation
|
||
|
|
||
|
Module Name:
|
||
|
|
||
|
reparse.c
|
||
|
|
||
|
Abstract:
|
||
|
|
||
|
This file contains code for commands that affect
|
||
|
reparse points.
|
||
|
|
||
|
Author:
|
||
|
|
||
|
Wesley Witt [wesw] 1-March-2000
|
||
|
|
||
|
Revision History:
|
||
|
|
||
|
--*/
|
||
|
|
||
|
#include <precomp.h>
|
||
|
|
||
|
|
||
|
INT
|
||
|
ReparseHelp(
|
||
|
IN INT argc,
|
||
|
IN PWSTR argv[]
|
||
|
)
|
||
|
{
|
||
|
DisplayMsg( MSG_USAGE_REPARSEPOINT );
|
||
|
return EXIT_CODE_SUCCESS;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// Microsoft tags for reparse points.
|
||
|
//
|
||
|
|
||
|
#define MAX_REPARSE_DATA 0x1000
|
||
|
|
||
|
INT
|
||
|
GetReparsePoint(
|
||
|
IN INT argc,
|
||
|
IN PWSTR argv[]
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine gets the reparse point for the file specified.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
argc - The argument count.
|
||
|
argv - Array of Strings of the form :
|
||
|
' fscutl getrp <pathname>'.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
PWSTR Filename = NULL;
|
||
|
HANDLE FileHandle = INVALID_HANDLE_VALUE;
|
||
|
PREPARSE_GUID_DATA_BUFFER lpOutBuffer = NULL;
|
||
|
BOOL Status;
|
||
|
DWORD nOutBufferSize;
|
||
|
DWORD BytesReturned;
|
||
|
ULONG ulMask;
|
||
|
WCHAR Buffer[256];
|
||
|
LPWSTR GuidStr;
|
||
|
INT ExitCode = EXIT_CODE_SUCCESS;
|
||
|
|
||
|
try {
|
||
|
|
||
|
if (argc != 1) {
|
||
|
DisplayMsg( MSG_USAGE_GETREPARSE );
|
||
|
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 = REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + MAX_REPARSE_DATA;
|
||
|
lpOutBuffer = (PREPARSE_GUID_DATA_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_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
|
||
|
NULL
|
||
|
);
|
||
|
if (FileHandle == INVALID_HANDLE_VALUE) {
|
||
|
DisplayError();
|
||
|
ExitCode = EXIT_CODE_FAILURE;
|
||
|
leave;
|
||
|
}
|
||
|
|
||
|
Status = DeviceIoControl(
|
||
|
FileHandle,
|
||
|
FSCTL_GET_REPARSE_POINT,
|
||
|
NULL,
|
||
|
0,
|
||
|
(LPVOID) lpOutBuffer,
|
||
|
nOutBufferSize,
|
||
|
&BytesReturned,
|
||
|
(LPOVERLAPPED)NULL
|
||
|
);
|
||
|
if (!Status) {
|
||
|
DisplayError();
|
||
|
ExitCode = EXIT_CODE_FAILURE;
|
||
|
leave;
|
||
|
}
|
||
|
|
||
|
DisplayMsg( MSG_GETREPARSE_TAGVAL, lpOutBuffer->ReparseTag );
|
||
|
|
||
|
if (IsReparseTagMicrosoft( lpOutBuffer->ReparseTag )) {
|
||
|
DisplayMsg( MSG_TAG_MICROSOFT );
|
||
|
}
|
||
|
if (IsReparseTagNameSurrogate( lpOutBuffer->ReparseTag )) {
|
||
|
DisplayMsg( MSG_TAG_NAME_SURROGATE );
|
||
|
}
|
||
|
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_SYMBOLIC_LINK) {
|
||
|
DisplayMsg( MSG_TAG_SYMBOLIC_LINK );
|
||
|
}
|
||
|
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
|
||
|
DisplayMsg( MSG_TAG_MOUNT_POINT );
|
||
|
}
|
||
|
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_HSM) {
|
||
|
DisplayMsg( MSG_TAG_HSM );
|
||
|
}
|
||
|
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_SIS) {
|
||
|
DisplayMsg( MSG_TAG_SIS );
|
||
|
}
|
||
|
if (lpOutBuffer->ReparseTag == IO_REPARSE_TAG_FILTER_MANAGER) {
|
||
|
DisplayMsg( MSG_TAG_FILTER_MANAGER );
|
||
|
}
|
||
|
|
||
|
Status = StringFromIID( &lpOutBuffer->ReparseGuid, &GuidStr );
|
||
|
if (Status != S_OK) {
|
||
|
DisplayErrorMsg( Status );
|
||
|
ExitCode = EXIT_CODE_FAILURE;
|
||
|
leave;
|
||
|
}
|
||
|
|
||
|
DisplayMsg( MSG_GETREPARSE_GUID, GuidStr, lpOutBuffer->ReparseDataLength );
|
||
|
|
||
|
if (lpOutBuffer->ReparseDataLength != 0) {
|
||
|
int i, j;
|
||
|
WCHAR Buf[17];
|
||
|
|
||
|
DisplayMsg( MSG_GETREPARSE_DATA );
|
||
|
for (i = 0; i < lpOutBuffer->ReparseDataLength; i += 16 ) {
|
||
|
wprintf( L"%04x: ", i );
|
||
|
for (j = 0; j < 16 && j + i < lpOutBuffer->ReparseDataLength; j++) {
|
||
|
UCHAR c = lpOutBuffer->GenericReparseBuffer.DataBuffer[ i + j ];
|
||
|
|
||
|
if (c >= 0x20 && c <= 0x7F) {
|
||
|
Buf[j] = c;
|
||
|
} else {
|
||
|
Buf[j] = L'.';
|
||
|
}
|
||
|
|
||
|
wprintf( L" %02x", c );
|
||
|
}
|
||
|
|
||
|
Buf[j] = L'\0';
|
||
|
|
||
|
for ( ; j < 16; j++ ) {
|
||
|
wprintf( L" " );
|
||
|
}
|
||
|
|
||
|
wprintf( L" %s\n", Buf );
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
CoTaskMemFree(GuidStr);
|
||
|
|
||
|
} finally {
|
||
|
|
||
|
if (FileHandle != INVALID_HANDLE_VALUE) {
|
||
|
CloseHandle( FileHandle );
|
||
|
}
|
||
|
free( lpOutBuffer );
|
||
|
free( Filename );
|
||
|
}
|
||
|
return ExitCode;
|
||
|
}
|
||
|
|
||
|
|
||
|
INT
|
||
|
DeleteReparsePoint(
|
||
|
IN INT argc,
|
||
|
IN PWSTR argv[]
|
||
|
)
|
||
|
/*++
|
||
|
|
||
|
Routine Description:
|
||
|
|
||
|
This routine deletes the reparse point associated with
|
||
|
the file specified.
|
||
|
|
||
|
Arguments:
|
||
|
|
||
|
argc - The argument count.
|
||
|
argv - Array of Strings of the form :
|
||
|
' fscutl delrp <pathname>'.
|
||
|
|
||
|
Return Value:
|
||
|
|
||
|
None
|
||
|
|
||
|
--*/
|
||
|
{
|
||
|
BOOL Status;
|
||
|
PWSTR Filename = NULL;
|
||
|
HANDLE FileHandle = INVALID_HANDLE_VALUE;
|
||
|
PREPARSE_GUID_DATA_BUFFER lpInOutBuffer = NULL;
|
||
|
DWORD nInOutBufferSize;
|
||
|
DWORD BytesReturned;
|
||
|
INT ExitCode = EXIT_CODE_SUCCESS;
|
||
|
|
||
|
try {
|
||
|
|
||
|
if (argc != 1) {
|
||
|
DisplayMsg( MSG_DELETE_REPARSE );
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
nInOutBufferSize = REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + MAX_REPARSE_DATA;
|
||
|
lpInOutBuffer = (PREPARSE_GUID_DATA_BUFFER) malloc ( nInOutBufferSize );
|
||
|
if (lpInOutBuffer == NULL) {
|
||
|
DisplayErrorMsg( ERROR_NOT_ENOUGH_MEMORY );
|
||
|
ExitCode = EXIT_CODE_FAILURE;
|
||
|
leave;
|
||
|
}
|
||
|
|
||
|
FileHandle = CreateFile(
|
||
|
Filename,
|
||
|
GENERIC_WRITE,
|
||
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS,
|
||
|
NULL
|
||
|
);
|
||
|
if (FileHandle == INVALID_HANDLE_VALUE) {
|
||
|
DisplayError();
|
||
|
ExitCode = EXIT_CODE_FAILURE;
|
||
|
leave;
|
||
|
}
|
||
|
|
||
|
Status = DeviceIoControl(
|
||
|
FileHandle,
|
||
|
FSCTL_GET_REPARSE_POINT,
|
||
|
NULL,
|
||
|
0,
|
||
|
(LPVOID) lpInOutBuffer,
|
||
|
nInOutBufferSize,
|
||
|
&BytesReturned,
|
||
|
(LPOVERLAPPED)NULL
|
||
|
);
|
||
|
if (!Status) {
|
||
|
DisplayError();
|
||
|
ExitCode = EXIT_CODE_FAILURE;
|
||
|
leave;
|
||
|
}
|
||
|
|
||
|
lpInOutBuffer->ReparseDataLength = 0;
|
||
|
|
||
|
Status = DeviceIoControl(
|
||
|
FileHandle,
|
||
|
FSCTL_DELETE_REPARSE_POINT,
|
||
|
(LPVOID) lpInOutBuffer,
|
||
|
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,
|
||
|
NULL,
|
||
|
0,
|
||
|
&BytesReturned,
|
||
|
(LPOVERLAPPED)NULL
|
||
|
);
|
||
|
if (!Status) {
|
||
|
DisplayError();
|
||
|
ExitCode = EXIT_CODE_FAILURE;
|
||
|
}
|
||
|
|
||
|
} finally {
|
||
|
|
||
|
if (FileHandle != INVALID_HANDLE_VALUE) {
|
||
|
CloseHandle( FileHandle );
|
||
|
}
|
||
|
free( lpInOutBuffer );
|
||
|
free( Filename );
|
||
|
}
|
||
|
|
||
|
return ExitCode;
|
||
|
}
|