1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS Kernel Streaming 4 * FILE: drivers/ksfilter/ks/device.c 5 * PURPOSE: KS IKsDevice interface functions 6 * PROGRAMMER: Johannes Anderwald 7 */ 8 9 #include "precomp.h" 10 11 #define NDEBUG 12 #include <debug.h> 13 14 NTSTATUS 15 NTAPI 16 IKsDevice_fnQueryInterface( 17 IN IKsDevice * iface, 18 REFIID refiid, 19 PVOID* Output) 20 { 21 NTSTATUS Status; 22 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 23 24 if (IsEqualGUIDAligned(refiid, &IID_IUnknown)) 25 { 26 *Output = &This->BasicHeader.OuterUnknown; 27 _InterlockedIncrement(&This->ref); 28 return STATUS_SUCCESS; 29 } 30 31 if (This->BasicHeader.ClientAggregate) 32 { 33 /* using client aggregate */ 34 Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output); 35 36 if (NT_SUCCESS(Status)) 37 { 38 /* client aggregate supports interface */ 39 return Status; 40 } 41 } 42 43 DPRINT("IKsDevice_fnQueryInterface no interface\n"); 44 return STATUS_NOT_SUPPORTED; 45 } 46 47 ULONG 48 NTAPI 49 IKsDevice_fnAddRef( 50 IN IKsDevice * iface) 51 { 52 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 53 54 return InterlockedIncrement(&This->ref); 55 } 56 57 ULONG 58 NTAPI 59 IKsDevice_fnRelease( 60 IN IKsDevice * iface) 61 { 62 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 63 64 InterlockedDecrement(&This->ref); 65 66 return This->ref; 67 } 68 69 70 71 PKSDEVICE 72 NTAPI 73 IKsDevice_fnGetStruct( 74 IN IKsDevice * iface) 75 { 76 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 77 78 return &This->KsDevice; 79 } 80 81 NTSTATUS 82 NTAPI 83 IKsDevice_fnInitializeObjectBag( 84 IN IKsDevice * iface, 85 IN PKSIOBJECT_BAG Bag, 86 IN PRKMUTEX Mutex) 87 { 88 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 89 90 if (!Mutex) 91 { 92 /* use device mutex */ 93 Mutex = &This->BagMutex; 94 } 95 96 /* initialize object bag */ 97 Bag->BagMutex = Mutex; 98 Bag->DeviceHeader = (PKSIDEVICE_HEADER)This; 99 InitializeListHead(&Bag->ObjectList); 100 101 /* insert bag into device list */ 102 InsertTailList(&This->ObjectBags, &Bag->Entry); 103 104 return STATUS_SUCCESS; 105 } 106 107 NTSTATUS 108 NTAPI 109 IKsDevice_fnAcquireDevice( 110 IN IKsDevice * iface) 111 { 112 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 113 114 return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL); 115 } 116 117 NTSTATUS 118 NTAPI 119 IKsDevice_fnReleaseDevice( 120 IN IKsDevice * iface) 121 { 122 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 123 124 return KeReleaseMutex(&This->DeviceMutex, FALSE); 125 } 126 127 NTSTATUS 128 NTAPI 129 IKsDevice_fnGetAdapterObject( 130 IN IKsDevice * iface, 131 IN PADAPTER_OBJECT * Object, 132 IN PULONG MaxMappingsByteCount, 133 IN PULONG MappingTableStride) 134 { 135 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 136 137 *Object = This->AdapterObject; 138 *MaxMappingsByteCount = This->MaxMappingsByteCount; 139 *MappingTableStride = This->MappingTableStride; 140 141 return STATUS_SUCCESS; 142 143 } 144 145 NTSTATUS 146 NTAPI 147 IKsDevice_fnAddPowerEntry( 148 IN IKsDevice * iface, 149 IN struct KSPOWER_ENTRY * Entry, 150 IN IKsPowerNotify* Notify) 151 { 152 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 153 154 UNIMPLEMENTED; 155 return STATUS_NOT_IMPLEMENTED; 156 } 157 158 NTSTATUS 159 NTAPI 160 IKsDevice_fnRemovePowerEntry( 161 IN IKsDevice * iface, 162 IN struct KSPOWER_ENTRY * Entry) 163 { 164 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 165 166 UNIMPLEMENTED; 167 return STATUS_NOT_IMPLEMENTED; 168 169 } 170 171 NTSTATUS 172 NTAPI 173 IKsDevice_fnPinStateChange( 174 IN IKsDevice * iface, 175 IN KSPIN Pin, 176 IN PIRP Irp, 177 IN KSSTATE OldState, 178 IN KSSTATE NewState) 179 { 180 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 181 182 UNIMPLEMENTED; 183 return STATUS_NOT_IMPLEMENTED; 184 185 } 186 187 NTSTATUS 188 NTAPI 189 IKsDevice_fnArbitrateAdapterChannel( 190 IN IKsDevice * iface, 191 IN ULONG NumberOfMapRegisters, 192 IN PDRIVER_CONTROL ExecutionRoutine, 193 IN PVOID Context) 194 { 195 PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 196 NTSTATUS Status; 197 198 DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql()); 199 200 /* sanity check */ 201 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL); 202 ASSERT(This->AdapterObject); 203 204 /* allocate adapter channel */ 205 Status = IoAllocateAdapterChannel(This->AdapterObject, This->KsDevice.FunctionalDeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context); 206 207 /* done */ 208 return Status; 209 } 210 211 NTSTATUS 212 NTAPI 213 IKsDevice_fnCheckIoCapability( 214 IN IKsDevice * iface, 215 IN ULONG Unknown) 216 { 217 //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown); 218 219 UNIMPLEMENTED; 220 return STATUS_NOT_IMPLEMENTED; 221 } 222 223 static IKsDeviceVtbl vt_IKsDevice = 224 { 225 IKsDevice_fnQueryInterface, 226 IKsDevice_fnAddRef, 227 IKsDevice_fnRelease, 228 IKsDevice_fnGetStruct, 229 IKsDevice_fnInitializeObjectBag, 230 IKsDevice_fnAcquireDevice, 231 IKsDevice_fnReleaseDevice, 232 IKsDevice_fnGetAdapterObject, 233 IKsDevice_fnAddPowerEntry, 234 IKsDevice_fnRemovePowerEntry, 235 IKsDevice_fnPinStateChange, 236 IKsDevice_fnArbitrateAdapterChannel, 237 IKsDevice_fnCheckIoCapability 238 }; 239 240 241 VOID 242 NTAPI 243 IKsDevice_PnpPostStart( 244 IN PDEVICE_OBJECT DeviceObject, 245 IN PVOID Context) 246 { 247 NTSTATUS Status; 248 PPNP_POSTSTART_CONTEXT Ctx = (PPNP_POSTSTART_CONTEXT)Context; 249 250 /* call driver pnp post routine */ 251 Status = Ctx->DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart(&Ctx->DeviceHeader->KsDevice); 252 253 if (!NT_SUCCESS(Status)) 254 { 255 /* set state to disabled */ 256 Ctx->DeviceHeader->TargetState = KSTARGET_STATE_DISABLED; 257 } 258 else 259 { 260 /* set state to enabled */ 261 Ctx->DeviceHeader->TargetState = KSTARGET_STATE_ENABLED; 262 Status = KspSetFilterFactoriesState(Ctx->DeviceHeader, TRUE); 263 } 264 265 /* free work item */ 266 IoFreeWorkItem(Ctx->WorkItem); 267 268 /* free work context */ 269 FreeItem(Ctx); 270 271 DPRINT("IKsDevice_PnpPostStart: PostStart Routine returned %x\n", Status); 272 } 273 274 NTSTATUS 275 NTAPI 276 IKsDevice_PnpStartDevice( 277 IN PDEVICE_OBJECT DeviceObject, 278 IN PIRP Irp) 279 { 280 PIO_STACK_LOCATION IoStack; 281 PDEVICE_EXTENSION DeviceExtension; 282 PKSIDEVICE_HEADER DeviceHeader; 283 PPNP_POSTSTART_CONTEXT Ctx = NULL; 284 NTSTATUS Status; 285 PCM_RESOURCE_LIST TranslatedResourceList; 286 PCM_RESOURCE_LIST UntranslatedResourceList; 287 288 /* get current stack location */ 289 IoStack = IoGetCurrentIrpStackLocation(Irp); 290 /* get device extension */ 291 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 292 /* get device header */ 293 DeviceHeader = DeviceExtension->DeviceHeader; 294 295 DPRINT("IKsDevice_PnpStartDevice DeviceHeader %p\n", DeviceHeader); 296 297 /* first forward irp to lower device object */ 298 if (!IoForwardIrpSynchronously(DeviceHeader->KsDevice.NextDeviceObject, Irp)) 299 { 300 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; 301 } 302 Status = Irp->IoStatus.Status; 303 304 /* check for success */ 305 if (!NT_SUCCESS(Status)) 306 { 307 DPRINT1("NextDevice object failed to start with %x\n", Status); 308 CompleteRequest(Irp, IO_NO_INCREMENT); 309 return Status; 310 } 311 312 TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated; 313 UntranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResources; 314 315 ASSERT(DeviceHeader->KsDevice.Descriptor); 316 317 /* do we have a device descriptor */ 318 if (DeviceHeader->KsDevice.Descriptor) 319 { 320 /* does the device want pnp notifications */ 321 if (DeviceHeader->KsDevice.Descriptor->Dispatch) 322 { 323 /* does the driver care about IRP_MN_START_DEVICE */ 324 if (DeviceHeader->KsDevice.Descriptor->Dispatch->Start) 325 { 326 /* call driver start device routine */ 327 Status = DeviceHeader->KsDevice.Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp, 328 TranslatedResourceList, 329 UntranslatedResourceList); 330 331 332 DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader->KsDevice.Descriptor->Dispatch->Start, DeviceHeader->KsDevice.Context); 333 ASSERT(Status != STATUS_PENDING); 334 335 if (!NT_SUCCESS(Status)) 336 { 337 DPRINT1("Driver: failed to start %x\n", Status); 338 Irp->IoStatus.Status = Status; 339 CompleteRequest(Irp, IO_NO_INCREMENT); 340 return Status; 341 } 342 343 /* set state to run */ 344 DeviceHeader->KsDevice.Started = TRUE; 345 346 } 347 348 /* does the driver need post start routine */ 349 if (DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart) 350 { 351 /* allocate pnp post workitem context */ 352 Ctx = (PPNP_POSTSTART_CONTEXT)AllocateItem(NonPagedPool, sizeof(PNP_POSTSTART_CONTEXT)); 353 if (!Ctx) 354 { 355 /* no memory */ 356 Status = STATUS_INSUFFICIENT_RESOURCES; 357 } 358 else 359 { 360 /* allocate a work item */ 361 Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); 362 363 if (!Ctx->WorkItem) 364 { 365 /* no memory */ 366 FreeItem(Ctx); 367 Ctx = NULL; 368 Status = STATUS_INSUFFICIENT_RESOURCES; 369 } 370 else 371 { 372 /* store device header for post-start pnp processing */ 373 Ctx->DeviceHeader = DeviceHeader; 374 } 375 } 376 } 377 else 378 { 379 /* set state to enabled, IRP_MJ_CREATE request may now succeed */ 380 DeviceHeader->TargetState = KSTARGET_STATE_ENABLED; 381 Status = KspSetFilterFactoriesState(DeviceHeader, TRUE); 382 } 383 } 384 else 385 { 386 /* set state to run */ 387 DeviceHeader->KsDevice.Started = TRUE; 388 } 389 } 390 391 /* store result */ 392 Irp->IoStatus.Status = Status; 393 /* complete request */ 394 CompleteRequest(Irp, IO_NO_INCREMENT); 395 396 if (Ctx) 397 { 398 /* queue a work item for driver post start routine */ 399 IoQueueWorkItem(Ctx->WorkItem, IKsDevice_PnpPostStart, DelayedWorkQueue, (PVOID)Ctx); 400 } 401 402 /* return result */ 403 DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx); 404 return Status; 405 } 406 407 NTSTATUS 408 NTAPI 409 IKsDevice_Pnp( 410 IN PDEVICE_OBJECT DeviceObject, 411 IN PIRP Irp) 412 { 413 PIO_STACK_LOCATION IoStack; 414 PDEVICE_EXTENSION DeviceExtension; 415 PKSIDEVICE_HEADER DeviceHeader; 416 PKSDEVICE_DISPATCH Dispatch = NULL; 417 NTSTATUS Status; 418 419 /* get current stack location */ 420 IoStack = IoGetCurrentIrpStackLocation(Irp); 421 422 /* get device extension */ 423 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 424 /* get device header */ 425 DeviceHeader = DeviceExtension->DeviceHeader; 426 427 /* do we have a device descriptor */ 428 if (DeviceHeader->KsDevice.Descriptor && DeviceHeader->KsDevice.Descriptor->Dispatch) 429 { 430 /* does the device want pnp notifications */ 431 Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->KsDevice.Descriptor->Dispatch; 432 } 433 434 switch (IoStack->MinorFunction) 435 { 436 case IRP_MN_START_DEVICE: 437 { 438 return IKsDevice_PnpStartDevice(DeviceObject, Irp); 439 } 440 441 case IRP_MN_QUERY_STOP_DEVICE: 442 { 443 Status = STATUS_SUCCESS; 444 /* check for pnp notification support */ 445 if (Dispatch) 446 { 447 /* check for query stop support */ 448 if (Dispatch->QueryStop) 449 { 450 /* call driver's query stop */ 451 Status = Dispatch->QueryStop(&DeviceHeader->KsDevice, Irp); 452 ASSERT(Status != STATUS_PENDING); 453 } 454 } 455 456 if (!NT_SUCCESS(Status)) 457 { 458 DPRINT1("Driver: query stop failed %x\n", Status); 459 Irp->IoStatus.Status = Status; 460 CompleteRequest(Irp, IO_NO_INCREMENT); 461 return Status; 462 } 463 464 /* pass the irp down the driver stack */ 465 IoSkipCurrentIrpStackLocation(Irp); 466 return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); 467 } 468 469 case IRP_MN_REMOVE_DEVICE: 470 { 471 /* Clean up */ 472 if (Dispatch) 473 { 474 /* check for remove support */ 475 if (Dispatch->Remove) 476 { 477 /* call driver's stop routine */ 478 Dispatch->Remove(&DeviceHeader->KsDevice, Irp); 479 } 480 } 481 482 /* pass the irp down the driver stack */ 483 IoSkipCurrentIrpStackLocation(Irp); 484 Status = IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); 485 /* FIXME delete device resources */ 486 return Status; 487 } 488 case IRP_MN_QUERY_INTERFACE: 489 { 490 Status = STATUS_UNSUCCESSFUL; 491 /* check for pnp notification support */ 492 if (Dispatch) 493 { 494 /* check for query interface support */ 495 if (Dispatch->QueryInterface) 496 { 497 /* call driver's query interface */ 498 Status = Dispatch->QueryInterface(&DeviceHeader->KsDevice, Irp); 499 ASSERT(Status != STATUS_PENDING); 500 } 501 } 502 503 if (NT_SUCCESS(Status)) 504 { 505 /* driver supports a private interface */ 506 DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n"); 507 Irp->IoStatus.Status = Status; 508 CompleteRequest(Irp, IO_NO_INCREMENT); 509 return Status; 510 } 511 512 /* pass the irp down the driver stack */ 513 IoSkipCurrentIrpStackLocation(Irp); 514 return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); 515 } 516 case IRP_MN_QUERY_DEVICE_RELATIONS: 517 { 518 /* pass the irp down the driver stack */ 519 IoSkipCurrentIrpStackLocation(Irp); 520 return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); 521 } 522 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 523 { 524 /* pass the irp down the driver stack */ 525 //Status = KspForwardIrpSynchronous(DeviceObject, Irp); 526 Status = Irp->IoStatus.Status; 527 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status); 528 529 //Irp->IoStatus.Status = Status; 530 CompleteRequest(Irp, IO_NO_INCREMENT); 531 return Status; 532 } 533 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 534 { 535 /* pass the irp down the driver stack */ 536 IoSkipCurrentIrpStackLocation(Irp); 537 return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); 538 } 539 default: 540 DPRINT1("unhandled function %u\n", IoStack->MinorFunction); 541 /* pass the irp down the driver stack */ 542 IoSkipCurrentIrpStackLocation(Irp); 543 return IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp); 544 } 545 } 546 547 NTSTATUS 548 NTAPI 549 IKsDevice_Power( 550 IN PDEVICE_OBJECT DeviceObject, 551 IN PIRP Irp) 552 { 553 UNIMPLEMENTED; 554 555 /* TODO */ 556 557 Irp->IoStatus.Status = STATUS_SUCCESS; 558 Irp->IoStatus.Information = 0; 559 CompleteRequest(Irp, IO_NO_INCREMENT); 560 561 return STATUS_SUCCESS; 562 } 563 564 NTSTATUS 565 NTAPI 566 IKsDevice_Create( 567 IN PDEVICE_OBJECT DeviceObject, 568 IN PIRP Irp) 569 { 570 PCREATE_ITEM_ENTRY CreateItemEntry; 571 PIO_STACK_LOCATION IoStack; 572 PDEVICE_EXTENSION DeviceExtension; 573 PKSIDEVICE_HEADER DeviceHeader; 574 PKSIOBJECT_HEADER ObjectHeader; 575 NTSTATUS Status; 576 577 DPRINT("IKsDevice_Create\n"); 578 /* get current stack location */ 579 IoStack = IoGetCurrentIrpStackLocation(Irp); 580 /* get device extension */ 581 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 582 /* get device header */ 583 DeviceHeader = DeviceExtension->DeviceHeader; 584 585 if (IoStack->FileObject->FileName.Buffer == NULL) 586 { 587 // ReactOS PnPMgr still sucks 588 ASSERT(IoStack->FileObject->FileName.Length == 0); 589 Irp->IoStatus.Status = STATUS_SUCCESS; 590 IoCompleteRequest(Irp, IO_NO_INCREMENT); 591 DPRINT1("ReactOS PnP hack\n"); 592 return STATUS_SUCCESS; 593 } 594 595 /* acquire list lock */ 596 IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); 597 598 /* sanity check */ 599 ASSERT(IoStack->FileObject); 600 601 /* check if the request is relative */ 602 if (IoStack->FileObject->RelatedFileObject != NULL) 603 { 604 /* request is to instantiate a pin / node / clock / allocator */ 605 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2; 606 607 /* sanity check */ 608 ASSERT(ObjectHeader); 609 610 /* find a matching a create item */ 611 Status = FindMatchingCreateItem(&ObjectHeader->ItemList, 612 &IoStack->FileObject->FileName, 613 &CreateItemEntry); 614 } 615 else 616 { 617 /* request to create a filter */ 618 Status = FindMatchingCreateItem(&DeviceHeader->ItemList, 619 &IoStack->FileObject->FileName, 620 &CreateItemEntry); 621 } 622 623 if (NT_SUCCESS(Status)) 624 { 625 /* set object create item */ 626 KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem; 627 628 /* call create function */ 629 Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp); 630 631 if (NT_SUCCESS(Status)) 632 { 633 /* increment create item reference count */ 634 InterlockedIncrement(&CreateItemEntry->ReferenceCount); 635 } 636 } 637 638 /* release list lock */ 639 IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); 640 641 /* done */ 642 return Status; 643 644 645 } 646 647 /* 648 @implemented 649 */ 650 KSDDKAPI 651 NTSTATUS 652 NTAPI 653 KsInitializeDevice( 654 IN PDEVICE_OBJECT FunctionalDeviceObject, 655 IN PDEVICE_OBJECT PhysicalDeviceObject, 656 IN PDEVICE_OBJECT NextDeviceObject, 657 IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL) 658 { 659 PDEVICE_EXTENSION DeviceExtension; 660 PKSIDEVICE_HEADER Header; 661 ULONG Index; 662 PKSIOBJECT_BAG Bag; 663 NTSTATUS Status = STATUS_SUCCESS; 664 665 DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor); 666 667 /* get device extension */ 668 DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension; 669 670 /* first allocate device header */ 671 Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 0, NULL); 672 673 /* point to allocated header */ 674 Header = DeviceExtension->DeviceHeader; 675 676 DPRINT1("DeviceHeader %p\n", DeviceExtension->DeviceHeader); 677 678 if (Descriptor && Descriptor->Dispatch) 679 { 680 DPRINT("Descriptor Add %p\n", Descriptor->Dispatch->Add); 681 DPRINT("Descriptor Start %p\n", Descriptor->Dispatch->Start); 682 DPRINT("Descriptor PostStart %p\n", Descriptor->Dispatch->PostStart); 683 DPRINT("Descriptor QueryStop %p\n", Descriptor->Dispatch->QueryStop); 684 DPRINT("Descriptor CancelStop %p\n", Descriptor->Dispatch->CancelStop); 685 DPRINT("Descriptor Stop %p\n", Descriptor->Dispatch->Stop); 686 DPRINT("Descriptor QueryRemove %p\n", Descriptor->Dispatch->QueryRemove); 687 DPRINT("Descriptor CancelRemove %p\n", Descriptor->Dispatch->CancelRemove); 688 DPRINT("Descriptor Remove %p\n", Descriptor->Dispatch->Remove); 689 DPRINT("Descriptor QueryCapabilities %p\n", Descriptor->Dispatch->QueryCapabilities); 690 DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor->Dispatch->SurpriseRemoval); 691 DPRINT("Descriptor QueryPower %p\n", Descriptor->Dispatch->QueryPower); 692 DPRINT("Descriptor SetPower %p\n", Descriptor->Dispatch->SetPower); 693 DPRINT("Descriptor QueryInterface %p\n", Descriptor->Dispatch->QueryInterface); 694 } 695 696 /* check for success */ 697 if (!NT_SUCCESS(Status)) 698 { 699 DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status); 700 return Status; 701 } 702 703 /* initialize IKsDevice interface */ 704 Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice; 705 Header->ref = 1; 706 707 /* allocate object bag */ 708 Header->KsDevice.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); 709 if (!Header->KsDevice.Bag) 710 { 711 /* no memory */ 712 KsFreeDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader); 713 return STATUS_INSUFFICIENT_RESOURCES; 714 } 715 716 /* initialize object bag */ 717 KeInitializeMutex(&Header->BagMutex, 0); 718 KeInitializeMutex(&Header->DeviceMutex, 0); 719 720 Bag = (PKSIOBJECT_BAG)Header->KsDevice.Bag; 721 Bag->BagMutex = &Header->BagMutex; 722 InitializeListHead(&Header->ObjectBags); 723 InitializeListHead(&Bag->ObjectList); 724 Bag->DeviceHeader = (PVOID)Header; 725 726 /* insert bag into device list */ 727 InsertTailList(&Header->ObjectBags, &Bag->Entry); 728 729 /* initialize device header */ 730 Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject; 731 Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject; 732 Header->KsDevice.NextDeviceObject = NextDeviceObject; 733 Header->KsDevice.Descriptor = Descriptor; 734 Header->KsDevice.SystemPowerState = PowerSystemWorking; 735 Header->KsDevice.DevicePowerState = PowerDeviceD0; 736 Header->KsDevice.Started = FALSE; 737 Header->KsDevice.Context = NULL; 738 KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject); 739 740 741 742 if (Descriptor) 743 { 744 /* create a filter factory for each filter descriptor */ 745 DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor->FilterDescriptorsCount); 746 for(Index = 0; Index < Descriptor->FilterDescriptorsCount; Index++) 747 { 748 Status = KspCreateFilterFactory(FunctionalDeviceObject, Descriptor->FilterDescriptors[Index], NULL, NULL, 0, NULL, NULL, NULL); 749 750 DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index, Status); 751 /* check for success */ 752 if (!NT_SUCCESS(Status)) 753 { 754 DPRINT1("KspCreateFilterFactory failed with %x\n", Status); 755 /* FIXME memory leak */ 756 return Status; 757 } 758 } 759 760 /* does the driver care about the add device */ 761 if (Descriptor->Dispatch && Descriptor->Dispatch->Add) 762 { 763 Status = Descriptor->Dispatch->Add(&Header->KsDevice); 764 DPRINT("Driver: AddHandler Status %x\n", Status); 765 } 766 767 Header->KsDevice.Descriptor = Descriptor; 768 } 769 770 771 return Status; 772 } 773 774 /* 775 @implemented 776 */ 777 KSDDKAPI 778 NTSTATUS 779 NTAPI 780 KsReferenceSoftwareBusObject( 781 IN KSDEVICE_HEADER Header) 782 { 783 IKsDevice * Device; 784 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 785 786 /* get device interface */ 787 Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; 788 789 if (Device) 790 { 791 /* reference device interface */ 792 Device->lpVtbl->AddRef(Device); 793 } 794 795 return STATUS_SUCCESS; 796 } 797 798 /* 799 @implemented 800 */ 801 KSDDKAPI 802 NTSTATUS 803 NTAPI 804 KsReferenceBusObject( 805 IN KSDEVICE_HEADER Header) 806 { 807 IKsDevice * Device; 808 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 809 810 /* get device interface */ 811 Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; 812 813 if (Device) 814 { 815 /* reference device interface */ 816 Device->lpVtbl->AddRef(Device); 817 } 818 819 return STATUS_SUCCESS; 820 821 } 822 823 /* 824 @implemented 825 */ 826 KSDDKAPI 827 VOID 828 NTAPI 829 KsDereferenceBusObject( 830 IN KSDEVICE_HEADER Header) 831 { 832 IKsDevice * Device; 833 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 834 835 /* get device interface */ 836 Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; 837 838 if (Device) 839 { 840 /* release device interface */ 841 Device->lpVtbl->Release(Device); 842 } 843 } 844 845 /* 846 @implemented 847 */ 848 KSDDKAPI 849 VOID 850 NTAPI 851 KsDereferenceSoftwareBusObject( 852 IN KSDEVICE_HEADER Header) 853 { 854 IKsDevice * Device; 855 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 856 857 DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header); 858 859 /* get device interface */ 860 Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; 861 862 if (Device) 863 { 864 /* release device interface */ 865 Device->lpVtbl->Release(Device); 866 } 867 } 868