ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

fsctrl.c
Go to the documentation of this file.
00001 /*
00002 * COPYRIGHT:  See COPYING in the top level directory
00003 * PROJECT:    ReactOS kernel
00004 * FILE:       drivers/fs/np/fsctrl.c
00005 * PURPOSE:    Named pipe filesystem
00006 * PROGRAMMER: David Welch <welch@cwcom.net>
00007 *             Eric Kohl
00008 *             Michael Martin
00009 */
00010 
00011 /* INCLUDES ******************************************************************/
00012 
00013 #include "npfs.h"
00014 
00015 #define NDEBUG
00016 #include <debug.h>
00017 
00018 //#define USING_PROPER_NPFS_WAIT_SEMANTICS
00019 
00020 /* FUNCTIONS *****************************************************************/
00021 
00022 static DRIVER_CANCEL NpfsListeningCancelRoutine;
00023 static VOID NTAPI
00024 NpfsListeningCancelRoutine(IN PDEVICE_OBJECT DeviceObject,
00025                            IN PIRP Irp)
00026 {
00027     PNPFS_WAITER_ENTRY Waiter;
00028 
00029     Waiter = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
00030 
00031     DPRINT("NpfsListeningCancelRoutine() called for <%wZ>\n",
00032         &Waiter->Ccb->Fcb->PipeName);
00033 
00034     IoReleaseCancelSpinLock(Irp->CancelIrql);
00035 
00036 
00037     KeLockMutex(&Waiter->Ccb->Fcb->CcbListLock);
00038     RemoveEntryList(&Waiter->Entry);
00039     KeUnlockMutex(&Waiter->Ccb->Fcb->CcbListLock);
00040 
00041     Irp->IoStatus.Status = STATUS_CANCELLED;
00042     Irp->IoStatus.Information = 0;
00043     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00044 }
00045 
00046 
00047 static NTSTATUS
00048 NpfsAddListeningServerInstance(PIRP Irp,
00049                                PNPFS_CCB Ccb)
00050 {
00051     PNPFS_WAITER_ENTRY Entry;
00052     KIRQL oldIrql;
00053 
00054     Entry = (PNPFS_WAITER_ENTRY)&Irp->Tail.Overlay.DriverContext;
00055 
00056     Entry->Ccb = Ccb;
00057 
00058     KeLockMutex(&Ccb->Fcb->CcbListLock);
00059 
00060     IoAcquireCancelSpinLock(&oldIrql);
00061     if (!Irp->Cancel)
00062     {
00063         Ccb->PipeState = FILE_PIPE_LISTENING_STATE;
00064         IoMarkIrpPending(Irp);
00065         InsertTailList(&Ccb->Fcb->WaiterListHead, &Entry->Entry);
00066         (void)IoSetCancelRoutine(Irp, NpfsListeningCancelRoutine);
00067         IoReleaseCancelSpinLock(oldIrql);
00068         KeUnlockMutex(&Ccb->Fcb->CcbListLock);
00069         return STATUS_PENDING;
00070     }
00071     IoReleaseCancelSpinLock(oldIrql);
00072 
00073     RemoveEntryList(&Entry->Entry);
00074 
00075     Irp->IoStatus.Status = STATUS_CANCELLED;
00076     Irp->IoStatus.Information = 0;
00077     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00078     KeUnlockMutex(&Ccb->Fcb->CcbListLock);
00079 
00080     return STATUS_CANCELLED;
00081 }
00082 
00083 
00084 static NTSTATUS
00085 NpfsConnectPipe(PIRP Irp,
00086                 PNPFS_CCB Ccb)
00087 {
00088     PIO_STACK_LOCATION IoStack;
00089     PFILE_OBJECT FileObject;
00090     ULONG Flags;
00091     PLIST_ENTRY current_entry;
00092     PNPFS_FCB Fcb;
00093     PNPFS_CCB ClientCcb;
00094     NTSTATUS Status;
00095     KPROCESSOR_MODE WaitMode;
00096 
00097     DPRINT("NpfsConnectPipe()\n");
00098 
00099     /* Fail, if the CCB is not a pipe CCB */
00100     if (Ccb->Type != CCB_PIPE)
00101     {
00102         DPRINT("Not a pipe\n");
00103         return STATUS_ILLEGAL_FUNCTION;
00104     }
00105 
00106     /* Fail, if the CCB is not a server end CCB */
00107     if (Ccb->PipeEnd != FILE_PIPE_SERVER_END)
00108     {
00109         DPRINT("Not the server end\n");
00110         return STATUS_ILLEGAL_FUNCTION;
00111     }
00112 
00113     if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
00114     {
00115         KeResetEvent(&Ccb->ConnectEvent);
00116         return STATUS_PIPE_CONNECTED;
00117     }
00118 
00119     if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
00120         return STATUS_PIPE_CLOSING;
00121 
00122     DPRINT("Waiting for connection...\n");
00123 
00124     Fcb = Ccb->Fcb;
00125     IoStack = IoGetCurrentIrpStackLocation(Irp);
00126     FileObject = IoStack->FileObject;
00127     Flags = FileObject->Flags;
00128     WaitMode = Irp->RequestorMode;
00129 
00130     /* search for a listening client fcb */
00131     KeLockMutex(&Fcb->CcbListLock);
00132 
00133     current_entry = Fcb->ClientCcbListHead.Flink;
00134     while (current_entry != &Fcb->ClientCcbListHead)
00135     {
00136         ClientCcb = CONTAINING_RECORD(current_entry,
00137             NPFS_CCB,
00138             CcbListEntry);
00139 
00140         if (ClientCcb->PipeState == 0)
00141         {
00142             /* found a passive (waiting) client CCB */
00143             DPRINT("Passive (waiting) client CCB found -- wake the client\n");
00144             KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
00145             break;
00146         }
00147 
00148 #if 0
00149         if (ClientCcb->PipeState == FILE_PIPE_LISTENING_STATE)
00150         {
00151             /* found a listening client CCB */
00152             DPRINT("Listening client CCB found -- connecting\n");
00153 
00154             /* connect client and server CCBs */
00155             Ccb->OtherSide = ClientCcb;
00156             ClientCcb->OtherSide = Ccb;
00157 
00158             /* set connected state */
00159             Ccb->PipeState = FILE_PIPE_CONNECTED_STATE;
00160             ClientCcb->PipeState = FILE_PIPE_CONNECTED_STATE;
00161 
00162             KeUnlockMutex(&Fcb->CcbListLock);
00163 
00164             /* FIXME: create and initialize data queues */
00165 
00166             /* signal client's connect event */
00167             DPRINT("Setting the ConnectEvent for %x\n", ClientCcb);
00168             KeSetEvent(&ClientCcb->ConnectEvent, IO_NO_INCREMENT, FALSE);
00169 
00170             return STATUS_PIPE_CONNECTED;
00171         }
00172 #endif
00173 
00174         current_entry = current_entry->Flink;
00175     }
00176 
00177     /* no listening client fcb found */
00178     DPRINT("No listening client fcb found -- waiting for client\n");
00179 
00180     Status = NpfsAddListeningServerInstance(Irp, Ccb);
00181 
00182     KeUnlockMutex(&Fcb->CcbListLock);
00183 
00184     if ((Status == STATUS_PENDING) && (Flags & FO_SYNCHRONOUS_IO))
00185     {
00186         KeWaitForSingleObject(&Ccb->ConnectEvent,
00187             UserRequest,
00188             WaitMode,
00189             (Flags & FO_ALERTABLE_IO),
00190             NULL);
00191     }
00192 
00193     DPRINT("NpfsConnectPipe() done (Status %lx)\n", Status);
00194 
00195     return Status;
00196 }
00197 
00198 
00199 static NTSTATUS
00200 NpfsDisconnectPipe(PNPFS_CCB Ccb)
00201 {
00202     NTSTATUS Status;
00203     PNPFS_FCB Fcb;
00204     PNPFS_CCB OtherSide;
00205     BOOLEAN Server;
00206 
00207     DPRINT("NpfsDisconnectPipe()\n");
00208 
00209     /* Fail, if the CCB is not a pipe CCB */
00210     if (Ccb->Type != CCB_PIPE)
00211     {
00212         DPRINT("Not a pipe\n");
00213         return STATUS_ILLEGAL_FUNCTION;
00214     }
00215 
00216     /* Fail, if the CCB is not a server end CCB */
00217     if (Ccb->PipeEnd != FILE_PIPE_SERVER_END)
00218     {
00219         DPRINT("Not the server end\n");
00220         return STATUS_ILLEGAL_FUNCTION;
00221     }
00222 
00223     Fcb = Ccb->Fcb;
00224     KeLockMutex(&Fcb->CcbListLock);
00225 
00226     if (Ccb->PipeState == FILE_PIPE_DISCONNECTED_STATE)
00227     {
00228         DPRINT("Pipe is already disconnected\n");
00229         Status = STATUS_PIPE_DISCONNECTED;
00230     }
00231     else if ((!Ccb->OtherSide) && (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE))
00232     {
00233         ExAcquireFastMutex(&Ccb->DataListLock);
00234         Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
00235         ExReleaseFastMutex(&Ccb->DataListLock);
00236         Status = STATUS_SUCCESS;
00237     }
00238     else if (Ccb->PipeState == FILE_PIPE_CONNECTED_STATE)
00239     {
00240         Server = (Ccb->PipeEnd == FILE_PIPE_SERVER_END);
00241         OtherSide = Ccb->OtherSide;
00242         //Ccb->OtherSide = NULL;
00243         Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
00244         /* Lock the server first */
00245         if (Server)
00246         {
00247             ExAcquireFastMutex(&Ccb->DataListLock);
00248             ExAcquireFastMutex(&OtherSide->DataListLock);
00249         }
00250         else
00251         {
00252             ExAcquireFastMutex(&OtherSide->DataListLock);
00253             ExAcquireFastMutex(&Ccb->DataListLock);
00254         }
00255         OtherSide->PipeState = FILE_PIPE_DISCONNECTED_STATE;
00256         //OtherSide->OtherSide = NULL;
00257         /*
00258         * Signaling the write event. If is possible that an other
00259         * thread waits for an empty buffer.
00260         */
00261         KeSetEvent(&OtherSide->ReadEvent, IO_NO_INCREMENT, FALSE);
00262         KeSetEvent(&OtherSide->WriteEvent, IO_NO_INCREMENT, FALSE);
00263         if (Server)
00264         {
00265             ExReleaseFastMutex(&OtherSide->DataListLock);
00266             ExReleaseFastMutex(&Ccb->DataListLock);
00267         }
00268         else
00269         {
00270             ExReleaseFastMutex(&Ccb->DataListLock);
00271             ExReleaseFastMutex(&OtherSide->DataListLock);
00272         }
00273         Status = STATUS_SUCCESS;
00274     }
00275     else if (Ccb->PipeState == FILE_PIPE_LISTENING_STATE)
00276     {
00277         PLIST_ENTRY Entry;
00278         PNPFS_WAITER_ENTRY WaitEntry = NULL;
00279         BOOLEAN Complete = FALSE;
00280         PIRP Irp = NULL;
00281 
00282         Entry = Ccb->Fcb->WaiterListHead.Flink;
00283         while (Entry != &Ccb->Fcb->WaiterListHead)
00284         {
00285             WaitEntry = CONTAINING_RECORD(Entry, NPFS_WAITER_ENTRY, Entry);
00286             if (WaitEntry->Ccb == Ccb)
00287             {
00288                 RemoveEntryList(Entry);
00289                 Irp = CONTAINING_RECORD(Entry, IRP, Tail.Overlay.DriverContext);
00290                 Complete = (NULL != IoSetCancelRoutine(Irp, NULL));
00291                 break;
00292             }
00293             Entry = Entry->Flink;
00294         }
00295 
00296         if (Irp)
00297         {
00298             if (Complete)
00299             {
00300                 Irp->IoStatus.Status = STATUS_PIPE_BROKEN;
00301                 Irp->IoStatus.Information = 0;
00302                 IoCompleteRequest(Irp, IO_NO_INCREMENT);
00303             }
00304         }
00305         Ccb->PipeState = FILE_PIPE_DISCONNECTED_STATE;
00306         Status = STATUS_SUCCESS;
00307     }
00308     else if (Ccb->PipeState == FILE_PIPE_CLOSING_STATE)
00309     {
00310         Status = STATUS_PIPE_CLOSING;
00311     }
00312     else
00313     {
00314         Status = STATUS_UNSUCCESSFUL;
00315     }
00316     KeUnlockMutex(&Fcb->CcbListLock);
00317     return Status;
00318 }
00319 
00320 static NTSTATUS
00321 NpfsWaitPipe(PIRP Irp,
00322              PNPFS_CCB Ccb)
00323 {
00324     PLIST_ENTRY current_entry;
00325     PNPFS_FCB Fcb;
00326     PNPFS_CCB ServerCcb;
00327     PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
00328     PLARGE_INTEGER TimeOut;
00329     NTSTATUS Status;
00330     PEXTENDED_IO_STACK_LOCATION IoStack;
00331     PFILE_OBJECT FileObject;
00332     PNPFS_VCB Vcb;
00333 
00334     IoStack = (PEXTENDED_IO_STACK_LOCATION)IoGetCurrentIrpStackLocation(Irp);
00335     ASSERT(IoStack);
00336     FileObject = IoStack->FileObject;
00337     ASSERT(FileObject);
00338 
00339     DPRINT("Waiting on Pipe %wZ\n", &FileObject->FileName);
00340 
00341     WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
00342 
00343     ASSERT(Ccb->Fcb);
00344     ASSERT(Ccb->Fcb->Vcb);
00345 
00346     /* Get the VCB */
00347     Vcb = Ccb->Fcb->Vcb;
00348 
00349     /* Lock the pipe list */
00350     KeLockMutex(&Vcb->PipeListLock);
00351 
00352     /* File a pipe with the given name */
00353     Fcb = NpfsFindPipe(Vcb,
00354                        &FileObject->FileName);
00355 
00356     /* Unlock the pipe list */
00357     KeUnlockMutex(&Vcb->PipeListLock);
00358 
00359     /* Fail if not pipe was found */
00360     if (Fcb == NULL)
00361     {
00362         DPRINT("No pipe found!\n", Fcb);
00363         return STATUS_OBJECT_NAME_NOT_FOUND;
00364     }
00365 
00366     /* search for listening server */
00367     current_entry = Fcb->ServerCcbListHead.Flink;
00368     while (current_entry != &Fcb->ServerCcbListHead)
00369     {
00370         ServerCcb = CONTAINING_RECORD(current_entry,
00371                                       NPFS_CCB,
00372                                       CcbListEntry);
00373 
00374         if (ServerCcb->PipeState == FILE_PIPE_LISTENING_STATE)
00375         {
00376             /* found a listening server CCB */
00377             DPRINT("Listening server CCB found -- connecting\n");
00378 
00379             return STATUS_SUCCESS;
00380         }
00381 
00382         current_entry = current_entry->Flink;
00383     }
00384 
00385     /* No listening server fcb found, so wait for one */
00386 
00387     /* If a timeout specified */
00388     if (WaitPipe->TimeoutSpecified)
00389     {
00390         /* NMPWAIT_USE_DEFAULT_WAIT = 0 */
00391         if (WaitPipe->Timeout.QuadPart == 0)
00392         {
00393             TimeOut = &Fcb->TimeOut;
00394         }
00395         else
00396         {
00397             TimeOut = &WaitPipe->Timeout;
00398         }
00399     }
00400     else
00401     {
00402         /* Wait forever */
00403         TimeOut = NULL;
00404     }
00405 
00406     Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
00407                                    UserRequest,
00408                                    Irp->RequestorMode,
00409                                    (Ccb->FileObject->Flags & FO_ALERTABLE_IO),
00410                                    TimeOut);
00411     if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC) || (Status == STATUS_ALERTED))
00412         Status = STATUS_CANCELLED;
00413 
00414     DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
00415 
00416     return Status;
00417 }
00418 
00419 NTSTATUS
00420 NpfsWaitPipe2(PIRP Irp,
00421              PNPFS_CCB Ccb)
00422 {
00423     PLIST_ENTRY current_entry;
00424     PNPFS_FCB Fcb;
00425     PNPFS_CCB ServerCcb;
00426     PFILE_PIPE_WAIT_FOR_BUFFER WaitPipe;
00427     LARGE_INTEGER TimeOut;
00428     NTSTATUS Status;
00429 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
00430     PNPFS_VCB Vcb;
00431     UNICODE_STRING PipeName;
00432 #endif
00433 
00434     DPRINT("NpfsWaitPipe\n");
00435 
00436     WaitPipe = (PFILE_PIPE_WAIT_FOR_BUFFER)Irp->AssociatedIrp.SystemBuffer;
00437 
00438 #ifdef USING_PROPER_NPFS_WAIT_SEMANTICS
00439     /* Fail, if the CCB does not represent the root directory */
00440     if (Ccb->Type != CCB_DIRECTORY)
00441         return STATUS_ILLEGAL_FUNCTION;
00442 
00443     /* Calculate the pipe name length and allocate the buffer */
00444     PipeName.Length = WaitPipe->NameLength + sizeof(WCHAR);
00445     PipeName.MaximumLength = PipeName.Length + sizeof(WCHAR);
00446     PipeName.Buffer = ExAllocatePoolWithTag(NonPagedPool,
00447                                             PipeName.MaximumLength,
00448                                             TAG_NPFS_NAMEBLOCK);
00449     if (PipeName.Buffer == NULL)
00450     {
00451         DPRINT1("Could not allocate memory for the pipe name!\n");
00452         return STATUS_NO_MEMORY;
00453     }
00454 
00455     /* Copy the pipe name into the buffer, prepend a backslash and append a 0 character */
00456     PipeName.Buffer[0] = L'\\';
00457     RtlCopyMemory(&PipeName.Buffer[1],
00458                   &WaitPipe->Name[0],
00459                   WaitPipe->NameLength);
00460     PipeName.Buffer[PipeName.Length / sizeof(WCHAR)] = 0;
00461 
00462     DPRINT("Waiting for Pipe %wZ\n", &PipeName);
00463 
00464     /* Get the VCB */
00465     Vcb = Ccb->Fcb->Vcb;
00466 
00467     /* Lock the pipe list */
00468     KeLockMutex(&Vcb->PipeListLock);
00469 
00470     /* File a pipe with the given name */
00471     Fcb = NpfsFindPipe(Vcb,
00472                        &PipeName);
00473 
00474     /* Unlock the pipe list */
00475     KeUnlockMutex(&Vcb->PipeListLock);
00476 
00477     /* Release the pipe name buffer */
00478     ExFreePoolWithTag(PipeName.Buffer, TAG_NPFS_NAMEBLOCK);
00479 
00480     /* Fail if not pipe was found */
00481     if (Fcb == NULL)
00482     {
00483         DPRINT("No pipe found!\n", Fcb);
00484         return STATUS_OBJECT_NAME_NOT_FOUND;
00485     }
00486 
00487     DPRINT("Fcb %p\n", Fcb);
00488 #else
00489     Fcb = Ccb->Fcb;
00490 
00491     if (Ccb->PipeState != 0)
00492     {
00493         DPRINT("Pipe is not in passive (waiting) state!\n");
00494         return STATUS_UNSUCCESSFUL;
00495     }
00496 #endif
00497 
00498     /* search for listening server */
00499     current_entry = Fcb->ServerCcbListHead.Flink;
00500     while (current_entry != &Fcb->ServerCcbListHead)
00501     {
00502         ServerCcb = CONTAINING_RECORD(current_entry,
00503             NPFS_CCB,
00504             CcbListEntry);
00505 
00506         if (ServerCcb->PipeState == FILE_PIPE_LISTENING_STATE)
00507         {
00508             /* found a listening server CCB */
00509             DPRINT("Listening server CCB found -- connecting\n");
00510 
00511             return STATUS_SUCCESS;
00512         }
00513 
00514         current_entry = current_entry->Flink;
00515     }
00516 
00517     /* No listening server fcb found */
00518 
00519     /* If no timeout specified, use the default one */
00520     if (WaitPipe->TimeoutSpecified)
00521         TimeOut = WaitPipe->Timeout;
00522     else
00523         TimeOut = Fcb->TimeOut;
00524 
00525     /* Wait for one */
00526     Status = KeWaitForSingleObject(&Ccb->ConnectEvent,
00527         UserRequest,
00528         Irp->RequestorMode,
00529         (Ccb->FileObject->Flags & FO_ALERTABLE_IO),
00530         &TimeOut);
00531     if ((Status == STATUS_USER_APC) || (Status == STATUS_KERNEL_APC) || (Status == STATUS_ALERTED))
00532         Status = STATUS_CANCELLED;
00533 
00534     DPRINT("KeWaitForSingleObject() returned (Status %lx)\n", Status);
00535 
00536     return Status;
00537 }
00538 
00539 
00540 /*
00541 * FUNCTION: Return current state of a pipe
00542 * ARGUMENTS:
00543 *     Irp   = Pointer to I/O request packet
00544 *     IrpSp = Pointer to current stack location of Irp
00545 * RETURNS:
00546 *     Status of operation
00547 */
00548 
00549 /*
00550 * FUNCTION: Peek at a pipe (get information about messages)
00551 * ARGUMENTS:
00552 *     Irp = Pointer to I/O request packet
00553 *     IoStack = Pointer to current stack location of Irp
00554 * RETURNS:
00555 *     Status of operation
00556 */
00557 static NTSTATUS
00558 NpfsPeekPipe(PIRP Irp,
00559              PIO_STACK_LOCATION IoStack)
00560 {
00561     ULONG OutputBufferLength;
00562     ULONG ReturnLength = 0;
00563     PFILE_PIPE_PEEK_BUFFER Reply;
00564     //PNPFS_FCB Fcb;
00565     PNPFS_CCB Ccb;
00566     NTSTATUS Status;
00567     ULONG MessageCount = 0;
00568     ULONG MessageLength;
00569     ULONG ReadDataAvailable;
00570     PVOID BufferPtr;
00571 
00572     DPRINT("NpfsPeekPipe\n");
00573 
00574     OutputBufferLength = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
00575     DPRINT("OutputBufferLength: %lu\n", OutputBufferLength);
00576 
00577     /* Validate parameters */
00578     if (OutputBufferLength < sizeof(FILE_PIPE_PEEK_BUFFER))
00579     {
00580         DPRINT1("Buffer too small\n");
00581         return STATUS_INVALID_PARAMETER;
00582     }
00583 
00584     Ccb = IoStack->FileObject->FsContext2;
00585     Reply = (PFILE_PIPE_PEEK_BUFFER)Irp->AssociatedIrp.SystemBuffer;
00586     //Fcb = Ccb->Fcb;
00587 
00588 
00589     Reply->NamedPipeState = Ccb->PipeState;
00590 
00591     Reply->ReadDataAvailable = Ccb->ReadDataAvailable;
00592     DPRINT("ReadDataAvailable: %lu\n", Ccb->ReadDataAvailable);
00593 
00594     ExAcquireFastMutex(&Ccb->DataListLock);
00595     BufferPtr = Ccb->ReadPtr;
00596     DPRINT("BufferPtr = %x\n", BufferPtr);
00597     if (Ccb->Fcb->PipeType == FILE_PIPE_BYTE_STREAM_TYPE)
00598     {
00599         DPRINT("Byte Stream Mode\n");
00600         Reply->MessageLength = Ccb->ReadDataAvailable;
00601         DPRINT("Reply->MessageLength  %lu\n",Reply->MessageLength );
00602         MessageCount = 1;
00603 
00604         if (Reply->Data[0] && (OutputBufferLength >= Ccb->ReadDataAvailable + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0])))
00605         {
00606             ReturnLength = Ccb->ReadDataAvailable;
00607             memcpy(&Reply->Data[0], (PVOID)BufferPtr, Ccb->ReadDataAvailable);
00608         }
00609     }
00610     else
00611     {
00612         DPRINT("Message Mode\n");
00613         ReadDataAvailable=Ccb->ReadDataAvailable;
00614 
00615         if (ReadDataAvailable > 0)
00616         {
00617             memcpy(&Reply->MessageLength, BufferPtr, sizeof(ULONG));
00618 
00619             while ((ReadDataAvailable > 0) && (BufferPtr < Ccb->WritePtr))
00620             {
00621                 memcpy(&MessageLength, BufferPtr, sizeof(MessageLength));
00622 
00623                 ASSERT(MessageLength > 0);
00624 
00625                 DPRINT("MessageLength = %lu\n",MessageLength);
00626                 ReadDataAvailable -= MessageLength;
00627                 MessageCount++;
00628 
00629                 /* If its the first message, copy the Message if the size of buffer is large enough */
00630                 if (MessageCount==1)
00631                 {
00632                     if ((Reply->Data[0])
00633                         && (OutputBufferLength >= (MessageLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]))))
00634                     {
00635                         memcpy(&Reply->Data[0], (PVOID)((ULONG_PTR)BufferPtr + sizeof(MessageLength)), MessageLength);
00636                         ReturnLength = MessageLength;
00637                     }
00638                 }
00639 
00640                 BufferPtr =(PVOID)((ULONG_PTR)BufferPtr + MessageLength + sizeof(MessageLength));
00641                 DPRINT("BufferPtr = %x\n", BufferPtr);
00642                 DPRINT("ReadDataAvailable: %lu\n", ReadDataAvailable);
00643             }
00644 
00645             if (ReadDataAvailable != 0)
00646             {
00647                 DPRINT1("Possible memory corruption.\n");
00648                 ASSERT(FALSE);
00649             }
00650         }
00651     }
00652     ExReleaseFastMutex(&Ccb->DataListLock);
00653 
00654     Reply->NumberOfMessages = MessageCount;
00655 
00656     Irp->IoStatus.Information = ReturnLength + FIELD_OFFSET(FILE_PIPE_PEEK_BUFFER, Data[0]);
00657     Irp->IoStatus.Status = STATUS_SUCCESS;
00658 
00659     Status = STATUS_SUCCESS;
00660 
00661     DPRINT("NpfsPeekPipe done\n");
00662 
00663     return Status;
00664 }
00665 
00666 
00667 NTSTATUS NTAPI
00668 NpfsFileSystemControl(PDEVICE_OBJECT DeviceObject,
00669                       PIRP Irp)
00670 {
00671     PIO_STACK_LOCATION IoStack;
00672     PFILE_OBJECT FileObject;
00673     NTSTATUS Status;
00674     //PNPFS_VCB Vcb;
00675     PNPFS_FCB Fcb;
00676     PNPFS_CCB Ccb;
00677 
00678     DPRINT("NpfsFileSystemContol(DeviceObject %p Irp %p)\n", DeviceObject, Irp);
00679 
00680     //Vcb = (PNPFS_VCB)DeviceObject->DeviceExtension;
00681     IoStack = IoGetCurrentIrpStackLocation(Irp);
00682     DPRINT("IoStack: %p\n", IoStack);
00683     FileObject = IoStack->FileObject;
00684     DPRINT("FileObject: %p\n", FileObject);
00685     Ccb = FileObject->FsContext2;
00686     DPRINT("CCB: %p\n", Ccb);
00687     Fcb = Ccb->Fcb;
00688     DPRINT("Pipe: %p\n", Fcb);
00689     DPRINT("PipeName: %wZ\n", &Fcb->PipeName);
00690 
00691     Irp->IoStatus.Information = 0;
00692 
00693     switch (IoStack->Parameters.FileSystemControl.FsControlCode)
00694     {
00695     case FSCTL_PIPE_ASSIGN_EVENT:
00696         DPRINT1("Assign event not implemented\n");
00697         Status = STATUS_NOT_IMPLEMENTED;
00698         break;
00699 
00700     case FSCTL_PIPE_DISCONNECT:
00701         DPRINT("Disconnecting pipe %wZ\n", &Fcb->PipeName);
00702         Status = NpfsDisconnectPipe(Ccb);
00703         break;
00704 
00705     case FSCTL_PIPE_LISTEN:
00706         DPRINT("Connecting pipe %wZ\n", &Fcb->PipeName);
00707         Status = NpfsConnectPipe(Irp, Ccb);
00708         break;
00709 
00710     case FSCTL_PIPE_PEEK:
00711         DPRINT("Peeking pipe %wZ\n", &Fcb->PipeName);
00712         Status = NpfsPeekPipe(Irp, (PIO_STACK_LOCATION)IoStack);
00713         break;
00714 
00715     case FSCTL_PIPE_QUERY_EVENT:
00716         DPRINT1("Query event not implemented\n");
00717         Status = STATUS_NOT_IMPLEMENTED;
00718         break;
00719 
00720     case FSCTL_PIPE_TRANSCEIVE:
00721         /* If you implement this, please remove the workaround in
00722         lib/kernel32/file/npipe.c function TransactNamedPipe() */
00723         DPRINT1("Transceive not implemented\n");
00724         Status = STATUS_NOT_IMPLEMENTED;
00725         break;
00726 
00727     case FSCTL_PIPE_WAIT:
00728         DPRINT("Waiting for pipe %wZ\n", &Fcb->PipeName);
00729         Status = NpfsWaitPipe(Irp, Ccb);
00730         break;
00731 
00732     case FSCTL_PIPE_IMPERSONATE:
00733         DPRINT1("Impersonate not implemented\n");
00734         Status = STATUS_NOT_IMPLEMENTED;
00735         break;
00736 
00737     case FSCTL_PIPE_SET_CLIENT_PROCESS:
00738         DPRINT1("Set client process not implemented\n");
00739         Status = STATUS_NOT_IMPLEMENTED;
00740         break;
00741 
00742     case FSCTL_PIPE_QUERY_CLIENT_PROCESS:
00743         DPRINT1("Query client process not implemented\n");
00744         Status = STATUS_NOT_IMPLEMENTED;
00745         break;
00746 
00747     case FSCTL_PIPE_INTERNAL_READ:
00748         DPRINT1("Internal read not implemented\n");
00749         Status = STATUS_NOT_IMPLEMENTED;
00750         break;
00751 
00752     case FSCTL_PIPE_INTERNAL_WRITE:
00753         DPRINT1("Internal write not implemented\n");
00754         Status = STATUS_NOT_IMPLEMENTED;
00755         break;
00756 
00757     case FSCTL_PIPE_INTERNAL_TRANSCEIVE:
00758         DPRINT1("Internal transceive not implemented\n");
00759         Status = STATUS_NOT_IMPLEMENTED;
00760         break;
00761 
00762     case FSCTL_PIPE_INTERNAL_READ_OVFLOW:
00763         DPRINT1("Internal read overflow not implemented\n");
00764         Status = STATUS_NOT_IMPLEMENTED;
00765         break;
00766 
00767     default:
00768         DPRINT1("Unrecognized IoControlCode: %x\n",
00769             IoStack->Parameters.FileSystemControl.FsControlCode);
00770         Status = STATUS_UNSUCCESSFUL;
00771     }
00772 
00773     if (Status != STATUS_PENDING)
00774     {
00775         Irp->IoStatus.Status = Status;
00776 
00777         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00778     }
00779 
00780     return Status;
00781 }
00782 
00783 
00784 NTSTATUS NTAPI
00785 NpfsFlushBuffers(PDEVICE_OBJECT DeviceObject,
00786                  PIRP Irp)
00787 {
00788     /* FIXME: Implement */
00789 
00790     Irp->IoStatus.Status = STATUS_SUCCESS;
00791     Irp->IoStatus.Information = 0;
00792 
00793     IoCompleteRequest(Irp, IO_NO_INCREMENT);
00794 
00795     return STATUS_SUCCESS;
00796 }
00797 
00798 /* EOF */

Generated on Sat May 26 2012 04:26:19 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.