- Revert 38790 as i broke autotests.

svn path=/trunk/; revision=38793
This commit is contained in:
Michael Martin 2009-01-16 15:59:03 +00:00
parent a12d7cd371
commit c8ed77432a
4 changed files with 117 additions and 178 deletions

View file

@ -373,9 +373,9 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
return STATUS_INSTANCE_NOT_AVAILABLE; return STATUS_INSTANCE_NOT_AVAILABLE;
} }
/* FIXME: Check pipe modes also! */
if (Fcb->MaximumInstances != Buffer->MaximumInstances || if (Fcb->MaximumInstances != Buffer->MaximumInstances ||
Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart || Fcb->TimeOut.QuadPart != Buffer->DefaultTimeout.QuadPart)
Fcb->PipeType != Buffer->NamedPipeType)
{ {
DPRINT("Asked for invalid pipe mode.\n"); DPRINT("Asked for invalid pipe mode.\n");
ExFreePool(Ccb); ExFreePool(Ccb);
@ -388,7 +388,6 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
{ {
NewPipe = TRUE; NewPipe = TRUE;
Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB)); Fcb = ExAllocatePool(NonPagedPool, sizeof(NPFS_FCB));
if (Fcb == NULL) if (Fcb == NULL)
{ {
KeUnlockMutex(&DeviceExt->PipeListLock); KeUnlockMutex(&DeviceExt->PipeListLock);
@ -421,11 +420,8 @@ NpfsCreateNamedPipe(PDEVICE_OBJECT DeviceObject,
KeInitializeMutex(&Fcb->CcbListLock, 0); KeInitializeMutex(&Fcb->CcbListLock, 0);
Fcb->PipeType = Buffer->NamedPipeType; Fcb->PipeType = Buffer->NamedPipeType;
/* FIXME: Verify which is correct */ Fcb->WriteMode = Buffer->ReadMode;
Fcb->WriteMode = Buffer->ReadMode;//Buffer->NamedPipeType; Fcb->ReadMode = Buffer->ReadMode;
/* MSDN documentation read that clients always start off in byte mode */
Fcb->ReadMode = FILE_PIPE_BYTE_STREAM_MODE;
Fcb->CompletionMode = Buffer->CompletionMode; Fcb->CompletionMode = Buffer->CompletionMode;
switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE)) switch (IoStack->Parameters.CreatePipe.ShareAccess & (FILE_SHARE_READ|FILE_SHARE_WRITE))
{ {
@ -741,10 +737,6 @@ NpfsClose(PDEVICE_OBJECT DeviceObject,
DPRINT("Client\n"); DPRINT("Client\n");
} }
/* Disconnect the pipes */
if (Ccb->OtherSide) Ccb->OtherSide->OtherSide = NULL;
if (Ccb) Ccb->OtherSide = NULL;
ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE); ASSERT(Ccb->PipeState == FILE_PIPE_CLOSING_STATE);
FileObject->FsContext2 = NULL; FileObject->FsContext2 = NULL;

View file

@ -30,12 +30,6 @@ NpfsSetPipeInformation(PDEVICE_OBJECT DeviceObject,
Fcb = Ccb->Fcb; Fcb = Ccb->Fcb;
Request = (PFILE_PIPE_INFORMATION)Info; Request = (PFILE_PIPE_INFORMATION)Info;
if ((Fcb->PipeType == FILE_PIPE_BYTE_STREAM_MODE) && (Request->ReadMode == FILE_PIPE_MESSAGE_MODE))
{
DPRINT("Cannot change readmode to message type on a byte type pipe!\n");
return STATUS_ACCESS_DENIED;
}
/* Set Pipe Data */ /* Set Pipe Data */
Fcb->ReadMode = Request->ReadMode; Fcb->ReadMode = Request->ReadMode;
Fcb->CompletionMode = Request->CompletionMode; Fcb->CompletionMode = Request->CompletionMode;

View file

@ -202,7 +202,7 @@ NpfsDisconnectPipe(PNPFS_CCB Ccb)
{ {
Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END); Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
OtherSide = Ccb->OtherSide; OtherSide = Ccb->OtherSide;
//Ccb->OtherSide = NULL; Ccb->OtherSide = NULL;
Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE; Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
/* Lock the server first */ /* Lock the server first */
if (Server) if (Server)
@ -216,7 +216,7 @@ NpfsDisconnectPipe(PNPFS_CCB Ccb)
ExAcquireFastMutex(&Ccb->DataListLock); ExAcquireFastMutex(&Ccb->DataListLock);
} }
OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE; OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
//OtherSide->OtherSide = NULL; OtherSide->OtherSide = NULL;
/* /*
* Signaling the write event. If is possible that an other * Signaling the write event. If is possible that an other
* thread waits for an empty buffer. * thread waits for an empty buffer.
@ -365,7 +365,6 @@ NpfsPeekPipe(PIRP Irp,
PIO_STACK_LOCATION IoStack) PIO_STACK_LOCATION IoStack)
{ {
ULONG OutputBufferLength; ULONG OutputBufferLength;
ULONG ReturnLength = 0;
PFILE_PIPE_PEEK_BUFFER Reply; PFILE_PIPE_PEEK_BUFFER Reply;
PNPFS_FCB Fcb; PNPFS_FCB Fcb;
PNPFS_CCB Ccb; PNPFS_CCB Ccb;
@ -397,21 +396,11 @@ NpfsPeekPipe(PIRP Irp,
Reply->ReadDataAvailable = Ccb->ReadDataAvailable; Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable); DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
ExAcquireFastMutex(&Ccb->DataListLock); if (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
BufferPtr = Ccb->Data;
DPRINT("BufferPtr = %x\n", BufferPtr);
if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_MODE)
{ {
DPRINT("Byte Stream Mode\n"); DPRINT("Byte Stream Mode\n");
Reply->MessageLength = Ccb->ReadDataAvailable; Reply->MessageLength = Ccb->ReadDataAvailable;
DPRINT("Reply->MessageLength %lu\n",Reply->MessageLength ); DPRINT("Reply->MessageLength %d\n",Reply->MessageLength );
MessageCount = 1;
ReturnLength = Ccb->ReadDataAvailable;
if (Reply->Data[0] && (OutputBufferLength >= ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
{
memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
}
} }
else else
{ {
@ -421,7 +410,7 @@ NpfsPeekPipe(PIRP Irp,
if (ReadDataAvailable > 0) if (ReadDataAvailable > 0)
{ {
memcpy(&Reply->MessageLength,Ccb->Data,sizeof(ULONG)); memcpy(&Reply->MessageLength,Ccb->Data,sizeof(ULONG));
BufferPtr = Ccb->Data;
/* NOTE: Modifying the structure in header file to keep track of NumberOfMessage would be better */ /* NOTE: Modifying the structure in header file to keep track of NumberOfMessage would be better */
while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr)) while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
{ {
@ -429,37 +418,34 @@ NpfsPeekPipe(PIRP Irp,
ASSERT(MessageLength > 0); ASSERT(MessageLength > 0);
DPRINT("MessageLength = %lu\n",MessageLength); DPRINT("MessageLength = %d\n",MessageLength);
MessageCount++; MessageCount++;
ReadDataAvailable -= MessageLength; ReadDataAvailable -= MessageLength;
/* If its the first message, copy the Message if the size of buffer is large enough */ /* If its the first message, copy the Message if the size of buffer is large enough */
if (MessageCount==1) if ((MessageCount==1) && (Reply->Data[0])
&& (OutputBufferLength >= (sizeof(FILE_PIPE_PEEK_BUFFER) + MessageLength)))
{ {
ReturnLength = MessageLength; memcpy(&Reply->Data[0], (PVOID)((ULONG)BufferPtr + sizeof(MessageLength)), MessageLength);
if ((Reply->Data[0])
&& (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
{
memcpy(&Reply->Data[0], (PVOID)((ULONG)BufferPtr + sizeof(MessageLength)), MessageLength);
}
} }
BufferPtr =(PVOID)((ULONG)BufferPtr + MessageLength + sizeof(MessageLength)); BufferPtr =(PVOID)((ULONG)BufferPtr + MessageLength + sizeof(MessageLength));
DPRINT("BufferPtr = %x\n", BufferPtr); DPRINT("Message %d\n",MessageCount);
DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable); DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
} }
if (ReadDataAvailable != 0) if (ReadDataAvailable != 0)
{ {
DPRINT1("Possible memory corruption.\n"); DPRINT1("This should never happen! Possible memory corruption.\n");
ASSERT(FALSE); return STATUS_UNSUCCESSFUL;
} }
} }
} }
ExReleaseFastMutex(&Ccb->DataListLock);
Reply->NumberOfMessages = MessageCount; Reply->NumberOfMessages = MessageCount;
if (MessageCount > 0)
Reply->Data[0] = 0;
Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]); Irp->IoStatus.Information = OutputBufferLength;
Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Status = STATUS_SUCCESS;
Status = STATUS_SUCCESS; Status = STATUS_SUCCESS;

View file

@ -16,6 +16,7 @@
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
#ifndef NDEBUG
VOID HexDump(PUCHAR Buffer, ULONG Length) VOID HexDump(PUCHAR Buffer, ULONG Length)
{ {
CHAR Line[65]; CHAR Line[65];
@ -41,6 +42,7 @@ VOID HexDump(PUCHAR Buffer, ULONG Length)
} }
DbgPrint("---------------\n"); DbgPrint("---------------\n");
} }
#endif
static DRIVER_CANCEL NpfsReadWriteCancelRoutine; static DRIVER_CANCEL NpfsReadWriteCancelRoutine;
static VOID NTAPI static VOID NTAPI
@ -358,6 +360,7 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
Irp->RequestorMode, Irp->RequestorMode,
FALSE, FALSE,
NULL); NULL);
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC)) if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
{ {
Status = STATUS_CANCELLED; Status = STATUS_CANCELLED;
@ -446,7 +449,7 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
Irp->RequestorMode, Irp->RequestorMode,
FALSE, FALSE,
NULL); NULL);
DPRINT("Finished waiting (%wZ)! Status: %x\n", &Ccb->Fcb->PipeName, Status); DPRINT("Finished waiting (%wZ)! Status: %x\n", &Ccb->Fcb->PipeName, Status);
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC)) if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
{ {
@ -477,11 +480,9 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
} }
} }
ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL); ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
if (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
/* If the pipe type and read mode are both byte stream */
if ((Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_MODE) && (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE))
{ {
DPRINT("Byte stream mode: Ccb->Data %x\n", Ccb->Data); DPRINT("Byte stream mode\n");
/* Byte stream mode */ /* Byte stream mode */
while (Length > 0 && Ccb->ReadDataAvailable > 0) while (Length > 0 && Ccb->ReadDataAvailable > 0)
{ {
@ -521,136 +522,116 @@ NpfsRead(IN PDEVICE_OBJECT DeviceObject,
break; break;
} }
} }
else if (Ccb->Fcb->PipeType == FILE_PIPE_MESSAGE_MODE) else
{ {
ULONG ThisCopyLength = 0; DPRINT("Message mode\n");
ULONG TotalLengthNeeded = min(Length, Ccb->ReadDataAvailable);
DPRINT("Message mode: Ccb>Data %x\n", Ccb->Data); /* For Message mode, the Message length will be stored in the buffer preceeding the Message. */
if (Ccb->ReadDataAvailable)
do
{ {
Buffer = (PVOID)((ULONG_PTR)Buffer + ThisCopyLength); ULONG NextMessageLength=0;
//HexDump(Ccb->Data, (ULONG)Ccb->WritePtr - (ULONG)Ccb->Data);
/* For Message mode, the Message length will be stored in the buffer preceeding the Message. */ /*First get the size of the message */
if (Ccb->ReadDataAvailable) memcpy(&NextMessageLength, Ccb->Data, sizeof(NextMessageLength));
if ((NextMessageLength == 0) || (NextMessageLength > Ccb->ReadDataAvailable))
{ {
ULONG NextMessageLength = 0; DPRINT1("This should never happen! Possible memory corruption.\n");
#ifndef NDEBUG
HexDump(Ccb->Data, (ULONG)Ccb->WritePtr - (ULONG)Ccb->Data);
#endif
ASSERT(FALSE);
}
/*First get the size of the message */ /* Use the smaller value */
memcpy(&NextMessageLength, Ccb->Data, sizeof(NextMessageLength));
if ((NextMessageLength == 0) || (NextMessageLength > Ccb->ReadDataAvailable)) CopyLength = min(NextMessageLength, Length);
/* retrieve the message from the buffer */
memcpy(Buffer, (PVOID)((ULONG)Ccb->Data + sizeof(NextMessageLength)), CopyLength);
if (Ccb->ReadDataAvailable > CopyLength)
{
if (CopyLength < NextMessageLength)
{ {
DPRINT("Possible memory corruption.\n"); /* Client only requested part of the message */
HexDump(Ccb->Data, (ULONG_PTR)Ccb->WritePtr - (ULONG_PTR)Ccb->Data);
ASSERT(FALSE);
}
/* Use the smaller value */ /* Calculate the remaining message new size */
ThisCopyLength = min(NextMessageLength, Length); ULONG NewMessageSize = NextMessageLength-CopyLength;
/* retrieve the message from the buffer */ /* Write a new Message size to buffer for the part of the message still there */
memcpy(Buffer, (PVOID)((ULONG_PTR)Ccb->Data + sizeof(NextMessageLength)), ThisCopyLength); memcpy(Ccb->Data, &NewMessageSize, sizeof(NewMessageSize));
if (Ccb->ReadDataAvailable > ThisCopyLength) /* Move the memory starting from end of partial Message just retrieved */
{ memmove((PVOID)((ULONG_PTR)Ccb->Data + sizeof(NewMessageSize)),
if (ThisCopyLength < NextMessageLength) (PVOID)((ULONG_PTR) Ccb->Data + CopyLength + sizeof(NewMessageSize)),
{ (ULONG)Ccb->WritePtr - ((ULONG)Ccb->Data + sizeof(NewMessageSize)) - CopyLength);
/* Client only requested part of the message */
/* Calculate the remaining message new size */ /* Update the write pointer */
ULONG NewMessageSize = NextMessageLength-ThisCopyLength; Ccb->WritePtr = (PVOID)((ULONG)Ccb->WritePtr - CopyLength);
/* Write a new Message size to buffer for the part of the message still there */ /* Add CopyLength only to WriteQuotaAvailable as the
memcpy(Ccb->Data, &NewMessageSize, sizeof(NewMessageSize)); Message Size was replaced in the buffer */
Ccb->WriteQuotaAvailable += CopyLength;
/* Move the memory starting from end of partial Message just retrieved */
memmove((PVOID)((ULONG_PTR)Ccb->Data + sizeof(NewMessageSize)),
(PVOID)((ULONG_PTR)Ccb->Data + ThisCopyLength + sizeof(NewMessageSize)),
(ULONG_PTR)Ccb->WritePtr - ((ULONG_PTR)Ccb->Data + sizeof(NewMessageSize)) -
ThisCopyLength);
/* Update the write pointer */
Ccb->WritePtr = (PVOID)((ULONG_PTR)Ccb->WritePtr - ThisCopyLength);
/* Add ThisCopyLength only to WriteQuotaAvailable as the
Message Size was replaced in the buffer */
Ccb->WriteQuotaAvailable += ThisCopyLength;
}
else
{
/* Client wanted the entire message */
/* Move the memory starting from the next Message just retrieved */
memmove(Ccb->Data,
(PVOID)((ULONG_PTR) Ccb->Data + NextMessageLength + sizeof(NextMessageLength)),
(ULONG_PTR)Ccb->WritePtr - (ULONG_PTR)Ccb->Data - NextMessageLength -
sizeof(NextMessageLength));
/* Update the write pointer */
Ccb->WritePtr = (PVOID)((ULONG_PTR)Ccb->WritePtr - ThisCopyLength -
sizeof(NextMessageLength));
/* Add both the message length and the header to the WriteQuotaAvailable
as they both were removed */
Ccb->WriteQuotaAvailable += (ThisCopyLength + sizeof(NextMessageLength));
}
} }
else else
{ {
/* This was the last Message, so just zero this messages for safety sake */ /* Client wanted the entire message */
memset(Ccb->Data, 0, NextMessageLength + sizeof(NextMessageLength));
/* reset the write pointer to beginning of buffer */ /* Move the memory starting from the next Message just retrieved */
Ccb->WritePtr = Ccb->Data; memmove(Ccb->Data,
(PVOID)((ULONG_PTR) Ccb->Data + NextMessageLength + sizeof(NextMessageLength)),
(ULONG)Ccb->WritePtr - (ULONG)Ccb->Data - NextMessageLength - sizeof(NextMessageLength));
/* Update the write pointer */
Ccb->WritePtr = (PVOID)((ULONG)Ccb->WritePtr - NextMessageLength);
/* Add both the message length and the header to the WriteQuotaAvailable /* Add both the message length and the header to the WriteQuotaAvailable
as they both were removed */ as they both were removed */
Ccb->WriteQuotaAvailable += (ThisCopyLength + sizeof(ULONG)); Ccb->WriteQuotaAvailable += (CopyLength + sizeof(NextMessageLength));
KeResetEvent(&Ccb->ReadEvent);
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
}
} }
}
else
{
/* This was the last Message, so just zero this messages for safety sake */
memset(Ccb->Data,0,NextMessageLength + sizeof(NextMessageLength));
/* reset the write pointer to beginning of buffer */
Ccb->WritePtr = Ccb->Data;
/* Add both the message length and the header to the WriteQuotaAvailable
as they both were removed */
Ccb->WriteQuotaAvailable += (CopyLength + sizeof(ULONG));
KeResetEvent(&Ccb->ReadEvent);
if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
{
KeSetEvent(&Ccb->OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
}
}
#ifndef NDEBUG #ifndef NDEBUG
DPRINT("Length %d Buffer %x\n",ThisCopyLength,Buffer); DPRINT("Length %d Buffer %x\n",CopyLength,Buffer);
HexDump((PUCHAR)Buffer, ThisCopyLength); HexDump((PUCHAR)Buffer, CopyLength);
#endif #endif
Information += ThisCopyLength; Information += CopyLength;
Ccb->ReadDataAvailable -= ThisCopyLength; Ccb->ReadDataAvailable -= CopyLength;
if ((ULONG)Ccb->WriteQuotaAvailable > (ULONG)Ccb->MaxDataLength) ASSERT(FALSE);
}
}while ((ThisCopyLength < TotalLengthNeeded)
&& (Ccb->Fcb->ReadMode == FILE_PIPE_BYTE_STREAM_MODE)
&& (Ccb->ReadDataAvailable));
if ((ULONG)Ccb->WriteQuotaAvailable > (ULONG)Ccb->MaxDataLength) ASSERT(FALSE);
}
if (Information > 0) if (Information > 0)
{ {
break; break;
} }
} }
else
{
DPRINT1("Unhandled Pipe Mode with Read Mode!\n");
ASSERT(FALSE);
}
} }
Irp->IoStatus.Information = Information; Irp->IoStatus.Information = Information;
Irp->IoStatus.Status = Status; Irp->IoStatus.Status = Status;
ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL); ASSERT(IoGetCurrentIrpStackLocation(Irp)->FileObject != NULL);
if (Status == STATUS_CANCELLED)
goto done;
if (IoIsOperationSynchronous(Irp)) if (IoIsOperationSynchronous(Irp))
{ {
RemoveEntryList(&Context->ListEntry); RemoveEntryList(&Context->ListEntry);
@ -737,15 +718,15 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
if (Irp->MdlAddress == NULL) if (Irp->MdlAddress == NULL)
{ {
DPRINT("Irp->MdlAddress == NULL\n"); DPRINT1("Irp->MdlAddress == NULL\n");
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
Length = 0; Length = 0;
goto done; goto done;
} }
if ((ReaderCcb == NULL) || (Ccb->PipeState != FILE_PIPE_CONNECTED_STATE)) if (ReaderCcb == NULL)
{ {
DPRINT("Pipe is NOT connected!\n"); DPRINT1("Pipe is NOT connected!\n");
if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE) if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
Status = STATUS_PIPE_LISTENING; Status = STATUS_PIPE_LISTENING;
else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE) else if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
@ -758,7 +739,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
if (ReaderCcb->Data == NULL) if (ReaderCcb->Data == NULL)
{ {
DPRINT("Pipe is NOT writable!\n"); DPRINT1("Pipe is NOT writable!\n");
Status = STATUS_UNSUCCESSFUL; Status = STATUS_UNSUCCESSFUL;
Length = 0; Length = 0;
goto done; goto done;
@ -768,7 +749,6 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress); Buffer = MmGetSystemAddressForMdl (Irp->MdlAddress);
ExAcquireFastMutex(&ReaderCcb->DataListLock); ExAcquireFastMutex(&ReaderCcb->DataListLock);
#ifndef NDEBUG #ifndef NDEBUG
DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset); DPRINT("Length %d Buffer %x Offset %x\n",Length,Buffer,Offset);
HexDump(Buffer, Length); HexDump(Buffer, Length);
@ -794,7 +774,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
FALSE, FALSE,
NULL); NULL);
DPRINT("Write Finished waiting (%S)! Status: %x\n", Fcb->PipeName.Buffer, Status); DPRINT("Write Finished waiting (%S)! Status: %x\n", Fcb->PipeName.Buffer, Status);
ExAcquireFastMutex(&ReaderCcb->DataListLock);
if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC)) if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC))
{ {
Status = STATUS_CANCELLED; Status = STATUS_CANCELLED;
@ -812,14 +792,14 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
{ {
DPRINT("PipeState: %x\n", Ccb->PipeState); DPRINT("PipeState: %x\n", Ccb->PipeState);
Status = STATUS_PIPE_BROKEN; Status = STATUS_PIPE_BROKEN;
// ExReleaseFastMutex(&ReaderCcb->DataListLock);
goto done; goto done;
} }
ExAcquireFastMutex(&ReaderCcb->DataListLock);
} }
if ((Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_MODE) && (Ccb->Fcb->WriteMode == FILE_PIPE_BYTE_STREAM_MODE)) if (Fcb->WriteMode == FILE_PIPE_BYTE_STREAM_MODE)
{ {
DPRINT("Byte stream mode: Ccb->Data %x, Ccb->WritePtr %x\n", ReaderCcb->Data, ReaderCcb->WritePtr); DPRINT("Byte stream mode\n");
while (Length > 0 && ReaderCcb->WriteQuotaAvailable > 0) while (Length > 0 && ReaderCcb->WriteQuotaAvailable > 0)
{ {
@ -836,10 +816,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
} }
else else
{ {
TempLength = (ULONG)((ULONG_PTR)ReaderCcb->Data + ReaderCcb->MaxDataLength - (ULONG_PTR)ReaderCcb->WritePtr);
TempLength = (ULONG)((ULONG_PTR)ReaderCcb->Data + ReaderCcb->MaxDataLength -
(ULONG_PTR)ReaderCcb->WritePtr);
memcpy(ReaderCcb->WritePtr, Buffer, TempLength); memcpy(ReaderCcb->WritePtr, Buffer, TempLength);
memcpy(ReaderCcb->Data, Buffer + TempLength, CopyLength - TempLength); memcpy(ReaderCcb->Data, Buffer + TempLength, CopyLength - TempLength);
ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->Data + CopyLength - TempLength); ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->Data + CopyLength - TempLength);
@ -860,38 +837,33 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
break; break;
} }
} }
else if ((Ccb->Fcb->PipeType == FILE_PIPE_MESSAGE_MODE) && (Ccb->Fcb->WriteMode == FILE_PIPE_MESSAGE_MODE)) else
{ {
/* For Message Type Pipe, the Pipes memory will be used to store the size of each message */ /* For Message Type Pipe, the Pipes memory will be used to store the size of each message */
DPRINT("Message mode: Ccb->Data %x, Ccb->WritePtr %x\n",ReaderCcb->Data, ReaderCcb->WritePtr); /* FIXME: Check and verify ReadMode ByteStream */
if (Length > 0) if (Length > 0)
{ {
/* Verify the WritePtr is still inside the buffer */ /* Verify the WritePtr is still inside the buffer */
if (((ULONG_PTR)ReaderCcb->WritePtr > ((ULONG_PTR)ReaderCcb->Data + (ULONG_PTR)ReaderCcb->MaxDataLength)) || if (((ULONG)ReaderCcb->WritePtr > ((ULONG)ReaderCcb->Data + (ULONG)ReaderCcb->MaxDataLength)) ||
((ULONG_PTR)ReaderCcb->WritePtr < (ULONG_PTR)ReaderCcb->Data)) ((ULONG)ReaderCcb->WritePtr < (ULONG)ReaderCcb->Data))
{ {
DPRINT1("NPFS is writing out of its buffer. Report to developer!\n"); DPRINT1("NPFS is writing out of its buffer. Report to developer!\n");
DPRINT1("ReaderCcb->WritePtr %x, ReaderCcb->Data %x, ReaderCcb->MaxDataLength %lu\n", DPRINT1("ReaderCcb->WritePtr %x, ReaderCcb->Data %x, ReaderCcb->MaxDataLength%d\n",
ReaderCcb->WritePtr, ReaderCcb->Data, ReaderCcb->MaxDataLength); ReaderCcb->WritePtr,ReaderCcb->Data,ReaderCcb->MaxDataLength);
ASSERT(FALSE); ASSERT(FALSE);
} }
CopyLength = min(Length, ReaderCcb->WriteQuotaAvailable - sizeof(ULONG)); CopyLength = min(Length, ReaderCcb->WriteQuotaAvailable - sizeof(ULONG));
if (CopyLength > ReaderCcb->WriteQuotaAvailable)
{
DPRINT1("Writing %lu byte to pipe would overflow as only %lu bytes are available\n",
CopyLength, ReaderCcb->ReadDataAvailable);
ASSERT(FALSE);
}
/* First Copy the Length of the message into the pipes buffer */ /* First Copy the Length of the message into the pipes buffer */
memcpy(ReaderCcb->WritePtr, &CopyLength, sizeof(CopyLength)); memcpy(ReaderCcb->WritePtr, &CopyLength, sizeof(CopyLength));
/* Now the user buffer itself */ /* Now the user buffer itself */
memcpy((PVOID)((ULONG_PTR)ReaderCcb->WritePtr + sizeof(CopyLength)), Buffer, CopyLength); memcpy((PVOID)((ULONG)ReaderCcb->WritePtr+ sizeof(CopyLength)), Buffer, CopyLength);
/* Update the write pointer */ /* Update the write pointer */
ReaderCcb->WritePtr = (PVOID)((ULONG_PTR)ReaderCcb->WritePtr + sizeof(CopyLength) + CopyLength); ReaderCcb->WritePtr = (PVOID)((ULONG)ReaderCcb->WritePtr + sizeof(CopyLength) + CopyLength);
Information += CopyLength; Information += CopyLength;
@ -899,7 +871,7 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
ReaderCcb->WriteQuotaAvailable -= (CopyLength + sizeof(ULONG)); ReaderCcb->WriteQuotaAvailable -= (CopyLength + sizeof(ULONG));
if ((ULONG_PTR)ReaderCcb->WriteQuotaAvailable > (ULONG)ReaderCcb->MaxDataLength) if ((ULONG)ReaderCcb->WriteQuotaAvailable > (ULONG)ReaderCcb->MaxDataLength)
{ {
DPRINT1("QuotaAvailable is greater than buffer size!\n"); DPRINT1("QuotaAvailable is greater than buffer size!\n");
ASSERT(FALSE); ASSERT(FALSE);
@ -913,11 +885,6 @@ NpfsWrite(PDEVICE_OBJECT DeviceObject,
break; break;
} }
} }
else
{
DPRINT1("Unhandled Pipe Type Mode and Read Write Mode!\n");
ASSERT(FALSE);
}
} }
ExReleaseFastMutex(&ReaderCcb->DataListLock); ExReleaseFastMutex(&ReaderCcb->DataListLock);