CPCTimeValue CPCTimeValue::TickCount() { #if defined(_WIN32) static LARGE_INTEGER TicksPerSecond = { 0 }; if (!TicksPerSecond.QuadPart) { QueryPerformanceFrequency(&TicksPerSecond); } LARGE_INTEGER Tick; QueryPerformanceCounter(&Tick); long long Seconds = Tick.QuadPart / TicksPerSecond.QuadPart; long long LeftPart = Tick.QuadPart - (TicksPerSecond.QuadPart*Seconds); long long MillSeconds = LeftPart * 1000 / TicksPerSecond.QuadPart; long long nRet = Seconds * 1000 + MillSeconds; PC_ASSERT(nRet > 0, "nRet <= 0"); return CPCTimeValue(nRet); #else /* 需要加上编译选项 -lrt */ struct timespec ts; int nRet = clock_gettime(CLOCK_MONOTONIC, &ts); PC_ASSERT(nRet == 0, "clock_gettime fail!"); return CPCTimeValue((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000)); #endif }
NTSTATUS NTAPI PinWavePciAllocatorFraming( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { CPortPinWavePci *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->PortPin); PC_ASSERT_IRQL(DISPATCH_LEVEL); // cast to pin impl Pin = (CPortPinWavePci*)Descriptor->PortPin; if (Request->Flags & KSPROPERTY_TYPE_GET) { // copy pin framing RtlMoveMemory(Data, &Pin->m_AllocatorFraming, sizeof(KSALLOCATOR_FRAMING)); Irp->IoStatus.Information = sizeof(KSALLOCATOR_FRAMING); return STATUS_SUCCESS; } // not supported return STATUS_NOT_SUPPORTED; }
NTAPI KsoGetIrpTargetFromFileObject( PFILE_OBJECT FileObject) { PC_ASSERT(FileObject); // IrpTarget is stored in FsContext return (IIrpTarget*)FileObject->FsContext; }
NTSTATUS NTAPI PcCompleteIrp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN NTSTATUS Status) { #if 0 PC_ASSERT(DeviceObject); PC_ASSERT(Irp); PC_ASSERT(Status != STATUS_PENDING); #endif Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI CPortWaveCyclic::GetDescriptor( IN SUBDEVICE_DESCRIPTOR ** Descriptor) { PC_ASSERT(m_SubDeviceDescriptor != NULL); *Descriptor = m_SubDeviceDescriptor; DPRINT("ISubDevice_GetDescriptor this %p desc %p\n", this, m_SubDeviceDescriptor); return STATUS_SUCCESS; }
PCLIB_NAMESPACE_BEG ////////////////////////////////////////////////////////////////////////// CPCTimeValue& CPCTimeValue::operator= (const char * pszTimeStamp) { if (pszTimeStamp == NULL || strlen(pszTimeStamp) != PC_TIMESTAMP_LEN) { PC_ASSERT(true, "param error!pszTimeStmp=%s", pszTimeStamp); return *this; } //解析原串到tm结构体 struct tm tmTimeMsValue; char szYear[5] = { 0 }, szMonth[3] = { 0 }, szDay[3] = { 0 }, szHour[3] = { 0 }, szMinute[3] = { 0 }, szSecond[3] = { 0 }; memcpy(szYear, pszTimeStamp, 4); memcpy(szMonth, pszTimeStamp + 5, 2); memcpy(szDay, pszTimeStamp + 8, 2); memcpy(szHour, pszTimeStamp + 11, 2); memcpy(szMinute, pszTimeStamp + 14, 2); memcpy(szSecond, pszTimeStamp + 17, 2); tmTimeMsValue.tm_year = atoi(szYear) - 1900; tmTimeMsValue.tm_mon = atoi(szMonth) - 1; tmTimeMsValue.tm_mday = atoi(szDay); tmTimeMsValue.tm_hour = atoi(szHour); tmTimeMsValue.tm_min = atoi(szMinute); tmTimeMsValue.tm_sec = atoi(szSecond); //tm转换为秒数 time_t tMakeTime = mktime(&tmTimeMsValue) * 1000; if (tMakeTime < 0) { PC_ASSERT(true, "mktime error!pszTimeStmp=%s", pszTimeStamp); return *this; } m_TimeMsValue = tMakeTime; return *this; }
NTSTATUS NTAPI PinWavePciAudioPosition( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { CPortPinWavePci *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->PortPin); PC_ASSERT_IRQL(DISPATCH_LEVEL); // cast to pin impl Pin = (CPortPinWavePci*)Descriptor->PortPin; //sanity check PC_ASSERT(Pin->m_Stream); if (Request->Flags & KSPROPERTY_TYPE_GET) { // FIXME non multithreading-safe // copy audio position RtlMoveMemory(Data, &Pin->m_Position, sizeof(KSAUDIO_POSITION)); DPRINT("Play %lu Record %lu\n", Pin->m_Position.PlayOffset, Pin->m_Position.WriteOffset); Irp->IoStatus.Information = sizeof(KSAUDIO_POSITION); return STATUS_SUCCESS; } // not supported return STATUS_NOT_SUPPORTED; }
NTSTATUS HandleDataIntersection( IN PIO_STATUS_BLOCK IoStatus, IN PKSIDENTIFIER Request, IN OUT PVOID Data, IN ULONG DataLength, IN PSUBDEVICE_DESCRIPTOR Descriptor, IN ISubdevice *SubDevice) { KSP_PIN * Pin = (KSP_PIN*)Request; PKSMULTIPLE_ITEM MultipleItem; PKSDATARANGE DataRange; NTSTATUS Status = STATUS_NO_MATCH; ULONG Index, Length; // Access parameters MultipleItem = (PKSMULTIPLE_ITEM)(Pin + 1); DataRange = (PKSDATARANGE)(MultipleItem + 1); for(Index = 0; Index < MultipleItem->Count; Index++) { // Call miniport's proprietary handler PC_ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRangesCount); PC_ASSERT(Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0]); Status = SubDevice->DataRangeIntersection(Pin->PinId, DataRange, (PKSDATARANGE)Descriptor->Factory.KsPinDescriptor[Pin->PinId].DataRanges[0], DataLength, Data, &Length); if (Status == STATUS_SUCCESS) { IoStatus->Information = Length; break; } DataRange = (PKSDATARANGE)((PUCHAR)DataRange + DataRange->FormatSize); } IoStatus->Status = Status; return Status; }
CPCTimeValue CPCTimeValue::Now() { #if defined (_WIN32) struct timeb tbTime; ftime(&tbTime); return CPCTimeValue(tbTime.time * 1000 + tbTime.millitm); #else /* 需要加上编译选项 -lrt */ struct timespec ts; int nRet = clock_gettime(CLOCK_REALTIME, &ts); PC_ASSERT(nRet == 0, "clock_gettime fail!"); return CPCTimeValue((ts.tv_sec * 1000) + (ts.tv_nsec / 1000000)); #endif }
VOID NTAPI CPortDMus::Notify( IN PSERVICEGROUP ServiceGroup OPTIONAL) { if (ServiceGroup) { ServiceGroup->RequestService (); return; } PC_ASSERT(m_ServiceGroup); // notify miniport service group m_ServiceGroup->RequestService(); // notify stream miniport service group if (m_Filter) { m_Filter->NotifyPins(); } }
NTSTATUS NTAPI PcCreateItemDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; ISubdevice * SubDevice; IIrpTarget *Filter; PKSOBJECT_CREATE_ITEM CreateItem, PinCreateItem; // access the create item CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); DPRINT("PcCreateItemDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer); // get the subdevice SubDevice = (ISubdevice*)CreateItem->Context; // sanity checks PC_ASSERT(SubDevice != NULL); #if KS_IMPLEMENTED Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) { DPRINT("PcCreateItemDispatch failed to reference device header\n"); FreeItem(Entry, TAG_PORTCLASS); goto cleanup; } #endif // get filter object Status = SubDevice->NewIrpTarget(&Filter, NULL, NULL, NonPagedPool, DeviceObject, Irp, NULL); if (!NT_SUCCESS(Status)) { DPRINT("Failed to get filter object\n"); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } // allocate pin create item PinCreateItem = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS); if (!PinCreateItem) { // not enough memory Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } // initialize pin create item PinCreateItem->Context = (PVOID)Filter; PinCreateItem->Create = PcCreatePinDispatch; RtlInitUnicodeString(&PinCreateItem->ObjectClass, KSSTRING_Pin); // FIXME copy security descriptor // now allocate a dispatch object Status = NewDispatchObject(Irp, Filter, 1, PinCreateItem); // complete request Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }
//------------------------------------------------------------------------------------------------- NTSTATUS CHCDController::HandleDeviceControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IoStack; PCOMMON_DEVICE_EXTENSION DeviceExtension; NTSTATUS Status = STATUS_NOT_IMPLEMENTED; PUSB_HCD_DRIVERKEY_NAME DriverKey; ULONG ResultLength; // // get current stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); // // get device extension // DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // sanity check // PC_ASSERT(DeviceExtension->IsFDO); DPRINT1("[%s] HandleDeviceControl>Type: IoCtl %x InputBufferLength %lu OutputBufferLength %lu\n", m_USBType, IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.InputBufferLength, IoStack->Parameters.DeviceIoControl.OutputBufferLength); // // perform ioctl for FDO // if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_GET_HCD_DRIVERKEY_NAME) { // // check if sizee is at least >= USB_HCD_DRIVERKEY_NAME // if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME)) { // // get device property size // Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, 0, NULL, &ResultLength); // // get input buffer // DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer; // // check result // if (Status == STATUS_BUFFER_TOO_SMALL) { // // does the caller provide enough buffer space // if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= ResultLength) { // // it does // Status = IoGetDeviceProperty(m_PhysicalDeviceObject, DevicePropertyDriverKeyName, IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength); } // // store result // DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR); Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength; Status = STATUS_SUCCESS; } } else { // // buffer is certainly too small // Status = STATUS_BUFFER_OVERFLOW; Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME); } } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_USB_GET_ROOT_HUB_NAME) { // // check if sizee is at least >= USB_HCD_DRIVERKEY_NAME // if(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(USB_HCD_DRIVERKEY_NAME)) { // // sanity check // PC_ASSERT(m_HubController); // // get input buffer // DriverKey = (PUSB_HCD_DRIVERKEY_NAME)Irp->AssociatedIrp.SystemBuffer; // // get symbolic link // Status = m_HubController->GetHubControllerSymbolicLink(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG), DriverKey->DriverKeyName, &ResultLength); if (NT_SUCCESS(Status)) { // // null terminate it // PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength - sizeof(ULONG) - sizeof(WCHAR) >= ResultLength); DriverKey->DriverKeyName[ResultLength / sizeof(WCHAR)] = L'\0'; } // // store result // DriverKey->ActualLength = ResultLength + FIELD_OFFSET(USB_HCD_DRIVERKEY_NAME, DriverKeyName) + sizeof(WCHAR); Irp->IoStatus.Information = IoStack->Parameters.DeviceIoControl.OutputBufferLength; Status = STATUS_SUCCESS; } else { // // buffer is certainly too small // Status = STATUS_BUFFER_OVERFLOW; Irp->IoStatus.Information = sizeof(USB_HCD_DRIVERKEY_NAME); } } // // complete the request // Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // // done // return Status; }
//------------------------------------------------------------------------------------------------- NTSTATUS CHCDController::Initialize( IN PROOTHDCCONTROLLER RootHCDController, IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject) { NTSTATUS Status; PCOMMON_DEVICE_EXTENSION DeviceExtension; // // create usb hardware // Status = CreateUSBHardware(&m_Hardware); if (!NT_SUCCESS(Status)) { // // failed to create hardware object // DPRINT1("Failed to create hardware object\n"); return STATUS_INSUFFICIENT_RESOURCES; } // // initialize members // m_DriverObject = DriverObject; m_PhysicalDeviceObject = PhysicalDeviceObject; m_RootController = RootHCDController; // // create FDO // Status = CreateFDO(m_DriverObject, &m_FunctionalDeviceObject); if (!NT_SUCCESS(Status)) { // // failed to create PDO // return Status; } // // now attach to device stack // m_NextDeviceObject = IoAttachDeviceToDeviceStack(m_FunctionalDeviceObject, m_PhysicalDeviceObject); if (!m_NextDeviceObject) { // // failed to attach to device stack // IoDeleteDevice(m_FunctionalDeviceObject); m_FunctionalDeviceObject = 0; return STATUS_NO_SUCH_DEVICE; } // // initialize hardware object // Status = m_Hardware->Initialize(m_DriverObject, m_FunctionalDeviceObject, m_PhysicalDeviceObject, m_NextDeviceObject); if (!NT_SUCCESS(Status)) { DPRINT1("[%s] Failed to initialize hardware object %x\n", m_Hardware->GetUSBType(), Status); // // failed to initialize hardware object, detach from device stack // IoDetachDevice(m_NextDeviceObject); // // now delete the device // IoDeleteDevice(m_FunctionalDeviceObject); // // nullify pointers :) // m_FunctionalDeviceObject = 0; m_NextDeviceObject = 0; return Status; } // // get usb controller type // m_USBType = m_Hardware->GetUSBType(); // // set device flags // m_FunctionalDeviceObject->Flags |= DO_BUFFERED_IO | DO_POWER_PAGABLE; // // get device extension // DeviceExtension = (PCOMMON_DEVICE_EXTENSION)m_FunctionalDeviceObject->DeviceExtension; PC_ASSERT(DeviceExtension); // // initialize device extension // DeviceExtension->IsFDO = TRUE; DeviceExtension->IsHub = FALSE; DeviceExtension->Dispatcher = PDISPATCHIRP(this); // // device is initialized // m_FunctionalDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING; // // is there a root controller // if (m_RootController) { // // add reference // m_RootController->AddRef(); // // register with controller // m_RootController->RegisterHCD(this); } // // done // return STATUS_SUCCESS; }
NTSTATUS NTAPI PcCreatePinDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; IIrpTarget *Filter; IIrpTarget *Pin; PKSOBJECT_CREATE_ITEM CreateItem; // access the create item CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(CreateItem); DPRINT("PcCreatePinDispatch called DeviceObject %p %S Name\n", DeviceObject, CreateItem->ObjectClass.Buffer); Filter = (IIrpTarget*)CreateItem->Context; // sanity checks PC_ASSERT(Filter != NULL); PC_ASSERT_IRQL(PASSIVE_LEVEL); #if KS_IMPLEMENTED Status = KsReferenceSoftwareBusObject(DeviceExt->KsDeviceHeader); if (!NT_SUCCESS(Status) && Status != STATUS_NOT_IMPLEMENTED) { DPRINT("PcCreatePinDispatch failed to reference device header\n"); FreeItem(Entry, TAG_PORTCLASS); goto cleanup; } #endif Status = Filter->NewIrpTarget(&Pin, KSSTRING_Pin, NULL, NonPagedPool, DeviceObject, Irp, NULL); DPRINT("PcCreatePinDispatch Status %x\n", Status); if (NT_SUCCESS(Status)) { // create the dispatch object // FIXME need create item for clock Status = NewDispatchObject(Irp, Pin, 0, NULL); DPRINT("Pin %p\n", Pin); } DPRINT("CreatePinWorkerRoutine completing irp %p\n", Irp); // save status in irp Irp->IoStatus.Status = Status; Irp->IoStatus.Information = 0; // complete the request IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI PinWavePciState( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { NTSTATUS Status = STATUS_UNSUCCESSFUL; CPortPinWavePci *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; PVOID FirstTag, LastTag; ULONG MappingsRevoked; PKSSTATE State = (PKSSTATE)Data; // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->PortPin); PC_ASSERT_IRQL(DISPATCH_LEVEL); // cast to pin impl Pin = (CPortPinWavePci*)Descriptor->PortPin; //sanity check PC_ASSERT(Pin->m_Stream); if (Request->Flags & KSPROPERTY_TYPE_SET) { // try set stream Status = Pin->m_Stream->SetState(*State); DPRINT("Setting state %u %x\n", *State, Status); if (NT_SUCCESS(Status)) { // store new state Pin->m_State = *State; if (Pin->m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING && Pin->m_State == KSSTATE_STOP) { // FIXME // complete with successful state Pin->m_IrpQueue->CancelBuffers(); while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag)) { Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked); DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked); KeStallExecutionProcessor(10); } Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; } else if (Pin->m_State == KSSTATE_STOP) { Pin->m_IrpQueue->CancelBuffers(); while(Pin->m_IrpQueue->GetAcquiredTagRange(&FirstTag, &LastTag)) { Status = Pin->m_Stream->RevokeMappings(FirstTag, LastTag, &MappingsRevoked); DPRINT("RevokeMappings Status %lx MappingsRevoked: %lu\n", Status, MappingsRevoked); KeStallExecutionProcessor(10); } Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; } // store result Irp->IoStatus.Information = sizeof(KSSTATE); } // store result Irp->IoStatus.Information = sizeof(KSSTATE); return Status; } else if (Request->Flags & KSPROPERTY_TYPE_GET) { // get current stream state *State = Pin->m_State; // store result Irp->IoStatus.Information = sizeof(KSSTATE); return STATUS_SUCCESS; } // unsupported request return STATUS_NOT_SUPPORTED; }
NTSTATUS NTAPI PropertyItemDispatch( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { PPCPROPERTY_REQUEST PropertyRequest; PSUBDEVICE_DESCRIPTOR Descriptor; PKSPROPERTY Property; PPCNODE_DESCRIPTOR NodeDescriptor; PKSNODEPROPERTY NodeProperty; PKSPROPERTY_SET PropertySet; PPCPROPERTY_ITEM PropertyItem; PPCAUTOMATION_TABLE NodeAutomation; PIO_STACK_LOCATION IoStack; ULONG InstanceSize, ValueSize, Index; PVOID Instance; NTSTATUS Status; // allocate a property request PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); if (!PropertyRequest) return STATUS_INSUFFICIENT_RESOURCES; // grab device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); // get input property request Property = (PKSPROPERTY)Request; // get property set PropertySet = (PKSPROPERTY_SET)KSPROPERTY_SET_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->UnknownMiniport); // get instance / value size InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength; Instance = Request; ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; // initialize property request PropertyRequest->MajorTarget = Descriptor->UnknownMiniport; PropertyRequest->MinorTarget = Descriptor->UnknownStream; PropertyRequest->Irp = Irp; PropertyRequest->Verb = Property->Flags; // check if this is filter / pin property request if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY)) { // adjust input buffer size InstanceSize -= sizeof(KSPROPERTY); Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSPROPERTY)); // filter / pin property request dont use node field PropertyRequest->Node = MAXULONG; } else if (InstanceSize >= sizeof(KSNODEPROPERTY)) { // request is for a node InstanceSize -= sizeof(KSNODEPROPERTY); Instance = (PVOID)((ULONG_PTR)Instance + sizeof(KSNODEPROPERTY)); // cast node property request NodeProperty = (PKSNODEPROPERTY)Request; // store node id PropertyRequest->Node = NodeProperty->NodeId; } else { // invalid buffer size return STATUS_INVALID_BUFFER_SIZE; } // store instance size PropertyRequest->InstanceSize = InstanceSize; PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL); // store value size PropertyRequest->ValueSize = ValueSize; PropertyRequest->Value = Data; // now scan the property set for the attached property set item stored in Relations member if (PropertySet) { // sanity check PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set)); for(Index = 0; Index < PropertySet->PropertiesCount; Index++) { // check if they got the same property id if (PropertySet->PropertyItem[Index].PropertyId == Property->Id) { // found item PropertyRequest->PropertyItem = (const PCPROPERTY_ITEM*)PropertySet->PropertyItem[Index].Relations; // done break; } } } // check if there has been a property set item attached if (!PropertyRequest->PropertyItem) { // is topology node id valid if (PropertyRequest->Node < Descriptor->DeviceDescriptor->NodeCount) { // get node descriptor NodeDescriptor = (PPCNODE_DESCRIPTOR) ((ULONG_PTR)Descriptor->DeviceDescriptor->Nodes + PropertyRequest->Node * Descriptor->DeviceDescriptor->NodeSize); // get node automation table NodeAutomation = (PPCAUTOMATION_TABLE)NodeDescriptor->AutomationTable; // has it got a automation table if (NodeAutomation) { // now scan the properties and check if it supports this request PropertyItem = (PPCPROPERTY_ITEM)NodeAutomation->Properties; for(Index = 0; Index < NodeAutomation->PropertyCount; Index++) { // are they same property if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Set)) { if (PropertyItem->Id == Property->Id) { // found match PropertyRequest->PropertyItem = PropertyItem; DPRINT("Using property item %p\n", PropertyItem); // done break; } } // move to next property item PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeAutomation->PropertyItemSize); } } } } if (PropertyRequest->PropertyItem && PropertyRequest->PropertyItem->Handler) { // now call the handler UNICODE_STRING GuidBuffer; RtlStringFromGUID(Property->Set, &GuidBuffer); DPRINT("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p PropertyItemFlags %lx PropertyItemId %lu\n", PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize, PropertyRequest->PropertyItem->Handler, PropertyRequest, PropertyRequest->PropertyItem->Flags, PropertyRequest->PropertyItem->Id); RtlFreeUnicodeString(&GuidBuffer); Status = PropertyRequest->PropertyItem->Handler(PropertyRequest); DPRINT("Status %lx ValueSize %lu Information %lu\n", Status, PropertyRequest->ValueSize, Irp->IoStatus.Information); Irp->IoStatus.Information = PropertyRequest->ValueSize; if (Status != STATUS_PENDING) { // free property request FreeItem(PropertyRequest, TAG_PORTCLASS); } } else { FreeItem(PropertyRequest, TAG_PORTCLASS); Status = STATUS_NOT_FOUND; } /* done */ return Status; }
NTSTATUS NTAPI PinWavePciDataFormat( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { NTSTATUS Status = STATUS_UNSUCCESSFUL; CPortPinWavePci *Pin; PSUBDEVICE_DESCRIPTOR Descriptor; PIO_STACK_LOCATION IoStack; // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); // get sub device descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); // sanity check PC_ASSERT(Descriptor); PC_ASSERT(Descriptor->PortPin); // cast to pin impl Pin = (CPortPinWavePci*)Descriptor->PortPin; //sanity check PC_ASSERT(Pin->m_Stream); PC_ASSERT(Pin->m_Format); if (Request->Flags & KSPROPERTY_TYPE_SET) { // try to change data format PKSDATAFORMAT NewDataFormat, DataFormat = (PKSDATAFORMAT)Irp->UserBuffer; ULONG Size = min(Pin->m_Format->FormatSize, DataFormat->FormatSize); if (RtlCompareMemory(DataFormat, Pin->m_Format, Size) == Size) { // format is identical Irp->IoStatus.Information = DataFormat->FormatSize; return STATUS_SUCCESS; } // new change request PC_ASSERT(Pin->m_State == KSSTATE_STOP); // FIXME queue a work item when Irql != PASSIVE_LEVEL PC_ASSERT(KeGetCurrentIrql() == PASSIVE_LEVEL); // allocate new data format NewDataFormat = (PKSDATAFORMAT)AllocateItem(NonPagedPool, DataFormat->FormatSize, TAG_PORTCLASS); if (!NewDataFormat) { // not enough memory return STATUS_NO_MEMORY; } // copy new data format RtlMoveMemory(NewDataFormat, DataFormat, DataFormat->FormatSize); // set new format Status = Pin->m_Stream->SetFormat(NewDataFormat); if (NT_SUCCESS(Status)) { // free old format FreeItem(Pin->m_Format, TAG_PORTCLASS); // store new format Pin->m_Format = NewDataFormat; Irp->IoStatus.Information = NewDataFormat->FormatSize; #if 0 PC_ASSERT(NewDataFormat->FormatSize == sizeof(KSDATAFORMAT_WAVEFORMATEX)); PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.MajorFormat, KSDATAFORMAT_TYPE_AUDIO)); PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.SubFormat, KSDATAFORMAT_SUBTYPE_PCM)); PC_ASSERT(IsEqualGUIDAligned(((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->DataFormat.Specifier, KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)); DPRINT("NewDataFormat: Channels %u Bits %u Samples %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)NewDataFormat)->WaveFormatEx.nSamplesPerSec); #endif } else { // failed to set format FreeItem(NewDataFormat, TAG_PORTCLASS); } // done return Status; } else if (Request->Flags & KSPROPERTY_TYPE_GET) { // get current data format PC_ASSERT(Pin->m_Format); if (Pin->m_Format->FormatSize > IoStack->Parameters.DeviceIoControl.OutputBufferLength) { // buffer too small Irp->IoStatus.Information = Pin->m_Format->FormatSize; return STATUS_MORE_ENTRIES; } // copy data format RtlMoveMemory(Data, Pin->m_Format, Pin->m_Format->FormatSize); // store result size Irp->IoStatus.Information = Pin->m_Format->FormatSize; // done return STATUS_SUCCESS; } // unsupported request return STATUS_NOT_SUPPORTED; }
NTSTATUS NTAPI USBLIB_Dispatch( PDEVICE_OBJECT DeviceObject, PIRP Irp) { PCOMMON_DEVICE_EXTENSION DeviceExtension; PIO_STACK_LOCATION IoStack; NTSTATUS Status; // // get common device extension // DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // get current stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); // // sanity checks // PC_ASSERT(DeviceExtension->Dispatcher); switch(IoStack->MajorFunction) { case IRP_MJ_PNP: { // // dispatch pnp // return DeviceExtension->Dispatcher->HandlePnp(DeviceObject, Irp); } case IRP_MJ_POWER: { // // dispatch power // return DeviceExtension->Dispatcher->HandlePower(DeviceObject, Irp); } case IRP_MJ_INTERNAL_DEVICE_CONTROL: case IRP_MJ_DEVICE_CONTROL: { // // dispatch io control // return DeviceExtension->Dispatcher->HandleDeviceControl(DeviceObject, Irp); } case IRP_MJ_SYSTEM_CONTROL: { // // dispatch system control // return DeviceExtension->Dispatcher->HandleSystemControl(DeviceObject, Irp); } default: { DPRINT1("USBLIB_Dispatch> Major %lu Minor %lu unhandeled\n", IoStack->MajorFunction, IoStack->MinorFunction); Status = STATUS_SUCCESS; } } // // complete request // Irp->IoStatus.Information = 0; Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI PortClsPnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; PPCLASS_DEVICE_EXTENSION DeviceExt; PIO_STACK_LOCATION IoStack; POWER_STATE PowerState; IResourceList* resource_list = NULL; //ULONG Index; //PCM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptor, UnPartialDescriptor; DeviceExt = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; IoStack = IoGetCurrentIrpStackLocation(Irp); DPRINT("PortClsPnp called %u\n", IoStack->MinorFunction); //PC_ASSERT(DeviceExt); switch (IoStack->MinorFunction) { case IRP_MN_START_DEVICE: DPRINT("IRP_MN_START_DEVICE\n"); // Create the resource list Status = PcNewResourceList( &resource_list, NULL, PagedPool, IoStack->Parameters.StartDevice.AllocatedResourcesTranslated, IoStack->Parameters.StartDevice.AllocatedResources); if (!NT_SUCCESS(Status)) { DPRINT("PcNewResourceList failed [0x%8x]\n", Status); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } // forward irp to lower device object Status = PcForwardIrpSynchronous(DeviceObject, Irp); if (!NT_SUCCESS(Status)) { // lower device object failed to start resource_list->Release(); // complete the request IoCompleteRequest(Irp, IO_NO_INCREMENT); // return result return Status; } // sanity check //PC_ASSERT(DeviceExt->StartDevice); // Call the StartDevice routine DPRINT("Calling StartDevice at 0x%8p\n", DeviceExt->StartDevice); Status = DeviceExt->StartDevice(DeviceObject, Irp, resource_list); if (!NT_SUCCESS(Status)) { DPRINT("StartDevice returned a failure code [0x%8x]\n", Status); Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; } // Assign the resource list to our extension DeviceExt->resources = resource_list; // store device power state DeviceExt->DevicePowerState = PowerDeviceD0; DeviceExt->SystemPowerState = PowerSystemWorking; // notify power manager of current state PowerState = *((POWER_STATE*)&DeviceExt->DevicePowerState); PoSetPowerState(DeviceObject, DevicePowerState, PowerState); Irp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; case IRP_MN_REMOVE_DEVICE: // Clean up DPRINT("IRP_MN_REMOVE_DEVICE\n"); // sanity check PC_ASSERT(DeviceExt); // FIXME more cleanup */ if (DeviceExt->resources) { // free resource list */ DeviceExt->resources->Release(); // set to null DeviceExt->resources = NULL; } // Forward request Status = PcForwardIrpSynchronous(DeviceObject, Irp); return PcCompleteIrp(DeviceObject, Irp, Status); case IRP_MN_QUERY_INTERFACE: DPRINT("IRP_MN_QUERY_INTERFACE\n"); Status = PcForwardIrpSynchronous(DeviceObject, Irp); return PcCompleteIrp(DeviceObject, Irp, Status); case IRP_MN_QUERY_DEVICE_RELATIONS: DPRINT("IRP_MN_QUERY_DEVICE_RELATIONS\n"); Status = PcForwardIrpSynchronous(DeviceObject, Irp); return PcCompleteIrp(DeviceObject, Irp, Status); case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: DPRINT("IRP_MN_FILTER_RESOURCE_REQUIREMENTS\n"); Status = PcForwardIrpSynchronous(DeviceObject, Irp); return PcCompleteIrp(DeviceObject, Irp, Status); case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: DPRINT("IRP_MN_QUERY_RESOURCE_REQUIREMENTS\n"); Status = PcForwardIrpSynchronous(DeviceObject, Irp); return PcCompleteIrp(DeviceObject, Irp, Status); case IRP_MN_READ_CONFIG: DPRINT("IRP_MN_READ_CONFIG\n"); Status = PcForwardIrpSynchronous(DeviceObject, Irp); return PcCompleteIrp(DeviceObject, Irp, Status); } DPRINT("unhandled function %u\n", IoStack->MinorFunction); Status = Irp->IoStatus.Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI PortClsPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IoStack; PPCLASS_DEVICE_EXTENSION DeviceExtension; PQUERY_POWER_CONTEXT PwrContext; POWER_STATE PowerState; NTSTATUS Status = STATUS_SUCCESS; DPRINT("PortClsPower called\n"); // get currrent stack location IoStack = IoGetCurrentIrpStackLocation(Irp); if (IoStack->MinorFunction != IRP_MN_SET_POWER && IoStack->MinorFunction != IRP_MN_QUERY_POWER) { // just forward the request Status = PcForwardIrpSynchronous(DeviceObject, Irp); // start next power irp PoStartNextPowerIrp(Irp); // complete request Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // done return Status; } // get device extension DeviceExtension = (PPCLASS_DEVICE_EXTENSION) DeviceObject->DeviceExtension; // get current request type if (IoStack->Parameters.Power.Type == DevicePowerState) { // request for device power state if (DeviceExtension->DevicePowerState == IoStack->Parameters.Power.State.DeviceState) { // nothing has changed if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) { // only forward query requests Status = PcForwardIrpSynchronous(DeviceObject, Irp); } // start next power irp PoStartNextPowerIrp(Irp); // complete request Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // done return Status; } if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) { // check if there is a registered adapter power management if (DeviceExtension->AdapterPowerManagement) { // it is query if the change can be changed PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState); Status = DeviceExtension->AdapterPowerManagement->QueryPowerChangeState(PowerState); // sanity check PC_ASSERT(Status == STATUS_SUCCESS); } // only forward query requests PcForwardIrpSynchronous(DeviceObject, Irp); // start next power irp PoStartNextPowerIrp(Irp); // complete request Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // done return Status; } else { // set power state PowerState = *((POWER_STATE*)&IoStack->Parameters.Power.State.DeviceState); PoSetPowerState(DeviceObject, DevicePowerState, PowerState); // check if there is a registered adapter power management if (DeviceExtension->AdapterPowerManagement) { // notify of a power change state DeviceExtension->AdapterPowerManagement->PowerChangeState(PowerState); } // FIXME call all registered IPowerNotify interfaces via ISubdevice interface // store new power state DeviceExtension->DevicePowerState = IoStack->Parameters.Power.State.DeviceState; // complete request Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // done return Status; } } else { // sanity check PC_ASSERT(IoStack->Parameters.Power.Type == SystemPowerState); if (IoStack->MinorFunction == IRP_MN_QUERY_POWER) { // mark irp as pending IoMarkIrpPending(Irp); // allocate power completion context PwrContext = (PQUERY_POWER_CONTEXT)AllocateItem(NonPagedPool, sizeof(QUERY_POWER_CONTEXT), TAG_PORTCLASS); if (!PwrContext) { // no memory PoStartNextPowerIrp(Irp); // complete and forget Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(Irp, IO_NO_INCREMENT); // done return Status; } // setup power context PwrContext->Irp = Irp; PwrContext->DeviceObject = DeviceObject; // pass the irp down PowerState = *((POWER_STATE*)IoStack->Parameters.Power.State.SystemState); Status = PoRequestPowerIrp(DeviceExtension->PhysicalDeviceObject, IoStack->MinorFunction, PowerState, PwrCompletionFunction, (PVOID)PwrContext, NULL); // check for success if (!NT_SUCCESS(Status)) { // failed Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // done return Status; } // done return STATUS_PENDING; } else { // set power request DeviceExtension->SystemPowerState = IoStack->Parameters.Power.State.SystemState; // only forward query requests Status = PcForwardIrpSynchronous(DeviceObject, Irp); // start next power irp PoStartNextPowerIrp(Irp); // complete request Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); // done return Status; } } }
NTSTATUS NTAPI PinPropertyHandler( IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data) { PIO_STACK_LOCATION IoStack; //PKSOBJECT_CREATE_ITEM CreateItem; PSUBDEVICE_DESCRIPTOR Descriptor; IIrpTarget * IrpTarget; IPort *Port; ISubdevice *SubDevice; PDISPATCH_CONTEXT DispatchContext; NTSTATUS Status = STATUS_UNSUCCESSFUL; Descriptor = (PSUBDEVICE_DESCRIPTOR)KSPROPERTY_ITEM_IRP_STORAGE(Irp); PC_ASSERT(Descriptor); // get current irp stack IoStack = IoGetCurrentIrpStackLocation(Irp); // get dispatch context DispatchContext = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext; // Get the IrpTarget IrpTarget = DispatchContext->Target; PC_ASSERT(IrpTarget); // Get the parent Status = IrpTarget->QueryInterface(IID_IPort, (PVOID*)&Port); if (!NT_SUCCESS(Status)) { DPRINT("Failed to obtain IPort interface from filter\n"); Irp->IoStatus.Information = 0; Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; return STATUS_UNSUCCESSFUL; } // Get private ISubdevice interface Status = Port->QueryInterface(IID_ISubdevice, (PVOID*)&SubDevice); if (!NT_SUCCESS(Status)) { DPRINT("Failed to obtain ISubdevice interface from port driver\n"); DbgBreakPoint(); while(TRUE); } // get current stack location IoStack = IoGetCurrentIrpStackLocation(Irp); switch(Request->Id) { case KSPROPERTY_PIN_CTYPES: case KSPROPERTY_PIN_DATAFLOW: case KSPROPERTY_PIN_DATARANGES: case KSPROPERTY_PIN_INTERFACES: case KSPROPERTY_PIN_MEDIUMS: case KSPROPERTY_PIN_COMMUNICATION: case KSPROPERTY_PIN_CATEGORY: case KSPROPERTY_PIN_NAME: case KSPROPERTY_PIN_PROPOSEDATAFORMAT: Status = KsPinPropertyHandler(Irp, Request, Data, Descriptor->Factory.PinDescriptorCount, Descriptor->Factory.KsPinDescriptor); break; case KSPROPERTY_PIN_GLOBALCINSTANCES: Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, TRUE, SubDevice); break; case KSPROPERTY_PIN_CINSTANCES: Status = HandlePropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, FALSE, SubDevice); break; case KSPROPERTY_PIN_NECESSARYINSTANCES: Status = HandleNecessaryPropertyInstances(&Irp->IoStatus, Request, Data, Descriptor, SubDevice); break; case KSPROPERTY_PIN_DATAINTERSECTION: Status = HandleDataIntersection(&Irp->IoStatus, Request, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor, SubDevice); break; case KSPROPERTY_PIN_PHYSICALCONNECTION: Status = HandlePhysicalConnection(&Irp->IoStatus, Request, IoStack->Parameters.DeviceIoControl.InputBufferLength, Data, IoStack->Parameters.DeviceIoControl.OutputBufferLength, Descriptor); break; case KSPROPERTY_PIN_CONSTRAINEDDATARANGES: UNIMPLEMENTED Status = STATUS_NOT_IMPLEMENTED; break; default: UNIMPLEMENTED Status = STATUS_UNSUCCESSFUL; } // Release reference Port->Release(); // Release subdevice reference SubDevice->Release(); return Status; }
NTSTATUS CHCDController::HandlePnp( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IoStack; PCOMMON_DEVICE_EXTENSION DeviceExtension; PCM_RESOURCE_LIST RawResourceList; PCM_RESOURCE_LIST TranslatedResourceList; PDEVICE_RELATIONS DeviceRelations; NTSTATUS Status; // // get device extension // DeviceExtension = (PCOMMON_DEVICE_EXTENSION)DeviceObject->DeviceExtension; // // sanity check // PC_ASSERT(DeviceExtension->IsFDO); // // get current stack location // IoStack = IoGetCurrentIrpStackLocation(Irp); switch(IoStack->MinorFunction) { case IRP_MN_START_DEVICE: { DPRINT("[%s] HandlePnp IRP_MN_START FDO\n", m_USBType); // // first start lower device object // Status = SyncForwardIrp(m_NextDeviceObject, Irp); if (NT_SUCCESS(Status)) { // // operation succeeded, lets start the device // RawResourceList = IoStack->Parameters.StartDevice.AllocatedResources; TranslatedResourceList = IoStack->Parameters.StartDevice.AllocatedResourcesTranslated; if (m_Hardware) { // // start the hardware // Status = m_Hardware->PnpStart(RawResourceList, TranslatedResourceList); } // // enable symbolic link // Status = SetSymbolicLink(TRUE); } DPRINT("[%s] HandlePnp IRP_MN_START FDO: Status %x\n", m_USBType ,Status); break; } case IRP_MN_QUERY_DEVICE_RELATIONS: { DPRINT("[%s] HandlePnp IRP_MN_QUERY_DEVICE_RELATIONS Type %lx\n", m_USBType, IoStack->Parameters.QueryDeviceRelations.Type); if (m_HubController == NULL) { // // create hub controller // Status = CreateHubController(&m_HubController); if (!NT_SUCCESS(Status)) { // // failed to create hub controller // break; } // // initialize hub controller // Status = m_HubController->Initialize(m_DriverObject, PHCDCONTROLLER(this), m_Hardware, TRUE, 0 /* FIXME*/); if (!NT_SUCCESS(Status)) { // // failed to initialize hub controller // break; } // // add reference to prevent it from getting deleting while hub driver adds / removes references // m_HubController->AddRef(); } if (IoStack->Parameters.QueryDeviceRelations.Type == BusRelations) { // // allocate device relations // DeviceRelations = (PDEVICE_RELATIONS)ExAllocatePool(PagedPool, sizeof(DEVICE_RELATIONS)); if (!DeviceRelations) { // // no memory // Status = STATUS_INSUFFICIENT_RESOURCES; break; } // // init device relations // DeviceRelations->Count = 1; Status = m_HubController->GetHubControllerDeviceObject(&DeviceRelations->Objects [0]); // // sanity check // PC_ASSERT(Status == STATUS_SUCCESS); ObReferenceObject(DeviceRelations->Objects [0]); // // store result // Irp->IoStatus.Information = (ULONG_PTR)DeviceRelations; Status = STATUS_SUCCESS; } else { // // not supported // Status = STATUS_NOT_SUPPORTED; } break; } case IRP_MN_STOP_DEVICE: { DPRINT("[%s] HandlePnp IRP_MN_STOP_DEVICE\n", m_USBType); if (m_Hardware) { // // stop the hardware // Status = m_Hardware->PnpStop(); } else { // // fake success // Status = STATUS_SUCCESS; } if (NT_SUCCESS(Status)) { // // stop lower device // Status = SyncForwardIrp(m_NextDeviceObject, Irp); } break; } case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: { #if 0 // // sure // Irp->IoStatus.Status = STATUS_SUCCESS; // // forward irp to next device object // IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(m_NextDeviceObject, Irp); #else DPRINT1("[%s] Denying controller removal due to reinitialization bugs\n", m_USBType); Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; #endif } case IRP_MN_REMOVE_DEVICE: { DPRINT("[%s] HandlePnp IRP_MN_REMOVE_DEVICE FDO\n", m_USBType); // // delete the symbolic link // SetSymbolicLink(FALSE); // // forward irp to next device object // IoSkipCurrentIrpStackLocation(Irp); IoCallDriver(m_NextDeviceObject, Irp); // // detach device from device stack // IoDetachDevice(m_NextDeviceObject); // // delete device // IoDeleteDevice(m_FunctionalDeviceObject); return STATUS_SUCCESS; } default: { // // forward irp to next device object // IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(m_NextDeviceObject, Irp); } } // // store result and complete request // Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); return Status; }
NTSTATUS NTAPI CPortPinWavePci::Close( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS Status; if (m_Format) { // free format FreeItem(m_Format, TAG_PORTCLASS); // format is freed m_Format = NULL; } if (m_IrpQueue) { // cancel remaining irps m_IrpQueue->CancelBuffers(); // release irp queue m_IrpQueue->Release(); // queue is freed m_IrpQueue = NULL; } if (m_ServiceGroup) { // remove member from service group m_ServiceGroup->RemoveMember(PSERVICESINK(this)); // do not release service group, it is released by the miniport object m_ServiceGroup = NULL; } if (m_Stream) { if (m_State != KSSTATE_STOP) { // stop stream Status = m_Stream->SetState(KSSTATE_STOP); if (!NT_SUCCESS(Status)) { DPRINT("Warning: failed to stop stream with %x\n", Status); PC_ASSERT(0); } } // set state to stop m_State = KSSTATE_STOP; DPRINT("Closing stream at Irql %u\n", KeGetCurrentIrql()); // release stream m_Stream->Release(); // stream is now freed m_Stream = NULL; } if (m_Filter) { // disconnect pin from filter m_Filter->FreePin((PPORTPINWAVEPCI)this); // release filter reference m_Filter->Release(); // pin is done with filter m_Filter = NULL; } if (m_Port) { // release reference to port driver m_Port->Release(); // work is done for port m_Port = NULL; } // successfully complete irp Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_SUCCESS; }