//--------------------------------------------------------------------------- // // Module: pins.c // // Description: // // //@@BEGIN_MSINTERNAL // Development Team: // S.Mohanraj // // History: Date Author Comment // // To Do: Date Author Comment // //@@END_MSINTERNAL // // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY // KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR // PURPOSE. // // Copyright (c) 1996-1999 Microsoft Corporation. All Rights Reserved. // //--------------------------------------------------------------------------- #include "common.h" //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- static const WCHAR AllocatorTypeName[] = KSSTRING_Allocator; static const WCHAR ClockTypeName[] = KSSTRING_Clock; DEFINE_KSCREATE_DISPATCH_TABLE(PinCreateItems) { DEFINE_KSCREATE_ITEM(AllocatorDispatchCreate, AllocatorTypeName, 0), DEFINE_KSCREATE_ITEM(CClockInstance::ClockDispatchCreate, ClockTypeName, 0), }; DEFINE_KSDISPATCH_TABLE( PinDispatchTable, CPinInstance::PinDispatchIoControl, // Ioctl DispatchInvalidDeviceRequest, // Read CInstance::DispatchForwardIrp, // Write DispatchInvalidDeviceRequest, // Flush CPinInstance::PinDispatchClose, // Close DispatchInvalidDeviceRequest, // QuerySecurity DispatchInvalidDeviceRequest, // SetSeturity DispatchFastIoDeviceControlFailure, // FastDeviceIoControl DispatchFastReadFailure, // FastRead DispatchFastWriteFailure // FastWrite ); DEFINE_KSPROPERTY_TABLE(SysaudioPinPropertyHandlers) { DEFINE_KSPROPERTY_ITEM( KSPROPERTY_SYSAUDIO_TOPOLOGY_CONNECTION_INDEX, // idProperty GetTopologyConnectionIndex, // pfnGetHandler sizeof(KSPROPERTY), // cbMinGetPropertyInput sizeof(ULONG), // cbMinGetDataInput NULL, // pfnSetHandler NULL, // Values 0, // RelationsCount NULL, // Relations NULL, // SupportHandler 0 // SerializedSize ), DEFINE_KSPROPERTY_ITEM( KSPROPERTY_SYSAUDIO_ATTACH_VIRTUAL_SOURCE, // idProperty NULL, // pfnGetHandler sizeof(SYSAUDIO_ATTACH_VIRTUAL_SOURCE), // cbMinGetPropertyInput 0, // cbMinGetDataInput AttachVirtualSource, // pfnSetHandler NULL, // Values 0, // RelationsCount NULL, // Relations NULL, // SupportHandler 0 // SerializedSize ), DEFINE_KSPROPERTY_ITEM( KSPROPERTY_SYSAUDIO_PIN_VOLUME_NODE, // idProperty GetPinVolumeNode, // pfnGetHandler sizeof(KSPROPERTY), // cbMinGetPropertyInput sizeof(ULONG), // cbMinGetDataInput NULL, // pfnSetHandler NULL, // Values 0, // RelationsCount NULL, // Relations NULL, // SupportHandler 0 // SerializedSize ), }; DEFINE_KSPROPERTY_TABLE(PinConnectionHandlers) { DEFINE_KSPROPERTY_ITEM( KSPROPERTY_CONNECTION_STATE, // idProperty CPinInstance::PinStateHandler, // pfnGetHandler sizeof(KSPROPERTY), // cbMinGetPropertyInput sizeof(ULONG), // cbMinGetDataInput CPinInstance::PinStateHandler, // pfnSetHandler NULL, // Values 0, // RelationsCount NULL, // Relations NULL, // SupportHandler 0 // SerializedSize ) }; DEFINE_KSPROPERTY_TABLE (AudioPinPropertyHandlers) { DEFINE_KSPROPERTY_ITEM( KSPROPERTY_AUDIO_VOLUMELEVEL, PinVirtualPropertyHandler, sizeof(KSNODEPROPERTY_AUDIO_CHANNEL), sizeof(LONG), PinVirtualPropertyHandler, &PropertyValuesVolume, 0, NULL, (PFNKSHANDLER)PinVirtualPropertySupportHandler, 0 ) }; DEFINE_KSPROPERTY_SET_TABLE(PinPropertySet) { DEFINE_KSPROPERTY_SET( &KSPROPSETID_Connection, // Set SIZEOF_ARRAY(PinConnectionHandlers), // PropertiesCount PinConnectionHandlers, // PropertyItem 0, // FastIoCount NULL // FastIoTable ), DEFINE_KSPROPERTY_SET( &KSPROPSETID_Sysaudio_Pin, // Set SIZEOF_ARRAY(SysaudioPinPropertyHandlers), // PropertiesCount SysaudioPinPropertyHandlers, // PropertyItem 0, // FastIoCount NULL // FastIoTable ), DEFINE_KSPROPERTY_SET( &KSPROPSETID_Audio, // Set SIZEOF_ARRAY(AudioPinPropertyHandlers), // PropertiesCount AudioPinPropertyHandlers, // PropertyItem 0, // FastIoCount NULL // FastIoTable ) }; //--------------------------------------------------------------------------- //--------------------------------------------------------------------------- CPinInstance::CPinInstance( IN PPARENT_INSTANCE pParentInstance ) : CInstance(pParentInstance) { } CPinInstance::~CPinInstance( ) { PGRAPH_NODE_INSTANCE pGraphNodeInstance; Assert(this); Assert(pFilterInstance); DPF1(100, "~CPinInstance: %08x", this); if(pStartNodeInstance != NULL) { pGraphNodeInstance = pFilterInstance->pGraphNodeInstance; if(pGraphNodeInstance != NULL) { Assert(pGraphNodeInstance); ASSERT(PinId < pGraphNodeInstance->cPins); ASSERT(pGraphNodeInstance->pacPinInstances != NULL); ASSERT(pGraphNodeInstance->pacPinInstances[PinId].CurrentCount > 0); pGraphNodeInstance->pacPinInstances[PinId].CurrentCount--; } else { DPF2(10, "~CPinInstance PI %08x FI %08x no GNI", this, pFilterInstance); } pStartNodeInstance->Destroy(); } else { DPF2(10, "~CPinInstance PI %08x FI %08x no SNI", this, pFilterInstance); } } NTSTATUS CPinInstance::PinDispatchCreate( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) { PGRAPH_NODE_INSTANCE pGraphNodeInstance; PPIN_INSTANCE pPinInstance = NULL; PKSPIN_CONNECT pPinConnect = NULL; NTSTATUS Status; ::GrabMutex(); Status = GetRelatedGraphNodeInstance(pIrp, &pGraphNodeInstance); if(!NT_SUCCESS(Status)) { goto exit; } Assert(pGraphNodeInstance); ASSERT(pGraphNodeInstance->pacPinInstances != NULL); ASSERT(pGraphNodeInstance->paPinDescriptors != NULL); // // Get the PinConnect structure from KS. // This function will copy creation parameters to pPinConnect. // Also do a basic connectibility testing by comparing KSDATAFORMAT of // pin descriptors and the request. // Status = KsValidateConnectRequest( pIrp, pGraphNodeInstance->cPins, pGraphNodeInstance->paPinDescriptors, &pPinConnect); if(!NT_SUCCESS(Status)) { #ifdef DEBUG DPF1(60, "PinDispatchCreate: KsValidateConnectReq FAILED %08x", Status); if(pPinConnect != NULL) { DumpPinConnect(60, pPinConnect); } #endif goto exit; } ASSERT(pPinConnect->PinId < pGraphNodeInstance->cPins); #ifdef DEBUG DPF(60, "PinDispatchCreate:"); DumpPinConnect(60, pPinConnect); #endif // Check the pin instance count if(!pGraphNodeInstance->IsPinInstances(pPinConnect->PinId)) { DPF4(60, "PinDispatchCreate: not enough ins GNI %08x #%d C %d P %d", pGraphNodeInstance, pPinConnect->PinId, pGraphNodeInstance->pacPinInstances[pPinConnect->PinId].CurrentCount, pGraphNodeInstance->pacPinInstances[pPinConnect->PinId].PossibleCount); Status = STATUS_DEVICE_BUSY; goto exit; } // Allocate per pin instance data pPinInstance = new PIN_INSTANCE( &pGraphNodeInstance->pFilterInstance->ParentInstance); if(pPinInstance == NULL) { Status = STATUS_INSUFFICIENT_RESOURCES; goto exit; } // Setup the pin's instance data pPinInstance->ulVolumeNodeNumber = MAXULONG; pPinInstance->pFilterInstance = pGraphNodeInstance->pFilterInstance; pPinInstance->PinId = pPinConnect->PinId; Status = pPinInstance->DispatchCreate( pIrp, (UTIL_PFN)PinDispatchCreateKP, pPinConnect, SIZEOF_ARRAY(PinCreateItems), PinCreateItems, &PinDispatchTable); pPinConnect->PinId = pPinInstance->PinId; if(!NT_SUCCESS(Status)) { #ifdef DEBUG DPF1(60, "PinDispatchCreate: FAILED: %08x ", Status); DumpPinConnect(60, pPinConnect); #endif goto exit; } // Increment the reference count on this pin ASSERT(pPinInstance->pStartNodeInstance != NULL); ASSERT(pGraphNodeInstance->pacPinInstances != NULL); pGraphNodeInstance->pacPinInstances[pPinInstance->PinId].CurrentCount++; exit: if(!NT_SUCCESS(Status)) { delete pPinInstance; } ::ReleaseMutex(); pIrp->IoStatus.Status = Status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return Status; } NTSTATUS CPinInstance::PinDispatchCreateKP( PPIN_INSTANCE pPinInstance, PKSPIN_CONNECT pPinConnect ) { PWAVEFORMATEX pWaveFormatExRequested = NULL; PFILTER_INSTANCE pFilterInstance; PSTART_NODE pStartNode; NTSTATUS Status; Assert(pPinInstance); pFilterInstance = pPinInstance->pFilterInstance; Assert(pFilterInstance); ASSERT(pPinInstance->PinId < pFilterInstance->pGraphNodeInstance->cPins); ASSERT(pPinConnect->PinId < pFilterInstance->pGraphNodeInstance->cPins); if(IsEqualGUID( &PKSDATAFORMAT(pPinConnect + 1)->Specifier, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX)) { pWaveFormatExRequested = &PKSDATAFORMAT_WAVEFORMATEX(pPinConnect + 1)->WaveFormatEx; } else if(IsEqualGUID( &PKSDATAFORMAT(pPinConnect + 1)->Specifier, &KSDATAFORMAT_SPECIFIER_DSOUND)) { pWaveFormatExRequested = &PKSDATAFORMAT_DSOUND(pPinConnect + 1)->BufferDesc.WaveFormatEx; } if(pWaveFormatExRequested != NULL) { // Fix SampleSize if zero if(PKSDATAFORMAT(pPinConnect + 1)->SampleSize == 0) { PKSDATAFORMAT(pPinConnect + 1)->SampleSize = pWaveFormatExRequested->nBlockAlign; } } // // Try each start node until success // Status = STATUS_INVALID_DEVICE_REQUEST; // // First loop through all the start nodes which are not marked SECONDPASS // and try to create a StartNodeInstance // FOR_EACH_LIST_ITEM( pFilterInstance->pGraphNodeInstance->aplstStartNode[pPinInstance->PinId], pStartNode) { Assert(pStartNode); Assert(pFilterInstance); if(pStartNode->ulFlags & STARTNODE_FLAGS_SECONDPASS) { continue; } if(pFilterInstance->pGraphNodeInstance->IsGraphValid( pStartNode, pPinInstance->PinId)) { Status = CStartNodeInstance::Create( pPinInstance, pStartNode, pPinConnect, pWaveFormatExRequested, NULL); if(NT_SUCCESS(Status)) { break; } } } END_EACH_LIST_ITEM if(!NT_SUCCESS(Status)) { // // If first pass failed to create an instance try all the second pass // StartNodes in the list. This is being done for creating paths with no GFX // because we created a path with AEC and no GFX earlier. // FOR_EACH_LIST_ITEM( pFilterInstance->pGraphNodeInstance->aplstStartNode[pPinInstance->PinId], pStartNode) { Assert(pStartNode); Assert(pFilterInstance); if((pStartNode->ulFlags & STARTNODE_FLAGS_SECONDPASS) == 0) { continue; } if(pFilterInstance->pGraphNodeInstance->IsGraphValid( pStartNode, pPinInstance->PinId)) { Status = CStartNodeInstance::Create( pPinInstance, pStartNode, pPinConnect, pWaveFormatExRequested, NULL); if(NT_SUCCESS(Status)) { break; } } } END_EACH_LIST_ITEM if(!NT_SUCCESS(Status)) { goto exit; } } Status = pPinInstance->SetNextFileObject( pPinInstance->pStartNodeInstance->pPinNodeInstance->hPin); if(!NT_SUCCESS(Status)) { Trap(); goto exit; } exit: return(Status); } NTSTATUS CPinInstance::PinDispatchClose( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) { PIO_STACK_LOCATION pIrpStack; PPIN_INSTANCE pPinInstance; ::GrabMutex(); pIrpStack = IoGetCurrentIrpStackLocation( pIrp ); pPinInstance = (PPIN_INSTANCE)pIrpStack->FileObject->FsContext; Assert(pPinInstance); pIrpStack->FileObject->FsContext = NULL; delete pPinInstance; ::ReleaseMutex(); pIrp->IoStatus.Status = STATUS_SUCCESS; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_SUCCESS; } NTSTATUS CPinInstance::PinDispatchIoControl( IN PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp ) { NTSTATUS Status = STATUS_INVALID_DEVICE_REQUEST; PSTART_NODE_INSTANCE pStartNodeInstance; PIO_STACK_LOCATION pIrpStack; PKSPROPERTY pProperty = NULL; PPIN_INSTANCE pPinInstance; BOOL fProperty = FALSE; ULONG ulFlags = 0; #ifdef DEBUG DumpIoctl(pIrp, "Pin"); #endif pIrpStack = IoGetCurrentIrpStackLocation(pIrp); switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_KS_PROPERTY: fProperty = TRUE; break; case IOCTL_KS_ENABLE_EVENT: case IOCTL_KS_DISABLE_EVENT: case IOCTL_KS_METHOD: break; default: return(DispatchForwardIrp(pDeviceObject, pIrp)); } ::GrabMutex(); pPinInstance = (PPIN_INSTANCE)pIrpStack->FileObject->FsContext; Status = pPinInstance->GetStartNodeInstance(&pStartNodeInstance); if(!NT_SUCCESS(Status)) { goto exit; } Assert(pPinInstance->pFilterInstance); Assert(pPinInstance->pFilterInstance->pGraphNodeInstance); if(pIrpStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSPROPERTY)) { __try { if(pIrp->AssociatedIrp.SystemBuffer == NULL) { pProperty = (PKSPROPERTY) (pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer); // Validate the pointers if the client is not trusted. if(pIrp->RequestorMode != KernelMode) { ProbeForWrite( pProperty, pIrpStack->Parameters.DeviceIoControl.InputBufferLength, sizeof(BYTE)); } } else { pProperty = (PKSPROPERTY)((PUCHAR)pIrp->AssociatedIrp.SystemBuffer + ((pIrpStack->Parameters.DeviceIoControl.OutputBufferLength + FILE_QUAD_ALIGNMENT) & ~FILE_QUAD_ALIGNMENT)); } ulFlags = pProperty->Flags; } __except (EXCEPTION_EXECUTE_HANDLER) { Trap(); Status = GetExceptionCode(); DPF1(5, "PinDispatchIoControl: Exception %08x", Status); goto exit; } // // This check allows the actual node or filter return the set's // supported, etc. instead of always return only the sets sysaudio // supports. // if(ulFlags & KSPROPERTY_TYPE_TOPOLOGY) { if(fProperty) { if((ulFlags & (KSPROPERTY_TYPE_GET | KSPROPERTY_TYPE_SET | KSPROPERTY_TYPE_BASICSUPPORT)) == 0) { // NOTE: ForwardIrpNode releases gMutex return(ForwardIrpNode( pIrp, pProperty, pPinInstance->pFilterInstance, pPinInstance)); } } else { // NOTE: ForwardIrpNode releases gMutex return(ForwardIrpNode( pIrp, pProperty, pPinInstance->pFilterInstance, pPinInstance)); } } } switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode) { case IOCTL_KS_PROPERTY: Status = KsPropertyHandler( pIrp, SIZEOF_ARRAY(PinPropertySet), (PKSPROPERTY_SET)PinPropertySet); if(Status != STATUS_NOT_FOUND && Status != STATUS_PROPSET_NOT_FOUND) { break; } // Fall through if property not found case IOCTL_KS_ENABLE_EVENT: case IOCTL_KS_DISABLE_EVENT: case IOCTL_KS_METHOD: // NOTE: ForwardIrpNode releases gMutex return(ForwardIrpNode( pIrp, NULL, pPinInstance->pFilterInstance, pPinInstance)); default: ASSERT(FALSE); // Can't happen because of above switch } exit: ::ReleaseMutex(); pIrp->IoStatus.Status = Status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return(Status); } NTSTATUS CPinInstance::PinStateHandler ( IN PIRP pIrp, IN PKSPROPERTY pProperty, IN OUT PKSSTATE pState ) { PSTART_NODE_INSTANCE pStartNodeInstance; NTSTATUS Status = STATUS_SUCCESS; #ifdef DEBUG extern PSZ apszStates[]; #endif Status = ::GetStartNodeInstance(pIrp, &pStartNodeInstance); if(!NT_SUCCESS(Status)) { Trap(); goto exit; } if(pProperty->Flags & KSPROPERTY_TYPE_GET) { *pState = pStartNodeInstance->CurrentState; pIrp->IoStatus.Information = sizeof(KSSTATE); if(*pState == KSSTATE_PAUSE) { if(pStartNodeInstance->pPinNodeInstance-> pPinNode->pPinInfo->DataFlow == KSPIN_DATAFLOW_OUT) { Status = STATUS_NO_DATA_DETECTED; } } } else { ASSERT(pProperty->Flags & KSPROPERTY_TYPE_SET); DPF3(90, "PinStateHandler from %s to %s - SNI: %08x", apszStates[pStartNodeInstance->CurrentState], apszStates[*pState], pStartNodeInstance); Status = pStartNodeInstance->SetState(*pState, 0); if(!NT_SUCCESS(Status)) { DPF1(90, "PinStateHandler FAILED: %08x", Status); goto exit; } } exit: return(Status); } NTSTATUS GetRelatedStartNodeInstance( IN PIRP pIrp, OUT PSTART_NODE_INSTANCE *ppStartNodeInstance ) { return(((PPIN_INSTANCE)IoGetCurrentIrpStackLocation(pIrp)->FileObject-> RelatedFileObject->FsContext)->GetStartNodeInstance(ppStartNodeInstance)); } NTSTATUS GetStartNodeInstance( IN PIRP pIrp, OUT PSTART_NODE_INSTANCE *ppStartNodeInstance ) { return(((PPIN_INSTANCE)IoGetCurrentIrpStackLocation(pIrp)->FileObject-> FsContext)->GetStartNodeInstance(ppStartNodeInstance)); } NTSTATUS CPinInstance::GetStartNodeInstance( OUT PSTART_NODE_INSTANCE *ppStartNodeInstance ) { NTSTATUS Status = STATUS_SUCCESS; if(this == NULL || pStartNodeInstance == NULL) { DPF(60, "GetStartNodeInstance: pStartNodeInstance == NULL"); Status = STATUS_NO_SUCH_DEVICE; goto exit; } Assert(this); *ppStartNodeInstance = pStartNodeInstance; exit: return(Status); } #pragma LOCKED_CODE #pragma LOCKED_DATA // NOTE: ForwardIrpNode releases gMutex NTSTATUS ForwardIrpNode( IN PIRP pIrp, IN OPTIONAL PKSPROPERTY pProperty, // already validated or NULL IN PFILTER_INSTANCE pFilterInstance, IN OPTIONAL PPIN_INSTANCE pPinInstance ) { PGRAPH_NODE_INSTANCE pGraphNodeInstance; PFILE_OBJECT pFileObject = NULL; PIO_STACK_LOCATION pIrpStack; PKSEVENTDATA pEventData; ULONG OriginalNodeId; NTSTATUS Status; Assert(pFilterInstance); pIrpStack = IoGetCurrentIrpStackLocation(pIrp); Status = pFilterInstance->GetGraphNodeInstance(&pGraphNodeInstance); if(!NT_SUCCESS(Status)) { goto exit; } Assert(pGraphNodeInstance); if(pPinInstance != NULL) { pFileObject = pPinInstance->GetNextFileObject(); } __try { if(pIrpStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSNODEPROPERTY) && pIrpStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_DISABLE_EVENT) { if(pProperty == NULL) { if(pIrp->AssociatedIrp.SystemBuffer == NULL) { Trap(); pProperty = (PKSPROPERTY) (pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer); // Validate the pointers if the client is not trusted. if(pIrp->RequestorMode != KernelMode) { ProbeForWrite( pProperty, pIrpStack->Parameters.DeviceIoControl.InputBufferLength, sizeof(BYTE)); } } else { pProperty = (PKSPROPERTY) ((PUCHAR)pIrp->AssociatedIrp.SystemBuffer + ((pIrpStack->Parameters.DeviceIoControl.OutputBufferLength + FILE_QUAD_ALIGNMENT) & ~FILE_QUAD_ALIGNMENT)); } } ASSERT(!IsEqualGUID(&pProperty->Set, &KSPROPSETID_Sysaudio)); ASSERT(!IsEqualGUID(&pProperty->Set, &KSEVENTSETID_Sysaudio)); if(pProperty->Flags & KSPROPERTY_TYPE_TOPOLOGY) { OriginalNodeId = ((PKSNODEPROPERTY)pProperty)->NodeId; if(pPinInstance == NULL) { Status = pGraphNodeInstance-> GetTopologyNodeFileObject( &pFileObject, OriginalNodeId); } else { Status = pPinInstance->pStartNodeInstance-> GetTopologyNodeFileObject( &pFileObject, OriginalNodeId); } if(!NT_SUCCESS(Status)) { DPF1(100, "ForwardIrpNode: GetTopologyNodeFileObject FAILED %08x", Status); goto exit; } // Put real node number in input buffer ((PKSNODEPROPERTY)pProperty)->NodeId = pGraphNodeInstance-> papTopologyNode[OriginalNodeId]->ulRealNodeNumber; } } else { // // If it is DisableEvent && if it is of type DPC. We look into the // Reserved field of KSEVENTDATA to extract the original node on // which the event was enabled (The high bit is set if we ever // stashed a NodeId in there). // if(pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT) { if(pIrpStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSEVENTDATA)) { pEventData = (PKSEVENTDATA) pIrpStack->Parameters.DeviceIoControl.Type3InputBuffer; if(pIrp->RequestorMode != KernelMode) { ProbeForWrite( pEventData, pIrpStack->Parameters.DeviceIoControl.InputBufferLength, sizeof (BYTE)); } OriginalNodeId = ULONG(pEventData->Dpc.Reserved); if((pEventData->NotificationType == KSEVENTF_DPC) && (OriginalNodeId & 0x80000000)) { OriginalNodeId = OriginalNodeId & 0x7fffffff; if(pPinInstance == NULL) { Status = pGraphNodeInstance-> GetTopologyNodeFileObject( &pFileObject, OriginalNodeId); } else { Status = pPinInstance->pStartNodeInstance-> GetTopologyNodeFileObject( &pFileObject, OriginalNodeId); } if(!NT_SUCCESS(Status)) { DPF1(100, "ForwardIrpNode: GetTopologyNodeFileObject FAILED %08x", Status); goto exit; } } } } } } __except (EXCEPTION_EXECUTE_HANDLER) { Trap(); Status = GetExceptionCode(); DPF1(5, "ForwardIrpNode: Exception %08x", Status); goto exit; } if(pFileObject == NULL) { Status = STATUS_NOT_FOUND; DPF1(100, "ForwardIrpNode: Property not forwarded: %08x", pProperty); goto exit; } pIrpStack->FileObject = pFileObject; // // If it was EnableEvent we stash away pointer to KSEVENTDATA, so that we // can stash the NodeID into it after we call the next driver on the stack // KPROCESSOR_MODE RequestorMode; if((pProperty != NULL) && (pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) && !(pProperty->Flags & KSEVENT_TYPE_BASICSUPPORT) && (pProperty->Flags & KSPROPERTY_TYPE_TOPOLOGY) && (pProperty->Flags & KSEVENT_TYPE_ENABLE)) { pEventData = (PKSEVENTDATA) pIrp->UserBuffer; RequestorMode = pIrp->RequestorMode; } else { pEventData = NULL; } IoSkipCurrentIrpStackLocation(pIrp); AssertFileObject(pIrpStack->FileObject); Status = IoCallDriver(IoGetRelatedDeviceObject(pFileObject), pIrp); // // Stash away the Node id in EventData // __try { if (pEventData != NULL) { if (RequestorMode == UserMode) { ProbeForWrite(pEventData, sizeof(KSEVENTDATA), sizeof(BYTE)); } if (pEventData->NotificationType == KSEVENTF_DPC) { pEventData->Dpc.Reserved = OriginalNodeId | 0x80000000; } } } __except (EXCEPTION_EXECUTE_HANDLER) { Trap(); Status = GetExceptionCode(); DPF1(5, "ForwardIrpNode: Exception %08x", Status); } if(!NT_SUCCESS(Status)) { DPF1(100, "ForwardIrpNode: Status %08x", Status); } ::ReleaseMutex(); return(Status); exit: ::ReleaseMutex(); pIrp->IoStatus.Status = Status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return(Status); } //--------------------------------------------------------------------------- #ifdef DEBUG extern PSZ apszStates[]; ENUMFUNC CPinInstance::Dump( ) { Assert(this); // .siv if(ulDebugFlags & (DEBUG_FLAGS_VERBOSE | DEBUG_FLAGS_OBJECT)) { dprintf("PI: %08x FI %08x SNI %08x ulVNN %08x PinId %d\n", this, pFilterInstance, pStartNodeInstance, ulVolumeNodeNumber, PinId); CInstance::Dump(); ParentInstance.Dump(); } else { dprintf(" Fr: Sysaudio\n PinId: %d\n", PinId); } if(ulDebugFlags & DEBUG_FLAGS_INSTANCE) { if(pStartNodeInstance != NULL) { pStartNodeInstance->Dump(); } } return(STATUS_CONTINUE); } ENUMFUNC CPinInstance::DumpAddress( ) { if(this != NULL) { Assert(this); dprintf(" %08x", this); } return(STATUS_CONTINUE); } #endif //--------------------------------------------------------------------------- // End of File: pins.c //---------------------------------------------------------------------------