ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

device.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/device.c
00005  * PURPOSE:         KS IKsDevice interface functions
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 
00010 #include "priv.h"
00011 
00012 NTSTATUS
00013 NTAPI
00014 IKsDevice_fnQueryInterface(
00015     IN IKsDevice * iface,
00016     REFIID refiid,
00017     PVOID* Output)
00018 {
00019     NTSTATUS Status;
00020     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00021 
00022     if (IsEqualGUIDAligned(refiid, &IID_IUnknown))
00023     {
00024         *Output = &This->BasicHeader.OuterUnknown;
00025         _InterlockedIncrement(&This->ref);
00026         return STATUS_SUCCESS;
00027     }
00028 
00029     if (This->BasicHeader.ClientAggregate)
00030     {
00031          /* using client aggregate */
00032          Status = This->BasicHeader.ClientAggregate->lpVtbl->QueryInterface(This->BasicHeader.ClientAggregate, refiid, Output);
00033 
00034          if (NT_SUCCESS(Status))
00035          {
00036              /* client aggregate supports interface */
00037              return Status;
00038          }
00039     }
00040 
00041     DPRINT("IKsDevice_fnQueryInterface no interface\n");
00042     return STATUS_NOT_SUPPORTED;
00043 }
00044 
00045 ULONG
00046 NTAPI
00047 IKsDevice_fnAddRef(
00048     IN IKsDevice * iface)
00049 {
00050     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00051 
00052     return InterlockedIncrement(&This->ref);
00053 }
00054 
00055 ULONG
00056 NTAPI
00057 IKsDevice_fnRelease(
00058     IN IKsDevice * iface)
00059 {
00060     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00061 
00062     InterlockedDecrement(&This->ref);
00063 
00064     return This->ref;
00065 }
00066 
00067 
00068 
00069 PKSDEVICE
00070 NTAPI
00071 IKsDevice_fnGetStruct(
00072     IN IKsDevice * iface)
00073 {
00074     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00075 
00076     return &This->KsDevice;
00077 }
00078 
00079 NTSTATUS
00080 NTAPI
00081 IKsDevice_fnInitializeObjectBag(
00082     IN IKsDevice * iface,
00083     IN PKSIOBJECT_BAG Bag,
00084     IN PRKMUTEX Mutex)
00085 {
00086     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00087 
00088     if (!Mutex)
00089     {
00090         /* use device mutex */
00091         Mutex = &This->BagMutex;
00092     }
00093 
00094     /* initialize object bag */
00095     Bag->BagMutex = Mutex;
00096     Bag->DeviceHeader = (PKSIDEVICE_HEADER)This;
00097     InitializeListHead(&Bag->ObjectList);
00098 
00099     /* insert bag into device list */
00100     InsertTailList(&This->ObjectBags, &Bag->Entry);
00101 
00102     return STATUS_SUCCESS;
00103 }
00104 
00105 NTSTATUS
00106 NTAPI
00107 IKsDevice_fnAcquireDevice(
00108     IN IKsDevice * iface)
00109 {
00110     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00111 
00112     return KeWaitForSingleObject(&This->DeviceMutex, Executive, KernelMode, FALSE, NULL);
00113 }
00114 
00115 NTSTATUS
00116 NTAPI
00117 IKsDevice_fnReleaseDevice(
00118     IN IKsDevice * iface)
00119 {
00120     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00121 
00122     return KeReleaseMutex(&This->DeviceMutex, FALSE);
00123 }
00124 
00125 NTSTATUS
00126 NTAPI
00127 IKsDevice_fnGetAdapterObject(
00128     IN IKsDevice * iface,
00129     IN PADAPTER_OBJECT * Object,
00130     IN PULONG MaxMappingsByteCount,
00131     IN PULONG MappingTableStride)
00132 {
00133     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00134 
00135     *Object = This->AdapterObject;
00136     *MaxMappingsByteCount = This->MaxMappingsByteCount;
00137     *MappingTableStride = This->MappingTableStride;
00138 
00139     return STATUS_SUCCESS;
00140 
00141 }
00142 
00143 NTSTATUS
00144 NTAPI
00145 IKsDevice_fnAddPowerEntry(
00146     IN IKsDevice * iface,
00147     IN struct KSPOWER_ENTRY * Entry,
00148     IN IKsPowerNotify* Notify)
00149 {
00150     //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00151 
00152     UNIMPLEMENTED
00153     return STATUS_NOT_IMPLEMENTED;
00154 }
00155 
00156 NTSTATUS
00157 NTAPI
00158 IKsDevice_fnRemovePowerEntry(
00159     IN IKsDevice * iface,
00160     IN struct KSPOWER_ENTRY * Entry)
00161 {
00162     //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00163 
00164     UNIMPLEMENTED
00165     return STATUS_NOT_IMPLEMENTED;
00166 
00167 }
00168 
00169 NTSTATUS
00170 NTAPI
00171 IKsDevice_fnPinStateChange(
00172     IN IKsDevice * iface,
00173     IN KSPIN Pin,
00174     IN PIRP Irp,
00175     IN KSSTATE OldState,
00176     IN KSSTATE NewState)
00177 {
00178     //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00179 
00180     UNIMPLEMENTED
00181     return STATUS_NOT_IMPLEMENTED;
00182 
00183 }
00184 
00185 NTSTATUS
00186 NTAPI
00187 IKsDevice_fnArbitrateAdapterChannel(
00188     IN IKsDevice * iface,
00189     IN ULONG NumberOfMapRegisters,
00190     IN PDRIVER_CONTROL ExecutionRoutine,
00191     IN PVOID Context)
00192 {
00193     PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00194     NTSTATUS Status;
00195 
00196     DPRINT("IKsDevice_fnArbitrateAdapterChannel NumberOfMapRegisters %lu ExecutionRoutine %p Context %p Irql %lu\n", NumberOfMapRegisters, ExecutionRoutine, Context, KeGetCurrentIrql());
00197 
00198     /* sanity check */
00199     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
00200     ASSERT(This->AdapterObject);
00201 
00202     /* allocate adapter channel */
00203     Status = IoAllocateAdapterChannel(This->AdapterObject, This->KsDevice.FunctionalDeviceObject, NumberOfMapRegisters, ExecutionRoutine, Context);
00204 
00205     /* done */
00206     return Status;
00207 }
00208 
00209 NTSTATUS
00210 NTAPI
00211 IKsDevice_fnCheckIoCapability(
00212     IN IKsDevice * iface,
00213     IN ULONG Unknown)
00214 {
00215     //PKSIDEVICE_HEADER This = (PKSIDEVICE_HEADER)CONTAINING_RECORD(iface, KSIDEVICE_HEADER, BasicHeader.OuterUnknown);
00216 
00217     UNIMPLEMENTED
00218     return STATUS_NOT_IMPLEMENTED;
00219 }
00220 
00221 static IKsDeviceVtbl vt_IKsDevice = 
00222 {
00223     IKsDevice_fnQueryInterface,
00224     IKsDevice_fnAddRef,
00225     IKsDevice_fnRelease,
00226     IKsDevice_fnGetStruct,
00227     IKsDevice_fnInitializeObjectBag,
00228     IKsDevice_fnAcquireDevice,
00229     IKsDevice_fnReleaseDevice,
00230     IKsDevice_fnGetAdapterObject,
00231     IKsDevice_fnAddPowerEntry,
00232     IKsDevice_fnRemovePowerEntry,
00233     IKsDevice_fnPinStateChange,
00234     IKsDevice_fnArbitrateAdapterChannel,
00235     IKsDevice_fnCheckIoCapability
00236 };
00237 
00238 
00239 VOID
00240 NTAPI
00241 IKsDevice_PnpPostStart(
00242     IN PDEVICE_OBJECT  DeviceObject,
00243     IN PVOID  Context)
00244 {
00245     NTSTATUS Status;
00246     PPNP_POSTSTART_CONTEXT Ctx = (PPNP_POSTSTART_CONTEXT)Context;
00247 
00248     /* call driver pnp post routine */
00249     Status = Ctx->DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart(&Ctx->DeviceHeader->KsDevice);
00250 
00251     if (!NT_SUCCESS(Status))
00252     {
00253         /* set state to disabled */
00254         Ctx->DeviceHeader->TargetState  = KSTARGET_STATE_DISABLED;
00255     }
00256     else
00257     {
00258         /* set state to enabled */
00259         Ctx->DeviceHeader->TargetState = KSTARGET_STATE_ENABLED;
00260         Status = KspSetFilterFactoriesState(Ctx->DeviceHeader, TRUE);
00261     }
00262 
00263     /* free work item */
00264     IoFreeWorkItem(Ctx->WorkItem);
00265 
00266     /* free work context */
00267     FreeItem(Ctx);
00268 
00269     DPRINT("IKsDevice_PnpPostStart: PostStart Routine returned %x\n", Status);
00270 }
00271 
00272 NTSTATUS
00273 NTAPI
00274 IKsDevice_PnpStartDevice(
00275     IN PDEVICE_OBJECT  DeviceObject,
00276     IN PIRP Irp)
00277 {
00278     PIO_STACK_LOCATION IoStack;
00279     PDEVICE_EXTENSION DeviceExtension;
00280     PKSIDEVICE_HEADER DeviceHeader;
00281     PPNP_POSTSTART_CONTEXT Ctx = NULL;
00282     NTSTATUS Status;
00283     PCM_RESOURCE_LIST TranslatedResourceList;
00284     PCM_RESOURCE_LIST UntranslatedResourceList;
00285 
00286     /* get current stack location */
00287     IoStack = IoGetCurrentIrpStackLocation(Irp);
00288     /* get device extension */
00289     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00290     /* get device header */
00291     DeviceHeader = DeviceExtension->DeviceHeader;
00292 
00293     DPRINT("IKsDevice_PnpStartDevice DeviceHeader %p\n", DeviceHeader);
00294 
00295     /* first forward irp to lower device object */
00296     Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00297 
00298     /* check for success */
00299     if (!NT_SUCCESS(Status))
00300     {
00301         DPRINT1("NextDevice object failed to start with %x\n", Status);
00302         Irp->IoStatus.Status = Status;
00303         CompleteRequest(Irp, IO_NO_INCREMENT);
00304         return Status;
00305     }
00306 
00307     TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated;
00308     UntranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResources;
00309 
00310     ASSERT(DeviceHeader->KsDevice.Descriptor);
00311 
00312     /* do we have a device descriptor */
00313     if (DeviceHeader->KsDevice.Descriptor)
00314     {
00315         /* does the device want pnp notifications */
00316         if (DeviceHeader->KsDevice.Descriptor->Dispatch)
00317         {
00318             /* does the driver care about IRP_MN_START_DEVICE */
00319             if (DeviceHeader->KsDevice.Descriptor->Dispatch->Start)
00320             {
00321                 /* call driver start device routine */
00322                 Status = DeviceHeader->KsDevice.Descriptor->Dispatch->Start(&DeviceHeader->KsDevice, Irp,
00323                                                                    TranslatedResourceList,
00324                                                                    UntranslatedResourceList);
00325 
00326 
00327                 DPRINT("IKsDevice_PnpStartDevice Start %p, Context %p\n", DeviceHeader->KsDevice.Descriptor->Dispatch->Start, DeviceHeader->KsDevice.Context);
00328                 ASSERT(Status != STATUS_PENDING);
00329 
00330                 if (!NT_SUCCESS(Status))
00331                 {
00332                     DPRINT1("Driver: failed to start %x\n", Status);
00333                     Irp->IoStatus.Status = Status;
00334                     CompleteRequest(Irp, IO_NO_INCREMENT);
00335                     return Status;
00336                 }
00337 
00338                 /* set state to run */
00339                 DeviceHeader->KsDevice.Started = TRUE;
00340 
00341             }
00342 
00343             /* does the driver need post start routine */
00344             if (DeviceHeader->KsDevice.Descriptor->Dispatch->PostStart)
00345             {
00346                 /* allocate pnp post workitem context */
00347                 Ctx = (PPNP_POSTSTART_CONTEXT)AllocateItem(NonPagedPool, sizeof(PNP_POSTSTART_CONTEXT));
00348                 if (!Ctx)
00349                 {
00350                     /* no memory */
00351                     Status = STATUS_INSUFFICIENT_RESOURCES;
00352                 }
00353                 else
00354                 {
00355                     /* allocate a work item */
00356                     Ctx->WorkItem = IoAllocateWorkItem(DeviceObject);
00357 
00358                     if (!Ctx->WorkItem)
00359                     {
00360                          /* no memory */
00361                         FreeItem(Ctx);
00362                         Ctx = NULL;
00363                         Status = STATUS_INSUFFICIENT_RESOURCES;
00364                     }
00365                     else
00366                     {
00367                         /* store device header for post-start pnp processing */
00368                         Ctx->DeviceHeader = DeviceHeader;
00369                     }
00370                 }
00371             }
00372             else
00373             {
00374                 /* set state to enabled, IRP_MJ_CREATE request may now succeed */
00375                 DeviceHeader->TargetState = KSTARGET_STATE_ENABLED;
00376                 Status = KspSetFilterFactoriesState(DeviceHeader, TRUE);
00377             }
00378         }
00379         else
00380         {
00381             /* set state to run */
00382             DeviceHeader->KsDevice.Started = TRUE;
00383         }
00384     }
00385 
00386     /* store result */
00387     Irp->IoStatus.Status = Status;
00388     /* complete request */
00389     CompleteRequest(Irp, IO_NO_INCREMENT);
00390 
00391     if (Ctx)
00392     {
00393         /* queue a work item for driver post start routine */
00394         IoQueueWorkItem(Ctx->WorkItem, IKsDevice_PnpPostStart, DelayedWorkQueue, (PVOID)Ctx);
00395     }
00396 
00397     /* return result */
00398     DPRINT("IKsDevice_PnpStartDevice Status %x PostStartRoutine %p\n", Status, Ctx);
00399     return Status;
00400 }
00401 
00402 NTSTATUS
00403 NTAPI
00404 IKsDevice_Pnp(
00405     IN PDEVICE_OBJECT  DeviceObject,
00406     IN PIRP Irp)
00407 {
00408     PIO_STACK_LOCATION IoStack;
00409     PDEVICE_EXTENSION DeviceExtension;
00410     PKSIDEVICE_HEADER DeviceHeader;
00411     PKSDEVICE_DISPATCH Dispatch = NULL;
00412     NTSTATUS Status;
00413 
00414     /* get current stack location */
00415     IoStack = IoGetCurrentIrpStackLocation(Irp);
00416 
00417     /* get device extension */
00418     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00419     /* get device header */
00420     DeviceHeader = DeviceExtension->DeviceHeader;
00421 
00422     /* do we have a device descriptor */
00423     if (DeviceHeader->KsDevice.Descriptor && DeviceHeader->KsDevice.Descriptor->Dispatch)
00424     {
00425         /* does the device want pnp notifications */
00426         Dispatch = (PKSDEVICE_DISPATCH)DeviceHeader->KsDevice.Descriptor->Dispatch;
00427     }
00428 
00429     switch (IoStack->MinorFunction)
00430     {
00431         case IRP_MN_START_DEVICE:
00432         {
00433             return IKsDevice_PnpStartDevice(DeviceObject, Irp);
00434         }
00435 
00436         case IRP_MN_QUERY_STOP_DEVICE:
00437         {
00438             Status = STATUS_SUCCESS;
00439             /* check for pnp notification support */
00440             if (Dispatch)
00441             {
00442                 /* check for query stop support */
00443                 if (Dispatch->QueryStop)
00444                 {
00445                     /* call driver's query stop */
00446                     Status = Dispatch->QueryStop(&DeviceHeader->KsDevice, Irp);
00447                     ASSERT(Status != STATUS_PENDING);
00448                 }
00449             }
00450 
00451             if (!NT_SUCCESS(Status))
00452             {
00453                 DPRINT1("Driver: query stop failed %x\n", Status);
00454                 Irp->IoStatus.Status = Status;
00455                 CompleteRequest(Irp, IO_NO_INCREMENT);
00456                 return Status;
00457             }
00458 
00459             /* pass the irp down the driver stack */
00460             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00461 
00462             DPRINT("Next Device: Status %x\n", Status);
00463 
00464             Irp->IoStatus.Status = Status;
00465             CompleteRequest(Irp, IO_NO_INCREMENT);
00466             return Status;
00467         }
00468 
00469         case IRP_MN_REMOVE_DEVICE:
00470         {
00471             /* Clean up */
00472             if (Dispatch)
00473             {
00474                 /* check for remove support */
00475                 if (Dispatch->Remove)
00476                 {
00477                     /* call driver's stop routine */
00478                     Dispatch->Remove(&DeviceHeader->KsDevice, Irp);
00479                 }
00480             }
00481 
00482             /* pass the irp down the driver stack */
00483             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00484 
00485             DPRINT("Next Device: Status %x\n", Status);
00486 
00487             /* FIXME delete device resources */
00488 
00489 
00490             Irp->IoStatus.Status = Status;
00491             CompleteRequest(Irp, IO_NO_INCREMENT);
00492             return Status;
00493         }
00494         case IRP_MN_QUERY_INTERFACE:
00495         {
00496             Status = STATUS_UNSUCCESSFUL;
00497             /* check for pnp notification support */
00498             if (Dispatch)
00499             {
00500                 /* check for query interface support */
00501                 if (Dispatch->QueryInterface)
00502                 {
00503                     /* call driver's query interface */
00504                     Status = Dispatch->QueryInterface(&DeviceHeader->KsDevice, Irp);
00505                     ASSERT(Status != STATUS_PENDING);
00506                 }
00507             }
00508 
00509             if (NT_SUCCESS(Status))
00510             {
00511                 /* driver supports a private interface */
00512                 DPRINT1("IRP_MN_QUERY_INTERFACE Device supports interface\n");
00513                 Irp->IoStatus.Status = Status;
00514                 CompleteRequest(Irp, IO_NO_INCREMENT);
00515                 return Status;
00516             }
00517 
00518             /* pass the irp down the driver stack */
00519             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00520 
00521             DPRINT1("IRP_MN_QUERY_INTERFACE Next Device: Status %x\n", Status);
00522             Irp->IoStatus.Status = Status;
00523             CompleteRequest(Irp, IO_NO_INCREMENT);
00524             return Status;
00525         }
00526         case IRP_MN_QUERY_DEVICE_RELATIONS:
00527         {
00528             /* pass the irp down the driver stack */
00529             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00530 
00531             DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS Next Device: Status %x\n", Status);
00532 
00533             //Irp->IoStatus.Status = Status;
00534             CompleteRequest(Irp, IO_NO_INCREMENT);
00535             return Status;
00536         }
00537         case IRP_MN_FILTER_RESOURCE_REQUIREMENTS:
00538         {
00539             /* pass the irp down the driver stack */
00540             //Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00541             Status = Irp->IoStatus.Status;
00542             DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
00543 
00544             //Irp->IoStatus.Status = Status;
00545             CompleteRequest(Irp, IO_NO_INCREMENT);
00546             return Status;
00547         }
00548        case IRP_MN_QUERY_RESOURCE_REQUIREMENTS:
00549        {
00550             /* pass the irp down the driver stack */
00551             Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00552 
00553             DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS Next Device: Status %x\n", Status);
00554 
00555             Irp->IoStatus.Status = Status;
00556             CompleteRequest(Irp, IO_NO_INCREMENT);
00557             return Status;
00558        }
00559        default:
00560           DPRINT1("unhandled function %u\n", IoStack->MinorFunction);
00561           /* pass the irp down the driver stack */
00562           Status = KspForwardIrpSynchronous(DeviceObject, Irp);
00563 
00564           Irp->IoStatus.Status = Status;
00565           CompleteRequest(Irp, IO_NO_INCREMENT);
00566           return Status;
00567     }
00568 }
00569 
00570 NTSTATUS
00571 NTAPI
00572 IKsDevice_Power(
00573     IN PDEVICE_OBJECT  DeviceObject,
00574     IN PIRP Irp)
00575 {
00576     UNIMPLEMENTED
00577 
00578     /* TODO */
00579 
00580     Irp->IoStatus.Status = STATUS_SUCCESS;
00581     Irp->IoStatus.Information = 0;
00582     CompleteRequest(Irp, IO_NO_INCREMENT);
00583 
00584     return STATUS_SUCCESS;
00585 }
00586 
00587 NTSTATUS
00588 NTAPI
00589 IKsDevice_Create(
00590     IN PDEVICE_OBJECT  DeviceObject,
00591     IN PIRP Irp)
00592 {
00593     PCREATE_ITEM_ENTRY CreateItemEntry;
00594     PIO_STACK_LOCATION IoStack;
00595     PDEVICE_EXTENSION DeviceExtension;
00596     PKSIDEVICE_HEADER DeviceHeader;
00597     PKSIOBJECT_HEADER ObjectHeader;
00598     NTSTATUS Status;
00599 
00600     DPRINT("IKsDevice_Create\n");
00601     /* get current stack location */
00602     IoStack = IoGetCurrentIrpStackLocation(Irp);
00603     /* get device extension */
00604     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
00605     /* get device header */
00606     DeviceHeader = DeviceExtension->DeviceHeader;
00607 
00608     if (IoStack->FileObject->FileName.Buffer == NULL)
00609     {
00610         // ReactOS PnPMgr still sucks
00611         ASSERT(IoStack->FileObject->FileName.Length == 0);
00612         Irp->IoStatus.Status = STATUS_SUCCESS;
00613         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00614         DPRINT1("ReactOS PnP hack\n");
00615         return STATUS_SUCCESS;
00616     }
00617 
00618     /* acquire list lock */
00619     IKsDevice_fnAcquireDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
00620 
00621     /* sanity check */
00622     ASSERT(IoStack->FileObject);
00623 
00624     /* check if the request is relative */
00625     if (IoStack->FileObject->RelatedFileObject != NULL)
00626     {
00627         /* request is to instantiate a pin / node / clock / allocator */
00628         ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2;
00629 
00630         /* sanity check */
00631         ASSERT(ObjectHeader);
00632 
00633         /* find a matching a create item */
00634         Status = FindMatchingCreateItem(&ObjectHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
00635     }
00636     else
00637     {
00638         /* request to create a filter */
00639         Status = FindMatchingCreateItem(&DeviceHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
00640     }
00641 
00642     if (NT_SUCCESS(Status))
00643     {
00644         /* set object create item */
00645         KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
00646 
00647         /* call create function */
00648         Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
00649 
00650         if (NT_SUCCESS(Status))
00651         {
00652             /* increment create item reference count */
00653             InterlockedIncrement(&CreateItemEntry->ReferenceCount);
00654         }
00655     }
00656 
00657     /* release list lock */
00658     IKsDevice_fnReleaseDevice((IKsDevice*)&DeviceHeader->BasicHeader.OuterUnknown);
00659 
00660     /* done */
00661     return Status;
00662 
00663 
00664 }
00665 
00666 /*
00667     @implemented
00668 */
00669 KSDDKAPI
00670 NTSTATUS
00671 NTAPI
00672 KsInitializeDevice(
00673     IN PDEVICE_OBJECT FunctionalDeviceObject,
00674     IN PDEVICE_OBJECT PhysicalDeviceObject,
00675     IN PDEVICE_OBJECT NextDeviceObject,
00676     IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL)
00677 {
00678     PDEVICE_EXTENSION DeviceExtension;
00679     PKSIDEVICE_HEADER Header;
00680     ULONG Index;
00681     PKSIOBJECT_BAG Bag;
00682     NTSTATUS Status = STATUS_SUCCESS;
00683 
00684     DPRINT1("KsInitializeDevice Descriptor %p\n", Descriptor);
00685 
00686     /* get device extension */
00687     DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
00688 
00689     /* first allocate device header */
00690     Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 0, NULL);
00691 
00692     /* point to allocated header */
00693     Header = DeviceExtension->DeviceHeader;
00694 
00695     DPRINT1("DeviceHeader %p\n", DeviceExtension->DeviceHeader);
00696 
00697     if (Descriptor && Descriptor->Dispatch)
00698     {
00699         DPRINT("Descriptor Add %p\n", Descriptor->Dispatch->Add);
00700         DPRINT("Descriptor Start %p\n", Descriptor->Dispatch->Start);
00701         DPRINT("Descriptor PostStart %p\n", Descriptor->Dispatch->PostStart);
00702         DPRINT("Descriptor QueryStop %p\n", Descriptor->Dispatch->QueryStop);
00703         DPRINT("Descriptor CancelStop %p\n", Descriptor->Dispatch->CancelStop);
00704         DPRINT("Descriptor Stop %p\n", Descriptor->Dispatch->Stop);
00705         DPRINT("Descriptor QueryRemove %p\n", Descriptor->Dispatch->QueryRemove);
00706         DPRINT("Descriptor CancelRemove %p\n", Descriptor->Dispatch->CancelRemove);
00707         DPRINT("Descriptor Remove %p\n", Descriptor->Dispatch->Remove);
00708         DPRINT("Descriptor QueryCapabilities %p\n", Descriptor->Dispatch->QueryCapabilities);
00709         DPRINT("Descriptor SurpriseRemoval %p\n", Descriptor->Dispatch->SurpriseRemoval);
00710         DPRINT("Descriptor QueryPower %p\n", Descriptor->Dispatch->QueryPower);
00711         DPRINT("Descriptor SetPower %p\n", Descriptor->Dispatch->SetPower);
00712         DPRINT("Descriptor QueryInterface %p\n", Descriptor->Dispatch->QueryInterface);
00713     }
00714 
00715     /* check for success */
00716     if (!NT_SUCCESS(Status))
00717     {
00718         DPRINT1("KsInitializeDevice Failed to allocate device header with %x\n", Status);
00719         return Status;
00720     }
00721 
00722     /* initialize IKsDevice interface */
00723     Header->BasicHeader.OuterUnknown = (PUNKNOWN)&vt_IKsDevice;
00724     Header->ref = 1;
00725 
00726     /* allocate object bag */
00727     Header->KsDevice.Bag = AllocateItem(NonPagedPool, sizeof(KSIOBJECT_BAG));
00728     if (!Header->KsDevice.Bag)
00729     {
00730         /* no memory */
00731         KsFreeDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader);
00732         return STATUS_INSUFFICIENT_RESOURCES;
00733     }
00734 
00735     /* initialize object bag */
00736     KeInitializeMutex(&Header->BagMutex, 0);
00737     KeInitializeMutex(&Header->DeviceMutex, 0);
00738 
00739     Bag = (PKSIOBJECT_BAG)Header->KsDevice.Bag;
00740     Bag->BagMutex = &Header->BagMutex;
00741     InitializeListHead(&Header->ObjectBags);
00742     InitializeListHead(&Bag->ObjectList);
00743     Bag->DeviceHeader = (PVOID)Header;
00744 
00745     /* insert bag into device list */
00746     InsertTailList(&Header->ObjectBags, &Bag->Entry);
00747 
00748     /* initialize device header */
00749     Header->KsDevice.FunctionalDeviceObject = FunctionalDeviceObject;
00750     Header->KsDevice.PhysicalDeviceObject = PhysicalDeviceObject;
00751     Header->KsDevice.NextDeviceObject = NextDeviceObject;
00752     Header->KsDevice.Descriptor = Descriptor;
00753     Header->KsDevice.SystemPowerState = PowerSystemWorking;
00754     Header->KsDevice.DevicePowerState = PowerDeviceD0;
00755     Header->KsDevice.Started = FALSE;
00756     Header->KsDevice.Context = NULL;
00757     KsSetDevicePnpAndBaseObject(Header, PhysicalDeviceObject, NextDeviceObject);
00758 
00759 
00760 
00761     if (Descriptor)
00762     {
00763         /* create a filter factory for each filter descriptor */
00764         DPRINT("KsInitializeDevice FilterDescriptorCount %lu\n", Descriptor->FilterDescriptorsCount);
00765         for(Index = 0; Index < Descriptor->FilterDescriptorsCount; Index++)
00766         {
00767             Status = KspCreateFilterFactory(FunctionalDeviceObject, Descriptor->FilterDescriptors[Index], NULL, NULL, 0, NULL, NULL, NULL);
00768 
00769             DPRINT("KsInitializeDevice Index %lu KspCreateFilterFactory Status %lx\n", Index, Status);
00770             /* check for success */
00771             if (!NT_SUCCESS(Status))
00772             {
00773                 DPRINT1("KspCreateFilterFactory failed with %x\n", Status);
00774                 /* FIXME memory leak */
00775                 return Status;
00776             }
00777         }
00778 
00779         /* does the driver pnp notification */
00780         if (Descriptor->Dispatch)
00781         {
00782             /* does the driver care about the add device */
00783             Status = Descriptor->Dispatch->Add(&Header->KsDevice);
00784 
00785             DPRINT("Driver: AddHandler Status %x\n", Status);
00786             Header->KsDevice.Descriptor = Descriptor;
00787         }
00788     }
00789 
00790 
00791    return Status;
00792 }
00793 
00794 /*
00795     @implemented
00796 */
00797 KSDDKAPI
00798 NTSTATUS
00799 NTAPI
00800 KsReferenceSoftwareBusObject(
00801     IN KSDEVICE_HEADER  Header)
00802 {
00803      IKsDevice * Device;
00804      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
00805 
00806      /* get device interface */
00807      Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
00808 
00809      if (Device)
00810      {
00811          /* reference device interface */
00812          Device->lpVtbl->AddRef(Device);
00813      }
00814 
00815     return STATUS_SUCCESS;
00816 }
00817 
00818 /*
00819     @implemented
00820 */
00821 KSDDKAPI
00822 NTSTATUS
00823 NTAPI
00824 KsReferenceBusObject(
00825     IN  KSDEVICE_HEADER Header)
00826 {
00827      IKsDevice * Device;
00828      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
00829 
00830      /* get device interface */
00831      Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
00832 
00833      if (Device)
00834      {
00835          /* reference device interface */
00836          Device->lpVtbl->AddRef(Device);
00837      }
00838 
00839     return STATUS_SUCCESS;
00840 
00841 }
00842 
00843 /*
00844     @implemented
00845 */
00846 KSDDKAPI
00847 VOID
00848 NTAPI
00849 KsDereferenceBusObject(
00850     IN  KSDEVICE_HEADER Header)
00851 {
00852      IKsDevice * Device;
00853      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
00854 
00855      /* get device interface */
00856      Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
00857 
00858      if (Device)
00859      {
00860          /* release device interface */
00861          Device->lpVtbl->Release(Device);
00862      }
00863 }
00864 
00865 /*
00866     @implemented
00867 */
00868 KSDDKAPI
00869 VOID
00870 NTAPI
00871 KsDereferenceSoftwareBusObject(
00872     IN KSDEVICE_HEADER  Header)
00873 {
00874      IKsDevice * Device;
00875      PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
00876 
00877      DPRINT("KsDereferenceSoftwareBusObject DeviceHeader %p\n", Header);
00878 
00879      /* get device interface */
00880      Device = (IKsDevice*)DeviceHeader->BasicHeader.OuterUnknown;
00881 
00882      if (Device)
00883      {
00884          /* release device interface */
00885          Device->lpVtbl->Release(Device);
00886      }
00887 }

Generated on Sun May 27 2012 04:21:22 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.