Abnormal Problem!

I made a function(including ZwReadFile internally) that read contents of
specification file(for example, c:\test.txt).
This function acted well, without problem.

By the way, If i try to call this function in the
FilemonHookRoutine(Dispatch-Routine of “FileMon of sysinternlas.com”),
BSOD appears.
Finally, My computer(Windows 2000) downed.
Error code was “0X0000007F(0X0000008, 0X0000000, 0X0000000, 0X0000000)”,
UNEXPECTED_KERNEL_MODE_TRAP.
It was Double-Fault message.
Assemble-code(taken by debugging tool) was MOV EBP, ESP.

Why does this phenomenon happen?
How can i solve this problem.

Thanks for any suggestions!
Sincerely!
Chang Sung, Jung.


Source code is following.

FilemonHookRoutine

NTSTATUS
FilemonHookRoutine(
PDEVICE_OBJECT HookDevice,
IN PIRP Irp
)
{
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
PMOVE_FILE_DATA moveFile;
PQUERY_DIRECTORY queryDirectory;
PFILE_OBJECT FileObject;
PHOOK_EXTENSION hookExt;
LARGE_INTEGER dateTime;
LARGE_INTEGER perfTime;
PCHAR fullPathName = NULL;
BOOLEAN hookCompletion, createPath;
CHAR controlCodeBuffer[ERRORLEN];
CHAR attributeString[ERRORLEN];
CHAR optionString[ERRORLEN];
CHAR name[PROCNAMELEN];
ULONG i;
ANSI_STRING directoryFilter;
PCHAR queryFilter;
ULONG seqNum;
KIRQL oldirql;
// Extract the file object from the IRP
FileObject = currentIrpStack->FileObject;
// Point at the device extension, which contains information on which
// file system this IRP is headed for
hookExt = HookDevice->DeviceExtension;
// We note open cases so that when we query the file name
// we don’t ask the file system for the name (since it won’t
// have seen the file object yet).
if( currentIrpStack->MajorFunction == IRP_MJ_CREATE ||
currentIrpStack->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE ||
currentIrpStack->MajorFunction == IRP_MJ_CREATE_MAILSLOT ) {
// Clear any existing fileobject/name association stored in the
// hash table
FilemonFreeHashEntry( FileObject );
createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLOSE ) {
// We treat close as a special case of create for name querying
// since calling into NTFS during a close can result in a
deadlock.
createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLEANUP &&
FileObject->Flags & FO_STREAM_FILE ) {
// Treat cleanup of stream file objects as special create case,
because
// querying them causes NTFS to screwup on NT 4
//
createPath = TRUE;
} else {
createPath = FALSE;
}
// Allocate a buffer and get the name only if we have to
if( FilterOn && hookExt->Hooked ) {

GETPATHNAME( createPath );
}
// Only log it if it passes the filter
if( hookExt->Hooked && fullPathName ) {
// If measuring absolute time go and get the timestamp.
KeQuerySystemTime( &dateTime );
perfTime = KeQueryPerformanceCounter( NULL );
// We want to watch this IRP complete
seqNum = (ULONG) -1;
hookCompletion = FALSE;
// Determine what function we’re dealing with
FilemonGetProcess( name );
switch( currentIrpStack->MajorFunction ) {
case IRP_MJ_CREATE:
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

ReadFunction(); // call a function(read contents of specification file)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL,
“%s\tIRP_MJ_CREATE\t%s\tAttributes:
%s Options: %s”,
name, fullPathName,
CreateAttributesString(
currentIrpStack->Parameters.Create.FileAttributes,

attributeString ),
CreateOptionsString(
currentIrpStack->Parameters.Create.Options,
optionString
));

//
// If its an open-by-id we free the hash entry now so that on
the next access to
// the file we’ll pick up the file’s real name.
//
if( currentIrpStack->Parameters.Create.Options &
FILE_OPEN_BY_FILE_ID ) {
FilemonFreeHashEntry( FileObject );
}
break;
default:
hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL,
“%s\t*UNKNOWN* 0x%X\t\t”, name,
currentIrpStack->MajorFunction );
break;
}
} else {
// We don’t care about this IRP’s completion
hookCompletion = FALSE;
// Do name processing for the sake of keeping the hash table
current
switch( currentIrpStack->MajorFunction ) {
case IRP_MJ_CLOSE:
// This fileobject/name association can be discarded now.
FilemonFreeHashEntry( FileObject );
break;
}
}
// Free the buffer if we have one
if( fullPathName && fullPathName != InsufficientResources ) {
ExFreeToNPagedLookasideList( &FullPathLookaside, fullPathName );
}
// Copy parameters down to next level in the stack for the driver
below us
*nextIrpStack = *currentIrpStack;
#if DBG
// If an unload isn’t in progress, we should register a completion
callback
// so that the IRP’s return status can be examined.
KeAcquireSpinLock( &CountMutex, &oldirql );
#endif
if( !UnloadInProgress && hookCompletion ) {
#if DBG
// Increment the outstanding IRP count since this IRP will be
headed
// for our completion routine
FilemonDriver->DriverUnload = NULL;
OutstandingIRPCount++;
DbgPrint((“+%d: %x\n”, OutstandingIRPCount, Irp ));;
#endif // DBG
//
// Grab the time stamp and Log it in the current stack location.
This
// is legal since the stack location is ours, and we’re done
looking at
// the parameters. This makes it easy to pass this to the
completion routine. The
// DiskPerf example in the NT DDK uses this trick.
//
currentIrpStack->Parameters.Read.ByteOffset = perfTime;
#if defined(IA64)
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) (ULONG_PTR)
seqNum, TRUE, TRUE, TRUE );
#else
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) seqNum,
TRUE, TRUE, TRUE );
#endif
} else {
// Set no completion routine
IoSetCompletionRoutine( Irp, FilemonHookDone, NULL, FALSE, FALSE,
FALSE );
}
#if DBG
KeReleaseSpinLock( &CountMutex, oldirql );
#endif
// Return the results of the call to the caller
return IoCallDriver( hookExt->FileSystem, Irp );
}

ReadFunction

VOID ReadFunction()
{
IO_STATUS_BLOCK ioStatus;
HANDLE ntFileHandle;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING fileNameUnicodeString;
WCHAR filename = L"\DosDevices\C:\test.txt";
NTSTATUS ntStatus;
FILE_STANDARD_INFORMATION eof;
char *FileBuffer = 0;
ULONG FileSize = 0;
RtlInitUnicodeString( &fileNameUnicodeString, filename );
InitializeObjectAttributes( &objectAttributes,
&fileNameUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwOpenFile( &ntFileHandle,
SYNCHRONIZE | GENERIC_READ,
&objectAttributes,
&ioStatus,
0,
FILE_SYNCHRONOUS_IO_ALERT );
ntStatus = ZwQueryInformationFile(ntFileHandle, &ioStatus, (void*)&eof,
sizeof(eof), FileStandardInformation);
FileSize=eof.EndOfFile.LowPart;

FileBuffer=(char*)ExAllocatePool(NonPagedPool,eof.EndOfFile.LowPart+1);
((char*)(FileBuffer))[FileSize]=0; // make the buffer ASCIIZ
// ÆÄÀÏ ³»¿ë Àбâ
ZwReadFile(ntFileHandle,
NULL,
NULL,
NULL,
&ioStatus,
FileBuffer,
FileSize,
NULL,
NULL);
DbgPrint((“*****File Content = %s File Size = %d\n”, FileBuffer,
FileSize));
ZwClose(ntFileHandle);
ExFreePool(FileBuffer); // F should be malloc-ed!!
return 0;
}

One of the most common causes of a double fault is a stack overflow. The
instruction you provided would not cause a stack overflow, but given that
all we can see from your information is the results of your analysis (and
not the actual information itself) it is always possible that your analysis
is incomplete.

I would strongly suggest looking at the stack limits on the machine for the
thread (!thread will display those limits) and I suspect you will find that
the ESP value is the same as the limit of the kernel stack for the current
thread.

This is one reason why it is dangerous to increase re-entrancy within the
file system driver stack - it is very easy to cause stack overflows.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Chang Sung, Jung. [mailto:xxxxx@korea.com]
Sent: Thursday, October 17, 2002 5:16 AM
To: File Systems Developers
Subject: [ntfsd] Abnormal Problem!

I made a function(including ZwReadFile internally) that read contents of
specification file(for example, c:\test.txt).
This function acted well, without problem.

By the way, If i try to call this function in the
FilemonHookRoutine(Dispatch-Routine of “FileMon of sysinternlas.com”),
BSOD appears.
Finally, My computer(Windows 2000) downed.
Error code was “0X0000007F(0X0000008, 0X0000000, 0X0000000, 0X0000000)”,
UNEXPECTED_KERNEL_MODE_TRAP.
It was Double-Fault message.
Assemble-code(taken by debugging tool) was MOV EBP, ESP.

Why does this phenomenon happen?
How can i solve this problem.

Thanks for any suggestions!
Sincerely!
Chang Sung, Jung.


Source code is following.

FilemonHookRoutine

NTSTATUS
FilemonHookRoutine(
PDEVICE_OBJECT HookDevice,
IN PIRP Irp
)
{
PIO_STACK_LOCATION currentIrpStack =
IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
PMOVE_FILE_DATA moveFile;
PQUERY_DIRECTORY queryDirectory;
PFILE_OBJECT FileObject;
PHOOK_EXTENSION hookExt;
LARGE_INTEGER dateTime;
LARGE_INTEGER perfTime;
PCHAR fullPathName = NULL;
BOOLEAN hookCompletion, createPath;
CHAR controlCodeBuffer[ERRORLEN];
CHAR attributeString[ERRORLEN];
CHAR optionString[ERRORLEN];
CHAR name[PROCNAMELEN];
ULONG i;
ANSI_STRING directoryFilter;
PCHAR queryFilter;
ULONG seqNum;
KIRQL oldirql;
// Extract the file object from the IRP
FileObject = currentIrpStack->FileObject;
// Point at the device extension, which contains information on which
// file system this IRP is headed for
hookExt = HookDevice->DeviceExtension;
// We note open cases so that when we query the file name
// we don’t ask the file system for the name (since it won’t
// have seen the file object yet).
if( currentIrpStack->MajorFunction == IRP_MJ_CREATE ||
currentIrpStack->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE ||
currentIrpStack->MajorFunction == IRP_MJ_CREATE_MAILSLOT ) {
// Clear any existing fileobject/name association stored in the
// hash table
FilemonFreeHashEntry( FileObject );
createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLOSE ) {
// We treat close as a special case of create for name querying
// since calling into NTFS during a close can result in a
deadlock.
createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLEANUP &&
FileObject->Flags & FO_STREAM_FILE ) {
// Treat cleanup of stream file objects as special create case,
because
// querying them causes NTFS to screwup on NT 4
//
createPath = TRUE;
} else {
createPath = FALSE;
}
// Allocate a buffer and get the name only if we have to
if( FilterOn && hookExt->Hooked ) {

GETPATHNAME( createPath );
}
// Only log it if it passes the filter
if( hookExt->Hooked && fullPathName ) {
// If measuring absolute time go and get the timestamp.
KeQuerySystemTime( &dateTime );
perfTime = KeQueryPerformanceCounter( NULL );
// We want to watch this IRP complete
seqNum = (ULONG) -1;
hookCompletion = FALSE;
// Determine what function we’re dealing with
FilemonGetProcess( name );
switch( currentIrpStack->MajorFunction ) {
case IRP_MJ_CREATE:

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++

ReadFunction(); // call a function(read contents of
specification file)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++

hookCompletion = LogRecord( TRUE, &seqNum,
&dateTime, NULL,
“%s\tIRP_MJ_CREATE\t%s\tAttributes:
%s Options: %s”,
name, fullPathName,
CreateAttributesString(
currentIrpStack->Parameters.Create.FileAttributes,

attributeString ),
CreateOptionsString(
currentIrpStack->Parameters.Create.Options,
optionString
));

//
// If its an open-by-id we free the hash entry now so that on
the next access to
// the file we’ll pick up the file’s real name.
//
if( currentIrpStack->Parameters.Create.Options &
FILE_OPEN_BY_FILE_ID ) {
FilemonFreeHashEntry( FileObject );
}
break;
default:
hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL,
“%s\t*UNKNOWN* 0x%X\t\t”, name,
currentIrpStack->MajorFunction );
break;
}
} else {
// We don’t care about this IRP’s completion
hookCompletion = FALSE;
// Do name processing for the sake of keeping the hash table
current
switch( currentIrpStack->MajorFunction ) {
case IRP_MJ_CLOSE:
// This fileobject/name association can be discarded now.
FilemonFreeHashEntry( FileObject );
break;
}
}
// Free the buffer if we have one
if( fullPathName && fullPathName != InsufficientResources ) {
ExFreeToNPagedLookasideList( &FullPathLookaside, fullPathName );
}
// Copy parameters down to next level in the stack for the driver
below us
*nextIrpStack = *currentIrpStack;
#if DBG
// If an unload isn’t in progress, we should register a completion
callback
// so that the IRP’s return status can be examined.
KeAcquireSpinLock( &CountMutex, &oldirql );
#endif
if( !UnloadInProgress && hookCompletion ) {
#if DBG
// Increment the outstanding IRP count since this IRP will be
headed
// for our completion routine
FilemonDriver->DriverUnload = NULL;
OutstandingIRPCount++;
DbgPrint((“+%d: %x\n”, OutstandingIRPCount, Irp ));;
#endif // DBG
//
// Grab the time stamp and Log it in the current stack location.
This
// is legal since the stack location is ours, and we’re done
looking at
// the parameters. This makes it easy to pass this to the
completion routine. The
// DiskPerf example in the NT DDK uses this trick.
//
currentIrpStack->Parameters.Read.ByteOffset = perfTime;
#if defined(IA64)
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) (ULONG_PTR)
seqNum, TRUE, TRUE, TRUE );
#else
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) seqNum,
TRUE, TRUE, TRUE );
#endif
} else {
// Set no completion routine
IoSetCompletionRoutine( Irp, FilemonHookDone, NULL, FALSE, FALSE,
FALSE );
}
#if DBG
KeReleaseSpinLock( &CountMutex, oldirql );
#endif
// Return the results of the call to the caller
return IoCallDriver( hookExt->FileSystem, Irp );
}

ReadFunction

VOID ReadFunction()
{
IO_STATUS_BLOCK ioStatus;
HANDLE ntFileHandle;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING fileNameUnicodeString;
WCHAR filename = L"\DosDevices\C:\test.txt";
NTSTATUS ntStatus;
FILE_STANDARD_INFORMATION eof;
char *FileBuffer = 0;
ULONG FileSize = 0;
RtlInitUnicodeString( &fileNameUnicodeString, filename );
InitializeObjectAttributes( &objectAttributes,
&fileNameUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwOpenFile( &ntFileHandle,
SYNCHRONIZE | GENERIC_READ,
&objectAttributes,
&ioStatus,
0,
FILE_SYNCHRONOUS_IO_ALERT );
ntStatus = ZwQueryInformationFile(ntFileHandle, &ioStatus,
(void*)&eof,
sizeof(eof), FileStandardInformation);
FileSize=eof.EndOfFile.LowPart;

FileBuffer=(char*)ExAllocatePool(NonPagedPool,eof.EndOfFile.LowPart+1);
((char*)(FileBuffer))[FileSize]=0; // make the buffer ASCIIZ
// ÆÄÀÏ ³»¿ë Àбâ
ZwReadFile(ntFileHandle,
NULL,
NULL,
NULL,
&ioStatus,
FileBuffer,
FileSize,
NULL,
NULL);
DbgPrint((“*****File Content = %s File Size = %d\n”, FileBuffer,
FileSize));
ZwClose(ntFileHandle);
ExFreePool(FileBuffer); // F should be malloc-ed!!
return 0;
}


You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to %%email.unsub%%

Hi,

zwcreatefile/zwopenfile in IRP_CREATE dispatch routine causes reenterency
problem. you should use shadow device object or rolling your own create
irp. ( see the OSR’s IFS FAQ documents. )

and, i think you should use kernel-thread or workitem techinque.

hope this helps.

Terra.

And you may want to move these arrays out of the locals. Stack space is tight as it is, with all the re-entrancy issues, without having locals crunching it all up

CHAR controlCodeBuffer[ERRORLEN];
CHAR attributeString[ERRORLEN];
CHAR optionString[ERRORLEN];
CHAR name[PROCNAMELEN]

-----Original Message-----
From: Tony Mason [mailto:xxxxx@osr.com]
Sent: Thursday, October 17, 2002 4:04 AM
To: File Systems Developers
Subject: [ntfsd] RE: Abnormal Problem!

One of the most common causes of a double fault is a stack overflow. The instruction you provided would not cause a stack overflow, but given that all we can see from your information is the results of your analysis (and not the actual information itself) it is always possible that your analysis is incomplete.

I would strongly suggest looking at the stack limits on the machine for the thread (!thread will display those limits) and I suspect you will find that the ESP value is the same as the limit of the kernel stack for the current thread.

This is one reason why it is dangerous to increase re-entrancy within the file system driver stack - it is very easy to cause stack overflows.

Regards,

Tony

Tony Mason
Consulting Partner
OSR Open Systems Resources, Inc.
http://www.osr.com

-----Original Message-----
From: Chang Sung, Jung. [mailto:xxxxx@korea.com]
Sent: Thursday, October 17, 2002 5:16 AM
To: File Systems Developers
Subject: [ntfsd] Abnormal Problem!

I made a function(including ZwReadFile internally) that read contents of specification file(for example, c:\test.txt). This function acted well, without problem.

By the way, If i try to call this function in the FilemonHookRoutine(Dispatch-Routine of “FileMon of sysinternlas.com”), BSOD appears. Finally, My computer(Windows 2000) downed. Error code was “0X0000007F(0X0000008, 0X0000000, 0X0000000, 0X0000000)”, UNEXPECTED_KERNEL_MODE_TRAP. It was Double-Fault message. Assemble-code(taken by debugging tool) was MOV EBP, ESP.

Why does this phenomenon happen?
How can i solve this problem.

Thanks for any suggestions!
Sincerely!
Chang Sung, Jung.


Source code is following.

FilemonHookRoutine

NTSTATUS
FilemonHookRoutine(
PDEVICE_OBJECT HookDevice,
IN PIRP Irp
)
{
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
PMOVE_FILE_DATA moveFile;
PQUERY_DIRECTORY queryDirectory;
PFILE_OBJECT FileObject;
PHOOK_EXTENSION hookExt;
LARGE_INTEGER dateTime;
LARGE_INTEGER perfTime;
PCHAR fullPathName = NULL;
BOOLEAN hookCompletion, createPath;
CHAR controlCodeBuffer[ERRORLEN];
CHAR attributeString[ERRORLEN];
CHAR optionString[ERRORLEN];
CHAR name[PROCNAMELEN];
ULONG i;
ANSI_STRING directoryFilter;
PCHAR queryFilter;
ULONG seqNum;
KIRQL oldirql;
// Extract the file object from the IRP
FileObject = currentIrpStack->FileObject;
// Point at the device extension, which contains information on which
// file system this IRP is headed for
hookExt = HookDevice->DeviceExtension;
// We note open cases so that when we query the file name
// we don’t ask the file system for the name (since it won’t
// have seen the file object yet).
if( currentIrpStack->MajorFunction == IRP_MJ_CREATE ||
currentIrpStack->MajorFunction == IRP_MJ_CREATE_NAMED_PIPE ||
currentIrpStack->MajorFunction == IRP_MJ_CREATE_MAILSLOT ) {
// Clear any existing fileobject/name association stored in the
// hash table
FilemonFreeHashEntry( FileObject );
createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLOSE ) {
// We treat close as a special case of create for name querying
// since calling into NTFS during a close can result in a deadlock.
createPath = TRUE;
} else if( currentIrpStack->MajorFunction == IRP_MJ_CLEANUP &&
FileObject->Flags & FO_STREAM_FILE ) {
// Treat cleanup of stream file objects as special create case, because
// querying them causes NTFS to screwup on NT 4
//
createPath = TRUE;
} else {
createPath = FALSE;
}
// Allocate a buffer and get the name only if we have to
if( FilterOn && hookExt->Hooked ) {

GETPATHNAME( createPath );
}
// Only log it if it passes the filter
if( hookExt->Hooked && fullPathName ) {
// If measuring absolute time go and get the timestamp.
KeQuerySystemTime( &dateTime );
perfTime = KeQueryPerformanceCounter( NULL );
// We want to watch this IRP complete
seqNum = (ULONG) -1;
hookCompletion = FALSE;
// Determine what function we’re dealing with
FilemonGetProcess( name );
switch( currentIrpStack->MajorFunction ) {
case IRP_MJ_CREATE:

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++

ReadFunction(); // call a function(read contents of specification file)

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+++++++++++++++

hookCompletion = LogRecord( TRUE, &seqNum,
&dateTime, NULL,
“%s\tIRP_MJ_CREATE\t%s\tAttributes:
%s Options: %s”,
name, fullPathName,
CreateAttributesString(
currentIrpStack->Parameters.Create.FileAttributes,

attributeString ),
CreateOptionsString(
currentIrpStack->Parameters.Create.Options,
optionString ));

//
// If its an open-by-id we free the hash entry now so that on the next access to
// the file we’ll pick up the file’s real name.
//
if( currentIrpStack->Parameters.Create.Options & FILE_OPEN_BY_FILE_ID ) {
FilemonFreeHashEntry( FileObject );
}
break;
default:
hookCompletion = LogRecord( TRUE, &seqNum, &dateTime, NULL,
“%s\t*UNKNOWN* 0x%X\t\t”, name,
currentIrpStack->MajorFunction );
break;
}
} else {
// We don’t care about this IRP’s completion
hookCompletion = FALSE;
// Do name processing for the sake of keeping the hash table current
switch( currentIrpStack->MajorFunction ) {
case IRP_MJ_CLOSE:
// This fileobject/name association can be discarded now.
FilemonFreeHashEntry( FileObject );
break;
}
}
// Free the buffer if we have one
if( fullPathName && fullPathName != InsufficientResources ) {
ExFreeToNPagedLookasideList( &FullPathLookaside, fullPathName );
}
// Copy parameters down to next level in the stack for the driver below us
*nextIrpStack = *currentIrpStack;
#if DBG
// If an unload isn’t in progress, we should register a completion callback
// so that the IRP’s return status can be examined.
KeAcquireSpinLock( &CountMutex, &oldirql );
#endif
if( !UnloadInProgress && hookCompletion ) {
#if DBG
// Increment the outstanding IRP count since this IRP will be headed
// for our completion routine
FilemonDriver->DriverUnload = NULL;
OutstandingIRPCount++;
DbgPrint((“+%d: %x\n”, OutstandingIRPCount, Irp ));; #endif // DBG
//
// Grab the time stamp and Log it in the current stack location. This
// is legal since the stack location is ours, and we’re done looking at
// the parameters. This makes it easy to pass this to the completion routine. The
// DiskPerf example in the NT DDK uses this trick.
//
currentIrpStack->Parameters.Read.ByteOffset = perfTime; #if defined(IA64)
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) (ULONG_PTR) seqNum, TRUE, TRUE, TRUE ); #else
IoSetCompletionRoutine( Irp, FilemonHookDone, (PVOID) seqNum, TRUE, TRUE, TRUE ); #endif
} else {
// Set no completion routine
IoSetCompletionRoutine( Irp, FilemonHookDone, NULL, FALSE, FALSE, FALSE );
}
#if DBG
KeReleaseSpinLock( &CountMutex, oldirql );
#endif
// Return the results of the call to the caller
return IoCallDriver( hookExt->FileSystem, Irp );
}

ReadFunction

VOID ReadFunction()
{
IO_STATUS_BLOCK ioStatus;
HANDLE ntFileHandle;
OBJECT_ATTRIBUTES objectAttributes;
UNICODE_STRING fileNameUnicodeString;
WCHAR filename = L"\DosDevices\C:\test.txt";
NTSTATUS ntStatus;
FILE_STANDARD_INFORMATION eof;
char *FileBuffer = 0;
ULONG FileSize = 0;
RtlInitUnicodeString( &fileNameUnicodeString, filename );
InitializeObjectAttributes( &objectAttributes,
&fileNameUnicodeString,
OBJ_CASE_INSENSITIVE,
NULL,
NULL );
ntStatus = ZwOpenFile( &ntFileHandle,
SYNCHRONIZE | GENERIC_READ,
&objectAttributes,
&ioStatus,
0,
FILE_SYNCHRONOUS_IO_ALERT );
ntStatus = ZwQueryInformationFile(ntFileHandle, &ioStatus, (void*)&eof, sizeof(eof), FileStandardInformation);
FileSize=eof.EndOfFile.LowPart;

FileBuffer=(char*)ExAllocatePool(NonPagedPool,eof.EndOfFile.LowPart+1);
((char*)(FileBuffer))[FileSize]=0; // make the buffer ASCIIZ
// ??? ??? ?б?
ZwReadFile(ntFileHandle,
NULL,
NULL,
NULL,
&ioStatus,
FileBuffer,
FileSize,
NULL,
NULL);
DbgPrint((“*****File Content = %s File Size = %d\n”, FileBuffer, FileSize));
ZwClose(ntFileHandle);
ExFreePool(FileBuffer); // F should be malloc-ed!!
return 0;
}


You are currently subscribed to ntfsd as: xxxxx@osr.com
To unsubscribe send a blank email to %%email.unsub%%


You are currently subscribed to ntfsd as: xxxxx@windows.microsoft.com To unsubscribe send a blank email to %%email.unsub%%