mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
175 lines
5.3 KiB
C
175 lines
5.3 KiB
C
/*
|
|
* PROJECT: ReactOS Named Pipe FileSystem
|
|
* LICENSE: BSD - See COPYING.ARM in the top level directory
|
|
* FILE: drivers/filesystems/npfs/writesup.c
|
|
* PURPOSE: Pipes Writing Support
|
|
* PROGRAMMERS: ReactOS Portable Systems Group
|
|
*/
|
|
|
|
/* INCLUDES *******************************************************************/
|
|
|
|
#include "npfs.h"
|
|
|
|
// File ID number for NPFS bugchecking support
|
|
#define NPFS_BUGCHECK_FILE_ID (NPFS_BUGCHECK_WRITESUP)
|
|
|
|
/* FUNCTIONS ******************************************************************/
|
|
|
|
NTSTATUS
|
|
NTAPI
|
|
NpWriteDataQueue(IN PNP_DATA_QUEUE WriteQueue,
|
|
IN ULONG Mode,
|
|
IN PVOID OutBuffer,
|
|
IN ULONG OutBufferSize,
|
|
IN ULONG PipeType,
|
|
OUT PULONG BytesNotWritten,
|
|
IN PNP_CCB Ccb,
|
|
IN ULONG NamedPipeEnd,
|
|
IN PETHREAD Thread,
|
|
IN PLIST_ENTRY List)
|
|
{
|
|
BOOLEAN HaveContext = FALSE, MoreProcessing, AllocatedBuffer;
|
|
PNP_DATA_QUEUE_ENTRY DataEntry;
|
|
ULONG DataSize, BufferSize;
|
|
PIRP WriteIrp;
|
|
PIO_STACK_LOCATION IoStack;
|
|
PVOID Buffer;
|
|
NTSTATUS Status;
|
|
PSECURITY_CLIENT_CONTEXT ClientContext;
|
|
PAGED_CODE();
|
|
|
|
*BytesNotWritten = OutBufferSize;
|
|
|
|
MoreProcessing = TRUE;
|
|
if ((PipeType != FILE_PIPE_MESSAGE_MODE) || (OutBufferSize))
|
|
{
|
|
MoreProcessing = FALSE;
|
|
}
|
|
|
|
for (DataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(WriteQueue, List),
|
|
NP_DATA_QUEUE_ENTRY,
|
|
QueueEntry);
|
|
((WriteQueue->QueueState == ReadEntries) &&
|
|
((*BytesNotWritten > 0) || (MoreProcessing)));
|
|
DataEntry = CONTAINING_RECORD(NpGetNextRealDataQueueEntry(WriteQueue, List),
|
|
NP_DATA_QUEUE_ENTRY,
|
|
QueueEntry))
|
|
{
|
|
DataSize = DataEntry->DataSize;
|
|
|
|
IoStack = IoGetCurrentIrpStackLocation(DataEntry->Irp);
|
|
|
|
if (IoStack->MajorFunction == IRP_MJ_FILE_SYSTEM_CONTROL &&
|
|
IoStack->Parameters.FileSystemControl.FsControlCode == FSCTL_PIPE_INTERNAL_READ_OVFLOW &&
|
|
(DataSize < OutBufferSize || MoreProcessing))
|
|
{
|
|
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, TRUE, List);
|
|
if (WriteIrp)
|
|
{
|
|
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
|
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
|
}
|
|
continue;
|
|
}
|
|
|
|
if (DataEntry->DataEntryType == Unbuffered)
|
|
{
|
|
DataEntry->Irp->Overlay.AllocationSize.QuadPart = 0;
|
|
}
|
|
|
|
BufferSize = *BytesNotWritten;
|
|
if (BufferSize >= DataSize) BufferSize = DataSize;
|
|
|
|
if (DataEntry->DataEntryType != Unbuffered && BufferSize)
|
|
{
|
|
Buffer = ExAllocatePoolWithTag(NonPagedPool, BufferSize, NPFS_DATA_ENTRY_TAG);
|
|
if (!Buffer) return STATUS_INSUFFICIENT_RESOURCES;
|
|
AllocatedBuffer = TRUE;
|
|
}
|
|
else
|
|
{
|
|
Buffer = DataEntry->Irp->AssociatedIrp.SystemBuffer;
|
|
AllocatedBuffer = FALSE;
|
|
}
|
|
|
|
_SEH2_TRY
|
|
{
|
|
RtlCopyMemory(Buffer,
|
|
(PVOID)((ULONG_PTR)OutBuffer + OutBufferSize - *BytesNotWritten),
|
|
BufferSize);
|
|
}
|
|
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
|
|
{
|
|
if (AllocatedBuffer) ExFreePool(Buffer);
|
|
_SEH2_YIELD(return _SEH2_GetExceptionCode());
|
|
}
|
|
_SEH2_END;
|
|
|
|
if (!HaveContext)
|
|
{
|
|
HaveContext = TRUE;
|
|
Status = NpGetClientSecurityContext(NamedPipeEnd, Ccb, Thread, &ClientContext);
|
|
if (!NT_SUCCESS(Status))
|
|
{
|
|
if (AllocatedBuffer) ExFreePool(Buffer);
|
|
return Status;
|
|
}
|
|
|
|
if (ClientContext)
|
|
{
|
|
NpFreeClientSecurityContext(Ccb->ClientContext);
|
|
Ccb->ClientContext = ClientContext;
|
|
}
|
|
}
|
|
|
|
WriteIrp = NpRemoveDataQueueEntry(WriteQueue, TRUE, List);
|
|
if (WriteIrp)
|
|
{
|
|
*BytesNotWritten -= BufferSize;
|
|
WriteIrp->IoStatus.Information = BufferSize;
|
|
|
|
if (AllocatedBuffer)
|
|
{
|
|
WriteIrp->AssociatedIrp.SystemBuffer = Buffer;
|
|
WriteIrp->Flags |= IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO | IRP_INPUT_OPERATION;
|
|
}
|
|
|
|
if (!*BytesNotWritten)
|
|
{
|
|
MoreProcessing = FALSE;
|
|
WriteIrp->IoStatus.Status = STATUS_SUCCESS;
|
|
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
|
continue;
|
|
}
|
|
|
|
if (Mode == FILE_PIPE_MESSAGE_MODE)
|
|
{
|
|
WriteIrp->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
|
|
}
|
|
else
|
|
{
|
|
WriteIrp->IoStatus.Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
InsertTailList(List, &WriteIrp->Tail.Overlay.ListEntry);
|
|
}
|
|
else if (AllocatedBuffer)
|
|
{
|
|
ExFreePool(Buffer);
|
|
}
|
|
}
|
|
|
|
if (*BytesNotWritten > 0 || MoreProcessing)
|
|
{
|
|
ASSERT(WriteQueue->QueueState != ReadEntries);
|
|
Status = STATUS_MORE_PROCESSING_REQUIRED;
|
|
}
|
|
else
|
|
{
|
|
Status = STATUS_SUCCESS;
|
|
}
|
|
|
|
return Status;
|
|
}
|
|
|
|
/* EOF */
|