Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenapi.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/api.c 00005 * PURPOSE: KS API functions 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 00010 #include "priv.h" 00011 00012 const GUID GUID_NULL = {0x00000000L, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}; 00013 const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; 00014 00015 /* 00016 @implemented 00017 */ 00018 KSDDKAPI 00019 NTSTATUS 00020 NTAPI 00021 KsAcquireResetValue( 00022 IN PIRP Irp, 00023 OUT KSRESET* ResetValue) 00024 { 00025 PIO_STACK_LOCATION IoStack; 00026 KSRESET* Value; 00027 NTSTATUS Status = STATUS_SUCCESS; 00028 00029 /* get current irp stack */ 00030 IoStack = IoGetCurrentIrpStackLocation(Irp); 00031 00032 /* check if there is reset value provided */ 00033 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSRESET)) 00034 return STATUS_INVALID_PARAMETER; 00035 00036 if (Irp->RequestorMode == UserMode) 00037 { 00038 /* need to probe the buffer */ 00039 _SEH2_TRY 00040 { 00041 ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSRESET), sizeof(UCHAR)); 00042 Value = (KSRESET*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00043 *ResetValue = *Value; 00044 } 00045 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER) 00046 { 00047 /* Exception, get the error code */ 00048 Status = _SEH2_GetExceptionCode(); 00049 } 00050 _SEH2_END; 00051 } 00052 else 00053 { 00054 Value = (KSRESET*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; 00055 *ResetValue = *Value; 00056 } 00057 00058 return Status; 00059 } 00060 00061 /* 00062 @implemented 00063 */ 00064 KSDDKAPI 00065 VOID 00066 NTAPI 00067 KsAcquireDeviceSecurityLock( 00068 IN KSDEVICE_HEADER DevHeader, 00069 IN BOOLEAN Exclusive) 00070 { 00071 PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader; 00072 00073 KeEnterCriticalRegion(); 00074 00075 if (Exclusive) 00076 { 00077 ExAcquireResourceExclusiveLite(&Header->SecurityLock, TRUE); 00078 } 00079 else 00080 { 00081 ExAcquireResourceSharedLite(&Header->SecurityLock, TRUE); 00082 } 00083 } 00084 00085 /* 00086 @implemented 00087 */ 00088 KSDDKAPI 00089 VOID 00090 NTAPI 00091 KsReleaseDeviceSecurityLock( 00092 IN KSDEVICE_HEADER DevHeader) 00093 { 00094 PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader; 00095 00096 DPRINT("KsReleaseDevice\n"); 00097 00098 ExReleaseResourceLite(&Header->SecurityLock); 00099 KeLeaveCriticalRegion(); 00100 } 00101 00102 /* 00103 @implemented 00104 */ 00105 KSDDKAPI 00106 NTSTATUS 00107 NTAPI 00108 KsDefaultDispatchPnp( 00109 IN PDEVICE_OBJECT DeviceObject, 00110 IN PIRP Irp) 00111 { 00112 PDEVICE_EXTENSION DeviceExtension; 00113 PKSIDEVICE_HEADER DeviceHeader; 00114 PIO_STACK_LOCATION IoStack; 00115 PDEVICE_OBJECT PnpDeviceObject; 00116 NTSTATUS Status; 00117 ULONG MinorFunction; 00118 00119 /* get current irp stack */ 00120 IoStack = IoGetCurrentIrpStackLocation(Irp); 00121 00122 /* caller wants to add the target device */ 00123 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 00124 00125 /* get device header */ 00126 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; 00127 00128 /* backup PnpBaseObject */ 00129 PnpDeviceObject = DeviceHeader->PnpDeviceObject; 00130 00131 00132 /* backup minor function code */ 00133 MinorFunction = IoStack->MinorFunction; 00134 00135 if(MinorFunction == IRP_MN_REMOVE_DEVICE) 00136 { 00137 /* remove the device */ 00138 KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader); 00139 } 00140 00141 /* skip current irp stack */ 00142 IoSkipCurrentIrpStackLocation(Irp); 00143 00144 /* call attached pnp device object */ 00145 Status = IoCallDriver(PnpDeviceObject, Irp); 00146 00147 if (MinorFunction == IRP_MN_REMOVE_DEVICE) 00148 { 00149 /* time is over */ 00150 IoDetachDevice(PnpDeviceObject); 00151 /* delete device */ 00152 IoDeleteDevice(DeviceObject); 00153 } 00154 /* done */ 00155 return Status; 00156 } 00157 00158 /* 00159 @implemented 00160 */ 00161 KSDDKAPI 00162 NTSTATUS 00163 NTAPI 00164 KsDefaultDispatchPower( 00165 IN PDEVICE_OBJECT DeviceObject, 00166 IN PIRP Irp) 00167 { 00168 PDEVICE_EXTENSION DeviceExtension; 00169 PKSIDEVICE_HEADER DeviceHeader; 00170 PKSIOBJECT_HEADER ObjectHeader; 00171 //PIO_STACK_LOCATION IoStack; 00172 PLIST_ENTRY ListEntry; 00173 NTSTATUS Status; 00174 00175 /* get current irp stack */ 00176 //IoStack = IoGetCurrentIrpStackLocation(Irp); 00177 00178 /* caller wants to add the target device */ 00179 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 00180 00181 /* get device header */ 00182 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; 00183 00184 /* FIXME locks */ 00185 00186 /* loop our power dispatch list and call registered notification functions */ 00187 ListEntry = DeviceHeader->PowerDispatchList.Flink; 00188 /* let's go */ 00189 while(ListEntry != &DeviceHeader->PowerDispatchList) 00190 { 00191 /* get object header */ 00192 ObjectHeader = (PKSIOBJECT_HEADER)CONTAINING_RECORD(ListEntry, KSIOBJECT_HEADER, PowerDispatchEntry); 00193 00194 /* does it have still a cb */ 00195 if (ObjectHeader->PowerDispatch) 00196 { 00197 /* call the power cb */ 00198 Status = ObjectHeader->PowerDispatch(ObjectHeader->PowerContext, Irp); 00199 ASSERT(NT_SUCCESS(Status)); 00200 } 00201 00202 /* iterate to next entry */ 00203 ListEntry = ListEntry->Flink; 00204 } 00205 00206 /* start next power irp */ 00207 PoStartNextPowerIrp(Irp); 00208 00209 /* skip current irp stack location */ 00210 IoSkipCurrentIrpStackLocation(Irp); 00211 00212 /* let's roll */ 00213 Status = PoCallDriver(DeviceHeader->PnpDeviceObject, Irp); 00214 00215 /* done */ 00216 return Status; 00217 } 00218 00219 /* 00220 @implemented 00221 */ 00222 KSDDKAPI 00223 NTSTATUS 00224 NTAPI 00225 KsDefaultForwardIrp( 00226 IN PDEVICE_OBJECT DeviceObject, 00227 IN PIRP Irp) 00228 { 00229 PDEVICE_EXTENSION DeviceExtension; 00230 PKSIDEVICE_HEADER DeviceHeader; 00231 //PIO_STACK_LOCATION IoStack; 00232 NTSTATUS Status; 00233 00234 /* get current irp stack */ 00235 //IoStack = IoGetCurrentIrpStackLocation(Irp); 00236 00237 /* caller wants to add the target device */ 00238 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 00239 00240 /* get device header */ 00241 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; 00242 00243 /* forward the request to the PDO */ 00244 Status = IoCallDriver(DeviceHeader->PnpDeviceObject, Irp); 00245 00246 return Status; 00247 } 00248 00249 /* 00250 @implemented 00251 */ 00252 KSDDKAPI 00253 VOID 00254 NTAPI 00255 KsSetDevicePnpAndBaseObject( 00256 IN KSDEVICE_HEADER Header, 00257 IN PDEVICE_OBJECT PnpDeviceObject, 00258 IN PDEVICE_OBJECT BaseDevice) 00259 { 00260 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 00261 00262 DeviceHeader->PnpDeviceObject = PnpDeviceObject; 00263 DeviceHeader->BaseDevice = BaseDevice; 00264 } 00265 00266 /* 00267 @implemented 00268 */ 00269 KSDDKAPI 00270 PDEVICE_OBJECT 00271 NTAPI 00272 KsQueryDevicePnpObject( 00273 IN KSDEVICE_HEADER Header) 00274 { 00275 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 00276 00277 /* return PnpDeviceObject */ 00278 return DeviceHeader->PnpDeviceObject; 00279 00280 } 00281 00282 /* 00283 @implemented 00284 */ 00285 KSDDKAPI 00286 ACCESS_MASK 00287 NTAPI 00288 KsQueryObjectAccessMask( 00289 IN KSOBJECT_HEADER Header) 00290 { 00291 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header; 00292 00293 /* return access mask */ 00294 return ObjectHeader->AccessMask; 00295 00296 } 00297 00298 /* 00299 @unimplemented 00300 */ 00301 KSDDKAPI 00302 VOID 00303 NTAPI 00304 KsRecalculateStackDepth( 00305 IN KSDEVICE_HEADER Header, 00306 IN BOOLEAN ReuseStackLocation) 00307 { 00308 UNIMPLEMENTED; 00309 } 00310 00311 00312 /* 00313 @implemented 00314 */ 00315 KSDDKAPI 00316 VOID 00317 NTAPI 00318 KsSetTargetState( 00319 IN KSOBJECT_HEADER Header, 00320 IN KSTARGET_STATE TargetState) 00321 { 00322 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 00323 00324 /* set target state */ 00325 DeviceHeader->TargetState = TargetState; 00326 } 00327 00328 /* 00329 @implemented 00330 */ 00331 KSDDKAPI 00332 VOID 00333 NTAPI 00334 KsSetTargetDeviceObject( 00335 IN KSOBJECT_HEADER Header, 00336 IN PDEVICE_OBJECT TargetDevice OPTIONAL) 00337 { 00338 PDEVICE_EXTENSION DeviceExtension; 00339 PKSIDEVICE_HEADER DeviceHeader; 00340 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header; 00341 00342 if(ObjectHeader->TargetDevice) 00343 { 00344 /* there is already a target device set */ 00345 if (!TargetDevice) 00346 { 00347 /* caller wants to remove the target device */ 00348 DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->TargetDevice->DeviceExtension; 00349 00350 /* get device header */ 00351 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; 00352 00353 /* acquire lock */ 00354 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE); 00355 00356 /* remove entry */ 00357 RemoveEntryList(&ObjectHeader->TargetDeviceListEntry); 00358 00359 /* remove device pointer */ 00360 ObjectHeader->TargetDevice = NULL; 00361 00362 /* release lock */ 00363 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); 00364 } 00365 } 00366 else 00367 { 00368 /* no target device yet set */ 00369 if (TargetDevice) 00370 { 00371 /* caller wants to add the target device */ 00372 DeviceExtension = (PDEVICE_EXTENSION)TargetDevice->DeviceExtension; 00373 00374 /* get device header */ 00375 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; 00376 00377 /* acquire lock */ 00378 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE); 00379 00380 /* insert list entry */ 00381 InsertTailList(&DeviceHeader->TargetDeviceList, &ObjectHeader->TargetDeviceListEntry); 00382 00383 /* store target device */ 00384 ObjectHeader->TargetDevice = TargetDevice; 00385 00386 /* release lock */ 00387 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); 00388 } 00389 } 00390 00391 } 00392 00393 /* 00394 @implemented 00395 */ 00396 KSDDKAPI 00397 VOID 00398 NTAPI 00399 KsSetPowerDispatch( 00400 IN KSOBJECT_HEADER Header, 00401 IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL, 00402 IN PVOID PowerContext OPTIONAL) 00403 { 00404 PDEVICE_EXTENSION DeviceExtension; 00405 PKSIDEVICE_HEADER DeviceHeader; 00406 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header; 00407 00408 /* caller wants to add the target device */ 00409 DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->ParentDeviceObject->DeviceExtension; 00410 00411 /* get device header */ 00412 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader; 00413 00414 /* acquire lock */ 00415 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE); 00416 00417 if (PowerDispatch) 00418 { 00419 /* add power dispatch entry */ 00420 InsertTailList(&DeviceHeader->PowerDispatchList, &ObjectHeader->PowerDispatchEntry); 00421 00422 /* store function and context */ 00423 ObjectHeader->PowerDispatch = PowerDispatch; 00424 ObjectHeader->PowerContext = PowerContext; 00425 } 00426 else 00427 { 00428 /* remove power dispatch entry */ 00429 RemoveEntryList(&ObjectHeader->PowerDispatchEntry); 00430 00431 /* store function and context */ 00432 ObjectHeader->PowerDispatch = NULL; 00433 ObjectHeader->PowerContext = NULL; 00434 00435 } 00436 00437 /* release lock */ 00438 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader); 00439 } 00440 00441 00442 /* 00443 @implemented 00444 */ 00445 KSDDKAPI 00446 PKSOBJECT_CREATE_ITEM 00447 NTAPI 00448 KsQueryObjectCreateItem( 00449 IN KSOBJECT_HEADER Header) 00450 { 00451 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header; 00452 return ObjectHeader->OriginalCreateItem; 00453 } 00454 00455 NTSTATUS 00456 KspAddCreateItemToList( 00457 OUT PLIST_ENTRY ListHead, 00458 IN ULONG ItemsCount, 00459 IN PKSOBJECT_CREATE_ITEM ItemsList) 00460 { 00461 ULONG Index; 00462 PCREATE_ITEM_ENTRY Entry; 00463 00464 /* add the items */ 00465 for(Index = 0; Index < ItemsCount; Index++) 00466 { 00467 /* allocate item */ 00468 Entry = AllocateItem(NonPagedPool, sizeof(CREATE_ITEM_ENTRY)); 00469 if (!Entry) 00470 { 00471 /* no memory */ 00472 return STATUS_INSUFFICIENT_RESOURCES; 00473 } 00474 00475 /* initialize entry */ 00476 InitializeListHead(&Entry->ObjectItemList); 00477 Entry->CreateItem = &ItemsList[Index]; 00478 Entry->ReferenceCount = 0; 00479 Entry->ItemFreeCallback = NULL; 00480 00481 InsertTailList(ListHead, &Entry->Entry); 00482 } 00483 return STATUS_SUCCESS; 00484 } 00485 00486 VOID 00487 KspFreeCreateItems( 00488 PLIST_ENTRY ListHead) 00489 { 00490 PCREATE_ITEM_ENTRY Entry; 00491 00492 while(!IsListEmpty(ListHead)) 00493 { 00494 /* remove create item from list */ 00495 Entry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(RemoveHeadList(ListHead), CREATE_ITEM_ENTRY, Entry); 00496 00497 /* caller shouldnt have any references */ 00498 //ASSERT(Entry->ReferenceCount == 0); 00499 //ASSERT(IsListEmpty(&Entry->ObjectItemList)); 00500 00501 /* does the creator wish notification */ 00502 if (Entry->ItemFreeCallback) 00503 { 00504 /* notify creator */ 00505 Entry->ItemFreeCallback(Entry->CreateItem); 00506 } 00507 00508 /* free create item entry */ 00509 FreeItem(Entry); 00510 } 00511 00512 } 00513 00514 /* 00515 @implemented 00516 */ 00517 KSDDKAPI 00518 NTSTATUS 00519 NTAPI 00520 KsAllocateDeviceHeader( 00521 OUT KSDEVICE_HEADER* OutHeader, 00522 IN ULONG ItemsCount, 00523 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL) 00524 { 00525 NTSTATUS Status = STATUS_SUCCESS; 00526 PKSIDEVICE_HEADER Header; 00527 00528 if (!OutHeader) 00529 return STATUS_INVALID_PARAMETER; 00530 00531 /* allocate a device header */ 00532 Header = AllocateItem(PagedPool, sizeof(KSIDEVICE_HEADER)); 00533 00534 /* check for success */ 00535 if (!Header) 00536 return STATUS_INSUFFICIENT_RESOURCES; 00537 00538 /* clear all memory */ 00539 RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER)); 00540 00541 /* initialize device mutex */ 00542 KeInitializeMutex(&Header->DeviceMutex, 0); 00543 00544 /* initialize target device list */ 00545 InitializeListHead(&Header->TargetDeviceList); 00546 /* initialize power dispatch list */ 00547 InitializeListHead(&Header->PowerDispatchList); 00548 /* initialize object bag lists */ 00549 InitializeListHead(&Header->ObjectBags); 00550 00551 /* initialize create item list */ 00552 InitializeListHead(&Header->ItemList); 00553 00554 /* initialize basic header */ 00555 Header->BasicHeader.Type = KsObjectTypeDevice; 00556 Header->BasicHeader.KsDevice = &Header->KsDevice; 00557 Header->BasicHeader.Parent.KsDevice = &Header->KsDevice; 00558 00559 /* are there any create items provided */ 00560 if (ItemsCount && ItemsList) 00561 { 00562 Status = KspAddCreateItemToList(&Header->ItemList, ItemsCount, ItemsList); 00563 00564 if (NT_SUCCESS(Status)) 00565 { 00566 /* store item count */ 00567 Header->ItemListCount = ItemsCount; 00568 } 00569 else 00570 { 00571 /* release create items */ 00572 KspFreeCreateItems(&Header->ItemList); 00573 } 00574 } 00575 00576 /* store result */ 00577 *OutHeader = Header; 00578 00579 return Status; 00580 } 00581 00582 /* 00583 @implemented 00584 */ 00585 KSDDKAPI 00586 VOID 00587 NTAPI 00588 KsFreeDeviceHeader( 00589 IN KSDEVICE_HEADER DevHeader) 00590 { 00591 PKSIDEVICE_HEADER Header; 00592 00593 Header = (PKSIDEVICE_HEADER)DevHeader; 00594 00595 if (!DevHeader) 00596 return; 00597 00598 KspFreeCreateItems(&Header->ItemList); 00599 FreeItem(Header); 00600 } 00601 00602 /* 00603 @implemented 00604 */ 00605 KSDDKAPI 00606 NTSTATUS 00607 NTAPI 00608 KsAllocateObjectHeader( 00609 OUT KSOBJECT_HEADER *Header, 00610 IN ULONG ItemsCount, 00611 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL, 00612 IN PIRP Irp, 00613 IN KSDISPATCH_TABLE* Table) 00614 { 00615 PIO_STACK_LOCATION IoStack; 00616 //PDEVICE_EXTENSION DeviceExtension; 00617 //PKSIDEVICE_HEADER DeviceHeader; 00618 PKSIOBJECT_HEADER ObjectHeader; 00619 //PKSOBJECT_CREATE_ITEM CreateItem; 00620 NTSTATUS Status; 00621 00622 if (!Header) 00623 return STATUS_INVALID_PARAMETER_1; 00624 00625 if (!Irp) 00626 return STATUS_INVALID_PARAMETER_4; 00627 00628 if (!Table) 00629 return STATUS_INVALID_PARAMETER_5; 00630 00631 /* get current stack location */ 00632 IoStack = IoGetCurrentIrpStackLocation(Irp); 00633 /* get device extension */ 00634 //DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension; 00635 /* get device header */ 00636 //DeviceHeader = DeviceExtension->DeviceHeader; 00637 00638 /* sanity check */ 00639 ASSERT(IoStack->FileObject); 00640 /* check for an file object */ 00641 00642 /* allocate the object header */ 00643 ObjectHeader = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_HEADER)); 00644 if (!ObjectHeader) 00645 return STATUS_INSUFFICIENT_RESOURCES; 00646 00647 /* initialize object header */ 00648 RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER)); 00649 00650 /* initialize create item list */ 00651 InitializeListHead(&ObjectHeader->ItemList); 00652 00653 /* get create item */ 00654 //CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); 00655 00656 /* do we have a name */ 00657 if (IoStack->FileObject->FileName.Buffer) 00658 { 00659 /* copy object class */ 00660 ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength; 00661 ObjectHeader->ObjectClass.Buffer = AllocateItem(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength); 00662 if (!ObjectHeader->ObjectClass.Buffer) 00663 { 00664 FreeItem(ObjectHeader); 00665 return STATUS_INSUFFICIENT_RESOURCES; 00666 } 00667 RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName); 00668 } 00669 00670 /* copy dispatch table */ 00671 RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE)); 00672 00673 /* store create items */ 00674 if (ItemsCount && ItemsList) 00675 { 00676 Status = KspAddCreateItemToList(&ObjectHeader->ItemList, ItemsCount, ItemsList); 00677 00678 if (NT_SUCCESS(Status)) 00679 { 00680 /* store item count */ 00681 ObjectHeader->ItemListCount = ItemsCount; 00682 } 00683 else 00684 { 00685 /* destroy header*/ 00686 KsFreeObjectHeader(ObjectHeader); 00687 return Status; 00688 } 00689 } 00690 /* store the object in the file object */ 00691 IoStack->FileObject->FsContext2 = ObjectHeader; 00692 00693 /* store parent device */ 00694 ObjectHeader->ParentDeviceObject = IoGetRelatedDeviceObject(IoStack->FileObject); 00695 00696 /* store originating create item */ 00697 ObjectHeader->OriginalCreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); 00698 00699 /* FIXME store access mask see KsQueryObjectAccessMask */ 00700 ObjectHeader->AccessMask = IoStack->Parameters.Create.SecurityContext->DesiredAccess; 00701 00702 00703 /* store result */ 00704 *Header = ObjectHeader; 00705 00706 DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader); 00707 00708 return STATUS_SUCCESS; 00709 00710 } 00711 00712 /* 00713 @implemented 00714 */ 00715 KSDDKAPI 00716 VOID 00717 NTAPI 00718 KsFreeObjectHeader( 00719 IN PVOID Header) 00720 { 00721 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER) Header; 00722 00723 DPRINT("KsFreeObjectHeader Header %p Class %wZ\n", Header, &ObjectHeader->ObjectClass); 00724 00725 if (ObjectHeader->ObjectClass.Buffer) 00726 { 00727 /* release object class buffer */ 00728 FreeItem(ObjectHeader->ObjectClass.Buffer); 00729 } 00730 00731 if (ObjectHeader->Unknown) 00732 { 00733 /* release associated object */ 00734 ObjectHeader->Unknown->lpVtbl->Release(ObjectHeader->Unknown); 00735 } 00736 00737 /* free create items */ 00738 KspFreeCreateItems(&ObjectHeader->ItemList); 00739 00740 /* free object header */ 00741 FreeItem(ObjectHeader); 00742 00743 } 00744 00745 NTSTATUS 00746 KspAddObjectCreateItemToList( 00747 PLIST_ENTRY ListHead, 00748 IN PDRIVER_DISPATCH Create, 00749 IN PVOID Context, 00750 IN PWCHAR ObjectClass, 00751 IN PSECURITY_DESCRIPTOR SecurityDescriptor) 00752 { 00753 PLIST_ENTRY Entry; 00754 PCREATE_ITEM_ENTRY CreateEntry; 00755 00756 /* point to first entry */ 00757 Entry = ListHead->Flink; 00758 00759 while(Entry != ListHead) 00760 { 00761 /* get create entry */ 00762 CreateEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry); 00763 /* if the create item has no create routine, then it is free to use */ 00764 if (CreateEntry->CreateItem->Create == NULL) 00765 { 00766 /* sanity check */ 00767 ASSERT(IsListEmpty(&CreateEntry->ObjectItemList)); 00768 ASSERT(CreateEntry->ReferenceCount == 0); 00769 /* use free entry */ 00770 CreateEntry->CreateItem->Context = Context; 00771 CreateEntry->CreateItem->Create = Create; 00772 RtlInitUnicodeString(&CreateEntry->CreateItem->ObjectClass, ObjectClass); 00773 CreateEntry->CreateItem->SecurityDescriptor = SecurityDescriptor; 00774 00775 return STATUS_SUCCESS; 00776 } 00777 00778 if (!wcsicmp(ObjectClass, CreateEntry->CreateItem->ObjectClass.Buffer)) 00779 { 00780 /* the same object class already exists */ 00781 return STATUS_OBJECT_NAME_COLLISION; 00782 } 00783 00784 /* iterate to next entry */ 00785 Entry = Entry->Flink; 00786 } 00787 return STATUS_ALLOTTED_SPACE_EXCEEDED; 00788 } 00789 00790 /* 00791 @implemented 00792 */ 00793 KSDDKAPI 00794 NTSTATUS 00795 NTAPI 00796 KsAddObjectCreateItemToDeviceHeader( 00797 IN KSDEVICE_HEADER DevHeader, 00798 IN PDRIVER_DISPATCH Create, 00799 IN PVOID Context, 00800 IN PWCHAR ObjectClass, 00801 IN PSECURITY_DESCRIPTOR SecurityDescriptor) 00802 { 00803 PKSIDEVICE_HEADER Header; 00804 NTSTATUS Status; 00805 00806 Header = (PKSIDEVICE_HEADER)DevHeader; 00807 00808 DPRINT("KsAddObjectCreateItemToDeviceHeader entered\n"); 00809 00810 /* check if a device header has been provided */ 00811 if (!DevHeader) 00812 return STATUS_INVALID_PARAMETER_1; 00813 00814 /* check if a create item has been provided */ 00815 if (!Create) 00816 return STATUS_INVALID_PARAMETER_2; 00817 00818 /* check if a object class has been provided */ 00819 if (!ObjectClass) 00820 return STATUS_INVALID_PARAMETER_4; 00821 00822 /* let others do the work */ 00823 Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor); 00824 00825 if (NT_SUCCESS(Status)) 00826 { 00827 /* increment create item count */ 00828 InterlockedIncrement(&Header->ItemListCount); 00829 } 00830 DPRINT("KsAddObjectCreateItemToDeviceHeader Status %x\n", Status); 00831 return Status; 00832 } 00833 00834 /* 00835 @implemented 00836 */ 00837 KSDDKAPI 00838 NTSTATUS 00839 NTAPI 00840 KsAddObjectCreateItemToObjectHeader( 00841 IN KSOBJECT_HEADER ObjectHeader, 00842 IN PDRIVER_DISPATCH Create, 00843 IN PVOID Context, 00844 IN PWCHAR ObjectClass, 00845 IN PSECURITY_DESCRIPTOR SecurityDescriptor) 00846 { 00847 PKSIOBJECT_HEADER Header; 00848 NTSTATUS Status; 00849 00850 Header = (PKSIOBJECT_HEADER)ObjectHeader; 00851 00852 DPRINT("KsAddObjectCreateItemToDeviceHeader entered\n"); 00853 00854 /* check if a device header has been provided */ 00855 if (!Header) 00856 return STATUS_INVALID_PARAMETER_1; 00857 00858 /* check if a create item has been provided */ 00859 if (!Create) 00860 return STATUS_INVALID_PARAMETER_2; 00861 00862 /* check if a object class has been provided */ 00863 if (!ObjectClass) 00864 return STATUS_INVALID_PARAMETER_4; 00865 00866 /* let's work */ 00867 Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor); 00868 00869 if (NT_SUCCESS(Status)) 00870 { 00871 /* increment create item count */ 00872 InterlockedIncrement(&Header->ItemListCount); 00873 } 00874 00875 return Status; 00876 } 00877 00878 /* 00879 @implemented 00880 */ 00881 KSDDKAPI 00882 NTSTATUS 00883 NTAPI 00884 KsAllocateObjectCreateItem( 00885 IN KSDEVICE_HEADER DevHeader, 00886 IN PKSOBJECT_CREATE_ITEM CreateItem, 00887 IN BOOLEAN AllocateEntry, 00888 IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL) 00889 { 00890 PCREATE_ITEM_ENTRY CreateEntry; 00891 PKSIDEVICE_HEADER Header; 00892 PKSOBJECT_CREATE_ITEM Item; 00893 00894 Header = (PKSIDEVICE_HEADER)DevHeader; 00895 00896 if (!DevHeader) 00897 return STATUS_INVALID_PARAMETER_1; 00898 00899 if (!CreateItem) 00900 return STATUS_INVALID_PARAMETER_2; 00901 00902 /* first allocate a create entry */ 00903 CreateEntry = AllocateItem(NonPagedPool, sizeof(CREATE_ITEM_ENTRY)); 00904 00905 /* check for allocation success */ 00906 if (!CreateEntry) 00907 { 00908 /* not enough resources */ 00909 return STATUS_INSUFFICIENT_RESOURCES; 00910 } 00911 00912 00913 if (AllocateEntry) 00914 { 00915 /* allocate create item */ 00916 Item = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); 00917 if (!Item) 00918 { 00919 /* no memory */ 00920 FreeItem(CreateEntry); 00921 return STATUS_INSUFFICIENT_RESOURCES; 00922 } 00923 00924 /* initialize descriptor */ 00925 Item->Context = CreateItem->Context; 00926 Item->Create = CreateItem->Create; 00927 Item->Flags = CreateItem->Flags; 00928 Item->SecurityDescriptor = CreateItem->SecurityDescriptor; 00929 Item->ObjectClass.Length = 0; 00930 Item->ObjectClass.MaximumLength = CreateItem->ObjectClass.MaximumLength; 00931 00932 /* copy object class */ 00933 Item->ObjectClass.Buffer = AllocateItem(NonPagedPool, Item->ObjectClass.MaximumLength); 00934 if (!Item->ObjectClass.Buffer) 00935 { 00936 /* release resources */ 00937 FreeItem(Item); 00938 FreeItem(CreateEntry); 00939 00940 return STATUS_INSUFFICIENT_RESOURCES; 00941 } 00942 RtlCopyUnicodeString(&Item->ObjectClass, &CreateItem->ObjectClass); 00943 } 00944 else 00945 { 00946 if (ItemFreeCallback) 00947 { 00948 /* callback is only accepted when the create item is copied */ 00949 ItemFreeCallback = NULL; 00950 } 00951 /* use passed create item */ 00952 Item = CreateItem; 00953 } 00954 00955 /* initialize create item entry */ 00956 InitializeListHead(&CreateEntry->ObjectItemList); 00957 CreateEntry->ItemFreeCallback = ItemFreeCallback; 00958 CreateEntry->CreateItem = Item; 00959 CreateEntry->ReferenceCount = 0; 00960 00961 /* now insert the create item entry */ 00962 InsertTailList(&Header->ItemList, &CreateEntry->Entry); 00963 00964 /* increment item count */ 00965 InterlockedIncrement(&Header->ItemListCount); 00966 00967 return STATUS_SUCCESS; 00968 } 00969 00970 NTSTATUS 00971 KspObjectFreeCreateItems( 00972 IN KSDEVICE_HEADER Header, 00973 IN PKSOBJECT_CREATE_ITEM CreateItem) 00974 { 00975 UNIMPLEMENTED 00976 return STATUS_NOT_IMPLEMENTED; 00977 } 00978 00979 /* 00980 @implemented 00981 */ 00982 KSDDKAPI 00983 NTSTATUS 00984 NTAPI 00985 KsFreeObjectCreateItem( 00986 IN KSDEVICE_HEADER Header, 00987 IN PUNICODE_STRING CreateItem) 00988 { 00989 KSOBJECT_CREATE_ITEM Item; 00990 00991 RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM)); 00992 RtlInitUnicodeString(&Item.ObjectClass, CreateItem->Buffer); 00993 00994 return KspObjectFreeCreateItems(Header, &Item); 00995 } 00996 00997 00998 /* 00999 @implemented 01000 */ 01001 KSDDKAPI 01002 NTSTATUS 01003 NTAPI 01004 KsFreeObjectCreateItemsByContext( 01005 IN KSDEVICE_HEADER Header, 01006 IN PVOID Context) 01007 { 01008 KSOBJECT_CREATE_ITEM Item; 01009 01010 RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM)); 01011 01012 Item.Context = Context; 01013 01014 return KspObjectFreeCreateItems(Header, &Item); 01015 } 01016 01017 /* 01018 @implemented 01019 */ 01020 KSDDKAPI 01021 NTSTATUS 01022 NTAPI 01023 KsCreateDefaultSecurity( 01024 IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL, 01025 OUT PSECURITY_DESCRIPTOR* DefaultSecurity) 01026 { 01027 PGENERIC_MAPPING Mapping; 01028 SECURITY_SUBJECT_CONTEXT SubjectContext; 01029 NTSTATUS Status; 01030 01031 /* start capturing security context of calling thread */ 01032 SeCaptureSubjectContext(&SubjectContext); 01033 /* get generic mapping */ 01034 Mapping = IoGetFileObjectGenericMapping(); 01035 /* build new descriptor */ 01036 Status = SeAssignSecurity(ParentSecurity, NULL, DefaultSecurity, FALSE, &SubjectContext, Mapping, NonPagedPool); 01037 /* release security descriptor */ 01038 SeReleaseSubjectContext(&SubjectContext); 01039 /* done */ 01040 return Status; 01041 } 01042 01043 /* 01044 @unimplemented 01045 */ 01046 KSDDKAPI 01047 NTSTATUS 01048 NTAPI 01049 KsForwardIrp( 01050 IN PIRP Irp, 01051 IN PFILE_OBJECT FileObject, 01052 IN BOOLEAN ReuseStackLocation) 01053 { 01054 UNIMPLEMENTED; 01055 return STATUS_UNSUCCESSFUL; 01056 } 01057 01058 01059 /* 01060 @unimplemented 01061 */ 01062 KSDDKAPI 01063 NTSTATUS 01064 NTAPI 01065 KsForwardAndCatchIrp( 01066 IN PDEVICE_OBJECT DeviceObject, 01067 IN PIRP Irp, 01068 IN PFILE_OBJECT FileObject, 01069 IN KSSTACK_USE StackUse) 01070 { 01071 UNIMPLEMENTED; 01072 return STATUS_UNSUCCESSFUL; 01073 } 01074 01075 01076 NTSTATUS 01077 NTAPI 01078 KspSynchronousIoControlDeviceCompletion( 01079 IN PDEVICE_OBJECT DeviceObject, 01080 IN PIRP Irp, 01081 IN PVOID Context) 01082 { 01083 PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)Context; 01084 01085 IoStatusBlock->Information = Irp->IoStatus.Information; 01086 IoStatusBlock->Status = Irp->IoStatus.Status; 01087 01088 return STATUS_SUCCESS; 01089 } 01090 01091 /* 01092 @implemented 01093 */ 01094 KSDDKAPI 01095 NTSTATUS 01096 NTAPI 01097 KsSynchronousIoControlDevice( 01098 IN PFILE_OBJECT FileObject, 01099 IN KPROCESSOR_MODE RequestorMode, 01100 IN ULONG IoControl, 01101 IN PVOID InBuffer, 01102 IN ULONG InSize, 01103 OUT PVOID OutBuffer, 01104 IN ULONG OutSize, 01105 OUT PULONG BytesReturned) 01106 { 01107 PKSIOBJECT_HEADER ObjectHeader; 01108 PDEVICE_OBJECT DeviceObject; 01109 KEVENT Event; 01110 PIRP Irp; 01111 IO_STATUS_BLOCK IoStatusBlock; 01112 PIO_STACK_LOCATION IoStack; 01113 NTSTATUS Status; 01114 01115 /* check for valid file object */ 01116 if (!FileObject) 01117 return STATUS_INVALID_PARAMETER; 01118 01119 /* get device object to send the request to */ 01120 DeviceObject = IoGetRelatedDeviceObject(FileObject); 01121 if (!DeviceObject) 01122 return STATUS_UNSUCCESSFUL; 01123 01124 01125 /* get object header */ 01126 ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext2; 01127 01128 /* check if there is fast device io function */ 01129 if (ObjectHeader && ObjectHeader->DispatchTable.FastDeviceIoControl) 01130 { 01131 IoStatusBlock.Status = STATUS_UNSUCCESSFUL; 01132 IoStatusBlock.Information = 0; 01133 01134 /* send the request */ 01135 Status = ObjectHeader->DispatchTable.FastDeviceIoControl(FileObject, TRUE, InBuffer, InSize, OutBuffer, OutSize, IoControl, &IoStatusBlock, DeviceObject); 01136 /* check if the request was handled */ 01137 //DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information); 01138 if (Status) 01139 { 01140 /* store bytes returned */ 01141 *BytesReturned = IoStatusBlock.Information; 01142 /* return status */ 01143 return IoStatusBlock.Status; 01144 } 01145 } 01146 01147 /* initialize the event */ 01148 KeInitializeEvent(&Event, NotificationEvent, FALSE); 01149 01150 /* create the irp */ 01151 Irp = IoBuildDeviceIoControlRequest(IoControl, DeviceObject, InBuffer, InSize, OutBuffer, OutSize, FALSE, &Event, &IoStatusBlock); 01152 01153 if (!Irp) 01154 { 01155 /* no memory to allocate the irp */ 01156 return STATUS_INSUFFICIENT_RESOURCES; 01157 } 01158 01159 01160 /* Store Fileobject */ 01161 IoStack = IoGetNextIrpStackLocation(Irp); 01162 IoStack->FileObject = FileObject; 01163 01164 if (IoControl == IOCTL_KS_WRITE_STREAM) 01165 { 01166 Irp->AssociatedIrp.SystemBuffer = OutBuffer; 01167 } 01168 else if (IoControl == IOCTL_KS_READ_STREAM) 01169 { 01170 Irp->AssociatedIrp.SystemBuffer = InBuffer; 01171 } 01172 01173 IoSetCompletionRoutine(Irp, KspSynchronousIoControlDeviceCompletion, (PVOID)&IoStatusBlock, TRUE, TRUE, TRUE); 01174 01175 Status = IoCallDriver(DeviceObject, Irp); 01176 if (Status == STATUS_PENDING) 01177 { 01178 KeWaitForSingleObject(&Event, Executive, RequestorMode, FALSE, NULL); 01179 Status = IoStatusBlock.Status; 01180 } 01181 01182 *BytesReturned = IoStatusBlock.Information; 01183 return Status; 01184 } 01185 01186 /* 01187 @unimplemented 01188 */ 01189 KSDDKAPI 01190 NTSTATUS 01191 NTAPI 01192 KsUnserializeObjectPropertiesFromRegistry( 01193 IN PFILE_OBJECT FileObject, 01194 IN HANDLE ParentKey OPTIONAL, 01195 IN PUNICODE_STRING RegistryPath OPTIONAL) 01196 { 01197 UNIMPLEMENTED 01198 return STATUS_NOT_IMPLEMENTED; 01199 } 01200 01201 01202 /* 01203 @implemented 01204 */ 01205 KSDDKAPI 01206 NTSTATUS 01207 NTAPI 01208 KsCacheMedium( 01209 IN PUNICODE_STRING SymbolicLink, 01210 IN PKSPIN_MEDIUM Medium, 01211 IN ULONG PinDirection) 01212 { 01213 HANDLE hKey; 01214 UNICODE_STRING Path; 01215 UNICODE_STRING BasePath = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediumCache\\"); 01216 UNICODE_STRING GuidString; 01217 NTSTATUS Status; 01218 OBJECT_ATTRIBUTES ObjectAttributes; 01219 BOOLEAN PathAdjusted = FALSE; 01220 ULONG Value = 0; 01221 01222 /* first check if the medium is standard */ 01223 if (IsEqualGUIDAligned(&KSMEDIUMSETID_Standard, &Medium->Set) || 01224 IsEqualGUIDAligned(&GUID_NULL, &Medium->Set)) 01225 { 01226 /* no need to cache that */ 01227 return STATUS_SUCCESS; 01228 } 01229 01230 /* convert guid to string */ 01231 Status = RtlStringFromGUID(&Medium->Set, &GuidString); 01232 if (!NT_SUCCESS(Status)) 01233 return Status; 01234 01235 /* allocate path buffer */ 01236 Path.Length = 0; 01237 Path.MaximumLength = BasePath.MaximumLength + GuidString.MaximumLength + 10 * sizeof(WCHAR); 01238 Path.Buffer = AllocateItem(PagedPool, Path.MaximumLength); 01239 if (!Path.Buffer) 01240 { 01241 /* not enough resources */ 01242 RtlFreeUnicodeString(&GuidString); 01243 return STATUS_INSUFFICIENT_RESOURCES; 01244 } 01245 01246 RtlAppendUnicodeStringToString(&Path, &BasePath); 01247 RtlAppendUnicodeStringToString(&Path, &GuidString); 01248 RtlAppendUnicodeToString(&Path, L"-"); 01249 /* FIXME append real instance id */ 01250 RtlAppendUnicodeToString(&Path, L"0"); 01251 RtlAppendUnicodeToString(&Path, L"-"); 01252 /* FIXME append real instance id */ 01253 RtlAppendUnicodeToString(&Path, L"0"); 01254 01255 /* free guid string */ 01256 RtlFreeUnicodeString(&GuidString); 01257 01258 /* initialize object attributes */ 01259 InitializeObjectAttributes(&ObjectAttributes, &Path, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL, NULL); 01260 /* create the key */ 01261 Status = ZwCreateKey(&hKey, GENERIC_WRITE, &ObjectAttributes, 0, NULL, 0, NULL); 01262 01263 /* free path buffer */ 01264 FreeItem(Path.Buffer); 01265 01266 if (NT_SUCCESS(Status)) 01267 { 01268 /* store symbolic link */ 01269 if (SymbolicLink->Buffer[1] == L'?' && SymbolicLink->Buffer[2] == L'?') 01270 { 01271 /* replace kernel path with user mode path */ 01272 SymbolicLink->Buffer[1] = L'\\'; 01273 PathAdjusted = TRUE; 01274 } 01275 01276 /* store the key */ 01277 Status = ZwSetValueKey(hKey, SymbolicLink, 0, REG_DWORD, &Value, sizeof(ULONG)); 01278 01279 if (PathAdjusted) 01280 { 01281 /* restore kernel path */ 01282 SymbolicLink->Buffer[1] = L'?'; 01283 } 01284 01285 ZwClose(hKey); 01286 } 01287 01288 /* done */ 01289 return Status; 01290 } 01291 01292 /* 01293 @implemented 01294 */ 01295 NTSTATUS 01296 NTAPI 01297 DllInitialize( 01298 PUNICODE_STRING RegistryPath) 01299 { 01300 return STATUS_SUCCESS; 01301 } 01302 01303 01304 NTSTATUS 01305 NTAPI 01306 KopDispatchClose( 01307 IN PDEVICE_OBJECT DeviceObject, 01308 IN PIRP Irp) 01309 { 01310 PKO_OBJECT_HEADER Header; 01311 PIO_STACK_LOCATION IoStack; 01312 PDEVICE_EXTENSION DeviceExtension; 01313 01314 /* get current irp stack location */ 01315 IoStack = IoGetCurrentIrpStackLocation(Irp); 01316 01317 /* get ko object header */ 01318 Header = (PKO_OBJECT_HEADER)IoStack->FileObject->FsContext2; 01319 01320 /* free ks object header */ 01321 KsFreeObjectHeader(Header->ObjectHeader); 01322 01323 /* free ko object header */ 01324 FreeItem(Header); 01325 01326 /* get device extension */ 01327 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 01328 01329 /* release bus object */ 01330 KsDereferenceBusObject((KSDEVICE_HEADER)DeviceExtension->DeviceHeader); 01331 01332 /* complete request */ 01333 Irp->IoStatus.Status = STATUS_SUCCESS; 01334 CompleteRequest(Irp, IO_NO_INCREMENT); 01335 01336 return STATUS_SUCCESS; 01337 } 01338 01339 01340 01341 static KSDISPATCH_TABLE KoDispatchTable = 01342 { 01343 KsDispatchInvalidDeviceRequest, 01344 KsDispatchInvalidDeviceRequest, 01345 KsDispatchInvalidDeviceRequest, 01346 KsDispatchInvalidDeviceRequest, 01347 KopDispatchClose, 01348 KsDispatchQuerySecurity, 01349 KsDispatchSetSecurity, 01350 KsDispatchFastIoDeviceControlFailure, 01351 KsDispatchFastReadFailure, 01352 KsDispatchFastReadFailure, 01353 }; 01354 01355 01356 NTSTATUS 01357 NTAPI 01358 KopDispatchCreate( 01359 IN PDEVICE_OBJECT DeviceObject, 01360 IN PIRP Irp) 01361 { 01362 PKO_OBJECT_HEADER Header = NULL; 01363 PIO_STACK_LOCATION IoStack; 01364 PKO_DRIVER_EXTENSION DriverObjectExtension; 01365 NTSTATUS Status; 01366 01367 /* get current irp stack location */ 01368 IoStack = IoGetCurrentIrpStackLocation(Irp); 01369 01370 if (!IoStack->FileObject) 01371 { 01372 DPRINT1("FileObject not attached!\n"); 01373 Status = STATUS_UNSUCCESSFUL; 01374 goto cleanup; 01375 } 01376 01377 /* get driver object extension */ 01378 DriverObjectExtension = (PKO_DRIVER_EXTENSION)IoGetDriverObjectExtension(DeviceObject->DriverObject, (PVOID)KoDriverInitialize); 01379 if (!DriverObjectExtension) 01380 { 01381 DPRINT1("No DriverObjectExtension!\n"); 01382 Status = STATUS_UNSUCCESSFUL; 01383 goto cleanup; 01384 } 01385 01386 /* allocate ko object header */ 01387 Header = (PKO_OBJECT_HEADER)AllocateItem(NonPagedPool, sizeof(KO_OBJECT_HEADER)); 01388 if (!Header) 01389 { 01390 DPRINT1("failed to allocate KO_OBJECT_HEADER\n"); 01391 Status = STATUS_INSUFFICIENT_RESOURCES; 01392 goto cleanup; 01393 } 01394 01395 /* initialize create item */ 01396 Header->CreateItem.Create = KopDispatchCreate; 01397 RtlInitUnicodeString(&Header->CreateItem.ObjectClass, KOSTRING_CreateObject); 01398 01399 01400 /* now allocate the object header */ 01401 Status = KsAllocateObjectHeader(&Header->ObjectHeader, 1, &Header->CreateItem, Irp, &KoDispatchTable); 01402 if (!NT_SUCCESS(Status)) 01403 { 01404 /* failed */ 01405 goto cleanup; 01406 } 01407 01408 /* FIXME 01409 * extract clsid and interface id from irp 01410 * call the standard create handler 01411 */ 01412 01413 UNIMPLEMENTED 01414 01415 IoStack->FileObject->FsContext2 = (PVOID)Header; 01416 01417 Irp->IoStatus.Status = Status; 01418 CompleteRequest(Irp, IO_NO_INCREMENT); 01419 01420 return Status; 01421 01422 cleanup: 01423 01424 if (Header && Header->ObjectHeader) 01425 KsFreeObjectHeader(Header->ObjectHeader); 01426 01427 if (Header) 01428 FreeItem(Header); 01429 01430 Irp->IoStatus.Status = Status; 01431 CompleteRequest(Irp, IO_NO_INCREMENT); 01432 return Status; 01433 } 01434 01435 01436 01437 NTSTATUS 01438 NTAPI 01439 KopAddDevice( 01440 IN PDRIVER_OBJECT DriverObject, 01441 IN PDEVICE_OBJECT PhysicalDeviceObject) 01442 { 01443 NTSTATUS Status = STATUS_DEVICE_REMOVED; 01444 PDEVICE_OBJECT FunctionalDeviceObject= NULL; 01445 PDEVICE_OBJECT NextDeviceObject; 01446 PDEVICE_EXTENSION DeviceExtension; 01447 PKSOBJECT_CREATE_ITEM CreateItem; 01448 01449 /* create the device object */ 01450 Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_DEVICE_SECURE_OPEN, FALSE, &FunctionalDeviceObject); 01451 if (!NT_SUCCESS(Status)) 01452 return Status; 01453 01454 /* allocate the create item */ 01455 CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); 01456 01457 if (!CreateItem) 01458 { 01459 /* not enough memory */ 01460 IoDeleteDevice(FunctionalDeviceObject); 01461 return STATUS_INSUFFICIENT_RESOURCES; 01462 } 01463 01464 /* initialize create item */ 01465 CreateItem->Create = KopDispatchCreate; 01466 RtlInitUnicodeString(&CreateItem->ObjectClass, KOSTRING_CreateObject); 01467 01468 /* get device extension */ 01469 DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension; 01470 01471 /* now allocate the device header */ 01472 Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 1, CreateItem); 01473 if (!NT_SUCCESS(Status)) 01474 { 01475 /* failed */ 01476 IoDeleteDevice(FunctionalDeviceObject); 01477 FreeItem(CreateItem); 01478 return Status; 01479 } 01480 01481 /* now attach to device stack */ 01482 NextDeviceObject = IoAttachDeviceToDeviceStack(FunctionalDeviceObject, PhysicalDeviceObject); 01483 if (NextDeviceObject) 01484 { 01485 /* store pnp base object */ 01486 KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER)DeviceExtension->DeviceHeader, NextDeviceObject, FunctionalDeviceObject); 01487 /* set device flags */ 01488 FunctionalDeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE; 01489 FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING; 01490 } 01491 else 01492 { 01493 /* failed */ 01494 KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceExtension->DeviceHeader); 01495 FreeItem(CreateItem); 01496 IoDeleteDevice(FunctionalDeviceObject); 01497 Status = STATUS_DEVICE_REMOVED; 01498 } 01499 01500 /* return result */ 01501 return Status; 01502 } 01503 01504 01505 /* 01506 @implemented 01507 */ 01508 COMDDKAPI 01509 NTSTATUS 01510 NTAPI 01511 KoDeviceInitialize( 01512 IN PDEVICE_OBJECT DeviceObject) 01513 { 01514 PDEVICE_EXTENSION DeviceExtension; 01515 01516 /* get device extension */ 01517 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 01518 01519 return KsAddObjectCreateItemToDeviceHeader((KSDEVICE_HEADER)DeviceExtension->DeviceHeader, KopDispatchCreate, NULL, KOSTRING_CreateObject, NULL); 01520 } 01521 01522 /* 01523 @implemented 01524 */ 01525 COMDDKAPI 01526 NTSTATUS 01527 NTAPI 01528 KoDriverInitialize( 01529 IN PDRIVER_OBJECT DriverObject, 01530 IN PUNICODE_STRING RegistryPathName, 01531 IN KoCreateObjectHandler CreateObjectHandler) 01532 { 01533 PKO_DRIVER_EXTENSION DriverObjectExtension; 01534 NTSTATUS Status; 01535 01536 /* allocate driver object extension */ 01537 Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)KoDriverInitialize, sizeof(KO_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension); 01538 01539 /* did it work */ 01540 if (NT_SUCCESS(Status)) 01541 { 01542 /* store create handler */ 01543 DriverObjectExtension->CreateObjectHandler = CreateObjectHandler; 01544 01545 /* Setting our IRP handlers */ 01546 DriverObject->MajorFunction[IRP_MJ_PNP] = KsDefaultDispatchPnp; 01547 DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower; 01548 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp; 01549 01550 /* The driver unload routine */ 01551 DriverObject->DriverUnload = KsNullDriverUnload; 01552 01553 /* The driver-supplied AddDevice */ 01554 DriverObject->DriverExtension->AddDevice = KopAddDevice; 01555 01556 /* KS handles these */ 01557 DPRINT1("Setting KS function handlers\n"); 01558 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE); 01559 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE); 01560 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL); 01561 01562 } 01563 01564 return Status; 01565 } 01566 01567 /* 01568 @unimplemented 01569 */ 01570 COMDDKAPI 01571 VOID 01572 NTAPI 01573 KoRelease( 01574 IN REFCLSID ClassId) 01575 { 01576 01577 } 01578 01579 /* 01580 @implemented 01581 */ 01582 KSDDKAPI 01583 VOID 01584 NTAPI 01585 KsAcquireControl( 01586 IN PVOID Object) 01587 { 01588 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); 01589 01590 /* sanity check */ 01591 ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); 01592 01593 KeWaitForSingleObject(BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL); 01594 01595 } 01596 01597 /* 01598 @implemented 01599 */ 01600 VOID 01601 NTAPI 01602 KsReleaseControl( 01603 IN PVOID Object) 01604 { 01605 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); 01606 01607 /* sanity check */ 01608 ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); 01609 01610 KeReleaseMutex(BasicHeader->ControlMutex, FALSE); 01611 } 01612 01613 01614 01615 /* 01616 @implemented 01617 */ 01618 KSDDKAPI 01619 VOID 01620 NTAPI 01621 KsAcquireDevice( 01622 IN PKSDEVICE Device) 01623 { 01624 IKsDevice *KsDevice; 01625 PKSIDEVICE_HEADER DeviceHeader; 01626 01627 DPRINT("KsAcquireDevice\n"); 01628 DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); 01629 01630 /* get device interface*/ 01631 KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; 01632 01633 /* acquire device mutex */ 01634 KsDevice->lpVtbl->AcquireDevice(KsDevice); 01635 } 01636 01637 /* 01638 @implemented 01639 */ 01640 VOID 01641 NTAPI 01642 KsReleaseDevice( 01643 IN PKSDEVICE Device) 01644 { 01645 IKsDevice *KsDevice; 01646 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); 01647 01648 /* get device interface*/ 01649 KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; 01650 01651 /* release device mutex */ 01652 KsDevice->lpVtbl->ReleaseDevice(KsDevice); 01653 } 01654 01655 /* 01656 @implemented 01657 */ 01658 KSDDKAPI 01659 VOID 01660 NTAPI 01661 KsTerminateDevice( 01662 IN PDEVICE_OBJECT DeviceObject) 01663 { 01664 IKsDevice *KsDevice; 01665 PKSIDEVICE_HEADER DeviceHeader; 01666 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 01667 01668 /* get device header */ 01669 DeviceHeader = DeviceExtension->DeviceHeader; 01670 01671 /* get device interface*/ 01672 KsDevice = (IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown; 01673 01674 /* now free device header */ 01675 KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader); 01676 01677 /* release interface when available */ 01678 if (KsDevice) 01679 { 01680 /* delete IKsDevice interface */ 01681 KsDevice->lpVtbl->Release(KsDevice); 01682 } 01683 } 01684 01685 /* 01686 @implemented 01687 */ 01688 KSDDKAPI 01689 VOID 01690 NTAPI 01691 KsCompletePendingRequest( 01692 IN PIRP Irp) 01693 { 01694 PIO_STACK_LOCATION IoStack; 01695 01696 /* get current irp stack location */ 01697 IoStack = IoGetCurrentIrpStackLocation(Irp); 01698 01699 /* sanity check */ 01700 ASSERT(Irp->IoStatus.Status != STATUS_PENDING); 01701 01702 if (IoStack->MajorFunction != IRP_MJ_CLOSE) 01703 { 01704 /* can be completed immediately */ 01705 CompleteRequest(Irp, IO_NO_INCREMENT); 01706 return; 01707 } 01708 01709 /* did close operation fail */ 01710 if (!NT_SUCCESS(Irp->IoStatus.Status)) 01711 { 01712 /* closing failed, complete irp */ 01713 CompleteRequest(Irp, IO_NO_INCREMENT); 01714 return; 01715 } 01716 01717 /* FIXME 01718 * delete object / device header 01719 * remove dead pin / filter instance 01720 */ 01721 UNIMPLEMENTED 01722 01723 } 01724 01725 NTSTATUS 01726 NTAPI 01727 KspSetGetBusDataCompletion( 01728 IN PDEVICE_OBJECT DeviceObject, 01729 IN PIRP Irp, 01730 IN PVOID Context) 01731 { 01732 /* signal completion */ 01733 KeSetEvent((PRKEVENT)Context, IO_NO_INCREMENT, FALSE); 01734 01735 /* more work needs be done, so dont free the irp */ 01736 return STATUS_MORE_PROCESSING_REQUIRED; 01737 01738 } 01739 01740 NTSTATUS 01741 KspDeviceSetGetBusData( 01742 IN PDEVICE_OBJECT DeviceObject, 01743 IN ULONG DataType, 01744 IN PVOID Buffer, 01745 IN ULONG Offset, 01746 IN ULONG Length, 01747 IN BOOL bGet) 01748 { 01749 PIO_STACK_LOCATION IoStack; 01750 PIRP Irp; 01751 NTSTATUS Status; 01752 KEVENT Event; 01753 01754 /* allocate the irp */ 01755 Irp = IoAllocateIrp(1, /*FIXME */ 01756 FALSE); 01757 01758 if (!Irp) 01759 return STATUS_INSUFFICIENT_RESOURCES; 01760 01761 /* initialize the event */ 01762 KeInitializeEvent(&Event, NotificationEvent, FALSE); 01763 01764 /* get next stack location */ 01765 IoStack = IoGetNextIrpStackLocation(Irp); 01766 01767 /* setup a completion routine */ 01768 IoSetCompletionRoutine(Irp, KspSetGetBusDataCompletion, (PVOID)&Event, TRUE, TRUE, TRUE); 01769 01770 /* setup parameters */ 01771 IoStack->Parameters.ReadWriteConfig.Buffer = Buffer; 01772 IoStack->Parameters.ReadWriteConfig.Length = Length; 01773 IoStack->Parameters.ReadWriteConfig.Offset = Offset; 01774 IoStack->Parameters.ReadWriteConfig.WhichSpace = DataType; 01775 /* setup function code */ 01776 IoStack->MajorFunction = IRP_MJ_PNP; 01777 IoStack->MinorFunction = (bGet ? IRP_MN_READ_CONFIG : IRP_MN_WRITE_CONFIG); 01778 01779 /* lets call the driver */ 01780 Status = IoCallDriver(DeviceObject, Irp); 01781 01782 /* is the request still pending */ 01783 if (Status == STATUS_PENDING) 01784 { 01785 /* have a nap */ 01786 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); 01787 /* update status */ 01788 Status = Irp->IoStatus.Status; 01789 } 01790 01791 /* free the irp */ 01792 IoFreeIrp(Irp); 01793 /* done */ 01794 return Status; 01795 } 01796 01797 /* 01798 @implemented 01799 */ 01800 KSDDKAPI 01801 ULONG 01802 NTAPI 01803 KsDeviceSetBusData( 01804 IN PKSDEVICE Device, 01805 IN ULONG DataType, 01806 IN PVOID Buffer, 01807 IN ULONG Offset, 01808 IN ULONG Length) 01809 { 01810 return KspDeviceSetGetBusData(Device->PhysicalDeviceObject, /* is this right? */ 01811 DataType, Buffer, Offset, Length, FALSE); 01812 } 01813 01814 01815 /* 01816 @implemented 01817 */ 01818 KSDDKAPI 01819 ULONG 01820 NTAPI 01821 KsDeviceGetBusData( 01822 IN PKSDEVICE Device, 01823 IN ULONG DataType, 01824 IN PVOID Buffer, 01825 IN ULONG Offset, 01826 IN ULONG Length) 01827 { 01828 return KspDeviceSetGetBusData(Device->PhysicalDeviceObject, /* is this right? */ 01829 DataType, Buffer, Offset, Length, TRUE); 01830 01831 } 01832 01833 /* 01834 @implemented 01835 */ 01836 KSDDKAPI 01837 void 01838 NTAPI 01839 KsDeviceRegisterAdapterObject( 01840 IN PKSDEVICE Device, 01841 IN PADAPTER_OBJECT AdapterObject, 01842 IN ULONG MaxMappingsByteCount, 01843 IN ULONG MappingTableStride) 01844 { 01845 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice); 01846 01847 DeviceHeader->AdapterObject = AdapterObject; 01848 DeviceHeader->MaxMappingsByteCount = MaxMappingsByteCount; 01849 DeviceHeader->MappingTableStride = MappingTableStride; 01850 01851 } 01852 01853 01854 /* 01855 @implemented 01856 */ 01857 KSDDKAPI 01858 PVOID 01859 NTAPI 01860 KsGetFirstChild( 01861 IN PVOID Object) 01862 { 01863 PKSBASIC_HEADER BasicHeader; 01864 01865 /* get the basic header */ 01866 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); 01867 01868 /* type has to be either a device or a filter factory */ 01869 ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory); 01870 01871 return (PVOID)BasicHeader->FirstChild.Filter; 01872 } 01873 01874 /* 01875 @implemented 01876 */ 01877 KSDDKAPI 01878 PVOID 01879 NTAPI 01880 KsGetNextSibling( 01881 IN PVOID Object) 01882 { 01883 PKSBASIC_HEADER BasicHeader; 01884 01885 /* get the basic header */ 01886 BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); 01887 01888 ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || 01889 BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); 01890 01891 return (PVOID)BasicHeader->Next.Pin; 01892 } 01893 01894 ULONG 01895 KspCountMethodSets( 01896 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, 01897 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL) 01898 { 01899 ULONG Index, SubIndex, Count; 01900 BOOL bFound; 01901 01902 if (!AutomationTableA) 01903 return AutomationTableB->MethodSetsCount; 01904 01905 if (!AutomationTableB) 01906 return AutomationTableA->MethodSetsCount; 01907 01908 01909 DPRINT("AutomationTableA MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableA->MethodItemSize, AutomationTableA->MethodSetsCount); 01910 DPRINT("AutomationTableB MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableB->MethodItemSize, AutomationTableB->MethodSetsCount); 01911 01912 if (AutomationTableA->MethodItemSize && AutomationTableB->MethodItemSize) 01913 { 01914 /* sanity check */ 01915 ASSERT(AutomationTableA->MethodItemSize == AutomationTableB->MethodItemSize); 01916 } 01917 01918 /* now iterate all property sets and compare their guids */ 01919 Count = AutomationTableA->MethodSetsCount; 01920 01921 for(Index = 0; Index < AutomationTableB->MethodSetsCount; Index++) 01922 { 01923 /* set found to false */ 01924 bFound = FALSE; 01925 01926 for(SubIndex = 0; SubIndex < AutomationTableA->MethodSetsCount; SubIndex++) 01927 { 01928 if (IsEqualGUIDAligned(AutomationTableB->MethodSets[Index].Set, AutomationTableA->MethodSets[SubIndex].Set)) 01929 { 01930 /* same property set found */ 01931 bFound = TRUE; 01932 break; 01933 } 01934 } 01935 01936 if (!bFound) 01937 Count++; 01938 } 01939 01940 return Count; 01941 } 01942 01943 ULONG 01944 KspCountEventSets( 01945 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, 01946 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL) 01947 { 01948 ULONG Index, SubIndex, Count; 01949 BOOL bFound; 01950 01951 if (!AutomationTableA) 01952 return AutomationTableB->EventSetsCount; 01953 01954 if (!AutomationTableB) 01955 return AutomationTableA->EventSetsCount; 01956 01957 DPRINT("AutomationTableA EventItemSize %lu EventSetsCount %lu\n", AutomationTableA->EventItemSize, AutomationTableA->EventSetsCount); 01958 DPRINT("AutomationTableB EventItemSize %lu EventSetsCount %lu\n", AutomationTableB->EventItemSize, AutomationTableB->EventSetsCount); 01959 01960 if (AutomationTableA->EventItemSize && AutomationTableB->EventItemSize) 01961 { 01962 /* sanity check */ 01963 ASSERT(AutomationTableA->EventItemSize == AutomationTableB->EventItemSize); 01964 } 01965 01966 /* now iterate all Event sets and compare their guids */ 01967 Count = AutomationTableA->EventSetsCount; 01968 01969 for(Index = 0; Index < AutomationTableB->EventSetsCount; Index++) 01970 { 01971 /* set found to false */ 01972 bFound = FALSE; 01973 01974 for(SubIndex = 0; SubIndex < AutomationTableA->EventSetsCount; SubIndex++) 01975 { 01976 if (IsEqualGUIDAligned(AutomationTableB->EventSets[Index].Set, AutomationTableA->EventSets[SubIndex].Set)) 01977 { 01978 /* same Event set found */ 01979 bFound = TRUE; 01980 break; 01981 } 01982 } 01983 01984 if (!bFound) 01985 Count++; 01986 } 01987 01988 return Count; 01989 } 01990 01991 01992 ULONG 01993 KspCountPropertySets( 01994 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, 01995 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL) 01996 { 01997 ULONG Index, SubIndex, Count; 01998 BOOL bFound; 01999 02000 if (!AutomationTableA) 02001 return AutomationTableB->PropertySetsCount; 02002 02003 if (!AutomationTableB) 02004 return AutomationTableA->PropertySetsCount; 02005 02006 /* sanity check */ 02007 DPRINT("AutomationTableA PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableA->PropertyItemSize, AutomationTableA->PropertySetsCount); 02008 DPRINT("AutomationTableB PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableB->PropertyItemSize, AutomationTableB->PropertySetsCount); 02009 ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize); 02010 02011 /* now iterate all property sets and compare their guids */ 02012 Count = AutomationTableA->PropertySetsCount; 02013 02014 for(Index = 0; Index < AutomationTableB->PropertySetsCount; Index++) 02015 { 02016 /* set found to false */ 02017 bFound = FALSE; 02018 02019 for(SubIndex = 0; SubIndex < AutomationTableA->PropertySetsCount; SubIndex++) 02020 { 02021 if (IsEqualGUIDAligned(AutomationTableB->PropertySets[Index].Set, AutomationTableA->PropertySets[SubIndex].Set)) 02022 { 02023 /* same property set found */ 02024 bFound = TRUE; 02025 break; 02026 } 02027 } 02028 02029 if (!bFound) 02030 Count++; 02031 } 02032 02033 return Count; 02034 } 02035 02036 NTSTATUS 02037 KspCopyMethodSets( 02038 OUT PKSAUTOMATION_TABLE Table, 02039 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, 02040 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL) 02041 { 02042 ULONG Index, SubIndex, Count; 02043 BOOL bFound; 02044 02045 if (!AutomationTableA) 02046 { 02047 /* copy of property set */ 02048 RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableB->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableB->MethodSetsCount); 02049 return STATUS_SUCCESS; 02050 } 02051 else if (!AutomationTableB) 02052 { 02053 /* copy of property set */ 02054 RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount); 02055 return STATUS_SUCCESS; 02056 } 02057 02058 /* first copy all property items from dominant table */ 02059 RtlMoveMemory((PVOID)Table->MethodSets, AutomationTableA->MethodSets, sizeof(KSMETHOD_SET) * AutomationTableA->MethodSetsCount); 02060 /* set counter */ 02061 Count = AutomationTableA->MethodSetsCount; 02062 02063 /* now copy entries which arent available in the dominant table */ 02064 for(Index = 0; Index < AutomationTableB->MethodSetsCount; Index++) 02065 { 02066 /* set found to false */ 02067 bFound = FALSE; 02068 02069 for(SubIndex = 0; SubIndex < AutomationTableA->MethodSetsCount; SubIndex++) 02070 { 02071 if (IsEqualGUIDAligned(AutomationTableB->MethodSets[Index].Set, AutomationTableA->MethodSets[SubIndex].Set)) 02072 { 02073 /* same property set found */ 02074 bFound = TRUE; 02075 break; 02076 } 02077 } 02078 02079 if (!bFound) 02080 { 02081 /* copy new property item set */ 02082 RtlMoveMemory((PVOID)&Table->MethodSets[Count], &AutomationTableB->MethodSets[Index], sizeof(KSMETHOD_SET)); 02083 Count++; 02084 } 02085 } 02086 02087 return STATUS_SUCCESS; 02088 } 02089 02090 VOID 02091 KspAddPropertyItem( 02092 OUT PKSPROPERTY_SET OutPropertySet, 02093 IN PKSPROPERTY_ITEM PropertyItem, 02094 IN ULONG PropertyItemSize) 02095 { 02096 PKSPROPERTY_ITEM CurrentPropertyItem; 02097 ULONG Index; 02098 02099 // check if the property item is already present 02100 CurrentPropertyItem = (PKSPROPERTY_ITEM)OutPropertySet->PropertyItem; 02101 for(Index = 0; Index < OutPropertySet->PropertiesCount; Index++) 02102 { 02103 if (CurrentPropertyItem->PropertyId == PropertyItem->PropertyId) 02104 { 02105 // item already present 02106 return; 02107 } 02108 02109 // next item 02110 CurrentPropertyItem = (PKSPROPERTY_ITEM)((ULONG_PTR)CurrentPropertyItem + PropertyItemSize); 02111 } 02112 // add item 02113 RtlCopyMemory(CurrentPropertyItem, PropertyItem, PropertyItemSize); 02114 OutPropertySet->PropertiesCount++; 02115 } 02116 02117 NTSTATUS 02118 KspMergePropertySet( 02119 OUT PKSAUTOMATION_TABLE Table, 02120 OUT PKSPROPERTY_SET OutPropertySet, 02121 IN PKSPROPERTY_SET PropertySetA, 02122 IN PKSPROPERTY_SET PropertySetB, 02123 IN KSOBJECT_BAG Bag OPTIONAL) 02124 { 02125 ULONG PropertyCount, Index; 02126 PKSPROPERTY_ITEM PropertyItem, CurrentPropertyItem; 02127 NTSTATUS Status; 02128 02129 // max properties 02130 PropertyCount = PropertySetA->PropertiesCount + PropertySetB->PropertiesCount; 02131 02132 // allocate items 02133 PropertyItem = AllocateItem(NonPagedPool, Table->PropertyItemSize * PropertyCount); 02134 if (!PropertyItem) 02135 return STATUS_INSUFFICIENT_RESOURCES; 02136 02137 if (Bag) 02138 { 02139 /* add table to object bag */ 02140 Status = KsAddItemToObjectBag(Bag, PropertyItem, NULL); 02141 /* check for success */ 02142 if (!NT_SUCCESS(Status)) 02143 { 02144 /* free table */ 02145 FreeItem(Table); 02146 return Status; 02147 } 02148 } 02149 02150 // copy entries from dominant table 02151 RtlCopyMemory(PropertyItem, PropertySetA->PropertyItem, Table->PropertyItemSize * PropertySetA->PropertiesCount); 02152 02153 // init property set 02154 OutPropertySet->PropertiesCount = PropertySetA->PropertiesCount; 02155 OutPropertySet->PropertyItem = PropertyItem; 02156 02157 // copy other entries 02158 CurrentPropertyItem = (PKSPROPERTY_ITEM)PropertySetB->PropertyItem; 02159 for(Index = 0; Index < PropertySetB->PropertiesCount; Index++) 02160 { 02161 02162 // add entries 02163 KspAddPropertyItem(OutPropertySet, CurrentPropertyItem, Table->PropertyItemSize); 02164 02165 // next entry 02166 CurrentPropertyItem = (PKSPROPERTY_ITEM)((ULONG_PTR)CurrentPropertyItem + Table->PropertyItemSize); 02167 } 02168 02169 // done 02170 return STATUS_SUCCESS; 02171 } 02172 02173 02174 NTSTATUS 02175 KspCopyPropertySets( 02176 OUT PKSAUTOMATION_TABLE Table, 02177 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, 02178 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL, 02179 IN KSOBJECT_BAG Bag OPTIONAL) 02180 { 02181 ULONG Index, SubIndex, Count; 02182 BOOL bFound; 02183 NTSTATUS Status; 02184 02185 if (!AutomationTableA) 02186 { 02187 /* copy of property set */ 02188 RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableB->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableB->PropertySetsCount); 02189 return STATUS_SUCCESS; 02190 } 02191 else if (!AutomationTableB) 02192 { 02193 /* copy of property set */ 02194 RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount); 02195 return STATUS_SUCCESS; 02196 } 02197 02198 /* first copy all property items from dominant table */ 02199 RtlMoveMemory((PVOID)Table->PropertySets, AutomationTableA->PropertySets, sizeof(KSPROPERTY_SET) * AutomationTableA->PropertySetsCount); 02200 /* set counter */ 02201 Count = AutomationTableA->PropertySetsCount; 02202 02203 /* now copy entries which arent available in the dominant table */ 02204 for(Index = 0; Index < AutomationTableB->PropertySetsCount; Index++) 02205 { 02206 /* set found to false */ 02207 bFound = FALSE; 02208 02209 for(SubIndex = 0; SubIndex < AutomationTableA->PropertySetsCount; SubIndex++) 02210 { 02211 if (IsEqualGUIDAligned(AutomationTableB->PropertySets[Index].Set, AutomationTableA->PropertySets[SubIndex].Set)) 02212 { 02213 /* same property set found */ 02214 bFound = TRUE; 02215 break; 02216 } 02217 } 02218 02219 if (!bFound) 02220 { 02221 /* copy new property item set */ 02222 RtlMoveMemory((PVOID)&Table->PropertySets[Count], &AutomationTableB->PropertySets[Index], sizeof(KSPROPERTY_SET)); 02223 Count++; 02224 } 02225 else 02226 { 02227 // merge property sets 02228 Status = KspMergePropertySet(Table, (PKSPROPERTY_SET)&Table->PropertySets[SubIndex], (PKSPROPERTY_SET)&AutomationTableA->PropertySets[SubIndex], (PKSPROPERTY_SET)&AutomationTableB->PropertySets[Index], Bag); 02229 if (!NT_SUCCESS(Status)) 02230 { 02231 // failed to merge 02232 DPRINT1("[KS] Failed to merge %x\n", Status); 02233 return Status; 02234 } 02235 } 02236 } 02237 02238 return STATUS_SUCCESS; 02239 } 02240 02241 NTSTATUS 02242 KspCopyEventSets( 02243 OUT PKSAUTOMATION_TABLE Table, 02244 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, 02245 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL) 02246 { 02247 ULONG Index, SubIndex, Count; 02248 BOOL bFound; 02249 02250 if (!AutomationTableA) 02251 { 02252 /* copy of Event set */ 02253 RtlMoveMemory((PVOID)Table->EventSets, AutomationTableB->EventSets, sizeof(KSEVENT_SET) * AutomationTableB->EventSetsCount); 02254 return STATUS_SUCCESS; 02255 } 02256 else if (!AutomationTableB) 02257 { 02258 /* copy of Event set */ 02259 RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount); 02260 return STATUS_SUCCESS; 02261 } 02262 02263 /* first copy all Event items from dominant table */ 02264 RtlMoveMemory((PVOID)Table->EventSets, AutomationTableA->EventSets, sizeof(KSEVENT_SET) * AutomationTableA->EventSetsCount); 02265 /* set counter */ 02266 Count = AutomationTableA->EventSetsCount; 02267 02268 /* now copy entries which arent available in the dominant table */ 02269 for(Index = 0; Index < AutomationTableB->EventSetsCount; Index++) 02270 { 02271 /* set found to false */ 02272 bFound = FALSE; 02273 02274 for(SubIndex = 0; SubIndex < AutomationTableA->EventSetsCount; SubIndex++) 02275 { 02276 if (IsEqualGUIDAligned(AutomationTableB->EventSets[Index].Set, AutomationTableA->EventSets[SubIndex].Set)) 02277 { 02278 /* same Event set found */ 02279 bFound = TRUE; 02280 break; 02281 } 02282 } 02283 02284 if (!bFound) 02285 { 02286 /* copy new Event item set */ 02287 RtlMoveMemory((PVOID)&Table->EventSets[Count], &AutomationTableB->EventSets[Index], sizeof(KSEVENT_SET)); 02288 Count++; 02289 } 02290 } 02291 02292 return STATUS_SUCCESS; 02293 } 02294 02295 02296 /* 02297 @implemented 02298 */ 02299 NTSTATUS 02300 NTAPI 02301 KsMergeAutomationTables( 02302 OUT PKSAUTOMATION_TABLE *AutomationTableAB, 02303 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL, 02304 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL, 02305 IN KSOBJECT_BAG Bag OPTIONAL) 02306 { 02307 PKSAUTOMATION_TABLE Table; 02308 NTSTATUS Status = STATUS_SUCCESS; 02309 02310 if (!AutomationTableA && !AutomationTableB) 02311 { 02312 /* nothing to merge */ 02313 return STATUS_SUCCESS; 02314 } 02315 02316 /* allocate an automation table */ 02317 Table = AllocateItem(NonPagedPool, sizeof(KSAUTOMATION_TABLE)); 02318 if (!Table) 02319 return STATUS_INSUFFICIENT_RESOURCES; 02320 02321 if (Bag) 02322 { 02323 /* add table to object bag */ 02324 Status = KsAddItemToObjectBag(Bag, Table, NULL); 02325 /* check for success */ 02326 if (!NT_SUCCESS(Status)) 02327 { 02328 /* free table */ 02329 FreeItem(Table); 02330 return Status; 02331 } 02332 } 02333 02334 /* count property sets */ 02335 Table->PropertySetsCount = KspCountPropertySets(AutomationTableA, AutomationTableB); 02336 02337 if (Table->PropertySetsCount) 02338 { 02339 if (AutomationTableA) 02340 { 02341 /* use item size from dominant automation table */ 02342 Table->PropertyItemSize = AutomationTableA->PropertyItemSize; 02343 } 02344 else 02345 { 02346 /* use item size from 2nd automation table */ 02347 Table->PropertyItemSize = AutomationTableB->PropertyItemSize; 02348 } 02349 02350 if (AutomationTableA && AutomationTableB) 02351 { 02352 // FIXME handle different propery item sizes 02353 ASSERT(AutomationTableA->PropertyItemSize == AutomationTableB->PropertyItemSize); 02354 } 02355 02356 /* now allocate the property sets */ 02357 Table->PropertySets = AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * Table->PropertySetsCount); 02358 02359 if (!Table->PropertySets) 02360 { 02361 /* not enough memory */ 02362 goto cleanup; 02363 } 02364 02365 if (Bag) 02366 { 02367 /* add set to property bag */ 02368 Status = KsAddItemToObjectBag(Bag, (PVOID)Table->PropertySets, NULL); 02369 /* check for success */ 02370 if (!NT_SUCCESS(Status)) 02371 { 02372 /* cleanup table */ 02373 goto cleanup; 02374 } 02375 } 02376 /* now copy the property sets */ 02377 Status = KspCopyPropertySets(Table, AutomationTableA, AutomationTableB, Bag); 02378 if(!NT_SUCCESS(Status)) 02379 goto cleanup; 02380 02381 } 02382 02383 /* now count the method sets */ 02384 Table->MethodSetsCount = KspCountMethodSets(AutomationTableA, AutomationTableB); 02385 02386 if (Table->MethodSetsCount) 02387 { 02388 if (AutomationTableA) 02389 { 02390 /* use item size from dominant automation table */ 02391 Table->MethodItemSize = AutomationTableA->MethodItemSize; 02392 } 02393 else 02394 { 02395 /* use item size from 2nd automation table */ 02396 Table->MethodItemSize = AutomationTableB->MethodItemSize; 02397 } 02398 02399 /* now allocate the property sets */ 02400 Table->MethodSets = AllocateItem(NonPagedPool, sizeof(KSMETHOD_SET) * Table->MethodSetsCount); 02401 02402 if (!Table->MethodSets) 02403 { 02404 /* not enough memory */ 02405 goto cleanup; 02406 } 02407 02408 if (Bag) 02409 { 02410 /* add set to property bag */ 02411 Status = KsAddItemToObjectBag(Bag, (PVOID)Table->MethodSets, NULL); 02412 /* check for success */ 02413 if (!NT_SUCCESS(Status)) 02414 { 02415 /* cleanup table */ 02416 goto cleanup; 02417 } 02418 } 02419 /* now copy the property sets */ 02420 Status = KspCopyMethodSets(Table, AutomationTableA, AutomationTableB); 02421 if(!NT_SUCCESS(Status)) 02422 goto cleanup; 02423 } 02424 02425 02426 /* now count the event sets */ 02427 Table->EventSetsCount = KspCountEventSets(AutomationTableA, AutomationTableB); 02428 02429 if (Table->EventSetsCount) 02430 { 02431 if (AutomationTableA) 02432 { 02433 /* use item size from dominant automation table */ 02434 Table->EventItemSize = AutomationTableA->EventItemSize; 02435 } 02436 else 02437 { 02438 /* use item size from 2nd automation table */ 02439 Table->EventItemSize = AutomationTableB->EventItemSize; 02440 } 02441 02442 /* now allocate the property sets */ 02443 Table->EventSets = AllocateItem(NonPagedPool, sizeof(KSEVENT_SET) * Table->EventSetsCount); 02444 02445 if (!Table->EventSets) 02446 { 02447 /* not enough memory */ 02448 goto cleanup; 02449 } 02450 02451 if (Bag) 02452 { 02453 /* add set to property bag */ 02454 Status = KsAddItemToObjectBag(Bag, (PVOID)Table->EventSets, NULL); 02455 /* check for success */ 02456 if (!NT_SUCCESS(Status)) 02457 { 02458 /* cleanup table */ 02459 goto cleanup; 02460 } 02461 } 02462 /* now copy the property sets */ 02463 Status = KspCopyEventSets(Table, AutomationTableA, AutomationTableB); 02464 if(!NT_SUCCESS(Status)) 02465 goto cleanup; 02466 } 02467 02468 /* store result */ 02469 *AutomationTableAB = Table; 02470 02471 return Status; 02472 02473 02474 cleanup: 02475 02476 if (Table) 02477 { 02478 if (Table->PropertySets) 02479 { 02480 /* clean property sets */ 02481 if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->PropertySets, TRUE))) 02482 FreeItem((PVOID)Table->PropertySets); 02483 } 02484 02485 if (Table->MethodSets) 02486 { 02487 /* clean property sets */ 02488 if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->MethodSets, TRUE))) 02489 FreeItem((PVOID)Table->MethodSets); 02490 } 02491 02492 if (Table->EventSets) 02493 { 02494 /* clean property sets */ 02495 if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, (PVOID)Table->EventSets, TRUE))) 02496 FreeItem((PVOID)Table->EventSets); 02497 } 02498 02499 if (!Bag || !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag, Table, TRUE))) 02500 FreeItem(Table); 02501 } 02502 02503 return STATUS_INSUFFICIENT_RESOURCES; 02504 } 02505 02506 /* 02507 @unimplemented 02508 */ 02509 KSDDKAPI 02510 PUNKNOWN 02511 NTAPI 02512 KsRegisterAggregatedClientUnknown( 02513 IN PVOID Object, 02514 IN PUNKNOWN ClientUnknown) 02515 { 02516 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER)); 02517 02518 /* sanity check */ 02519 ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory || 02520 BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin); 02521 02522 if (BasicHeader->ClientAggregate) 02523 { 02524 /* release existing aggregate */ 02525 BasicHeader->ClientAggregate->lpVtbl->Release(BasicHeader->ClientAggregate); 02526 } 02527 02528 /* increment reference count */ 02529 ClientUnknown->lpVtbl->AddRef(ClientUnknown); 02530 02531 /* store client aggregate */ 02532 BasicHeader->ClientAggregate = ClientUnknown; 02533 02534 /* return objects outer unknown */ 02535 return BasicHeader->OuterUnknown; 02536 } 02537 02538 /* 02539 @unimplemented 02540 */ 02541 NTSTATUS 02542 NTAPI 02543 KsRegisterFilterWithNoKSPins( 02544 IN PDEVICE_OBJECT DeviceObject, 02545 IN const GUID* InterfaceClassGUID, 02546 IN ULONG PinCount, 02547 IN BOOL* PinDirection, 02548 IN KSPIN_MEDIUM* MediumList, 02549 IN GUID* CategoryList OPTIONAL) 02550 { 02551 ULONG Size, Index; 02552 NTSTATUS Status; 02553 PWSTR SymbolicLinkList; 02554 //PUCHAR Buffer; 02555 HANDLE hKey; 02556 UNICODE_STRING InterfaceString; 02557 //UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData"); 02558 02559 if (!InterfaceClassGUID || !PinCount || !PinDirection || !MediumList) 02560 { 02561 /* all these parameters are required */ 02562 return STATUS_INVALID_PARAMETER; 02563 } 02564 02565 /* calculate filter data value size */ 02566 Size = PinCount * sizeof(KSPIN_MEDIUM); 02567 if (CategoryList) 02568 { 02569 /* add category list */ 02570 Size += PinCount * sizeof(GUID); 02571 } 02572 02573 /* FIXME generate filter data blob */ 02574 UNIMPLEMENTED 02575 02576 /* get symbolic link list */ 02577 Status = IoGetDeviceInterfaces(InterfaceClassGUID, DeviceObject, DEVICE_INTERFACE_INCLUDE_NONACTIVE, &SymbolicLinkList); 02578 if (NT_SUCCESS(Status)) 02579 { 02580 /* initialize first symbolic link */ 02581 RtlInitUnicodeString(&InterfaceString, SymbolicLinkList); 02582 02583 /* open first device interface registry key */ 02584 Status = IoOpenDeviceInterfaceRegistryKey(&InterfaceString, GENERIC_WRITE, &hKey); 02585 02586 if (NT_SUCCESS(Status)) 02587 { 02588 /* write filter data */ 02589 //Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Buffer, Size); 02590 02591 /* close the key */ 02592 ZwClose(hKey); 02593 } 02594 02595 if (PinCount) 02596 { 02597 /* update medium cache */ 02598 for(Index = 0; Index < PinCount; Index++) 02599 { 02600 KsCacheMedium(&InterfaceString, &MediumList[Index], PinDirection[Index]); 02601 } 02602 } 02603 02604 /* free the symbolic link list */ 02605 FreeItem(SymbolicLinkList); 02606 } 02607 02608 return Status; 02609 } Generated on Sat May 26 2012 04:21:02 for ReactOS by
1.7.6.1
|