/*++ Copyright (c) 1989 Microsoft Corporation Module Name: FlushBuf.c Abstract: This module implements the File Flush Buffers routine for NPFS called by the dispatch driver. Author: Gary Kimura [GaryKi] 21-Aug-1990 Revision History: --*/ #include "NpProcs.h" // // The debug trace level // #define Dbg (DEBUG_TRACE_FLUSH_BUFFERS) // // local procedure prototypes // NTSTATUS NpCommonFlushBuffers ( IN PNPFS_DEVICE_OBJECT NpfsDeviceObject, IN PIRP Irp ); #ifdef ALLOC_PRAGMA #pragma alloc_text(PAGE, NpCommonFlushBuffers) #pragma alloc_text(PAGE, NpFsdFlushBuffers) #endif NTSTATUS NpFsdFlushBuffers ( IN PNPFS_DEVICE_OBJECT NpfsDeviceObject, IN PIRP Irp ) /*++ Routine Description: This routine implements the FSD part of the NtFlushBuffersFile API calls. Arguments: NpfsDeviceObject - Supplies the device object to use. Irp - Supplies the Irp being processed Return Value: NTSTATUS - The Fsd status for the Irp --*/ { NTSTATUS Status; PAGED_CODE(); DebugTrace(+1, Dbg, "NpFsdFlushBuffers\n", 0); // // Call the common Flush routine. // FsRtlEnterFileSystem(); NpAcquireSharedVcb(); Status = NpCommonFlushBuffers( NpfsDeviceObject, Irp ); NpReleaseVcb(); FsRtlExitFileSystem(); if (Status != STATUS_PENDING) { NpCompleteRequest( Irp, Status ); } // // And return to our caller // DebugTrace(-1, Dbg, "NpFsdFlushBuffers -> %08lx\n", Status ); return Status; } // // Internal support routine // NTSTATUS NpCommonFlushBuffers ( IN PNPFS_DEVICE_OBJECT NpfsDeviceObject, IN PIRP Irp ) /*++ Routine Description: This is the common routine for Flushing buffers for a file. Arguments: Irp - Supplies the Irp to process Return Value: NTSTATUS - the return status for the operation --*/ { NTSTATUS Status; PIO_STACK_LOCATION IrpSp; PCCB Ccb; NAMED_PIPE_END NamedPipeEnd; PDATA_QUEUE WriteQueue; // // Get the current stack location // PAGED_CODE(); IrpSp = IoGetCurrentIrpStackLocation( Irp ); DebugTrace(+1, Dbg, "NpCommonFlushBuffers\n", 0); DebugTrace( 0, Dbg, "Irp = %08lx\n", Irp); DebugTrace( 0, Dbg, "FileObject = %08lx\n", IrpSp->FileObject); // // Decode the file object to figure out who we are. If the result // is not a ccb then the pipe has been disconnected. We don't need the // Fcb back from the call // if (NpDecodeFileObject( IrpSp->FileObject, NULL, &Ccb, &NamedPipeEnd ) != NPFS_NTC_CCB) { DebugTrace(0, Dbg, "Pipe is disconnected from us\n", 0); Status = STATUS_PIPE_DISCONNECTED; DebugTrace(-1, Dbg, "NpCommonFlushBuffers -> %08lx\n", Status ); return Status; } NpAcquireExclusiveCcb(Ccb); try { // // Figure out the data queue that the flush buffer is // targetted at. It is the queue that we do writes into // if (NamedPipeEnd == FILE_PIPE_SERVER_END) { WriteQueue = &Ccb->DataQueue[ FILE_PIPE_OUTBOUND ]; } else { WriteQueue = &Ccb->DataQueue[ FILE_PIPE_INBOUND ]; } // // Now from the write queue check if contains write entries. If // it does not contain write entries then we immediately complete // this irp with success because there isn't anything to flush // if (!NpIsDataQueueWriters( WriteQueue )) { DebugTrace(0, Dbg, "Pipe does not contain write entries\n", 0); try_return(Status = STATUS_SUCCESS); } // // Otherwise the queue is full of writes so we simply // enqueue this irp to the back to the queue and set our // return status to pending, also mark the irp pending // Status = NpAddDataQueueEntry( NamedPipeEnd, Ccb, WriteQueue, WriteEntries, Flush, 0, Irp, NULL, 0 ); try_exit: NOTHING; } finally { NpReleaseCcb(Ccb); } DebugTrace(-1, Dbg, "NpCommonFlushBuffers -> %08lx\n", Status); return Status; }