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 Status = KspForwardIrpSynchronous(DeviceObject, Irp); 299 300 /* check for success */ 301 if (!NT_SUCCESS(Status)) 302 { 303 DPRINT1("NextDevice object failed to start with %x\n", Status); 304 Irp->IoStatus.Status = Status; 305 CompleteRequest(Irp, IO_NO_INCREMENT); 306 return Status; 307 } 308 309 TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated; 310 UntranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResources; 311 312 ASSERT(DeviceHeader->KsDevice.Descriptor); 313 314 /* do we have a device descriptor */ 315 if (DeviceHeader->KsDevice.Descriptor) 316 { 317 /* does the device want pnp notifications */ 318 if (DeviceHeader->KsDevice.Descriptor->Dispatch) 319 { 320 /* does the driver care about IRP_MN_START_DEVICE */ 321 if (DeviceHeader->KsDevice.Descriptor->Dispatch->Start) 322 { 323 /* call driver start device routine */ 324 Status = DeviceHeader->KsDevice.Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp, 325 TranslatedResourceList, 326 UntranslatedResourceList); 327 328 329 DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader->KsDevice.Descriptor->Dispatch->Start, DeviceHeader->KsDevice.Context); 330 ASSERT(Status != STATUS_PENDING); 331 332 if (!NT_SUCCESS(Status)) 333 { 334 DPRINT1("Driver: failed to start %x\n", Status); 335 Irp->IoStatus.Status = Status; 336 CompleteRequest(Irp, IO_NO_INCREMENT); 337 return Status; 338 } 339 340 /* set state to run */ 341 DeviceHeader->KsDevice.Started = TRUE; 342 343 } 344 345 /* does the driver need post start routine */ 346 if (DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart) 347 { 348 /* allocate pnp post workitem context */ 349 Ctx = (PPNP_POSTSTART_CONTEXT)AllocateItem(NonPagedPool, sizeof(PNP_POSTSTART_CONTEXT)); 350 if (!Ctx) 351 { 352 /* no memory */ 353 Status = STATUS_INSUFFICIENT_RESOURCES; 354 } 355 else 356 { 357 /* allocate a work item */ 358 Ctx->WorkItem = IoAllocateWorkItem(DeviceObject); 359 360 if (!Ctx->WorkItem) 361 { 362 /* no memory */ 363 FreeItem(Ctx); 364 Ctx = NULL; 365 Status = STATUS_INSUFFICIENT_RESOURCES; 366 } 367 else 368 { 369 /* store device header for post-start pnp processing */ 370 Ctx->DeviceHeader = DeviceHeader; 371 } 372 } 373 } 374 else 375 { 376 /* set state to enabled, IRP_MJ_CREATE request may now succeed */ 377 DeviceHeader->TargetState = KSTARGET_STATE_ENABLED; 378 Status = KspSetFilterFactoriesState(DeviceHeader, TRUE); 379 } 380 } 381 else 382 { 383 /* set state to run */ 384 DeviceHeader->KsDevice.Started = TRUE; 385 } 386 } 387 388 /* store result */ 389 Irp->IoStatus.Status = Status; 390 /* complete request */ 391 CompleteRequest(Irp, IO_NO_INCREMENT); 392 393 if (Ctx) 394 { 395 /* queue a work item for driver post start routine */ 396 IoQueueWorkItem(Ctx->WorkItem, IKsDevice_PnpPostStart, DelayedWorkQueue, (PVOID)Ctx); 397 } 398 399 /* return result */ 400 DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx); 401 return Status; 402 } 403 404 NTSTATUS 405 NTAPI 406 IKsDevice_Pnp( 407 IN PDEVICE_OBJECT DeviceObject, 408 IN PIRP Irp) 409 { 410 PIO_STACK_LOCATION IoStack; 411 PDEVICE_EXTENSION DeviceExtension; 412 PKSIDEVICE_HEADER DeviceHeader; 413 PKSDEVICE_DISPATCH Dispatch = NULL; 414 NTSTATUS Status; 415 416 /* get current stack location */ 417 IoStack = IoGetCurrentIrpStackLocation(Irp); 418 419 /* get device extension */ 420 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 421 /* get device header */ 422 DeviceHeader = DeviceExtension->DeviceHeader; 423 424 /* do we have a device descriptor */ 425 if (DeviceHeader->KsDevice.Descriptor && DeviceHeader->KsDevice.Descriptor->Dispatch) 426 { 427 /* does the device want pnp notifications */ 428 Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->KsDevice.Descriptor->Dispatch; 429 } 430 431 switch (IoStack->MinorFunction) 432 { 433 case IRP_MN_START_DEVICE: 434 { 435 return IKsDevice_PnpStartDevice(DeviceObject, Irp); 436 } 437 438 case IRP_MN_QUERY_STOP_DEVICE: 439 { 440 Status = STATUS_SUCCESS; 441 /* check for pnp notification support */ 442 if (Dispatch) 443 { 444 /* check for query stop support */ 445 if (Dispatch->QueryStop) 446 { 447 /* call driver's query stop */ 448 Status = Dispatch->QueryStop(&DeviceHeader->KsDevice, Irp); 449 ASSERT(Status != STATUS_PENDING); 450 } 451 } 452 453 if (!NT_SUCCESS(Status)) 454 { 455 DPRINT1("Driver: query stop failed %x\n", Status); 456 Irp->IoStatus.Status = Status; 457 CompleteRequest(Irp, IO_NO_INCREMENT); 458 return Status; 459 } 460 461 /* pass the irp down the driver stack */ 462 Status = KspForwardIrpSynchronous(DeviceObject, Irp); 463 464 DPRINT("Next Device: Status %x\n", Status); 465 466 Irp->IoStatus.Status = Status; 467 CompleteRequest(Irp, IO_NO_INCREMENT); 468 return Status; 469 } 470 471 case IRP_MN_REMOVE_DEVICE: 472 { 473 /* Clean up */ 474 if (Dispatch) 475 { 476 /* check for remove support */ 477 if (Dispatch->Remove) 478 { 479 /* call driver's stop routine */ 480 Dispatch->Remove(&DeviceHeader->KsDevice, Irp); 481 } 482 } 483 484 /* pass the irp down the driver stack */ 485 Status = KspForwardIrpSynchronous(DeviceObject, Irp); 486 487 DPRINT("Next Device: Status %x\n", Status); 488 489 /* FIXME delete device resources */ 490 491 492 Irp->IoStatus.Status = Status; 493 CompleteRequest(Irp, IO_NO_INCREMENT); 494 return Status; 495 } 496 case IRP_MN_QUERY_INTERFACE: 497 { 498 Status = STATUS_UNSUCCESSFUL; 499 /* check for pnp notification support */ 500 if (Dispatch) 501 { 502 /* check for query interface support */ 503 if (Dispatch->QueryInterface) 504 { 505 /* call driver's query interface */ 506 Status = Dispatch->QueryInterface(&DeviceHeader->KsDevice, Irp); 507 ASSERT(Status != STATUS_PENDING); 508 } 509 } 510 511 if (NT_SUCCESS(Status)) 512 { 513 /* driver supports a private interface */ 514 DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n"); 515 Irp->IoStatus.Status = Status; 516 CompleteRequest(Irp, IO_NO_INCREMENT); 517 return Status; 518 } 519 520 /* pass the irp down the driver stack */ 521 Status = KspForwardIrpSynchronous(DeviceObject, Irp); 522 523 DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status); 524 Irp->IoStatus.Status = Status; 525 CompleteRequest(Irp, IO_NO_INCREMENT); 526 return Status; 527 } 528 case IRP_MN_QUERY_DEVICE_RELATIONS: 529 { 530 /* pass the irp down the driver stack */ 531 Status = KspForwardIrpSynchronous(DeviceObject, Irp); 532 533 DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status); 534 535 //Irp->IoStatus.Status = Status; 536 CompleteRequest(Irp, IO_NO_INCREMENT); 537 return Status; 538 } 539 case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: 540 { 541 /* pass the irp down the driver stack */ 542 //Status = KspForwardIrpSynchronous(DeviceObject, Irp); 543 Status = Irp->IoStatus.Status; 544 DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status); 545 546 //Irp->IoStatus.Status = Status; 547 CompleteRequest(Irp, IO_NO_INCREMENT); 548 return Status; 549 } 550 case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: 551 { 552 /* pass the irp down the driver stack */ 553 Status = KspForwardIrpSynchronous(DeviceObject, Irp); 554 555 DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status); 556 557 Irp->IoStatus.Status = Status; 558 CompleteRequest(Irp, IO_NO_INCREMENT); 559 return Status; 560 } 561 default: 562 DPRINT1("unhandled function %u\n", IoStack->MinorFunction); 563 /* pass the irp down the driver stack */ 564 Status = KspForwardIrpSynchronous(DeviceObject, Irp); 565 566 Irp->IoStatus.Status = Status; 567 CompleteRequest(Irp, IO_NO_INCREMENT); 568 return Status; 569 } 570 } 571 572 NTSTATUS 573 NTAPI 574 IKsDevice_Power( 575 IN PDEVICE_OBJECT DeviceObject, 576 IN PIRP Irp) 577 { 578 UNIMPLEMENTED; 579 580 /* TODO */ 581 582 Irp->IoStatus.Status = STATUS_SUCCESS; 583 Irp->IoStatus.Information = 0; 584 CompleteRequest(Irp, IO_NO_INCREMENT); 585 586 return STATUS_SUCCESS; 587 } 588 589 NTSTATUS 590 NTAPI 591 IKsDevice_Create( 592 IN PDEVICE_OBJECT DeviceObject, 593 IN PIRP Irp) 594 { 595 PCREATE_ITEM_ENTRY CreateItemEntry; 596 PIO_STACK_LOCATION IoStack; 597 PDEVICE_EXTENSION DeviceExtension; 598 PKSIDEVICE_HEADER DeviceHeader; 599 PKSIOBJECT_HEADER ObjectHeader; 600 NTSTATUS Status; 601 602 DPRINT("IKsDevice_Create\n"); 603 /* get current stack location */ 604 IoStack = IoGetCurrentIrpStackLocation(Irp); 605 /* get device extension */ 606 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; 607 /* get device header */ 608 DeviceHeader = DeviceExtension->DeviceHeader; 609 610 if (IoStack->FileObject->FileName.Buffer == NULL) 611 { 612 // ReactOS PnPMgr still sucks 613 ASSERT(IoStack->FileObject->FileName.Length == 0); 614 Irp->IoStatus.Status = STATUS_SUCCESS; 615 IoCompleteRequest(Irp, IO_NO_INCREMENT); 616 DPRINT1("ReactOS PnP hack\n"); 617 return STATUS_SUCCESS; 618 } 619 620 /* acquire list lock */ 621 IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); 622 623 /* sanity check */ 624 ASSERT(IoStack->FileObject); 625 626 /* check if the request is relative */ 627 if (IoStack->FileObject->RelatedFileObject != NULL) 628 { 629 /* request is to instantiate a pin / node / clock / allocator */ 630 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2; 631 632 /* sanity check */ 633 ASSERT(ObjectHeader); 634 635 /* find a matching a create item */ 636 Status = FindMatchingCreateItem(&ObjectHeader->ItemList, 637 &IoStack->FileObject->FileName, 638 &CreateItemEntry); 639 } 640 else 641 { 642 /* request to create a filter */ 643 Status = FindMatchingCreateItem(&DeviceHeader->ItemList, 644 &IoStack->FileObject->FileName, 645 &CreateItemEntry); 646 } 647 648 if (NT_SUCCESS(Status)) 649 { 650 /* set object create item */ 651 KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem; 652 653 /* call create function */ 654 Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp); 655 656 if (NT_SUCCESS(Status)) 657 { 658 /* increment create item reference count */ 659 InterlockedIncrement(&CreateItemEntry->ReferenceCount); 660 } 661 } 662 663 /* release list lock */ 664 IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown); 665 666 /* done */ 667 return Status; 668 669 670 } 671 672 /* 673 @implemented 674 */ 675 KSDDKAPI 676 NTSTATUS 677 NTAPI 678 KsInitializeDevice( 679 IN PDEVICE_OBJECT FunctionalDeviceObject, 680 IN PDEVICE_OBJECT PhysicalDeviceObject, 681 IN PDEVICE_OBJECT NextDeviceObject, 682 IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL) 683 { 684 PDEVICE_EXTENSION DeviceExtension; 685 PKSIDEVICE_HEADER Header; 686 ULONG Index; 687 PKSIOBJECT_BAG Bag; 688 NTSTATUS Status = STATUS_SUCCESS; 689 690 DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor); 691 692 /* get device extension */ 693 DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension; 694 695 /* first allocate device header */ 696 Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 0, NULL); 697 698 /* point to allocated header */ 699 Header = DeviceExtension->DeviceHeader; 700 701 DPRINT1("DeviceHeader %p\n", DeviceExtension->DeviceHeader); 702 703 if (Descriptor && Descriptor->Dispatch) 704 { 705 DPRINT("Descriptor Add %p\n", Descriptor->Dispatch->Add); 706 DPRINT("Descriptor Start %p\n", Descriptor->Dispatch->Start); 707 DPRINT("Descriptor PostStart %p\n", Descriptor->Dispatch->PostStart); 708 DPRINT("Descriptor QueryStop %p\n", Descriptor->Dispatch->QueryStop); 709 DPRINT("Descriptor CancelStop %p\n", Descriptor->Dispatch->CancelStop); 710 DPRINT("Descriptor Stop %p\n", Descriptor->Dispatch->Stop); 711 DPRINT("Descriptor QueryRemove %p\n", Descriptor->Dispatch->QueryRemove); 712 DPRINT("Descriptor CancelRemove %p\n", Descriptor->Dispatch->CancelRemove); 713 DPRINT("Descriptor Remove %p\n", Descriptor->Dispatch->Remove); 714 DPRINT("Descriptor QueryCapabilities %p\n", Descriptor->Dispatch->QueryCapabilities); 715 DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor->Dispatch->SurpriseRemoval); 716 DPRINT("Descriptor QueryPower %p\n", Descriptor->Dispatch->QueryPower); 717 DPRINT("Descriptor SetPower %p\n", Descriptor->Dispatch->SetPower); 718 DPRINT("Descriptor QueryInterface %p\n", Descriptor->Dispatch->QueryInterface); 719 } 720 721 /* check for success */ 722 if (!NT_SUCCESS(Status)) 723 { 724 DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status); 725 return Status; 726 } 727 728 /* initialize IKsDevice interface */ 729 Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice; 730 Header->ref = 1; 731 732 /* allocate object bag */ 733 Header->KsDevice.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG)); 734 if (!Header->KsDevice.Bag) 735 { 736 /* no memory */ 737 KsFreeDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader); 738 return STATUS_INSUFFICIENT_RESOURCES; 739 } 740 741 /* initialize object bag */ 742 KeInitializeMutex(&Header->BagMutex, 0); 743 KeInitializeMutex(&Header->DeviceMutex, 0); 744 745 Bag = (PKSIOBJECT_BAG)Header->KsDevice.Bag; 746 Bag->BagMutex = &Header->BagMutex; 747 InitializeListHead(&Header->ObjectBags); 748 InitializeListHead(&Bag->ObjectList); 749 Bag->DeviceHeader = (PVOID)Header; 750 751 /* insert bag into device list */ 752 InsertTailList(&Header->ObjectBags, &Bag->Entry); 753 754 /* initialize device header */ 755 Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject; 756 Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject; 757 Header->KsDevice.NextDeviceObject = NextDeviceObject; 758 Header->KsDevice.Descriptor = Descriptor; 759 Header->KsDevice.SystemPowerState = PowerSystemWorking; 760 Header->KsDevice.DevicePowerState = PowerDeviceD0; 761 Header->KsDevice.Started = FALSE; 762 Header->KsDevice.Context = NULL; 763 KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject); 764 765 766 767 if (Descriptor) 768 { 769 /* create a filter factory for each filter descriptor */ 770 DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor->FilterDescriptorsCount); 771 for(Index = 0; Index < Descriptor->FilterDescriptorsCount; Index++) 772 { 773 Status = KspCreateFilterFactory(FunctionalDeviceObject, Descriptor->FilterDescriptors[Index], NULL, NULL, 0, NULL, NULL, NULL); 774 775 DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index, Status); 776 /* check for success */ 777 if (!NT_SUCCESS(Status)) 778 { 779 DPRINT1("KspCreateFilterFactory failed with %x\n", Status); 780 /* FIXME memory leak */ 781 return Status; 782 } 783 } 784 785 /* does the driver care about the add device */ 786 if (Descriptor->Dispatch && Descriptor->Dispatch->Add) 787 { 788 Status = Descriptor->Dispatch->Add(&Header->KsDevice); 789 DPRINT("Driver: AddHandler Status %x\n", Status); 790 } 791 792 Header->KsDevice.Descriptor = Descriptor; 793 } 794 795 796 return Status; 797 } 798 799 /* 800 @implemented 801 */ 802 KSDDKAPI 803 NTSTATUS 804 NTAPI 805 KsReferenceSoftwareBusObject( 806 IN KSDEVICE_HEADER Header) 807 { 808 IKsDevice * Device; 809 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 810 811 /* get device interface */ 812 Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; 813 814 if (Device) 815 { 816 /* reference device interface */ 817 Device->lpVtbl->AddRef(Device); 818 } 819 820 return STATUS_SUCCESS; 821 } 822 823 /* 824 @implemented 825 */ 826 KSDDKAPI 827 NTSTATUS 828 NTAPI 829 KsReferenceBusObject( 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 /* reference device interface */ 841 Device->lpVtbl->AddRef(Device); 842 } 843 844 return STATUS_SUCCESS; 845 846 } 847 848 /* 849 @implemented 850 */ 851 KSDDKAPI 852 VOID 853 NTAPI 854 KsDereferenceBusObject( 855 IN KSDEVICE_HEADER Header) 856 { 857 IKsDevice * Device; 858 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 859 860 /* get device interface */ 861 Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; 862 863 if (Device) 864 { 865 /* release device interface */ 866 Device->lpVtbl->Release(Device); 867 } 868 } 869 870 /* 871 @implemented 872 */ 873 KSDDKAPI 874 VOID 875 NTAPI 876 KsDereferenceSoftwareBusObject( 877 IN KSDEVICE_HEADER Header) 878 { 879 IKsDevice * Device; 880 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header; 881 882 DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header); 883 884 /* get device interface */ 885 Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown; 886 887 if (Device) 888 { 889 /* release device interface */ 890 Device->lpVtbl->Release(Device); 891 } 892 } 893