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.
327 lines
6.8 KiB
327 lines
6.8 KiB
|
|
#include <stdio.h>
|
|
#include <stdlib.h> // exit
|
|
#include <io.h> // _get_osfhandle
|
|
#include <nt.h>
|
|
#include <ntrtl.h>
|
|
#include <nturtl.h>
|
|
#include <ntioapi.h>
|
|
#include <windef.h>
|
|
#include <winbase.h>
|
|
|
|
|
|
VOID
|
|
PrintError(
|
|
DWORD Error
|
|
)
|
|
{
|
|
LPVOID lpMsgBuf = NULL;
|
|
|
|
FormatMessage(
|
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
|
NULL,
|
|
Error,
|
|
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
|
|
(LPTSTR) &lpMsgBuf,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
printf("%ws\n",lpMsgBuf);
|
|
|
|
LocalFree( lpMsgBuf );
|
|
|
|
}
|
|
|
|
VOID
|
|
Usage(
|
|
PCHAR AppName,
|
|
DWORD ExitStatus
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Print usage and exit
|
|
|
|
Arguments:
|
|
ExitStatus - exits with this status
|
|
|
|
Return Value:
|
|
Exit(ExitStatus)
|
|
--*/
|
|
{
|
|
printf("%s create <filename> <reparse tag value in hex> <reparse point value in quotes>\n",
|
|
AppName);
|
|
printf("\n");
|
|
printf("%s read <filename>\n", AppName);
|
|
printf("\n");
|
|
printf("%s delete <filename>\n", AppName);
|
|
printf("\n");
|
|
|
|
exit(ExitStatus);
|
|
}
|
|
|
|
VOID
|
|
DeleteReparsePoint(
|
|
IN DWORD argc,
|
|
IN PCHAR *argv
|
|
)
|
|
{
|
|
HANDLE File = INVALID_HANDLE_VALUE;
|
|
PREPARSE_GUID_DATA_BUFFER ReparsePointData = NULL;
|
|
DWORD BytesReturned = 0;
|
|
CHAR *Data = NULL;
|
|
REPARSE_GUID_DATA_BUFFER Header;
|
|
DWORD WStatus = ERROR_SUCCESS;
|
|
|
|
ReparsePointData = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
|
|
|
if(!ReparsePointData) {
|
|
printf("Out of memory.\n");
|
|
exit(1);
|
|
}
|
|
|
|
File = CreateFileA(argv[2],
|
|
MAXIMUM_ALLOWED,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS ,
|
|
NULL
|
|
);
|
|
|
|
if(File == INVALID_HANDLE_VALUE) {
|
|
WStatus = GetLastError();
|
|
printf("Error opening file %s: %d\n", argv[2], WStatus);
|
|
PrintError(WStatus);
|
|
free(ReparsePointData);
|
|
exit(1);
|
|
}
|
|
|
|
if(!DeviceIoControl(File,
|
|
FSCTL_GET_REPARSE_POINT,
|
|
NULL,
|
|
0,
|
|
ReparsePointData,
|
|
MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
|
|
&BytesReturned,
|
|
NULL
|
|
)) {
|
|
WStatus = GetLastError();
|
|
printf("Error reading reparse point data: %d\n", WStatus);
|
|
PrintError(WStatus);
|
|
CloseHandle(File);
|
|
free(ReparsePointData);
|
|
exit(1);
|
|
}
|
|
|
|
Header.ReparseGuid = ReparsePointData->ReparseGuid;
|
|
Header.ReparseTag = ReparsePointData->ReparseTag;
|
|
Header.ReparseDataLength = 0;
|
|
|
|
if(!DeviceIoControl(File,
|
|
FSCTL_DELETE_REPARSE_POINT,
|
|
&Header,
|
|
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE,
|
|
NULL,
|
|
0,
|
|
&BytesReturned,
|
|
NULL
|
|
)) {
|
|
WStatus = GetLastError();
|
|
printf("Error deleting reparse point data: %d\n", WStatus);
|
|
PrintError(WStatus);
|
|
CloseHandle(File);
|
|
free(ReparsePointData);
|
|
exit(1);
|
|
}
|
|
|
|
|
|
CloseHandle(File);
|
|
/*
|
|
if(!DeleteFileA(argv[2])){
|
|
WStatus = GetLastError();
|
|
printf("Error deleting file %s: %d\n", argv[2], WStatus);
|
|
PrintError(WStatus);
|
|
CloseHandle(File);
|
|
free(ReparsePointData);
|
|
exit(1);
|
|
}
|
|
*/
|
|
free(ReparsePointData);
|
|
}
|
|
|
|
VOID
|
|
ReadReparsePoint(
|
|
IN DWORD argc,
|
|
IN PCHAR *argv
|
|
)
|
|
{
|
|
HANDLE File = INVALID_HANDLE_VALUE;
|
|
PREPARSE_GUID_DATA_BUFFER ReparsePointData = NULL;
|
|
DWORD BytesReturned = 0;
|
|
CHAR *Data = NULL;
|
|
DWORD WStatus = ERROR_SUCCESS;
|
|
|
|
ReparsePointData = malloc(MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
|
|
|
|
if(!ReparsePointData) {
|
|
printf("Out of memory.\n");
|
|
exit(1);
|
|
}
|
|
|
|
File = CreateFileA(argv[2],
|
|
MAXIMUM_ALLOWED,
|
|
0,
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS ,
|
|
NULL
|
|
);
|
|
|
|
if(File == INVALID_HANDLE_VALUE) {
|
|
WStatus = GetLastError();
|
|
printf("Error opening file %s: %d\n", argv[2], WStatus);
|
|
PrintError(WStatus);
|
|
exit(1);
|
|
}
|
|
|
|
if(!DeviceIoControl(File,
|
|
FSCTL_GET_REPARSE_POINT,
|
|
NULL,
|
|
0,
|
|
ReparsePointData,
|
|
MAXIMUM_REPARSE_DATA_BUFFER_SIZE,
|
|
&BytesReturned,
|
|
NULL
|
|
)) {
|
|
WStatus = GetLastError();
|
|
printf("Error reading reparse point data: %d\n", WStatus);
|
|
PrintError(WStatus);
|
|
CloseHandle(File);
|
|
exit(1);
|
|
}
|
|
|
|
CloseHandle(File);
|
|
|
|
printf("Reparse tag = 0x%08x\n", ReparsePointData->ReparseTag);
|
|
Data = (CHAR *)&(ReparsePointData->GenericReparseBuffer.DataBuffer);
|
|
Data[ReparsePointData->ReparseDataLength] = '\0';
|
|
printf("Reparse data = \"%s\"\n", Data);
|
|
printf("\n");
|
|
|
|
free(ReparsePointData);
|
|
|
|
}
|
|
|
|
VOID
|
|
CreateReparsePoint(
|
|
IN DWORD argc,
|
|
IN PCHAR *argv
|
|
)
|
|
{
|
|
ULONG TagValue = 0;
|
|
HANDLE File = INVALID_HANDLE_VALUE;
|
|
PREPARSE_GUID_DATA_BUFFER ReparsePointData = NULL;
|
|
DWORD BytesReturned = 0;
|
|
USHORT DataSize = strlen(argv[4]) + sizeof(char);
|
|
DWORD WStatus = ERROR_SUCCESS;
|
|
|
|
sscanf(argv[3],"%x", &TagValue);
|
|
|
|
ReparsePointData = malloc(REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + DataSize);
|
|
|
|
if(!ReparsePointData) {
|
|
printf("Out of memory.\n");
|
|
exit(1);
|
|
}
|
|
|
|
ReparsePointData->ReparseTag = TagValue;
|
|
ReparsePointData->ReparseDataLength = DataSize;
|
|
|
|
memcpy(&(ReparsePointData->GenericReparseBuffer.DataBuffer), argv[4], DataSize );
|
|
|
|
File = CreateFileA(argv[2],
|
|
MAXIMUM_ALLOWED,
|
|
0,
|
|
NULL,
|
|
OPEN_ALWAYS,
|
|
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS ,
|
|
NULL
|
|
);
|
|
|
|
if(File == INVALID_HANDLE_VALUE) {
|
|
WStatus = GetLastError();
|
|
printf("Error opening file %s: %d\n", argv[2], WStatus);
|
|
PrintError(WStatus);
|
|
free(ReparsePointData);
|
|
exit(1);
|
|
}
|
|
|
|
if(!DeviceIoControl(File,
|
|
FSCTL_SET_REPARSE_POINT,
|
|
ReparsePointData,
|
|
REPARSE_GUID_DATA_BUFFER_HEADER_SIZE + DataSize,
|
|
NULL,
|
|
0,
|
|
&BytesReturned,
|
|
NULL
|
|
)) {
|
|
WStatus = GetLastError();
|
|
printf("Error setting reparse point data: %d\n", WStatus);
|
|
PrintError(WStatus);
|
|
CloseHandle(File);
|
|
free(ReparsePointData);
|
|
exit(1);
|
|
}
|
|
|
|
CloseHandle(File);
|
|
free(ReparsePointData);
|
|
|
|
}
|
|
|
|
|
|
VOID _cdecl
|
|
main(
|
|
IN DWORD argc,
|
|
IN PCHAR *argv
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
Process the command line.
|
|
|
|
Arguments:
|
|
argc
|
|
argv
|
|
|
|
Return Value:
|
|
Exits with 0 if everything went okay. Otherwise, 1.
|
|
--*/
|
|
{
|
|
|
|
//
|
|
// Print usage and exit
|
|
//
|
|
if (argc <= 2 ) {
|
|
Usage(argv[0], 0);
|
|
}
|
|
|
|
//
|
|
// Find the subcommand
|
|
//
|
|
if (!strcmp(argv[1], "create") && (argc == 5)) {
|
|
CreateReparsePoint(argc, argv);
|
|
} else if (!strcmp(argv[1], "read") && (argc == 3)) {
|
|
ReadReparsePoint(argc, argv);
|
|
} else if (!strcmp(argv[1], "delete") && (argc == 3)) {
|
|
DeleteReparsePoint(argc, argv);
|
|
} else if (!strcmp(argv[1], "/?")) {
|
|
Usage(argv[0], 0);
|
|
} else {
|
|
fprintf(stderr, "Invalid usage.\n");
|
|
Usage(argv[0], 0);
|
|
}
|
|
exit(0);
|
|
}
|
|
|