303 lines
6.1 KiB
C++
303 lines
6.1 KiB
C++
/*++
|
||
|
||
Copyright (c) 1989-1997 Microsoft Corporation
|
||
|
||
Module Name:
|
||
|
||
enumfile.c
|
||
|
||
Abstract:
|
||
|
||
This module contains tests for enumeration-by-fileref and bulk security test
|
||
|
||
--*/
|
||
|
||
|
||
extern "C" {
|
||
#include <nt.h>
|
||
#include <ntioapi.h>
|
||
#include <ntrtl.h>
|
||
#include <nturtl.h>
|
||
}
|
||
|
||
#include <windows.h>
|
||
|
||
#include <stdio.h>
|
||
|
||
#include <ddeml.h> // for CP_WINUNICODE
|
||
|
||
#include <objidl.h>
|
||
|
||
extern "C"
|
||
{
|
||
#include <propapi.h>
|
||
}
|
||
|
||
#include <stgprop.h>
|
||
|
||
#include <stgvar.hxx>
|
||
#include <propstm.hxx>
|
||
#include <align.hxx>
|
||
#include <sstream.hxx>
|
||
|
||
#define Add2Ptr(P,I) ((PVOID)((PUCHAR)(P) + (I)))
|
||
|
||
#define QuadAlign(P) ( \
|
||
((((ULONG)(P)) + 7) & 0xfffffff8) \
|
||
)
|
||
|
||
|
||
//
|
||
// Simple wrapper for NtCreateFile
|
||
//
|
||
|
||
NTSTATUS
|
||
OpenObject (
|
||
WCHAR const *pwszFile,
|
||
ULONG CreateOptions,
|
||
ULONG DesiredAccess,
|
||
ULONG ShareAccess,
|
||
ULONG CreateDisposition,
|
||
HANDLE *ph)
|
||
{
|
||
NTSTATUS Status;
|
||
OBJECT_ATTRIBUTES oa;
|
||
UNICODE_STRING str;
|
||
IO_STATUS_BLOCK isb;
|
||
|
||
RtlDosPathNameToNtPathName_U(pwszFile, &str, NULL, NULL);
|
||
|
||
InitializeObjectAttributes(
|
||
&oa,
|
||
&str,
|
||
OBJ_CASE_INSENSITIVE,
|
||
NULL,
|
||
NULL);
|
||
|
||
Status = NtCreateFile(
|
||
ph,
|
||
DesiredAccess | SYNCHRONIZE,
|
||
&oa,
|
||
&isb,
|
||
NULL, // pallocationsize (none!)
|
||
FILE_ATTRIBUTE_NORMAL,
|
||
ShareAccess,
|
||
CreateDisposition,
|
||
CreateOptions,
|
||
NULL, // EA buffer (none!)
|
||
0);
|
||
|
||
RtlFreeHeap(RtlProcessHeap(), 0, str.Buffer);
|
||
return(Status);
|
||
}
|
||
|
||
|
||
void
|
||
SzToWsz (
|
||
OUT WCHAR *Unicode,
|
||
IN char *Ansi
|
||
)
|
||
{
|
||
while (*Unicode++ = *Ansi++)
|
||
;
|
||
}
|
||
|
||
|
||
void
|
||
BulkSecurityTest (
|
||
char *FileName
|
||
)
|
||
{
|
||
NTSTATUS Status;
|
||
HANDLE Handle;
|
||
WCHAR WFileName[MAX_PATH];
|
||
IO_STATUS_BLOCK Iosb;
|
||
|
||
|
||
//
|
||
// Open the file
|
||
//
|
||
|
||
SzToWsz( WFileName, FileName );
|
||
|
||
Status = OpenObject( WFileName,
|
||
FILE_SYNCHRONOUS_IO_NONALERT,
|
||
FILE_READ_DATA | FILE_WRITE_DATA,
|
||
FALSE,
|
||
FILE_OPEN,
|
||
&Handle );
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
printf( "Unable to open %s - %x\n", FileName, Status );
|
||
return;
|
||
}
|
||
|
||
#define SECURITY_COUNT 10
|
||
char InputBuffer[sizeof( BULK_SECURITY_TEST_DATA ) - sizeof( ULONG ) + SECURITY_COUNT * sizeof( ULONG )];
|
||
PBULK_SECURITY_TEST_DATA SecurityData = (PBULK_SECURITY_TEST_DATA) InputBuffer;
|
||
|
||
SecurityData->DesiredAccess = FILE_READ_DATA | FILE_WRITE_DATA;
|
||
for (int i = 0; i < SECURITY_COUNT; i++) {
|
||
SecurityData->SecurityIds[i] = 0xFF + i;
|
||
}
|
||
|
||
NTSTATUS Output[SECURITY_COUNT];
|
||
|
||
Status = NtFsControlFile(
|
||
Handle,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&Iosb,
|
||
FSCTL_SECURITY_ID_CHECK,
|
||
&InputBuffer,
|
||
sizeof( InputBuffer ),
|
||
Output,
|
||
sizeof( Output ));
|
||
|
||
printf( "Bulk test returned %x\n", Status );
|
||
for (i = 0; i < SECURITY_COUNT; i++) {
|
||
printf( " Status[%d] = %x\n", i, Output[i] );
|
||
}
|
||
|
||
NtClose( Handle );
|
||
}
|
||
|
||
void
|
||
EnumFile (
|
||
char *FileName
|
||
)
|
||
{
|
||
NTSTATUS Status;
|
||
HANDLE Handle;
|
||
WCHAR WFileName[MAX_PATH];
|
||
char InputBuffer[10];
|
||
char OutputBuffer[200];
|
||
IO_STATUS_BLOCK Iosb;
|
||
|
||
|
||
//
|
||
// Open the file
|
||
//
|
||
|
||
SzToWsz( WFileName, FileName );
|
||
|
||
Status = OpenObject( WFileName,
|
||
FILE_SYNCHRONOUS_IO_NONALERT,
|
||
FILE_READ_DATA | FILE_WRITE_DATA,
|
||
FALSE,
|
||
FILE_OPEN,
|
||
&Handle );
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
printf( "Unable to open %s - %x\n", FileName, Status );
|
||
return;
|
||
}
|
||
|
||
//
|
||
// Set up input data
|
||
//
|
||
|
||
MFT_ENUM_DATA EnumData = { 1, 0, 1 };
|
||
|
||
//
|
||
// Set up output buffer
|
||
//
|
||
|
||
BYTE Output[4096];
|
||
|
||
while (TRUE) {
|
||
|
||
Status = NtFsControlFile(
|
||
Handle,
|
||
NULL,
|
||
NULL,
|
||
NULL,
|
||
&Iosb,
|
||
FSCTL_ENUM_USN_DATA,
|
||
&EnumData,
|
||
sizeof( EnumData ),
|
||
Output,
|
||
sizeof( Output ));
|
||
|
||
if (!NT_SUCCESS( Status )) {
|
||
printf( "NtfsControlFile returned %x\n", Status );
|
||
break;
|
||
}
|
||
|
||
//
|
||
// Display output buffer
|
||
//
|
||
|
||
printf( "Length is %x\n", Iosb.Information );
|
||
|
||
if (Iosb.Information < sizeof( ULONGLONG ) + sizeof( USN_RECORD )) {
|
||
break;
|
||
}
|
||
|
||
printf( "Next file reference is %16I64x\n", *(PULONGLONG)Output );
|
||
|
||
PUSN_RECORD UsnRecord = (PUSN_RECORD) (Output + sizeof( ULONGLONG ));
|
||
|
||
while ((PBYTE)UsnRecord < Output + Iosb.Information) {
|
||
printf( "FR %16I64x Parent %016I64x Usn %016I64x SecurityId %08x Reason %08x Name(%d): '%.*ws'\n",
|
||
UsnRecord->FileReferenceNumber,
|
||
UsnRecord->ParentFileReferenceNumber,
|
||
UsnRecord->Usn,
|
||
UsnRecord->SecurityId,
|
||
UsnRecord->Reason,
|
||
UsnRecord->FileNameLength,
|
||
UsnRecord->FileNameLength / sizeof( WCHAR ),
|
||
UsnRecord->FileName );
|
||
|
||
ULONG Length = sizeof( USN_RECORD ) + UsnRecord->FileNameLength - sizeof( WCHAR );
|
||
Length = QuadAlign( Length );
|
||
UsnRecord = (PUSN_RECORD) Add2Ptr( UsnRecord, Length );
|
||
}
|
||
|
||
EnumData.StartFileReferenceNumber = *(PLONGLONG)Output;
|
||
}
|
||
|
||
|
||
//
|
||
// Close the file
|
||
//
|
||
|
||
Status = NtClose( Handle );
|
||
if (!NT_SUCCESS( Status )) {
|
||
printf( "Unable to close %s - %x\n", FileName, Status );
|
||
}
|
||
|
||
}
|
||
|
||
|
||
|
||
|
||
#define SHIFT(c,v) ((c)--,(v)++)
|
||
|
||
int __cdecl
|
||
main (
|
||
int argc,
|
||
char **argv)
|
||
{
|
||
SHIFT( argc, argv );
|
||
|
||
if (argc > 0) {
|
||
if (!strcmp( *argv, "-e")) {
|
||
|
||
SHIFT( argc, argv );
|
||
|
||
while (argc != 0) {
|
||
EnumFile( *argv );
|
||
SHIFT( argc, argv );
|
||
}
|
||
} else {
|
||
BulkSecurityTest( *argv );
|
||
}
|
||
}
|
||
|
||
return 0;
|
||
}
|
||
|
||
|