WindowsXP-SP1/base/fs/ntfs/tests/enumfile.cxx
2020-09-30 16:53:49 +02:00

303 lines
6.4 KiB
C++
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*++
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;
}