Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfsctrl.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
1.7.6.1
|