Same kind of fixes for NtFlushBuffersFile

svn path=/trunk/; revision=14942
This commit is contained in:
Alex Ionescu 2005-05-02 05:27:32 +00:00
parent fb52d69134
commit f19732f822

View file

@ -1532,10 +1532,6 @@ NtFlushWriteBuffer(VOID)
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
NTSTATUS
STDCALL
NtFlushBuffersFile (IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock)
/* /*
* FUNCTION: Flushes cached file data to disk * FUNCTION: Flushes cached file data to disk
* ARGUMENTS: * ARGUMENTS:
@ -1546,54 +1542,98 @@ NtFlushBuffersFile (IN HANDLE FileHandle,
* RETURNS: Status * RETURNS: Status
* REMARKS: This function maps to the win32 FlushFileBuffers * REMARKS: This function maps to the win32 FlushFileBuffers
*/ */
NTSTATUS
STDCALL
NtFlushBuffersFile(IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock)
{ {
PFILE_OBJECT FileObject = NULL; PFILE_OBJECT FileObject = NULL;
PIRP Irp; PIRP Irp;
PIO_STACK_LOCATION StackPtr; PIO_STACK_LOCATION StackPtr;
NTSTATUS Status; NTSTATUS Status;
KPROCESSOR_MODE PreviousMode; PDEVICE_OBJECT DeviceObject;
KEVENT Event;
PreviousMode = ExGetPreviousMode(); BOOLEAN LocalEvent = FALSE;
KPROCESSOR_MODE PreviousMode = ExGetPreviousMode();
/* Get the File Object */
Status = ObReferenceObjectByHandle(FileHandle, Status = ObReferenceObjectByHandle(FileHandle,
FILE_WRITE_DATA, FILE_WRITE_DATA,
NULL, NULL,
PreviousMode, PreviousMode,
(PVOID*)&FileObject, (PVOID*)&FileObject,
NULL); NULL);
if (Status != STATUS_SUCCESS) if (Status != STATUS_SUCCESS) return(Status);
{
return(Status);
}
KeResetEvent( &FileObject->Event );
Irp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS,
FileObject->DeviceObject,
NULL,
0,
NULL,
&FileObject->Event,
IoStatusBlock);
/* Trigger FileObject/Event dereferencing */ /* Check if this is a direct open or not */
if (FileObject->Flags & FO_DIRECT_DEVICE_OPEN)
{
DeviceObject = IoGetAttachedDevice(FileObject->DeviceObject);
}
else
{
DeviceObject = IoGetRelatedDeviceObject(FileObject);
}
/* Check if we should use Sync IO or not */
if (FileObject->Flags & FO_SYNCHRONOUS_IO)
{
/* Use File Object event */
KeClearEvent(&FileObject->Event);
}
else
{
/* Use local event */
KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
LocalEvent = TRUE;
}
/* Allocate the IRP */
if (!(Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE)))
{
ObDereferenceObject(FileObject);
return STATUS_INSUFFICIENT_RESOURCES;
}
/* Set up the IRP */
Irp->Flags = (LocalEvent) ? IRP_SYNCHRONOUS_API : 0;
Irp->RequestorMode = PreviousMode;
Irp->UserIosb = IoStatusBlock;
Irp->UserEvent = (LocalEvent) ? &Event : NULL;
Irp->Tail.Overlay.Thread = PsGetCurrentThread();
Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->Tail.Overlay.OriginalFileObject = FileObject;
Irp->RequestorMode = PreviousMode; /* Set up Stack Data */
StackPtr = IoGetNextIrpStackLocation(Irp); StackPtr = IoGetNextIrpStackLocation(Irp);
StackPtr->MajorFunction = IRP_MJ_FLUSH_BUFFERS;
StackPtr->FileObject = FileObject; StackPtr->FileObject = FileObject;
Status = IoCallDriver(FileObject->DeviceObject,Irp); /* Call the Driver */
Status = IoCallDriver(DeviceObject, Irp);
if (Status == STATUS_PENDING) if (Status == STATUS_PENDING)
{ {
KeWaitForSingleObject(&FileObject->Event, if (LocalEvent)
{
KeWaitForSingleObject(&Event,
Executive, Executive,
PreviousMode, PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO, FileObject->Flags & FO_ALERTABLE_IO,
NULL); NULL);
Status = IoStatusBlock->Status; Status = IoStatusBlock->Status;
} }
else
{
KeWaitForSingleObject(&FileObject->Event,
Executive,
PreviousMode,
FileObject->Flags & FO_ALERTABLE_IO,
NULL);
Status = FileObject->FinalStatus;
}
}
return(Status); /* Return the Status */
return Status;
} }
/* /*
@ -1656,13 +1696,12 @@ NtNotifyChangeDirectoryFile(IN HANDLE FileHandle,
PreviousMode, PreviousMode,
(PVOID *)&FileObject, (PVOID *)&FileObject,
NULL); NULL);
if (Status != STATUS_SUCCESS) return(Status);
if (Status != STATUS_SUCCESS)
{
return(Status);
}
DeviceObject = FileObject->DeviceObject; DeviceObject = FileObject->DeviceObject;
Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE); Irp = IoAllocateIrp(DeviceObject->StackSize, TRUE);
if (Irp==NULL) if (Irp==NULL)
{ {