mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
NPFS read/write functionality.
svn path=/trunk/; revision=2309
This commit is contained in:
parent
26090a1b08
commit
f611cbbe42
5 changed files with 441 additions and 80 deletions
|
@ -1,4 +1,4 @@
|
|||
/* $Id: create.c,v 1.9 2001/10/20 15:30:07 ekohl Exp $
|
||||
/* $Id: create.c,v 1.10 2001/10/21 18:58:31 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include "npfs.h"
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
|
@ -178,7 +178,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
{
|
||||
PIO_STACK_LOCATION IoStack;
|
||||
PFILE_OBJECT FileObject;
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
PNPFS_DEVICE_EXTENSION DeviceExt;
|
||||
PNPFS_PIPE Pipe;
|
||||
PNPFS_FCB Fcb;
|
||||
|
@ -239,7 +238,13 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
InitializeListHead(&Pipe->ClientFcbListHead);
|
||||
KeInitializeSpinLock(&Pipe->FcbListLock);
|
||||
|
||||
InitializeListHead(&Pipe->ServerDataListHead);
|
||||
KeInitializeSpinLock(&Pipe->ServerDataListLock);
|
||||
InitializeListHead(&Pipe->ClientDataListHead);
|
||||
KeInitializeSpinLock(&Pipe->ClientDataListLock);
|
||||
|
||||
Pipe->PipeType = Buffer->WriteModeMessage;
|
||||
Pipe->PipeWriteMode = Buffer->WriteModeMessage;
|
||||
Pipe->PipeReadMode = Buffer->ReadModeMessage;
|
||||
Pipe->PipeBlockMode = Buffer->NonBlocking;
|
||||
Pipe->PipeConfiguration = IoStack->Parameters.Create.Options & 0x3;
|
||||
|
@ -300,12 +305,12 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
FileObject->FsContext = Fcb;
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Status = STATUS_SUCCESS;
|
||||
Irp->IoStatus.Information = 0;
|
||||
|
||||
IoCompleteRequest(Irp, IO_NO_INCREMENT);
|
||||
|
||||
return(Status);
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: fsctrl.c,v 1.6 2001/10/20 15:30:07 ekohl Exp $
|
||||
/* $Id: fsctrl.c,v 1.7 2001/10/21 18:58:31 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -13,7 +13,7 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include "npfs.h"
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
|
@ -203,6 +203,154 @@ NpfsWaitPipe(PIRP Irp,
|
|||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NpfsGetState(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
/*
|
||||
* FUNCTION: Return current state of a pipe
|
||||
* ARGUMENTS:
|
||||
* Irp = Pointer to I/O request packet
|
||||
* IrpSp = Pointer to current stack location of Irp
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
ULONG OutputBufferLength;
|
||||
PNPFS_GET_STATE Reply;
|
||||
NTSTATUS Status;
|
||||
PNPFS_PIPE Pipe;
|
||||
PNPFS_FCB Fcb;
|
||||
|
||||
OutputBufferLength = IrpSp->Parameters.DeviceIoControl.OutputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if (OutputBufferLength >= sizeof(NPFS_GET_STATE))
|
||||
{
|
||||
Fcb = IrpSp->FileObject->FsContext;
|
||||
Reply = (PNPFS_GET_STATE)Irp->AssociatedIrp.SystemBuffer;
|
||||
Pipe = Fcb->Pipe;
|
||||
|
||||
if (Pipe->PipeWriteMode == FILE_PIPE_MESSAGE_MODE)
|
||||
{
|
||||
Reply->WriteModeMessage = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Reply->WriteModeMessage = FALSE;
|
||||
}
|
||||
|
||||
if (Pipe->PipeReadMode == FILE_PIPE_MESSAGE_MODE)
|
||||
{
|
||||
Reply->ReadModeMessage = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Reply->ReadModeMessage = FALSE;
|
||||
}
|
||||
|
||||
if (Pipe->PipeBlockMode == FILE_PIPE_QUEUE_OPERATION)
|
||||
{
|
||||
Reply->NonBlocking = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Reply->NonBlocking = FALSE;
|
||||
}
|
||||
|
||||
Reply->InBufferSize = Pipe->InboundQuota;
|
||||
|
||||
Reply->OutBufferSize = Pipe->OutboundQuota;
|
||||
|
||||
Reply->Timeout = Pipe->TimeOut;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
DPRINT("Status (0x%X).\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
static NTSTATUS
|
||||
NpfsSetState(
|
||||
PIRP Irp,
|
||||
PIO_STACK_LOCATION IrpSp)
|
||||
/*
|
||||
* FUNCTION: Set state of a pipe
|
||||
* ARGUMENTS:
|
||||
* Irp = Pointer to I/O request packet
|
||||
* IrpSp = Pointer to current stack location of Irp
|
||||
* RETURNS:
|
||||
* Status of operation
|
||||
*/
|
||||
{
|
||||
ULONG InputBufferLength;
|
||||
PNPFS_SET_STATE Request;
|
||||
PNPFS_PIPE Pipe;
|
||||
NTSTATUS Status;
|
||||
PNPFS_FCB Fcb;
|
||||
|
||||
InputBufferLength = IrpSp->Parameters.DeviceIoControl.InputBufferLength;
|
||||
|
||||
/* Validate parameters */
|
||||
if (InputBufferLength >= sizeof(NPFS_SET_STATE))
|
||||
{
|
||||
Fcb = IrpSp->FileObject->FsContext;
|
||||
Request = (PNPFS_SET_STATE)Irp->AssociatedIrp.SystemBuffer;
|
||||
Pipe = Fcb->Pipe;
|
||||
|
||||
if (Request->WriteModeMessage)
|
||||
{
|
||||
Pipe->PipeWriteMode = FILE_PIPE_MESSAGE_MODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe->PipeWriteMode = FILE_PIPE_BYTE_STREAM_MODE;
|
||||
}
|
||||
|
||||
if (Request->ReadModeMessage)
|
||||
{
|
||||
Pipe->PipeReadMode = FILE_PIPE_MESSAGE_MODE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe->PipeReadMode = FILE_PIPE_BYTE_STREAM_MODE;
|
||||
}
|
||||
|
||||
if (Request->NonBlocking)
|
||||
{
|
||||
Pipe->PipeBlockMode = FILE_PIPE_QUEUE_OPERATION;
|
||||
}
|
||||
else
|
||||
{
|
||||
Pipe->PipeBlockMode = FILE_PIPE_COMPLETE_OPERATION;
|
||||
}
|
||||
|
||||
Pipe->InboundQuota = Request->InBufferSize;
|
||||
|
||||
Pipe->OutboundQuota = Request->OutBufferSize;
|
||||
|
||||
Pipe->TimeOut = Request->Timeout;
|
||||
|
||||
Status = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = STATUS_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
DPRINT("Status (0x%X).\n", Status);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
|
||||
PIRP Irp)
|
||||
|
@ -229,9 +377,9 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
|
|||
|
||||
switch (IoStack->Parameters.FileSystemControl.IoControlCode)
|
||||
{
|
||||
case FSCTL_PIPE_LISTEN:
|
||||
DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
|
||||
Status = NpfsConnectPipe(Fcb);
|
||||
case FSCTL_PIPE_ASSIGN_EVENT:
|
||||
DPRINT("Assign event\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_DISCONNECT:
|
||||
|
@ -239,11 +387,76 @@ NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
|
|||
Status = NpfsDisconnectPipe(Fcb);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_LISTEN:
|
||||
DPRINT("Connecting pipe %wZ\n", &Pipe->PipeName);
|
||||
Status = NpfsConnectPipe(Fcb);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_PEEK:
|
||||
DPRINT("Peek\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_QUERY_EVENT:
|
||||
DPRINT("Query event\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_TRANSCEIVE:
|
||||
DPRINT("Transceive\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_WAIT:
|
||||
DPRINT("Waiting for pipe %wZ\n", &Pipe->PipeName);
|
||||
Status = NpfsWaitPipe(Irp, Fcb);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_IMPERSONATE:
|
||||
DPRINT("Impersonate\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_SET_CLIENT_PROCESS:
|
||||
DPRINT("Set client process\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
|
||||
DPRINT("Query client process\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_GET_STATE:
|
||||
DPRINT("Get state\n");
|
||||
Status = NpfsGetState(Irp, IoStack);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_SET_STATE:
|
||||
DPRINT("Set state\n");
|
||||
Status = NpfsSetState(Irp, IoStack);
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_READ:
|
||||
DPRINT("Internal read\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_WRITE:
|
||||
DPRINT("Internal write\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
|
||||
DPRINT("Internal transceive\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
|
||||
DPRINT("Internal read overflow\n");
|
||||
Status = STATUS_NOT_IMPLEMENTED;
|
||||
break;
|
||||
|
||||
default:
|
||||
DPRINT("IoControlCode: %x\n", IoStack->Parameters.FileSystemControl.IoControlCode)
|
||||
Status = STATUS_UNSUCCESSFUL;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: npfs.c,v 1.1 2001/07/29 16:40:20 ekohl Exp $
|
||||
/* $Id: npfs.c,v 1.2 2001/10/21 18:58:31 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -12,9 +12,10 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include "npfs.h"
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
|
@ -75,6 +76,15 @@ DriverEntry(PDRIVER_OBJECT DriverObject,
|
|||
KeInitializeMutex(&DeviceExtension->PipeListLock,
|
||||
0);
|
||||
|
||||
ExInitializeNPagedLookasideList(
|
||||
&NpfsPipeDataLookasideList,
|
||||
NULL,
|
||||
NULL,
|
||||
0,
|
||||
sizeof(NPFS_PIPE_DATA),
|
||||
TAG('N', 'P', 'D', 'A'),
|
||||
0);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,14 @@ typedef struct
|
|||
KMUTEX PipeListLock;
|
||||
} NPFS_DEVICE_EXTENSION, *PNPFS_DEVICE_EXTENSION;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
ULONG Size;
|
||||
PVOID Data;
|
||||
ULONG Offset;
|
||||
} NPFS_PIPE_DATA, *PNPFS_PIPE_DATA;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
UNICODE_STRING PipeName;
|
||||
|
@ -15,9 +23,16 @@ typedef struct
|
|||
KSPIN_LOCK FcbListLock;
|
||||
LIST_ENTRY ServerFcbListHead;
|
||||
LIST_ENTRY ClientFcbListHead;
|
||||
/* Server posted data */
|
||||
LIST_ENTRY ServerDataListHead;
|
||||
KSPIN_LOCK ServerDataListLock;
|
||||
/* Client posted data */
|
||||
LIST_ENTRY ClientDataListHead;
|
||||
KSPIN_LOCK ClientDataListLock;
|
||||
ULONG ReferenceCount;
|
||||
ULONG PipeType;
|
||||
ULONG PipeReadMode;
|
||||
ULONG PipeWriteMode;
|
||||
ULONG PipeBlockMode;
|
||||
ULONG PipeConfiguration;
|
||||
ULONG MaximumInstances;
|
||||
|
@ -40,6 +55,9 @@ typedef struct _NPFS_FCB
|
|||
} NPFS_FCB, *PNPFS_FCB;
|
||||
|
||||
|
||||
extern NPAGED_LOOKASIDE_LIST NpfsPipeDataLookasideList;
|
||||
|
||||
|
||||
#define KeLockMutex(x) KeWaitForSingleObject(x, \
|
||||
UserRequest, \
|
||||
KernelMode, \
|
||||
|
@ -48,6 +66,8 @@ typedef struct _NPFS_FCB
|
|||
|
||||
#define KeUnlockMutex(x) KeReleaseMutex(x, FALSE);
|
||||
|
||||
#define CP DPRINT("\n");
|
||||
|
||||
NTSTATUS STDCALL NpfsCreate(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
NTSTATUS STDCALL NpfsClose(PDEVICE_OBJECT DeviceObject, PIRP Irp);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $Id: rw.c,v 1.3 2001/07/29 16:40:20 ekohl Exp $
|
||||
/* $Id: rw.c,v 1.4 2001/10/21 18:58:32 chorns Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
|
@ -12,12 +12,71 @@
|
|||
#include <ddk/ntddk.h>
|
||||
#include "npfs.h"
|
||||
|
||||
//#define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
static inline VOID NpfsFreePipeData(
|
||||
PNPFS_PIPE_DATA PipeData)
|
||||
{
|
||||
if (PipeData->Data)
|
||||
{
|
||||
ExFreePool(PipeData->Data);
|
||||
}
|
||||
|
||||
ExFreeToNPagedLookasideList(&NpfsPipeDataLookasideList, PipeData);
|
||||
}
|
||||
|
||||
|
||||
static inline PNPFS_PIPE_DATA
|
||||
NpfsAllocatePipeData(
|
||||
PVOID Data,
|
||||
ULONG Size)
|
||||
{
|
||||
PNPFS_PIPE_DATA PipeData;
|
||||
|
||||
PipeData = ExAllocateFromNPagedLookasideList(&NpfsPipeDataLookasideList);
|
||||
if (!PipeData)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
PipeData->Data = Data;
|
||||
PipeData->Size = Size;
|
||||
PipeData->Offset = 0;
|
||||
|
||||
return PipeData;
|
||||
}
|
||||
|
||||
|
||||
static inline PNPFS_PIPE_DATA
|
||||
NpfsInitializePipeData(
|
||||
PVOID Data,
|
||||
ULONG Size)
|
||||
{
|
||||
PNPFS_PIPE_DATA PipeData;
|
||||
PVOID Buffer;
|
||||
|
||||
Buffer = ExAllocatePool(NonPagedPool, Size);
|
||||
if (!Buffer)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RtlMoveMemory(Buffer, Data, Size);
|
||||
|
||||
PipeData = NpfsAllocatePipeData(Buffer, Size);
|
||||
if (!PipeData)
|
||||
{
|
||||
ExFreePool(Buffer);
|
||||
}
|
||||
|
||||
return PipeData;
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS STDCALL
|
||||
NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
{
|
||||
|
@ -26,56 +85,92 @@ NpfsRead(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
|||
NTSTATUS Status;
|
||||
PNPFS_DEVICE_EXTENSION DeviceExt;
|
||||
PWSTR PipeName;
|
||||
// PNPFS_FSCONTEXT PipeDescr;
|
||||
KIRQL oldIrql;
|
||||
PLIST_ENTRY current_entry;
|
||||
// PNPFS_CONTEXT current;
|
||||
KIRQL OldIrql;
|
||||
PLIST_ENTRY CurrentEntry;
|
||||
PNPFS_PIPE_DATA Current;
|
||||
ULONG Information;
|
||||
PNPFS_FCB Fcb;
|
||||
PNPFS_PIPE Pipe;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
ULONG CopyLength;
|
||||
|
||||
DPRINT1("NpfsRead()\n");
|
||||
DPRINT("NpfsRead(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
|
||||
|
||||
DeviceExt = (PNPFS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
|
||||
IoStack = IoGetCurrentIrpStackLocation(Irp);
|
||||
FileObject = IoStack->FileObject;
|
||||
|
||||
Fcb = FileObject->FsContext;
|
||||
Pipe = Fcb->Pipe;
|
||||
Status = STATUS_SUCCESS;
|
||||
Information = 0;
|
||||
|
||||
#if 0
|
||||
PipeDescr = FileObject->FsContext;
|
||||
|
||||
if (PipeType & NPFS_READMODE_BYTE)
|
||||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
PNPFS_MSG current;
|
||||
KIRQL oldIrql;
|
||||
ULONG Length;
|
||||
PVOID Buffer;
|
||||
|
||||
KeAcquireSpinLock(&PipeDescr->MsgListLock, &oldIrql);
|
||||
current_entry = PipeDescr->MsgListHead.Flink;
|
||||
Information = 0;
|
||||
Length = IoStack->Parameters.Read.Length;
|
||||
|
||||
DPRINT("Irp->MdlAddress %p\n", Irp->MdlAddress);
|
||||
|
||||
Buffer = MmGetSystemAddressForMdl(Irp->MdlAddress);
|
||||
while (Length > 0 &&
|
||||
current_entry != &PipeDescr->MsgListHead)
|
||||
KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
|
||||
|
||||
if (Pipe->PipeReadMode & FILE_PIPE_BYTE_STREAM_MODE)
|
||||
{
|
||||
current = CONTAINING_RECORD(current_entry,
|
||||
NPFS_MSG,
|
||||
ListEntry);
|
||||
DPRINT("Byte stream mode\n");
|
||||
|
||||
memcpy(Buffer, current->Buffer, current->Length);
|
||||
Buffer = Buffer + current->Length;
|
||||
Length = Length - current->Length;
|
||||
Information = Information + current->Length;
|
||||
/* Byte stream mode */
|
||||
Information = 0;
|
||||
CurrentEntry = Pipe->ServerDataListHead.Flink;
|
||||
while ((Length > 0) && (CurrentEntry = RemoveHeadList(&Pipe->ServerDataListHead)))
|
||||
{
|
||||
Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
|
||||
|
||||
current_entry = current_entry->Flink;
|
||||
DPRINT("Took pipe data at %p off the queue\n", Current);
|
||||
|
||||
CopyLength = RtlMin(Current->Size, Length);
|
||||
RtlCopyMemory(Buffer,
|
||||
((PVOID)((ULONG_PTR)Current->Data + Current->Offset)),
|
||||
CopyLength);
|
||||
Buffer += CopyLength;
|
||||
Length -= CopyLength;
|
||||
Information += CopyLength;
|
||||
|
||||
/* Update the data buffer */
|
||||
Current->Offset += CopyLength;
|
||||
Current->Size -= CopyLength;
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
|
||||
if ((CurrentEntry != &Pipe->ServerDataListHead) && (Current->Offset != Current->Size))
|
||||
{
|
||||
DPRINT("Putting pipe data at %p back in queue\n", Current);
|
||||
|
||||
/* The caller's buffer could not contain the complete message,
|
||||
so put it back on the queue */
|
||||
InsertHeadList(&Pipe->ServerDataListHead, &Current->ListEntry);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Message mode\n");
|
||||
|
||||
/* Message mode */
|
||||
CurrentEntry = Pipe->ServerDataListHead.Flink;
|
||||
if (CurrentEntry = RemoveHeadList(&Pipe->ServerDataListHead))
|
||||
{
|
||||
Current = CONTAINING_RECORD(CurrentEntry, NPFS_PIPE_DATA, ListEntry);
|
||||
|
||||
DPRINT("Took pipe data at %p off the queue\n", Current);
|
||||
|
||||
/* Truncate the message if the receive buffer is too small */
|
||||
CopyLength = RtlMin(Current->Size, Length);
|
||||
RtlCopyMemory(Buffer, Current->Data, CopyLength);
|
||||
Information = CopyLength;
|
||||
|
||||
Current->Offset += CopyLength;
|
||||
|
||||
CurrentEntry = CurrentEntry->Flink;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
KeReleaseSpinLock(&Pipe->ServerDataListLock, OldIrql);
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Information;
|
||||
|
@ -98,6 +193,8 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
ULONG Length;
|
||||
ULONG Offset;
|
||||
KIRQL OldIrql;
|
||||
PNPFS_PIPE_DATA PipeData;
|
||||
|
||||
DPRINT("NpfsWrite()\n");
|
||||
|
||||
|
@ -113,6 +210,22 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
|
|||
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
|
||||
Offset = IoStack->Parameters.Write.ByteOffset.u.LowPart;
|
||||
|
||||
PipeData = NpfsInitializePipeData(Buffer, Length);
|
||||
if (PipeData)
|
||||
{
|
||||
DPRINT("Attaching pipe data at %p (%d bytes)\n", PipeData, Length);
|
||||
|
||||
KeAcquireSpinLock(&Pipe->ServerDataListLock, &OldIrql);
|
||||
|
||||
InsertTailList(&Pipe->ServerDataListHead, &PipeData->ListEntry);
|
||||
|
||||
KeReleaseSpinLock(&Pipe->ServerDataListLock, OldIrql);
|
||||
}
|
||||
else
|
||||
{
|
||||
Length = 0;
|
||||
Status = STATUS_INSUFFICIENT_RESOURCES;
|
||||
}
|
||||
|
||||
Irp->IoStatus.Status = Status;
|
||||
Irp->IoStatus.Information = Length;
|
||||
|
|
Loading…
Reference in a new issue