Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenirp.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/ksfilter/ks/factory.c 00005 * PURPOSE: KS Allocator functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 00010 #include "priv.h" 00011 00012 /* 00013 @implemented 00014 */ 00015 KSDDKAPI 00016 NTSTATUS 00017 NTAPI 00018 KsDispatchQuerySecurity( 00019 IN PDEVICE_OBJECT DeviceObject, 00020 IN PIRP Irp) 00021 { 00022 PKSOBJECT_CREATE_ITEM CreateItem; 00023 PIO_STACK_LOCATION IoStack; 00024 NTSTATUS Status; 00025 ULONG Length; 00026 00027 /* get current irp stack */ 00028 IoStack = IoGetCurrentIrpStackLocation(Irp); 00029 00030 /* get create item */ 00031 CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); 00032 00033 if (!CreateItem || !CreateItem->SecurityDescriptor) 00034 { 00035 /* no create item */ 00036 Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT; 00037 CompleteRequest(Irp, IO_NO_INCREMENT); 00038 return STATUS_NO_SECURITY_ON_OBJECT; 00039 } 00040 00041 00042 /* get input length */ 00043 Length = IoStack->Parameters.QuerySecurity.Length; 00044 00045 /* clone the security descriptor */ 00046 Status = SeQuerySecurityDescriptorInfo(&IoStack->Parameters.QuerySecurity.SecurityInformation, (PSECURITY_DESCRIPTOR)Irp->UserBuffer, &Length, &CreateItem->SecurityDescriptor); 00047 00048 DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status); 00049 /* store result */ 00050 Irp->IoStatus.Status = Status; 00051 Irp->IoStatus.Information = Length; 00052 00053 CompleteRequest(Irp, IO_NO_INCREMENT); 00054 return Status; 00055 } 00056 00057 /* 00058 @implemented 00059 */ 00060 KSDDKAPI 00061 NTSTATUS 00062 NTAPI 00063 KsDispatchSetSecurity( 00064 IN PDEVICE_OBJECT DeviceObject, 00065 IN PIRP Irp) 00066 { 00067 PKSOBJECT_CREATE_ITEM CreateItem; 00068 PIO_STACK_LOCATION IoStack; 00069 PGENERIC_MAPPING Mapping; 00070 PSECURITY_DESCRIPTOR Descriptor; 00071 NTSTATUS Status; 00072 00073 /* get current irp stack */ 00074 IoStack = IoGetCurrentIrpStackLocation(Irp); 00075 00076 /* get create item */ 00077 CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); 00078 00079 if (!CreateItem || !CreateItem->SecurityDescriptor) 00080 { 00081 /* no create item */ 00082 Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT; 00083 CompleteRequest(Irp, IO_NO_INCREMENT); 00084 return STATUS_NO_SECURITY_ON_OBJECT; 00085 } 00086 00087 /* backup old descriptor */ 00088 Descriptor = CreateItem->SecurityDescriptor; 00089 00090 /* get generic mapping */ 00091 Mapping = IoGetFileObjectGenericMapping(); 00092 00093 /* change security descriptor */ 00094 Status = SeSetSecurityDescriptorInfo(NULL, /*FIXME */ 00095 &IoStack->Parameters.SetSecurity.SecurityInformation, 00096 IoStack->Parameters.SetSecurity.SecurityDescriptor, 00097 &CreateItem->SecurityDescriptor, 00098 NonPagedPool, 00099 Mapping); 00100 00101 if (NT_SUCCESS(Status)) 00102 { 00103 /* free old descriptor */ 00104 FreeItem(Descriptor); 00105 00106 /* mark create item as changed */ 00107 CreateItem->Flags |= KSCREATE_ITEM_SECURITYCHANGED; 00108 } 00109 00110 /* store result */ 00111 Irp->IoStatus.Status = Status; 00112 CompleteRequest(Irp, IO_NO_INCREMENT); 00113 00114 return Status; 00115 } 00116 00117 /* 00118 @unimplemented 00119 */ 00120 KSDDKAPI 00121 NTSTATUS 00122 NTAPI 00123 KsDispatchSpecificMethod( 00124 IN PIRP Irp, 00125 IN PFNKSHANDLER Handler) 00126 { 00127 UNIMPLEMENTED; 00128 return STATUS_UNSUCCESSFUL; 00129 } 00130 00131 00132 /* 00133 @implemented 00134 */ 00135 KSDDKAPI 00136 NTSTATUS 00137 NTAPI 00138 KsReadFile( 00139 IN PFILE_OBJECT FileObject, 00140 IN PKEVENT Event OPTIONAL, 00141 IN PVOID PortContext OPTIONAL, 00142 OUT PIO_STATUS_BLOCK IoStatusBlock, 00143 OUT PVOID Buffer, 00144 IN ULONG Length, 00145 IN ULONG Key OPTIONAL, 00146 IN KPROCESSOR_MODE RequestorMode) 00147 { 00148 PDEVICE_OBJECT DeviceObject; 00149 PIRP Irp; 00150 NTSTATUS Status; 00151 BOOLEAN Result; 00152 KEVENT LocalEvent; 00153 00154 if (Event) 00155 { 00156 /* make sure event is reset */ 00157 KeClearEvent(Event); 00158 } 00159 00160 if (RequestorMode == UserMode) 00161 { 00162 /* probe the user buffer */ 00163 _SEH2_TRY 00164 { 00165 ProbeForWrite(Buffer, Length, sizeof(UCHAR)); 00166 Status = STATUS_SUCCESS; 00167 } 00168 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00169 { 00170 /* Exception, get the error code */ 00171 Status = _SEH2_GetExceptionCode(); 00172 } 00173 _SEH2_END; 00174 00175 if (!NT_SUCCESS(Status)) 00176 { 00177 DPRINT1("Invalid user buffer provided\n"); 00178 return Status; 00179 } 00180 } 00181 00182 /* get corresponding device object */ 00183 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00184 00185 /* fast-io read is only available for kernel mode clients */ 00186 if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode && 00187 DeviceObject->DriverObject->FastIoDispatch->FastIoRead) 00188 { 00189 /* call fast io write */ 00190 Result = DeviceObject->DriverObject->FastIoDispatch->FastIoRead(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject); 00191 00192 if (Result && NT_SUCCESS(IoStatusBlock->Status)) 00193 { 00194 /* request was handeled and succeeded */ 00195 return STATUS_SUCCESS; 00196 } 00197 } 00198 00199 /* do the slow way */ 00200 if (!Event) 00201 { 00202 /* initialize temp event */ 00203 KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE); 00204 Event = &LocalEvent; 00205 } 00206 00207 /* build the irp packet */ 00208 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, Buffer, Length, &FileObject->CurrentByteOffset, Event, IoStatusBlock); 00209 if (!Irp) 00210 { 00211 /* not enough resources */ 00212 return STATUS_INSUFFICIENT_RESOURCES; 00213 } 00214 00215 /* send the packet */ 00216 Status = IoCallDriver(DeviceObject, Irp); 00217 00218 if (Status == STATUS_PENDING) 00219 { 00220 /* operation is pending, is sync file object */ 00221 if (FileObject->Flags & FO_SYNCHRONOUS_IO) 00222 { 00223 /* it is so wait */ 00224 KeWaitForSingleObject(Event, Executive, RequestorMode, FALSE, NULL); 00225 Status = IoStatusBlock->Status; 00226 } 00227 } 00228 /* return result */ 00229 return Status; 00230 } 00231 00232 /* 00233 @implemented 00234 */ 00235 KSDDKAPI 00236 NTSTATUS 00237 NTAPI 00238 KsWriteFile( 00239 IN PFILE_OBJECT FileObject, 00240 IN PKEVENT Event OPTIONAL, 00241 IN PVOID PortContext OPTIONAL, 00242 OUT PIO_STATUS_BLOCK IoStatusBlock, 00243 IN PVOID Buffer, 00244 IN ULONG Length, 00245 IN ULONG Key OPTIONAL, 00246 IN KPROCESSOR_MODE RequestorMode) 00247 { 00248 PDEVICE_OBJECT DeviceObject; 00249 PIRP Irp; 00250 NTSTATUS Status; 00251 BOOLEAN Result; 00252 KEVENT LocalEvent; 00253 00254 if (Event) 00255 { 00256 /* make sure event is reset */ 00257 KeClearEvent(Event); 00258 } 00259 00260 if (RequestorMode == UserMode) 00261 { 00262 /* probe the user buffer */ 00263 _SEH2_TRY 00264 { 00265 ProbeForRead(Buffer, Length, sizeof(UCHAR)); 00266 Status = STATUS_SUCCESS; 00267 } 00268 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00269 { 00270 /* Exception, get the error code */ 00271 Status = _SEH2_GetExceptionCode(); 00272 } 00273 _SEH2_END; 00274 00275 if (!NT_SUCCESS(Status)) 00276 { 00277 DPRINT1("Invalid user buffer provided\n"); 00278 return Status; 00279 } 00280 } 00281 00282 /* get corresponding device object */ 00283 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00284 00285 /* fast-io write is only available for kernel mode clients */ 00286 if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode && 00287 DeviceObject->DriverObject->FastIoDispatch->FastIoWrite) 00288 { 00289 /* call fast io write */ 00290 Result = DeviceObject->DriverObject->FastIoDispatch->FastIoWrite(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject); 00291 00292 if (Result && NT_SUCCESS(IoStatusBlock->Status)) 00293 { 00294 /* request was handeled and succeeded */ 00295 return STATUS_SUCCESS; 00296 } 00297 } 00298 00299 /* do the slow way */ 00300 if (!Event) 00301 { 00302 /* initialize temp event */ 00303 KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE); 00304 Event = &LocalEvent; 00305 } 00306 00307 /* build the irp packet */ 00308 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject, Buffer, Length, &FileObject->CurrentByteOffset, Event, IoStatusBlock); 00309 if (!Irp) 00310 { 00311 /* not enough resources */ 00312 return STATUS_INSUFFICIENT_RESOURCES; 00313 } 00314 00315 /* send the packet */ 00316 Status = IoCallDriver(DeviceObject, Irp); 00317 00318 if (Status == STATUS_PENDING) 00319 { 00320 /* operation is pending, is sync file object */ 00321 if (FileObject->Flags & FO_SYNCHRONOUS_IO) 00322 { 00323 /* it is so wait */ 00324 KeWaitForSingleObject(Event, Executive, RequestorMode, FALSE, NULL); 00325 Status = IoStatusBlock->Status; 00326 } 00327 } 00328 /* return result */ 00329 return Status; 00330 } 00331 00332 /* 00333 @implemented 00334 */ 00335 KSDDKAPI 00336 NTSTATUS 00337 NTAPI 00338 KsQueryInformationFile( 00339 IN PFILE_OBJECT FileObject, 00340 OUT PVOID FileInformation, 00341 IN ULONG Length, 00342 IN FILE_INFORMATION_CLASS FileInformationClass) 00343 { 00344 PDEVICE_OBJECT DeviceObject; 00345 PFAST_IO_DISPATCH FastIoDispatch; 00346 PIRP Irp; 00347 PIO_STACK_LOCATION IoStack; 00348 IO_STATUS_BLOCK IoStatus; 00349 KEVENT Event; 00350 LARGE_INTEGER Offset; 00351 IO_STATUS_BLOCK StatusBlock; 00352 NTSTATUS Status; 00353 00354 /* get related file object */ 00355 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00356 00357 /* get fast i/o table */ 00358 FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch; 00359 00360 /* is there a fast table */ 00361 if (FastIoDispatch) 00362 { 00363 /* check the class */ 00364 if (FileInformationClass == FileBasicInformation) 00365 { 00366 /* use FastIoQueryBasicInfo routine */ 00367 if (FastIoDispatch->FastIoQueryBasicInfo) 00368 { 00369 return FastIoDispatch->FastIoQueryBasicInfo(FileObject, TRUE, (PFILE_BASIC_INFORMATION)FileInformation, &IoStatus, DeviceObject); 00370 } 00371 } 00372 else if (FileInformationClass == FileStandardInformation) 00373 { 00374 /* use FastIoQueryBasicInfo routine */ 00375 if (FastIoDispatch->FastIoQueryBasicInfo) 00376 { 00377 return FastIoDispatch->FastIoQueryStandardInfo(FileObject, TRUE, (PFILE_STANDARD_INFORMATION)FileInformation, &IoStatus, DeviceObject); 00378 } 00379 } 00380 } 00381 /* clear event */ 00382 KeClearEvent(&FileObject->Event); 00383 00384 /* initialize event */ 00385 KeInitializeEvent(&Event, NotificationEvent, FALSE); 00386 00387 /* set offset to zero */ 00388 Offset.QuadPart = 0L; 00389 00390 /* build the request */ 00391 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_INFORMATION, IoGetRelatedDeviceObject(FileObject), NULL, 0, &Offset, &Event, &StatusBlock); 00392 00393 if (!Irp) 00394 return STATUS_INSUFFICIENT_RESOURCES; 00395 00396 /* get next stack location */ 00397 IoStack = IoGetNextIrpStackLocation(Irp); 00398 00399 /* setup parameters */ 00400 IoStack->Parameters.QueryFile.FileInformationClass = FileInformationClass; 00401 IoStack->Parameters.QueryFile.Length = Length; 00402 Irp->AssociatedIrp.SystemBuffer = FileInformation; 00403 00404 00405 /* call the driver */ 00406 Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp); 00407 00408 if (Status == STATUS_PENDING) 00409 { 00410 /* wait for the operation to complete */ 00411 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 00412 00413 /* is object sync */ 00414 if (FileObject->Flags & FO_SYNCHRONOUS_IO) 00415 Status = FileObject->FinalStatus; 00416 else 00417 Status = StatusBlock.Status; 00418 } 00419 00420 /* done */ 00421 return Status; 00422 } 00423 00424 /* 00425 @implemented 00426 */ 00427 KSDDKAPI 00428 NTSTATUS 00429 NTAPI 00430 KsSetInformationFile( 00431 IN PFILE_OBJECT FileObject, 00432 IN PVOID FileInformation, 00433 IN ULONG Length, 00434 IN FILE_INFORMATION_CLASS FileInformationClass) 00435 { 00436 PIO_STACK_LOCATION IoStack; 00437 PDEVICE_OBJECT DeviceObject; 00438 PIRP Irp; 00439 PVOID Buffer; 00440 KEVENT Event; 00441 LARGE_INTEGER Offset; 00442 IO_STATUS_BLOCK IoStatus; 00443 NTSTATUS Status; 00444 00445 /* get related device object */ 00446 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00447 00448 /* copy file information */ 00449 Buffer = AllocateItem(NonPagedPool, Length); 00450 if (!Buffer) 00451 return STATUS_INSUFFICIENT_RESOURCES; 00452 00453 _SEH2_TRY 00454 { 00455 ProbeForRead(Buffer, Length, sizeof(UCHAR)); 00456 RtlMoveMemory(Buffer, FileInformation, Length); 00457 Status = STATUS_SUCCESS; 00458 } 00459 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00460 { 00461 /* Exception, get the error code */ 00462 Status = _SEH2_GetExceptionCode(); 00463 } 00464 _SEH2_END; 00465 00466 if (!NT_SUCCESS(Status)) 00467 { 00468 /* invalid user buffer */ 00469 FreeItem(Buffer); 00470 return Status; 00471 } 00472 00473 /* initialize the event */ 00474 KeInitializeEvent(&Event, SynchronizationEvent, FALSE); 00475 00476 /* zero offset */ 00477 Offset.QuadPart = 0LL; 00478 00479 /* build the irp */ 00480 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION, DeviceObject, NULL, 0, &Offset, &Event, &IoStatus); 00481 00482 if (!Irp) 00483 { 00484 /* failed to allocate irp */ 00485 FreeItem(Buffer); 00486 return STATUS_INSUFFICIENT_RESOURCES; 00487 } 00488 00489 /* get next stack location */ 00490 IoStack = IoGetNextIrpStackLocation(Irp); 00491 00492 /* set irp parameters */ 00493 IoStack->Parameters.SetFile.FileInformationClass = FileInformationClass; 00494 IoStack->Parameters.SetFile.Length = Length; 00495 IoStack->Parameters.SetFile.FileObject = FileObject; 00496 Irp->AssociatedIrp.SystemBuffer = Buffer; 00497 Irp->UserBuffer = FileInformation; 00498 00499 /* dispatch the irp */ 00500 Status = IoCallDriver(DeviceObject, Irp); 00501 00502 if (Status == STATUS_PENDING) 00503 { 00504 /* wait untill the operation has completed */ 00505 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 00506 /* is a sync file object */ 00507 if (FileObject->Flags & FO_SYNCHRONOUS_IO) 00508 Status = FileObject->FinalStatus; 00509 else 00510 Status = IoStatus.Status; 00511 } 00512 /* done */ 00513 return Status; 00514 } 00515 00516 /* 00517 @implemented 00518 */ 00519 KSDDKAPI 00520 NTSTATUS 00521 NTAPI 00522 KsStreamIo( 00523 IN PFILE_OBJECT FileObject, 00524 IN PKEVENT Event OPTIONAL, 00525 IN PVOID PortContext OPTIONAL, 00526 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL, 00527 IN PVOID CompletionContext OPTIONAL, 00528 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL, 00529 OUT PIO_STATUS_BLOCK IoStatusBlock, 00530 IN OUT PVOID StreamHeaders, 00531 IN ULONG Length, 00532 IN ULONG Flags, 00533 IN KPROCESSOR_MODE RequestorMode) 00534 { 00535 PIRP Irp; 00536 PIO_STACK_LOCATION IoStack; 00537 PDEVICE_OBJECT DeviceObject; 00538 NTSTATUS Status; 00539 LARGE_INTEGER Offset; 00540 PKSIOBJECT_HEADER ObjectHeader; 00541 BOOLEAN Ret; 00542 00543 /* get related device object */ 00544 DeviceObject = IoGetRelatedDeviceObject(FileObject); 00545 /* sanity check */ 00546 ASSERT(DeviceObject != NULL); 00547 00548 /* is there a event provided */ 00549 if (Event) 00550 { 00551 /* reset event */ 00552 KeClearEvent(Event); 00553 } 00554 00555 if (RequestorMode || ExGetPreviousMode() == KernelMode) 00556 { 00557 /* requestor is from kernel land */ 00558 ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext2; 00559 00560 if (ObjectHeader) 00561 { 00562 /* there is a object header */ 00563 if (Flags == KSSTREAM_READ) 00564 { 00565 /* is fast read supported */ 00566 if (ObjectHeader->DispatchTable.FastRead) 00567 { 00568 /* call fast read dispatch routine */ 00569 Ret = ObjectHeader->DispatchTable.FastRead(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject); 00570 00571 if (Ret) 00572 { 00573 /* the request was handeled */ 00574 return IoStatusBlock->Status; 00575 } 00576 } 00577 } 00578 else if (Flags == KSSTREAM_WRITE) 00579 { 00580 /* is fast write supported */ 00581 if (ObjectHeader->DispatchTable.FastWrite) 00582 { 00583 /* call fast write dispatch routine */ 00584 Ret = ObjectHeader->DispatchTable.FastWrite(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject); 00585 00586 if (Ret) 00587 { 00588 /* the request was handeled */ 00589 return IoStatusBlock->Status; 00590 } 00591 } 00592 } 00593 } 00594 } 00595 00596 /* clear file object event */ 00597 KeClearEvent(&FileObject->Event); 00598 00599 /* set the offset to zero */ 00600 Offset.QuadPart = 0LL; 00601 00602 /* now build the irp */ 00603 Irp = IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL, 00604 DeviceObject, (PVOID)StreamHeaders, Length, &Offset, Event, IoStatusBlock); 00605 if (!Irp) 00606 { 00607 /* not enough memory */ 00608 return STATUS_INSUFFICIENT_RESOURCES; 00609 } 00610 00611 /* setup irp parameters */ 00612 Irp->RequestorMode = RequestorMode; 00613 Irp->Overlay.AsynchronousParameters.UserApcContext = PortContext; 00614 Irp->Tail.Overlay.OriginalFileObject = FileObject; 00615 Irp->UserBuffer = StreamHeaders; 00616 00617 /* get next irp stack location */ 00618 IoStack = IoGetNextIrpStackLocation(Irp); 00619 /* setup stack parameters */ 00620 IoStack->FileObject = FileObject; 00621 IoStack->Parameters.DeviceIoControl.InputBufferLength = Length; 00622 IoStack->Parameters.DeviceIoControl.Type3InputBuffer = StreamHeaders; 00623 IoStack->Parameters.DeviceIoControl.IoControlCode = (Flags == KSSTREAM_READ ? IOCTL_KS_READ_STREAM : IOCTL_KS_WRITE_STREAM); 00624 00625 if (CompletionRoutine) 00626 { 00627 /* setup completion routine for async processing */ 00628 IoSetCompletionRoutine(Irp, CompletionRoutine, CompletionContext, (CompletionInvocationFlags & KsInvokeOnSuccess), (CompletionInvocationFlags & KsInvokeOnError), (CompletionInvocationFlags & KsInvokeOnCancel)); 00629 } 00630 00631 /* now call the driver */ 00632 Status = IoCallDriver(DeviceObject, Irp); 00633 /* done */ 00634 return Status; 00635 } 00636 00637 /* 00638 @implemented 00639 */ 00640 KSDDKAPI 00641 NTSTATUS 00642 NTAPI 00643 KsProbeStreamIrp( 00644 IN PIRP Irp, 00645 IN ULONG ProbeFlags, 00646 IN ULONG HeaderSize) 00647 { 00648 PMDL Mdl; 00649 PVOID Buffer; 00650 LOCK_OPERATION Operation; 00651 NTSTATUS Status = STATUS_SUCCESS; 00652 PKSSTREAM_HEADER StreamHeader; 00653 PIO_STACK_LOCATION IoStack; 00654 ULONG Length; 00655 //BOOLEAN AllocateMdl = FALSE; 00656 00657 /* get current irp stack */ 00658 IoStack = IoGetCurrentIrpStackLocation(Irp); 00659 00660 Length = IoStack->Parameters.DeviceIoControl.OutputBufferLength; 00661 00662 if (Irp->RequestorMode == KernelMode || Irp->AssociatedIrp.SystemBuffer) 00663 { 00664 if (Irp->RequestorMode == KernelMode) 00665 { 00666 /* no need to allocate stream header */ 00667 Irp->AssociatedIrp.SystemBuffer = Irp->UserBuffer; 00668 } 00669 AllocMdl: 00670 /* check if alloc mdl flag is passed */ 00671 if (!(ProbeFlags & KSPROBE_ALLOCATEMDL)) 00672 { 00673 /* nothing more to do */ 00674 return STATUS_SUCCESS; 00675 } 00676 if (Irp->MdlAddress) 00677 { 00678 ProbeMdl: 00679 if (ProbeFlags & KSPROBE_PROBEANDLOCK) 00680 { 00681 if (Irp->MdlAddress->MdlFlags & (MDL_PAGES_LOCKED | MDL_SOURCE_IS_NONPAGED_POOL)) 00682 { 00683 if (ProbeFlags & KSPROBE_SYSTEMADDRESS) 00684 { 00685 _SEH2_TRY 00686 { 00687 /* loop through all mdls and probe them */ 00688 Mdl = Irp->MdlAddress; 00689 do 00690 { 00691 /* the mapping can fail */ 00692 Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL; 00693 00694 if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL)) 00695 { 00696 /* no need to probe these pages */ 00697 Buffer = Mdl->MappedSystemVa; 00698 } 00699 else 00700 { 00701 /* probe that mdl */ 00702 Buffer = MmMapLockedPages(Mdl, KernelMode); 00703 } 00704 00705 /* check if the mapping succeeded */ 00706 if (!Buffer) 00707 { 00708 /* raise exception we'll catch */ 00709 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); 00710 } 00711 00712 /* iterate to next mdl */ 00713 Mdl = Mdl->Next; 00714 00715 }while(Mdl); 00716 } 00717 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00718 { 00719 /* Exception, get the error code */ 00720 Status = _SEH2_GetExceptionCode(); 00721 } _SEH2_END; 00722 } 00723 } 00724 else 00725 { 00726 _SEH2_TRY 00727 { 00728 /* loop through all mdls and probe them */ 00729 Mdl = Irp->MdlAddress; 00730 00731 /* determine operation */ 00732 if (!(ProbeFlags & KSPROBE_STREAMWRITE) || (ProbeFlags & KSPROBE_MODIFY)) 00733 { 00734 /* operation is read / modify stream, need write access */ 00735 Operation = IoWriteAccess; 00736 } 00737 else 00738 { 00739 /* operation is write to device, so we need read access */ 00740 Operation = IoReadAccess; 00741 } 00742 00743 do 00744 { 00745 /* probe the pages */ 00746 MmProbeAndLockPages(Mdl, Irp->RequestorMode, Operation); 00747 00748 if (ProbeFlags & KSPROBE_SYSTEMADDRESS) 00749 { 00750 /* the mapping can fail */ 00751 Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL; 00752 00753 if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL)) 00754 { 00755 /* no need to probe these pages */ 00756 Buffer = Mdl->MappedSystemVa; 00757 } 00758 else 00759 { 00760 /* probe that mdl */ 00761 Buffer = MmMapLockedPages(Mdl, KernelMode); 00762 } 00763 00764 /* check if the mapping succeeded */ 00765 if (!Buffer) 00766 { 00767 /* raise exception we'll catch */ 00768 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); 00769 } 00770 } 00771 00772 /* iterate to next mdl */ 00773 Mdl = Mdl->Next; 00774 00775 }while(Mdl); 00776 } 00777 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00778 { 00779 /* Exception, get the error code */ 00780 Status = _SEH2_GetExceptionCode(); 00781 } _SEH2_END; 00782 } 00783 } 00784 return Status; 00785 } 00786 00787 /* check all stream headers */ 00788 StreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; 00789 ASSERT(StreamHeader); 00790 _SEH2_TRY 00791 { 00792 do 00793 { 00794 if (HeaderSize) 00795 { 00796 /* does the supplied header size match stream header size and no type changed */ 00797 if (StreamHeader->Size != HeaderSize && !(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)) 00798 { 00799 /* invalid stream header */ 00800 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00801 } 00802 } 00803 else 00804 { 00805 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */ 00806 if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) || (StreamHeader->Size & 7)) 00807 { 00808 /* invalid stream header */ 00809 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00810 } 00811 } 00812 00813 if (Length < StreamHeader->Size) 00814 { 00815 /* length is too short */ 00816 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00817 } 00818 00819 if (ProbeFlags & KSPROBE_STREAMWRITE) 00820 { 00821 if (StreamHeader->DataUsed > StreamHeader->FrameExtent) 00822 { 00823 /* frame extend can never be smaller */ 00824 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00825 } 00826 00827 /* is this stream change packet */ 00828 if (StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED) 00829 { 00830 if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader != Irp->AssociatedIrp.SystemBuffer) 00831 { 00832 /* stream changed - must be send in a single packet */ 00833 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00834 } 00835 00836 if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE)) 00837 { 00838 /* caller does not permit format changes */ 00839 ExRaiseStatus(STATUS_INVALID_PARAMETER); 00840 } 00841 00842 if (StreamHeader->FrameExtent) 00843 { 00844 /* allocate an mdl */ 00845 Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp); 00846 00847 if (!Mdl) 00848 { 00849 /* not enough memory */ 00850 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); 00851 } 00852 00853 /* break-out to probe for the irp */ 00854 break; 00855 } 00856 } 00857 } 00858 else 00859 { 00860 if (StreamHeader->DataUsed) 00861 { 00862 /* DataUsed must be zero for stream read operation */ 00863 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00864 } 00865 00866 if (StreamHeader->OptionsFlags) 00867 { 00868 /* no flags supported for reading */ 00869 ExRaiseStatus(STATUS_INVALID_PARAMETER); 00870 } 00871 } 00872 00873 if (StreamHeader->FrameExtent) 00874 { 00875 /* allocate an mdl */ 00876 ASSERT(Irp->MdlAddress == NULL); 00877 Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp); 00878 if (!Mdl) 00879 { 00880 /* not enough memory */ 00881 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); 00882 } 00883 } 00884 00885 /* move to next stream header */ 00886 Length -= StreamHeader->Size; 00887 StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size); 00888 }while(Length); 00889 } 00890 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00891 { 00892 /* Exception, get the error code */ 00893 Status = _SEH2_GetExceptionCode(); 00894 }_SEH2_END; 00895 00896 /* now probe the allocated mdl's */ 00897 if (!NT_SUCCESS(Status)) 00898 { 00899 DPRINT("Status %x\n", Status); 00900 return Status; 00901 } 00902 else 00903 goto ProbeMdl; 00904 } 00905 00906 /* probe user mode buffers */ 00907 if (Length && ( (!HeaderSize) || (Length % HeaderSize == 0) || ((ProbeFlags & KSPROBE_ALLOWFORMATCHANGE) && (Length == sizeof(KSSTREAM_HEADER))) ) ) 00908 { 00909 /* allocate stream header buffer */ 00910 Irp->AssociatedIrp.SystemBuffer = AllocateItem(NonPagedPool, Length); 00911 00912 if (!Irp->AssociatedIrp.SystemBuffer) 00913 { 00914 /* no memory */ 00915 return STATUS_INSUFFICIENT_RESOURCES; 00916 } 00917 00918 /* mark irp as buffered so that changes the stream headers are propagated back */ 00919 Irp->Flags = IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO; 00920 00921 _SEH2_TRY 00922 { 00923 if (ProbeFlags & KSPROBE_STREAMWRITE) 00924 { 00925 if (ProbeFlags & KSPROBE_MODIFY) 00926 ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR)); 00927 else 00928 ProbeForRead(Irp->UserBuffer, Length, sizeof(UCHAR)); 00929 } 00930 else 00931 { 00932 /* stream reads means writing */ 00933 ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR)); 00934 00935 /* set input operation flags */ 00936 Irp->Flags |= IRP_INPUT_OPERATION; 00937 } 00938 00939 /* copy stream buffer */ 00940 RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, Irp->UserBuffer, Length); 00941 } 00942 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00943 { 00944 /* Exception, get the error code */ 00945 Status = _SEH2_GetExceptionCode(); 00946 }_SEH2_END; 00947 00948 if (!NT_SUCCESS(Status)) 00949 { 00950 /* failed */ 00951 return Status; 00952 } 00953 00954 if (ProbeFlags & KSPROBE_ALLOCATEMDL) 00955 { 00956 /* alloc mdls */ 00957 goto AllocMdl; 00958 } 00959 00960 /* check all stream headers */ 00961 StreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; 00962 00963 _SEH2_TRY 00964 { 00965 do 00966 { 00967 if (HeaderSize) 00968 { 00969 /* does the supplied header size match stream header size and no type changed */ 00970 if (StreamHeader->Size != HeaderSize && !(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)) 00971 { 00972 /* invalid stream header */ 00973 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00974 } 00975 } 00976 else 00977 { 00978 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */ 00979 if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) || (StreamHeader->Size & 7)) 00980 { 00981 /* invalid stream header */ 00982 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00983 } 00984 } 00985 00986 if (Length < StreamHeader->Size) 00987 { 00988 /* length is too short */ 00989 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00990 } 00991 00992 if (ProbeFlags & KSPROBE_STREAMWRITE) 00993 { 00994 if (StreamHeader->DataUsed > StreamHeader->FrameExtent) 00995 { 00996 /* frame extend can never be smaller */ 00997 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 00998 } 00999 01000 /* is this stream change packet */ 01001 if (StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED) 01002 { 01003 if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader != Irp->AssociatedIrp.SystemBuffer) 01004 { 01005 /* stream changed - must be send in a single packet */ 01006 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 01007 } 01008 01009 if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE)) 01010 { 01011 /* caller does not permit format changes */ 01012 ExRaiseStatus(STATUS_INVALID_PARAMETER); 01013 } 01014 01015 if (StreamHeader->FrameExtent) 01016 { 01017 /* allocate an mdl */ 01018 Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp); 01019 01020 if (!Mdl) 01021 { 01022 /* not enough memory */ 01023 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES); 01024 } 01025 01026 /* break out to probe for the irp */ 01027 //AllocateMdl = TRUE; 01028 break; 01029 } 01030 } 01031 } 01032 else 01033 { 01034 if (StreamHeader->DataUsed) 01035 { 01036 /* DataUsed must be zero for stream read operation */ 01037 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE); 01038 } 01039 01040 if (StreamHeader->OptionsFlags) 01041 { 01042 /* no flags supported for reading */ 01043 ExRaiseStatus(STATUS_INVALID_PARAMETER); 01044 } 01045 } 01046 01047 /* move to next stream header */ 01048 Length -= StreamHeader->Size; 01049 StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size); 01050 }while(Length); 01051 01052 }_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 01053 { 01054 /* Exception, get the error code */ 01055 Status = _SEH2_GetExceptionCode(); 01056 }_SEH2_END; 01057 01058 /* now probe the allocated mdl's */ 01059 if (NT_SUCCESS(Status)) 01060 goto AllocMdl; 01061 else 01062 return Status; 01063 } 01064 01065 return STATUS_INVALID_BUFFER_SIZE; 01066 } 01067 01068 /* 01069 @implemented 01070 */ 01071 KSDDKAPI 01072 NTSTATUS 01073 NTAPI 01074 KsAllocateExtraData( 01075 IN PIRP Irp, 01076 IN ULONG ExtraSize, 01077 OUT PVOID* ExtraBuffer) 01078 { 01079 PIO_STACK_LOCATION IoStack; 01080 ULONG Count, Index; 01081 PUCHAR Buffer, BufferOrg; 01082 PKSSTREAM_HEADER Header; 01083 NTSTATUS Status = STATUS_SUCCESS; 01084 01085 /* get current irp stack */ 01086 IoStack = IoGetCurrentIrpStackLocation(Irp); 01087 01088 /* sanity check */ 01089 ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSSTREAM_HEADER)); 01090 01091 /* get total length */ 01092 Count = IoStack->Parameters.DeviceIoControl.InputBufferLength / sizeof(KSSTREAM_HEADER); 01093 01094 /* allocate buffer */ 01095 Buffer = BufferOrg = AllocateItem(NonPagedPool, Count * (sizeof(KSSTREAM_HEADER) + ExtraSize)); 01096 if (!Buffer) 01097 return STATUS_INSUFFICIENT_RESOURCES; 01098 01099 _SEH2_TRY 01100 { 01101 /* get input buffer */ 01102 Header = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 01103 for(Index = 0; Index < Count; Index++) 01104 { 01105 /* copy stream header */ 01106 RtlMoveMemory(Buffer, Header, sizeof(KSSTREAM_HEADER)); 01107 01108 /* move to next header */ 01109 Header++; 01110 /* increment output buffer offset */ 01111 Buffer += sizeof(KSSTREAM_HEADER) + ExtraSize; 01112 } 01113 } 01114 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 01115 { 01116 /* Exception, get the error code */ 01117 Status = _SEH2_GetExceptionCode(); 01118 } 01119 _SEH2_END; 01120 01121 if (!NT_SUCCESS(Status)) 01122 { 01123 /* free buffer on exception */ 01124 FreeItem(Buffer); 01125 return Status; 01126 } 01127 01128 /* store result */ 01129 *ExtraBuffer = BufferOrg; 01130 01131 /* done */ 01132 return STATUS_SUCCESS; 01133 } 01134 01135 /* 01136 @implemented 01137 */ 01138 KSDDKAPI 01139 VOID 01140 NTAPI 01141 KsNullDriverUnload( 01142 IN PDRIVER_OBJECT DriverObject) 01143 { 01144 } 01145 01146 /* 01147 @implemented 01148 */ 01149 KSDDKAPI 01150 NTSTATUS 01151 NTAPI 01152 KsDispatchInvalidDeviceRequest( 01153 IN PDEVICE_OBJECT DeviceObject, 01154 IN PIRP Irp) 01155 { 01156 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 01157 CompleteRequest(Irp, IO_NO_INCREMENT); 01158 01159 return STATUS_INVALID_DEVICE_REQUEST; 01160 } 01161 01162 /* 01163 @implemented 01164 */ 01165 KSDDKAPI 01166 NTSTATUS 01167 NTAPI 01168 KsDefaultDeviceIoCompletion( 01169 IN PDEVICE_OBJECT DeviceObject, 01170 IN PIRP Irp) 01171 { 01172 PIO_STACK_LOCATION IoStack; 01173 NTSTATUS Status; 01174 01175 /* get current irp stack */ 01176 IoStack = IoGetCurrentIrpStackLocation(Irp); 01177 01178 if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY && 01179 IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_METHOD && 01180 IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY) 01181 { 01182 if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) 01183 { 01184 /* fake success */ 01185 Status = STATUS_SUCCESS; 01186 } 01187 else 01188 { 01189 /* request unsupported */ 01190 Status = STATUS_INVALID_DEVICE_REQUEST; 01191 } 01192 } 01193 else 01194 { 01195 /* property / method / event not found */ 01196 Status = STATUS_PROPSET_NOT_FOUND; 01197 } 01198 01199 /* complete request */ 01200 Irp->IoStatus.Status = Status; 01201 CompleteRequest(Irp, IO_NO_INCREMENT); 01202 01203 01204 return Status; 01205 } 01206 01207 /* 01208 @implemented 01209 */ 01210 KSDDKAPI 01211 BOOLEAN 01212 NTAPI 01213 KsDispatchFastIoDeviceControlFailure( 01214 IN PFILE_OBJECT FileObject, 01215 IN BOOLEAN Wait, 01216 IN PVOID InputBuffer OPTIONAL, 01217 IN ULONG InputBufferLength, 01218 OUT PVOID OutputBuffer OPTIONAL, 01219 IN ULONG OutputBufferLength, 01220 IN ULONG IoControlCode, 01221 OUT PIO_STATUS_BLOCK IoStatus, 01222 IN PDEVICE_OBJECT DeviceObject) 01223 { 01224 return FALSE; 01225 } 01226 01227 /* 01228 @implemented 01229 */ 01230 KSDDKAPI 01231 BOOLEAN 01232 NTAPI 01233 KsDispatchFastReadFailure( 01234 IN PFILE_OBJECT FileObject, 01235 IN PLARGE_INTEGER FileOffset, 01236 IN ULONG Length, 01237 IN BOOLEAN Wait, 01238 IN ULONG LockKey, 01239 OUT PVOID Buffer, 01240 OUT PIO_STATUS_BLOCK IoStatus, 01241 IN PDEVICE_OBJECT DeviceObject) 01242 { 01243 return FALSE; 01244 } 01245 01246 01247 /* 01248 @implemented 01249 */ 01250 KSDDKAPI 01251 VOID 01252 NTAPI 01253 KsCancelIo( 01254 IN OUT PLIST_ENTRY QueueHead, 01255 IN PKSPIN_LOCK SpinLock) 01256 { 01257 PDRIVER_CANCEL OldDriverCancel; 01258 PIO_STACK_LOCATION IoStack; 01259 PLIST_ENTRY Entry; 01260 PLIST_ENTRY NextEntry; 01261 PIRP Irp; 01262 KIRQL OldLevel; 01263 01264 /* acquire spinlock */ 01265 KeAcquireSpinLock(SpinLock, &OldLevel); 01266 /* point to first entry */ 01267 Entry = QueueHead->Flink; 01268 /* loop all items */ 01269 while(Entry != QueueHead) 01270 { 01271 /* get irp offset */ 01272 Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry); 01273 01274 /* get next entry */ 01275 NextEntry = Entry->Flink; 01276 01277 /* set cancelled bit */ 01278 Irp->Cancel = TRUE; 01279 01280 /* now set the cancel routine */ 01281 OldDriverCancel = IoSetCancelRoutine(Irp, NULL); 01282 if (OldDriverCancel) 01283 { 01284 /* this irp hasnt been yet used, so free to cancel */ 01285 KeReleaseSpinLock(SpinLock, OldLevel); 01286 01287 /* get current irp stack */ 01288 IoStack = IoGetCurrentIrpStackLocation(Irp); 01289 01290 /* acquire cancel spinlock */ 01291 IoAcquireCancelSpinLock(&Irp->CancelIrql); 01292 01293 /* call provided cancel routine */ 01294 OldDriverCancel(IoStack->DeviceObject, Irp); 01295 01296 /* re-acquire spinlock */ 01297 KeAcquireSpinLock(SpinLock, &OldLevel); 01298 } 01299 01300 /* move on to next entry */ 01301 Entry = NextEntry; 01302 } 01303 01304 /* the irp has already been canceled */ 01305 KeReleaseSpinLock(SpinLock, OldLevel); 01306 01307 } 01308 01309 /* 01310 @implemented 01311 */ 01312 KSDDKAPI 01313 VOID 01314 NTAPI 01315 KsReleaseIrpOnCancelableQueue( 01316 IN PIRP Irp, 01317 IN PDRIVER_CANCEL DriverCancel OPTIONAL) 01318 { 01319 PKSPIN_LOCK SpinLock; 01320 PDRIVER_CANCEL OldDriverCancel; 01321 PIO_STACK_LOCATION IoStack; 01322 KIRQL OldLevel; 01323 01324 /* check for required parameters */ 01325 if (!Irp) 01326 return; 01327 01328 if (!DriverCancel) 01329 { 01330 /* default to KsCancelRoutine */ 01331 DriverCancel = KsCancelRoutine; 01332 } 01333 01334 /* get current irp stack */ 01335 IoStack = IoGetCurrentIrpStackLocation(Irp); 01336 01337 /* get internal queue lock */ 01338 SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp); 01339 01340 /* acquire spinlock */ 01341 KeAcquireSpinLock(SpinLock, &OldLevel); 01342 01343 /* now set the cancel routine */ 01344 OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel); 01345 01346 if (Irp->Cancel && OldDriverCancel == NULL) 01347 { 01348 /* the irp has already been canceled */ 01349 KeReleaseSpinLock(SpinLock, OldLevel); 01350 01351 /* cancel routine requires that cancel spinlock is held */ 01352 IoAcquireCancelSpinLock(&Irp->CancelIrql); 01353 01354 /* cancel irp */ 01355 DriverCancel(IoStack->DeviceObject, Irp); 01356 } 01357 else 01358 { 01359 /* done */ 01360 KeReleaseSpinLock(SpinLock, OldLevel); 01361 } 01362 } 01363 01364 /* 01365 @implemented 01366 */ 01367 KSDDKAPI 01368 PIRP 01369 NTAPI 01370 KsRemoveIrpFromCancelableQueue( 01371 IN OUT PLIST_ENTRY QueueHead, 01372 IN PKSPIN_LOCK SpinLock, 01373 IN KSLIST_ENTRY_LOCATION ListLocation, 01374 IN KSIRP_REMOVAL_OPERATION RemovalOperation) 01375 { 01376 PIRP Irp; 01377 PLIST_ENTRY CurEntry; 01378 KIRQL OldIrql; 01379 01380 DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation); 01381 01382 /* check parameters */ 01383 if (!QueueHead || !SpinLock) 01384 return NULL; 01385 01386 /* check if parameter ListLocation is valid */ 01387 if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead) 01388 return NULL; 01389 01390 /* acquire list lock */ 01391 KeAcquireSpinLock(SpinLock, &OldIrql); 01392 01393 /* point to queue head */ 01394 CurEntry = QueueHead; 01395 01396 do 01397 { 01398 /* reset irp to null */ 01399 Irp = NULL; 01400 01401 /* iterate to next entry */ 01402 if (ListLocation == KsListEntryHead) 01403 CurEntry = CurEntry->Flink; 01404 else 01405 CurEntry = CurEntry->Blink; 01406 01407 /* is the end of list reached */ 01408 if (CurEntry == QueueHead) 01409 { 01410 /* reached end of list */ 01411 break; 01412 } 01413 01414 /* get irp offset */ 01415 Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry); 01416 01417 if (Irp->Cancel) 01418 { 01419 /* irp has been canceled */ 01420 break; 01421 } 01422 01423 if (Irp->CancelRoutine) 01424 { 01425 /* remove cancel routine */ 01426 Irp->CancelRoutine = NULL; 01427 01428 if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem) 01429 { 01430 /* remove irp from list */ 01431 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 01432 } 01433 01434 if (RemovalOperation == KsAcquireAndRemoveOnlySingleItem || RemovalOperation == KsAcquireOnlySingleItem) 01435 break; 01436 } 01437 01438 }while(TRUE); 01439 01440 /* release lock */ 01441 KeReleaseSpinLock(SpinLock, OldIrql); 01442 01443 if (!Irp || Irp->CancelRoutine == NULL) 01444 { 01445 /* either an irp has been acquired or nothing found */ 01446 return Irp; 01447 } 01448 01449 /* time to remove the canceled irp */ 01450 IoAcquireCancelSpinLock(&OldIrql); 01451 /* acquire list lock */ 01452 KeAcquireSpinLockAtDpcLevel(SpinLock); 01453 01454 if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem) 01455 { 01456 /* remove it */ 01457 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 01458 } 01459 01460 /* release list lock */ 01461 KeReleaseSpinLockFromDpcLevel(SpinLock); 01462 01463 /* release cancel spinlock */ 01464 IoReleaseCancelSpinLock(OldIrql); 01465 /* no non canceled irp has been found */ 01466 return NULL; 01467 } 01468 01469 /* 01470 @implemented 01471 */ 01472 KSDDKAPI 01473 NTSTATUS 01474 NTAPI 01475 KsMoveIrpsOnCancelableQueue( 01476 IN OUT PLIST_ENTRY SourceList, 01477 IN PKSPIN_LOCK SourceLock, 01478 IN OUT PLIST_ENTRY DestinationList, 01479 IN PKSPIN_LOCK DestinationLock OPTIONAL, 01480 IN KSLIST_ENTRY_LOCATION ListLocation, 01481 IN PFNKSIRPLISTCALLBACK ListCallback, 01482 IN PVOID Context) 01483 { 01484 KIRQL OldLevel; 01485 PLIST_ENTRY SrcEntry; 01486 PIRP Irp; 01487 NTSTATUS Status = STATUS_SUCCESS; 01488 01489 if (!DestinationLock) 01490 { 01491 /* no destination lock just acquire the source lock */ 01492 KeAcquireSpinLock(SourceLock, &OldLevel); 01493 } 01494 else 01495 { 01496 /* acquire cancel spinlock */ 01497 IoAcquireCancelSpinLock(&OldLevel); 01498 01499 /* now acquire source lock */ 01500 KeAcquireSpinLockAtDpcLevel(SourceLock); 01501 01502 /* now acquire destination lock */ 01503 KeAcquireSpinLockAtDpcLevel(DestinationLock); 01504 } 01505 01506 /* point to list head */ 01507 SrcEntry = SourceList; 01508 01509 /* now move all irps */ 01510 while(TRUE) 01511 { 01512 if (ListLocation == KsListEntryTail) 01513 { 01514 /* move queue downwards */ 01515 SrcEntry = SrcEntry->Flink; 01516 } 01517 else 01518 { 01519 /* move queue upwards */ 01520 SrcEntry = SrcEntry->Blink; 01521 } 01522 01523 if (SrcEntry == SourceList) 01524 { 01525 /* eof list reached */ 01526 break; 01527 } 01528 01529 /* get irp offset */ 01530 Irp = (PIRP)CONTAINING_RECORD(SrcEntry, IRP, Tail.Overlay.ListEntry); 01531 01532 /* now check if irp can be moved */ 01533 Status = ListCallback(Irp, Context); 01534 01535 /* check if irp can be moved */ 01536 if (Status == STATUS_SUCCESS) 01537 { 01538 /* remove irp from src list */ 01539 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 01540 01541 if (ListLocation == KsListEntryTail) 01542 { 01543 /* insert irp end of list */ 01544 InsertTailList(DestinationList, &Irp->Tail.Overlay.ListEntry); 01545 } 01546 else 01547 { 01548 /* insert irp head of list */ 01549 InsertHeadList(DestinationList, &Irp->Tail.Overlay.ListEntry); 01550 } 01551 01552 /* do we need to update the irp lock */ 01553 if (DestinationLock) 01554 { 01555 /* update irp lock */ 01556 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) = DestinationLock; 01557 } 01558 } 01559 else 01560 { 01561 if (Status != STATUS_NO_MATCH) 01562 { 01563 /* callback decided to stop enumeration */ 01564 break; 01565 } 01566 01567 /* reset return value */ 01568 Status = STATUS_SUCCESS; 01569 } 01570 } 01571 01572 if (!DestinationLock) 01573 { 01574 /* release source lock */ 01575 KeReleaseSpinLock(SourceLock, OldLevel); 01576 } 01577 else 01578 { 01579 /* now release destination lock */ 01580 KeReleaseSpinLockFromDpcLevel(DestinationLock); 01581 01582 /* now release source lock */ 01583 KeReleaseSpinLockFromDpcLevel(SourceLock); 01584 01585 01586 /* now release cancel spinlock */ 01587 IoReleaseCancelSpinLock(OldLevel); 01588 } 01589 01590 /* done */ 01591 return Status; 01592 } 01593 01594 /* 01595 @implemented 01596 */ 01597 KSDDKAPI 01598 VOID 01599 NTAPI 01600 KsRemoveSpecificIrpFromCancelableQueue( 01601 IN PIRP Irp) 01602 { 01603 PKSPIN_LOCK SpinLock; 01604 KIRQL OldLevel; 01605 01606 DPRINT("KsRemoveSpecificIrpFromCancelableQueue %p\n", Irp); 01607 01608 /* get internal queue lock */ 01609 SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp); 01610 01611 /* acquire spinlock */ 01612 KeAcquireSpinLock(SpinLock, &OldLevel); 01613 01614 /* remove the irp from the list */ 01615 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 01616 01617 /* release spinlock */ 01618 KeReleaseSpinLock(SpinLock, OldLevel); 01619 } 01620 01621 01622 /* 01623 @implemented 01624 */ 01625 KSDDKAPI 01626 VOID 01627 NTAPI 01628 KsAddIrpToCancelableQueue( 01629 IN OUT PLIST_ENTRY QueueHead, 01630 IN PKSPIN_LOCK SpinLock, 01631 IN PIRP Irp, 01632 IN KSLIST_ENTRY_LOCATION ListLocation, 01633 IN PDRIVER_CANCEL DriverCancel OPTIONAL) 01634 { 01635 PDRIVER_CANCEL OldDriverCancel; 01636 PIO_STACK_LOCATION IoStack; 01637 KIRQL OldLevel; 01638 01639 /* check for required parameters */ 01640 if (!QueueHead || !SpinLock || !Irp) 01641 return; 01642 01643 /* get current irp stack */ 01644 IoStack = IoGetCurrentIrpStackLocation(Irp); 01645 01646 DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel); 01647 01648 // HACK for ms portcls 01649 if (IoStack->MajorFunction == IRP_MJ_CREATE) 01650 { 01651 // complete the request 01652 DPRINT1("MS HACK\n"); 01653 Irp->IoStatus.Status = STATUS_SUCCESS; 01654 CompleteRequest(Irp, IO_NO_INCREMENT); 01655 01656 return; 01657 } 01658 01659 01660 if (!DriverCancel) 01661 { 01662 /* default to KsCancelRoutine */ 01663 DriverCancel = KsCancelRoutine; 01664 } 01665 01666 01667 /* acquire spinlock */ 01668 KeAcquireSpinLock(SpinLock, &OldLevel); 01669 01670 if (ListLocation == KsListEntryTail) 01671 { 01672 /* insert irp to tail of list */ 01673 InsertTailList(QueueHead, &Irp->Tail.Overlay.ListEntry); 01674 } 01675 else 01676 { 01677 /* insert irp to head of list */ 01678 InsertHeadList(QueueHead, &Irp->Tail.Overlay.ListEntry); 01679 } 01680 01681 /* store internal queue lock */ 01682 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) = SpinLock; 01683 01684 /* now set the cancel routine */ 01685 OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel); 01686 01687 if (Irp->Cancel && OldDriverCancel == NULL) 01688 { 01689 /* the irp has already been canceled */ 01690 KeReleaseSpinLock(SpinLock, OldLevel); 01691 01692 /* cancel routine requires that cancel spinlock is held */ 01693 IoAcquireCancelSpinLock(&Irp->CancelIrql); 01694 01695 /* cancel irp */ 01696 DriverCancel(IoStack->DeviceObject, Irp); 01697 } 01698 else 01699 { 01700 /* done */ 01701 KeReleaseSpinLock(SpinLock, OldLevel); 01702 } 01703 } 01704 01705 /* 01706 @implemented 01707 */ 01708 KSDDKAPI 01709 VOID 01710 NTAPI 01711 KsCancelRoutine( 01712 IN PDEVICE_OBJECT DeviceObject, 01713 IN PIRP Irp) 01714 { 01715 PKSPIN_LOCK SpinLock; 01716 01717 /* get internal queue lock */ 01718 SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp); 01719 01720 /* acquire spinlock */ 01721 KeAcquireSpinLockAtDpcLevel(SpinLock); 01722 01723 /* sanity check */ 01724 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); 01725 01726 /* release cancel spinlock */ 01727 IoReleaseCancelSpinLock(Irp->CancelIrql); 01728 01729 /* remove the irp from the list */ 01730 RemoveEntryList(&Irp->Tail.Overlay.ListEntry); 01731 01732 /* release spinlock */ 01733 KeReleaseSpinLock(SpinLock, Irp->CancelIrql); 01734 01735 /* has the irp already been canceled */ 01736 if (Irp->IoStatus.Status != STATUS_CANCELLED) 01737 { 01738 /* let's complete it */ 01739 Irp->IoStatus.Status = STATUS_CANCELLED; 01740 CompleteRequest(Irp, IO_NO_INCREMENT); 01741 } 01742 } 01743 01744 NTSTATUS 01745 FindMatchingCreateItem( 01746 PLIST_ENTRY ListHead, 01747 ULONG BufferSize, 01748 LPWSTR Buffer, 01749 OUT PCREATE_ITEM_ENTRY *OutCreateItem) 01750 { 01751 PLIST_ENTRY Entry; 01752 PCREATE_ITEM_ENTRY CreateItemEntry; 01753 UNICODE_STRING RefString; 01754 LPWSTR pStr; 01755 01756 /* get terminator */ 01757 pStr = wcschr(Buffer, L'\\'); 01758 01759 /* sanity check */ 01760 ASSERT(pStr != NULL); 01761 01762 if (pStr == Buffer) 01763 { 01764 // skip slash 01765 RtlInitUnicodeString(&RefString, ++pStr); 01766 } 01767 else 01768 { 01769 // request is for pin / node / allocator 01770 RefString.Buffer = Buffer; 01771 RefString.Length = BufferSize = RefString.MaximumLength = ((ULONG_PTR)pStr - (ULONG_PTR)Buffer); 01772 } 01773 01774 /* point to first entry */ 01775 Entry = ListHead->Flink; 01776 01777 /* loop all device items */ 01778 while(Entry != ListHead) 01779 { 01780 /* get create item entry */ 01781 CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry); 01782 01783 ASSERT(CreateItemEntry->CreateItem); 01784 01785 if(CreateItemEntry->CreateItem->Flags & KSCREATE_ITEM_WILDCARD) 01786 { 01787 /* create item is default */ 01788 *OutCreateItem = CreateItemEntry; 01789 return STATUS_SUCCESS; 01790 } 01791 01792 if (!CreateItemEntry->CreateItem->Create) 01793 { 01794 /* skip free create item */ 01795 Entry = Entry->Flink; 01796 continue; 01797 } 01798 01799 DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer, 01800 CreateItemEntry->CreateItem->ObjectClass.Length, 01801 &RefString, 01802 RefString.Length); 01803 01804 if (CreateItemEntry->CreateItem->ObjectClass.Length > RefString.Length) 01805 { 01806 /* create item doesnt match in length */ 01807 Entry = Entry->Flink; 01808 continue; 01809 } 01810 01811 /* now check if the object class is the same */ 01812 if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE)) 01813 { 01814 /* found matching create item */ 01815 *OutCreateItem = CreateItemEntry; 01816 return STATUS_SUCCESS; 01817 } 01818 /* iterate to next */ 01819 Entry = Entry->Flink; 01820 } 01821 01822 return STATUS_NOT_FOUND; 01823 } 01824 01825 NTSTATUS 01826 NTAPI 01827 KspCreate( 01828 IN PDEVICE_OBJECT DeviceObject, 01829 IN PIRP Irp) 01830 { 01831 PCREATE_ITEM_ENTRY CreateItemEntry; 01832 PIO_STACK_LOCATION IoStack; 01833 PDEVICE_EXTENSION DeviceExtension; 01834 PKSIDEVICE_HEADER DeviceHeader; 01835 PKSIOBJECT_HEADER ObjectHeader; 01836 NTSTATUS Status; 01837 01838 DPRINT("KS / CREATE\n"); 01839 01840 /* get current stack location */ 01841 IoStack = IoGetCurrentIrpStackLocation(Irp); 01842 /* get device extension */ 01843 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 01844 /* get device header */ 01845 DeviceHeader = DeviceExtension->DeviceHeader; 01846 01847 01848 if (IoStack->FileObject->FileName.Buffer == NULL) 01849 { 01850 /* FIXME Pnp-Issue */ 01851 DPRINT("Using reference string hack\n"); 01852 Irp->IoStatus.Information = 0; 01853 /* set return status */ 01854 Irp->IoStatus.Status = STATUS_SUCCESS; 01855 CompleteRequest(Irp, IO_NO_INCREMENT); 01856 return STATUS_SUCCESS; 01857 } 01858 01859 if (IoStack->FileObject->RelatedFileObject != NULL) 01860 { 01861 /* request is to instantiate a pin / node / clock / allocator */ 01862 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2; 01863 01864 /* sanity check */ 01865 ASSERT(ObjectHeader); 01866 01867 /* find a matching a create item */ 01868 Status = FindMatchingCreateItem(&ObjectHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry); 01869 } 01870 else 01871 { 01872 /* request to create a filter */ 01873 Status = FindMatchingCreateItem(&DeviceHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry); 01874 } 01875 01876 if (NT_SUCCESS(Status)) 01877 { 01878 /* set object create item */ 01879 KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem; 01880 01881 /* call create function */ 01882 Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp); 01883 01884 if (NT_SUCCESS(Status)) 01885 { 01886 /* increment create item reference count */ 01887 InterlockedIncrement(&CreateItemEntry->ReferenceCount); 01888 } 01889 return Status; 01890 } 01891 01892 Irp->IoStatus.Information = 0; 01893 /* set return status */ 01894 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 01895 CompleteRequest(Irp, IO_NO_INCREMENT); 01896 return STATUS_UNSUCCESSFUL; 01897 } 01898 01899 NTSTATUS 01900 NTAPI 01901 KspDispatchIrp( 01902 IN PDEVICE_OBJECT DeviceObject, 01903 IN PIRP Irp) 01904 { 01905 PIO_STACK_LOCATION IoStack; 01906 //PDEVICE_EXTENSION DeviceExtension; 01907 PKSIOBJECT_HEADER ObjectHeader; 01908 //PKSIDEVICE_HEADER DeviceHeader; 01909 PDRIVER_DISPATCH Dispatch; 01910 NTSTATUS Status; 01911 01912 /* get current stack location */ 01913 IoStack = IoGetCurrentIrpStackLocation(Irp); 01914 01915 /* get device extension */ 01916 //DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 01917 /* get device header */ 01918 //DeviceHeader = DeviceExtension->DeviceHeader; 01919 01920 ASSERT(IoStack->FileObject); 01921 01922 /* get object header */ 01923 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext2; 01924 01925 if (!ObjectHeader) 01926 { 01927 /* FIXME Pnp-Issue*/ 01928 Irp->IoStatus.Status = STATUS_SUCCESS; 01929 Irp->IoStatus.Information = 0; 01930 /* complete and forget */ 01931 CompleteRequest(Irp, IO_NO_INCREMENT); 01932 return STATUS_SUCCESS; 01933 } 01934 01935 /* sanity check */ 01936 ASSERT(ObjectHeader); 01937 /* store create item */ 01938 //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem; 01939 01940 /* retrieve matching dispatch function */ 01941 switch(IoStack->MajorFunction) 01942 { 01943 case IRP_MJ_CLOSE: 01944 Dispatch = ObjectHeader->DispatchTable.Close; 01945 break; 01946 case IRP_MJ_DEVICE_CONTROL: 01947 Dispatch = ObjectHeader->DispatchTable.DeviceIoControl; 01948 break; 01949 case IRP_MJ_READ: 01950 Dispatch = ObjectHeader->DispatchTable.Read; 01951 break; 01952 case IRP_MJ_WRITE: 01953 Dispatch = ObjectHeader->DispatchTable.Write; 01954 break; 01955 case IRP_MJ_FLUSH_BUFFERS : 01956 Dispatch = ObjectHeader->DispatchTable.Flush; 01957 break; 01958 case IRP_MJ_QUERY_SECURITY: 01959 Dispatch = ObjectHeader->DispatchTable.QuerySecurity; 01960 break; 01961 case IRP_MJ_SET_SECURITY: 01962 Dispatch = ObjectHeader->DispatchTable.SetSecurity; 01963 break; 01964 case IRP_MJ_PNP: 01965 Dispatch = KsDefaultDispatchPnp; 01966 break; 01967 default: 01968 Dispatch = NULL; 01969 } 01970 01971 /* is the request supported */ 01972 if (Dispatch) 01973 { 01974 /* now call the dispatch function */ 01975 Status = Dispatch(DeviceObject, Irp); 01976 } 01977 else 01978 { 01979 /* not supported request */ 01980 Status = KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 01981 } 01982 01983 /* done */ 01984 return Status; 01985 } 01986 01987 /* 01988 @implemented 01989 */ 01990 KSDDKAPI 01991 NTSTATUS 01992 NTAPI 01993 KsSetMajorFunctionHandler( 01994 IN PDRIVER_OBJECT DriverObject, 01995 IN ULONG MajorFunction) 01996 { 01997 DPRINT("KsSetMajorFunctionHandler Function %x\n", MajorFunction); 01998 01999 switch ( MajorFunction ) 02000 { 02001 case IRP_MJ_CREATE: 02002 DriverObject->MajorFunction[MajorFunction] = KspCreate; 02003 break; 02004 case IRP_MJ_DEVICE_CONTROL: 02005 case IRP_MJ_CLOSE: 02006 case IRP_MJ_READ: 02007 case IRP_MJ_WRITE: 02008 case IRP_MJ_FLUSH_BUFFERS : 02009 case IRP_MJ_QUERY_SECURITY: 02010 case IRP_MJ_SET_SECURITY: 02011 DriverObject->MajorFunction[MajorFunction] = KspDispatchIrp; 02012 break; 02013 default: 02014 DPRINT1("NotSupported %x\n", MajorFunction); 02015 return STATUS_INVALID_PARAMETER; 02016 }; 02017 02018 return STATUS_SUCCESS; 02019 } 02020 02021 /* 02022 @implemented 02023 */ 02024 KSDDKAPI 02025 NTSTATUS 02026 NTAPI 02027 KsDispatchIrp( 02028 IN PDEVICE_OBJECT DeviceObject, 02029 IN PIRP Irp) 02030 { 02031 PIO_STACK_LOCATION IoStack; 02032 PKSIDEVICE_HEADER DeviceHeader; 02033 PDEVICE_EXTENSION DeviceExtension; 02034 02035 DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp); 02036 02037 /* get device extension */ 02038 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 02039 02040 /* get device header */ 02041 DeviceHeader = DeviceExtension->DeviceHeader; 02042 02043 02044 /* get current irp stack */ 02045 IoStack = IoGetCurrentIrpStackLocation(Irp); 02046 02047 if (IoStack->MajorFunction <= IRP_MJ_DEVICE_CONTROL) 02048 { 02049 if (IoStack->MajorFunction == IRP_MJ_CREATE) 02050 { 02051 /* check internal type */ 02052 if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ 02053 { 02054 /* AVStream client */ 02055 return IKsDevice_Create(DeviceObject, Irp); 02056 } 02057 else 02058 { 02059 /* external client (portcls) */ 02060 return KspCreate(DeviceObject, Irp); 02061 } 02062 } 02063 02064 switch (IoStack->MajorFunction) 02065 { 02066 case IRP_MJ_CLOSE: 02067 case IRP_MJ_READ: 02068 case IRP_MJ_WRITE: 02069 case IRP_MJ_FLUSH_BUFFERS: 02070 case IRP_MJ_QUERY_SECURITY: 02071 case IRP_MJ_SET_SECURITY: 02072 case IRP_MJ_PNP: 02073 case IRP_MJ_DEVICE_CONTROL: 02074 return KspDispatchIrp(DeviceObject, Irp); 02075 default: 02076 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 02077 } 02078 } 02079 02080 /* dispatch power */ 02081 if (IoStack->MajorFunction == IRP_MJ_POWER) 02082 { 02083 /* check internal type */ 02084 if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ 02085 { 02086 /* AVStream client */ 02087 return IKsDevice_Power(DeviceObject, Irp); 02088 } 02089 else 02090 { 02091 /* external client (portcls) */ 02092 return KsDefaultDispatchPower(DeviceObject, Irp); 02093 } 02094 } 02095 else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */ 02096 { 02097 /* check internal type */ 02098 if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */ 02099 { 02100 /* AVStream client */ 02101 return IKsDevice_Pnp(DeviceObject, Irp); 02102 } 02103 else 02104 { 02105 /* external client (portcls) */ 02106 return KsDefaultDispatchPnp(DeviceObject, Irp); 02107 } 02108 } 02109 else if (IoStack->MajorFunction == IRP_MJ_SYSTEM_CONTROL) 02110 { 02111 /* forward irp */ 02112 return KsDefaultForwardIrp(DeviceObject, Irp); 02113 } 02114 else 02115 { 02116 /* not supported */ 02117 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp); 02118 } 02119 } 02120 02121 /* 02122 @unimplemented 02123 */ 02124 KSDDKAPI 02125 ULONG 02126 NTAPI 02127 KsGetNodeIdFromIrp( 02128 IN PIRP Irp) 02129 { 02130 UNIMPLEMENTED 02131 return KSFILTER_NODE; 02132 } 02133 Generated on Sat May 26 2012 04:26:33 for ReactOS by
1.7.6.1
|