Something went wrong. Try again.
Reactos
Something went wrong. Try again.
7.3 kB · 255 lines
C
at master
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256/* * PROJECT: ReactOS Named Pipe FileSystem * LICENSE: BSD - See COPYING.ARM in the top level directory * FILE: drivers/filesystems/npfs/write.c * PURPOSE: Pipes Writing * PROGRAMMERS: ReactOS Portable Systems Group */
/* INCLUDES *******************************************************************/
#include "npfs.h"
// File ID number for NPFS bugchecking support#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_WRITE)
/* GLOBALS ********************************************************************/
LONG NpSlowWriteCalls;ULONG NpFastWriteTrue;ULONG NpFastWriteFalse;
/* FUNCTIONS ******************************************************************/
BOOLEANNTAPINpCommonWrite(IN PFILE_OBJECT FileObject, IN PVOID Buffer, IN ULONG DataSize, IN PETHREAD Thread, IN PIO_STATUS_BLOCK IoStatus, IN PIRP Irp, IN PLIST_ENTRY List){ NODE_TYPE_CODE NodeType; BOOLEAN WriteOk; PNP_CCB Ccb; PNP_NONPAGED_CCB NonPagedCcb; PNP_DATA_QUEUE WriteQueue; NTSTATUS Status; PNP_EVENT_BUFFER EventBuffer; ULONG BytesWritten, NamedPipeEnd, ReadMode; PAGED_CODE();
IoStatus->Information = 0; NodeType = NpDecodeFileObject(FileObject, NULL, &Ccb, &NamedPipeEnd);
if (!NodeType) { IoStatus->Status = STATUS_PIPE_DISCONNECTED; return TRUE; }
if (NodeType != NPFS_NTC_CCB) { IoStatus->Status = STATUS_INVALID_PARAMETER; return TRUE; }
NonPagedCcb = Ccb->NonPagedCcb; ExAcquireResourceExclusiveLite(&NonPagedCcb->Lock, TRUE);
if (Ccb->NamedPipeState != FILE_PIPE_CONNECTED_STATE) { if (Ccb->NamedPipeState == FILE_PIPE_DISCONNECTED_STATE) { IoStatus->Status = STATUS_PIPE_DISCONNECTED; } else if (Ccb->NamedPipeState == FILE_PIPE_LISTENING_STATE) { IoStatus->Status = STATUS_PIPE_LISTENING; } else { ASSERT(Ccb->NamedPipeState == FILE_PIPE_CLOSING_STATE); IoStatus->Status = STATUS_PIPE_CLOSING; }
WriteOk = TRUE; goto Quickie; }
if ((NamedPipeEnd == FILE_PIPE_SERVER_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_INBOUND) || (NamedPipeEnd == FILE_PIPE_CLIENT_END && Ccb->Fcb->NamedPipeConfiguration == FILE_PIPE_OUTBOUND)) { IoStatus->Status = STATUS_INVALID_PARAMETER; WriteOk = TRUE; goto Quickie; }
IoStatus->Status = STATUS_SUCCESS; IoStatus->Information = DataSize;
if (NamedPipeEnd == FILE_PIPE_SERVER_END) { WriteQueue = &Ccb->DataQueue[FILE_PIPE_OUTBOUND]; ReadMode = Ccb->ReadMode[FILE_PIPE_CLIENT_END]; } else { WriteQueue = &Ccb->DataQueue[FILE_PIPE_INBOUND]; ReadMode = Ccb->ReadMode[FILE_PIPE_SERVER_END]; }
EventBuffer = NonPagedCcb->EventBuffer[NamedPipeEnd];
if ((WriteQueue->QueueState == ReadEntries && WriteQueue->BytesInQueue < DataSize && WriteQueue->Quota < DataSize - WriteQueue->BytesInQueue) || (WriteQueue->QueueState != ReadEntries && WriteQueue->Quota - WriteQueue->QuotaUsed < DataSize)) { if (Ccb->Fcb->NamedPipeType == FILE_PIPE_MESSAGE_TYPE && Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION) { IoStatus->Information = 0; IoStatus->Status = STATUS_SUCCESS; WriteOk = TRUE; goto Quickie; }
if (!Irp) { WriteOk = FALSE; goto Quickie; } }
Status = NpWriteDataQueue(WriteQueue, ReadMode, Buffer, DataSize, Ccb->Fcb->NamedPipeType, &BytesWritten, Ccb, NamedPipeEnd, Thread, List); IoStatus->Status = Status;
if (Status == STATUS_MORE_PROCESSING_REQUIRED) { ASSERT(WriteQueue->QueueState != ReadEntries); if ((Ccb->CompletionMode[NamedPipeEnd] == FILE_PIPE_COMPLETE_OPERATION || !Irp) && ((WriteQueue->Quota - WriteQueue->QuotaUsed) < BytesWritten)) { IoStatus->Information = DataSize - BytesWritten; IoStatus->Status = STATUS_SUCCESS; } else { ASSERT(WriteQueue->QueueState != ReadEntries);
IoStatus->Status = NpAddDataQueueEntry(NamedPipeEnd, Ccb, WriteQueue, WriteEntries, Buffered, DataSize, Irp, Buffer, DataSize - BytesWritten); } }
if (EventBuffer) KeSetEvent(EventBuffer->Event, IO_NO_INCREMENT, FALSE); WriteOk = TRUE;
Quickie: ExReleaseResourceLite(&Ccb->NonPagedCcb->Lock); return WriteOk;}
NTSTATUSNTAPINpFsdWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp){ PIO_STACK_LOCATION IoStack; IO_STATUS_BLOCK IoStatus; LIST_ENTRY DeferredList; PAGED_CODE(); NpSlowWriteCalls++;
InitializeListHead(&DeferredList); IoStack = IoGetCurrentIrpStackLocation(Irp);
FsRtlEnterFileSystem(); NpAcquireSharedVcb();
NpCommonWrite(IoStack->FileObject, Irp->UserBuffer, IoStack->Parameters.Write.Length, Irp->Tail.Overlay.Thread, &IoStatus, Irp, &DeferredList);
NpReleaseVcb(); NpCompleteDeferredIrps(&DeferredList); FsRtlExitFileSystem();
if (IoStatus.Status != STATUS_PENDING) { Irp->IoStatus.Information = IoStatus.Information; Irp->IoStatus.Status = IoStatus.Status; IoCompleteRequest(Irp, IO_NAMED_PIPE_INCREMENT); }
return IoStatus.Status;}
_Function_class_(FAST_IO_WRITE)_IRQL_requires_same_BOOLEANNTAPINpFastWrite( _In_ PFILE_OBJECT FileObject, _In_ PLARGE_INTEGER FileOffset, _In_ ULONG Length, _In_ BOOLEAN Wait, _In_ ULONG LockKey, _In_ PVOID Buffer, _Out_ PIO_STATUS_BLOCK IoStatus, _In_ PDEVICE_OBJECT DeviceObject){ LIST_ENTRY DeferredList; BOOLEAN Result; PAGED_CODE();
InitializeListHead(&DeferredList);
FsRtlEnterFileSystem(); NpAcquireSharedVcb();
Result = NpCommonWrite(FileObject, Buffer, Length, PsGetCurrentThread(), IoStatus, NULL, &DeferredList); if (Result) ++NpFastWriteTrue; else ++NpFastWriteFalse;
NpReleaseVcb(); NpCompleteDeferredIrps(&DeferredList); FsRtlExitFileSystem();
return Result;}
/* EOF */