From 7a2f3e30fcfd3f910f6a9287d155494151c3f2d4 Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Mon, 25 Oct 2010 15:26:06 +0000 Subject: [PATCH] Merge trunk head (r49270) svn path=/branches/reactos-yarotows/; revision=49272 --- base/system/services/rpcserver.c | 66 +- dll/win32/user32/include/user32.h | 2 +- drivers/wdm/audio/backpln/portcls/guids.cpp | 1 + .../wdm/audio/backpln/portcls/interfaces.hpp | 6 +- .../wdm/audio/backpln/portcls/irpstream.cpp | 16 +- .../wdm/audio/backpln/portcls/pin_dmus.cpp | 2 +- .../audio/backpln/portcls/pin_wavecyclic.cpp | 117 ++- .../wdm/audio/backpln/portcls/pin_wavepci.cpp | 2 +- .../wdm/audio/backpln/portcls/pin_wavert.cpp | 2 +- drivers/wdm/audio/backpln/portcls/private.hpp | 16 + drivers/wdm/audio/backpln/portcls/undoc.cpp | 829 +++++++++++------- hal/halx86/generic/usage.c | 11 +- include/psdk/ks.h | 5 - include/psdk/ksmedia.h | 9 + ntoskrnl/include/internal/io.h | 15 + ntoskrnl/io/iomgr/iorsrce.c | 64 +- ntoskrnl/io/pnpmgr/pnpreport.c | 5 +- ntoskrnl/io/pnpmgr/pnpres.c | 117 ++- ntoskrnl/mm/ARM3/virtual.c | 43 +- subsystems/win32/win32k/ntuser/callback.c | 6 +- subsystems/win32/win32k/ntuser/hook.c | 18 +- subsystems/win32/win32k/ntuser/msgqueue.c | 4 +- 22 files changed, 885 insertions(+), 471 deletions(-) diff --git a/base/system/services/rpcserver.c b/base/system/services/rpcserver.c index b4b5bb88335..30df18d071f 100644 --- a/base/system/services/rpcserver.c +++ b/base/system/services/rpcserver.c @@ -31,9 +31,6 @@ typedef struct _SCMGR_HANDLE typedef struct _MANAGER_HANDLE { SCMGR_HANDLE Handle; - - /* FIXME: Insert more data here */ - WCHAR DatabaseName[1]; } MANAGER_HANDLE, *PMANAGER_HANDLE; @@ -41,11 +38,7 @@ typedef struct _MANAGER_HANDLE typedef struct _SERVICE_HANDLE { SCMGR_HANDLE Handle; - PSERVICE ServiceEntry; - - /* FIXME: Insert more data here */ - } SERVICE_HANDLE, *PSERVICE_HANDLE; @@ -149,7 +142,7 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName, if (lpDatabaseName == NULL) lpDatabaseName = SERVICES_ACTIVE_DATABASEW; - if (_wcsicmp(lpDatabaseName,SERVICES_FAILED_DATABASEW)==0) + if (_wcsicmp(lpDatabaseName, SERVICES_FAILED_DATABASEW) == 0) { DPRINT("Database %S, does not exist\n",lpDatabaseName); return ERROR_DATABASE_DOES_NOT_EXIST; @@ -168,8 +161,6 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName, Ptr->Handle.Tag = MANAGER_TAG; - /* FIXME: initialize more data here */ - wcscpy(Ptr->DatabaseName, lpDatabaseName); *Handle = (SC_HANDLE)Ptr; @@ -192,7 +183,6 @@ ScmCreateServiceHandle(PSERVICE lpServiceEntry, Ptr->Handle.Tag = SERVICE_TAG; - /* FIXME: initialize more data here */ Ptr->ServiceEntry = lpServiceEntry; *Handle = (SC_HANDLE)Ptr; @@ -453,9 +443,10 @@ DWORD RCloseServiceHandle( if (*hSCObject == 0) return ERROR_INVALID_HANDLE; - hManager = (PMANAGER_HANDLE)*hSCObject; - hService = (PSERVICE_HANDLE)*hSCObject; - if (hManager->Handle.Tag == MANAGER_TAG) + hManager = ScmGetServiceManagerFromHandle(*hSCObject); + hService = ScmGetServiceFromHandle(*hSCObject); + + if (hManager != NULL) { DPRINT("Found manager handle\n"); @@ -467,7 +458,7 @@ DWORD RCloseServiceHandle( DPRINT("RCloseServiceHandle() done\n"); return ERROR_SUCCESS; } - else if (hService->Handle.Tag == SERVICE_TAG) + else if (hService != NULL) { DPRINT("Found service handle\n"); @@ -561,6 +552,8 @@ DWORD RControlService( DWORD dwError = ERROR_SUCCESS; DWORD pcbBytesNeeded = 0; DWORD dwServicesReturned = 0; + DWORD dwControlsAccepted; + DWORD dwCurrentState; HKEY hServicesKey = NULL; DPRINT("RControlService() called\n"); @@ -662,6 +655,49 @@ DWORD RControlService( } else { + dwControlsAccepted = lpService->Status.dwControlsAccepted; + dwCurrentState = lpService->Status.dwCurrentState; + + /* Check the current state before sending a control request */ + switch (dwCurrentState) + { + case SERVICE_STOP_PENDING: + case SERVICE_STOPPED: + return ERROR_SERVICE_CANNOT_ACCEPT_CTRL; + + case SERVICE_START_PENDING: + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + break; + + case SERVICE_CONTROL_INTERROGATE: + RtlCopyMemory(lpServiceStatus, + &lpService->Status, + sizeof(SERVICE_STATUS)); + return ERROR_SUCCESS; + + default: + return ERROR_SERVICE_CANNOT_ACCEPT_CTRL; + } + break; + } + + /* Check if the control code is acceptable to the service */ + switch (dwControl) + { + case SERVICE_CONTROL_STOP: + if ((dwControlsAccepted & SERVICE_ACCEPT_STOP) == 0) + return ERROR_INVALID_SERVICE_CONTROL; + break; + + case SERVICE_CONTROL_PAUSE: + case SERVICE_CONTROL_CONTINUE: + if ((dwControlsAccepted & SERVICE_ACCEPT_PAUSE_CONTINUE) == 0) + return ERROR_INVALID_SERVICE_CONTROL; + break; + } + /* Send control code to the service */ dwError = ScmControlService(lpService, dwControl); diff --git a/dll/win32/user32/include/user32.h b/dll/win32/user32/include/user32.h index c6dbbc7279c..a0472b3ae62 100644 --- a/dll/win32/user32/include/user32.h +++ b/dll/win32/user32/include/user32.h @@ -169,7 +169,7 @@ SharedPtrToKernel(PVOID Ptr) static __inline BOOL IsThreadHooked(PCLIENTINFO pci) { - return pci->fsHooks != 0; + return (pci->fsHooks|pci->pDeskInfo->fsHooks) != 0; } static __inline PDESKTOPINFO diff --git a/drivers/wdm/audio/backpln/portcls/guids.cpp b/drivers/wdm/audio/backpln/portcls/guids.cpp index 457868d2c62..34fed4811fb 100644 --- a/drivers/wdm/audio/backpln/portcls/guids.cpp +++ b/drivers/wdm/audio/backpln/portcls/guids.cpp @@ -79,6 +79,7 @@ const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, { const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}}; const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; const GUID KSPROPTYPESETID_General = {0x97E99BA0L, 0xBDEA, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}}; +const GUID KSPROPSETID_DrmAudioStream = {0x2f2c8ddd, 0x4198, 0x4fac, {0xba, 0x29, 0x61, 0xbb, 0x05, 0xb7, 0xde, 0x06}}; const GUID KSEVENTSETID_LoopedStreaming = {0x4682B940L, 0xC6EF, 0x11D0, {0x96, 0xD8, 0x00, 0xAA, 0x00, 0x51, 0xE5, 0x1D}}; const GUID KSEVENTSETID_Connection = {0x7f4bcbe0L, 0x9ea5, 0x11cf, {0xa5, 0xd6, 0x28, 0xdb, 0x04, 0xc1, 0x00, 0x00}}; diff --git a/drivers/wdm/audio/backpln/portcls/interfaces.hpp b/drivers/wdm/audio/backpln/portcls/interfaces.hpp index 6caebb951d5..248bcbe9012 100644 --- a/drivers/wdm/audio/backpln/portcls/interfaces.hpp +++ b/drivers/wdm/audio/backpln/portcls/interfaces.hpp @@ -321,8 +321,7 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown) STDMETHOD_(NTSTATUS, Init)(THIS_ IN KSPIN_CONNECT *ConnectDetails, IN ULONG FrameSize, - IN ULONG Alignment, - IN PVOID SilenceBuffer) PURE; + IN ULONG Alignment) PURE; STDMETHOD_(NTSTATUS, AddMapping)(THIS_ IN PIRP Irp, @@ -363,8 +362,7 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown) STDMETHODIMP_(NTSTATUS) Init(THIS_ \ IN KSPIN_CONNECT *ConnectDetails, \ IN ULONG FrameSize, \ - IN ULONG Alignment, \ - IN PVOID SilenceBuffer); \ + IN ULONG Alignment); \ \ STDMETHODIMP_(NTSTATUS) AddMapping(THIS_ \ IN PIRP Irp, \ diff --git a/drivers/wdm/audio/backpln/portcls/irpstream.cpp b/drivers/wdm/audio/backpln/portcls/irpstream.cpp index aa6f392f87d..a19a6da6e5c 100644 --- a/drivers/wdm/audio/backpln/portcls/irpstream.cpp +++ b/drivers/wdm/audio/backpln/portcls/irpstream.cpp @@ -43,7 +43,6 @@ protected: LIST_ENTRY m_IrpList; LIST_ENTRY m_FreeIrpList; PIRP m_Irp; - PVOID m_SilenceBuffer; ULONG m_OutOfMapping; ULONG m_MaxFrameSize; @@ -84,12 +83,10 @@ NTAPI CIrpQueue::Init( IN KSPIN_CONNECT *ConnectDetails, IN ULONG FrameSize, - IN ULONG Alignment, - IN PVOID SilenceBuffer) + IN ULONG Alignment) { m_ConnectDetails = ConnectDetails; m_MaxFrameSize = FrameSize; - m_SilenceBuffer = SilenceBuffer; m_Alignment = Alignment; InitializeListHead(&m_IrpList); @@ -259,22 +256,13 @@ CIrpQueue::GetMapping( m_CurrentOffset = Offset = 0; } - if (!Irp && m_SilenceBuffer && m_MaxFrameSize) - { - DPRINT("NoIrp\n"); - // no irp available, use silence buffer - *Buffer = (PUCHAR)m_SilenceBuffer; - *BufferSize = m_MaxFrameSize; - return STATUS_SUCCESS; - } - if (!Irp) { // no irp buffer available + DPRINT("NoIrp\n"); return STATUS_UNSUCCESSFUL; } - // get stream header StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2]; diff --git a/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp b/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp index 4bcad8c49d0..5a616f302ec 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_dmus.cpp @@ -604,7 +604,7 @@ CPortPinDMus::Init( } } - Status = m_IrpQueue->Init(ConnectDetails, 0, 0, NULL); + Status = m_IrpQueue->Init(ConnectDetails, 0, 0); if (!NT_SUCCESS(Status)) { DPRINT("IrpQueue_Init failed with %x\n", Status); diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp index e615413b7e2..226457c1059 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp @@ -73,7 +73,7 @@ protected: ULONG m_StopCount; KSAUDIO_POSITION m_Position; KSALLOCATOR_FRAMING m_AllocatorFraming; - SUBDEVICE_DESCRIPTOR m_Descriptor; + PSUBDEVICE_DESCRIPTOR m_Descriptor; KSPIN_LOCK m_EventListLock; LIST_ENTRY m_EventList; @@ -105,10 +105,12 @@ NTSTATUS NTAPI PinWaveCyclicAudioPosition(IN PIRP Irp, IN PKSIDENTIFIER Request, NTSTATUS NTAPI PinWaveCyclicAllocatorFraming(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); NTSTATUS NTAPI PinWaveCyclicAddLoopedStreamEvent(IN PIRP Irp, IN PKSEVENTDATA EventData, IN PKSEVENT_ENTRY EventEntry); +NTSTATUS NTAPI PinWaveCyclicDRMHandler(IN PIRP Irp, IN PKSIDENTIFIER Request, IN OUT PVOID Data); DEFINE_KSPROPERTY_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming); DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition); +DEFINE_KSPROPERTY_DRMSET(PinWaveCyclicDRMSet, PinWaveCyclicDRMHandler); KSEVENT_ITEM PinWaveCyclicConnectionEventSet = { @@ -146,6 +148,13 @@ KSPROPERTY_SET PinWaveCyclicPropertySet[] = (const KSPROPERTY_ITEM*)&PinWaveCyclicAudioSet, 0, NULL + }, + { + &KSPROPSETID_DrmAudioStream, + sizeof(PinWaveCyclicDRMSet) / sizeof(KSPROPERTY_ITEM), + (const KSPROPERTY_ITEM*)&PinWaveCyclicDRMSet, + 0, + NULL } }; @@ -192,6 +201,19 @@ CPortPinWaveCyclic::QueryInterface( return STATUS_UNSUCCESSFUL; } +NTSTATUS +NTAPI +PinWaveCyclicDRMHandler( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) +{ + DPRINT1("PinWaveCyclicDRMHandler\n"); + ASSERT(0); + return STATUS_INVALID_PARAMETER; +} + + NTSTATUS NTAPI PinWaveCyclicAddEndOfStreamEvent( @@ -448,12 +470,14 @@ PinWaveCyclicState( { // FIXME // complete with successful state + Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); Pin->m_IrpQueue->CancelBuffers(); Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; } else if (Pin->m_State == KSSTATE_STOP) { + Pin->m_Stream->Silence(Pin->m_CommonBuffer, Pin->m_CommonBufferSize); Pin->m_IrpQueue->CancelBuffers(); Pin->m_Position.PlayOffset = 0; Pin->m_Position.WriteOffset = 0; @@ -662,6 +686,7 @@ CPortPinWaveCyclic::UpdateCommonBuffer( ULONG BufferLength; ULONG BytesToCopy; ULONG BufferSize; + ULONG Gap; PUCHAR Buffer; NTSTATUS Status; @@ -672,7 +697,18 @@ CPortPinWaveCyclic::UpdateCommonBuffer( { Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); if (!NT_SUCCESS(Status)) - return; + { + Gap = Position - m_CommonBufferOffset; + if (Gap > m_FrameSize) + { + // insert silence samples + DPRINT1("Inserting Silence Buffer Offset %lu GapLength %lu\n", m_CommonBufferOffset, BufferLength); + m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); + + m_CommonBufferOffset += BufferLength; + break; + } + } BytesToCopy = min(BufferLength, BufferSize); @@ -688,7 +724,7 @@ CPortPinWaveCyclic::UpdateCommonBuffer( m_IrpQueue->UpdateMapping(BytesToCopy); m_CommonBufferOffset += BytesToCopy; - BufferLength = Position - m_CommonBufferOffset; + BufferLength -= BytesToCopy; m_Position.PlayOffset += BytesToCopy; if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) @@ -720,7 +756,18 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap( { Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); if (!NT_SUCCESS(Status)) - return; + { + Gap = m_CommonBufferSize - m_CommonBufferOffset + Position; + if (Gap > m_FrameSize) + { + // insert silence samples + DPRINT1("Overlap Inserting Silence Buffer Size %lu Offset %lu Gap %lu Position %lu\n", m_CommonBufferSize, m_CommonBufferOffset, Gap, Position); + m_Stream->Silence((PUCHAR)m_CommonBuffer + m_CommonBufferOffset, BufferLength); + + m_CommonBufferOffset += BufferLength; + } + break; + } BytesToCopy = min(BufferLength, BufferSize); @@ -741,7 +788,7 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap( m_CommonBufferOffset += BytesToCopy; m_Position.PlayOffset += BytesToCopy; - BufferLength = m_CommonBufferSize - m_CommonBufferOffset; + BufferLength -=BytesToCopy; if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING) { @@ -751,7 +798,6 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap( m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset; } } - } if (Gap == Length) @@ -773,22 +819,13 @@ CPortPinWaveCyclic::RequestService() { ULONG Position; NTSTATUS Status; - PUCHAR Buffer; - ULONG BufferSize; ULONGLONG OldOffset, NewOffset; PC_ASSERT_IRQL(DISPATCH_LEVEL); if (m_State == KSSTATE_RUN) { - Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize); - if (!NT_SUCCESS(Status)) - { - return; - } - Status = m_Stream->GetPosition(&Position); - DPRINT("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u Capture %u\n", Position, Buffer, m_CommonBufferSize, BufferSize, m_Capture); OldOffset = m_Position.PlayOffset; @@ -841,7 +878,7 @@ CPortPinWaveCyclic::DeviceIoControl( if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { /* handle property with subdevice descriptor */ - Status = PcHandlePropertyWithTable(Irp, m_Descriptor.FilterPropertySetCount, m_Descriptor.FilterPropertySet, &m_Descriptor); + Status = PcHandlePropertyWithTable(Irp, m_Descriptor->FilterPropertySetCount, m_Descriptor->FilterPropertySet, m_Descriptor); if (Status == STATUS_NOT_FOUND) { @@ -854,11 +891,11 @@ CPortPinWaveCyclic::DeviceIoControl( } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT) { - Status = PcHandleEnableEventWithTable(Irp, &m_Descriptor); + Status = PcHandleEnableEventWithTable(Irp, m_Descriptor); } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_DISABLE_EVENT) { - Status = PcHandleDisableEventWithTable(Irp, &m_Descriptor); + Status = PcHandleDisableEventWithTable(Irp, m_Descriptor); } else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE) { @@ -1120,7 +1157,6 @@ CPortPinWaveCyclic::Init( PKSDATAFORMAT DataFormat; PDEVICE_OBJECT DeviceObject; BOOLEAN Capture; - PVOID SilenceBuffer; PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL; //IDrmAudioStream * DrmAudio = NULL; @@ -1179,7 +1215,6 @@ CPortPinWaveCyclic::Init( #endif DPRINT1("CPortPinWaveCyclic::Init Status %x PinId %u Capture %u\n", Status, ConnectDetails->PinId, Capture); - DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize); if (!NT_SUCCESS(Status)) return Status; @@ -1203,18 +1238,26 @@ CPortPinWaveCyclic::Init( InitializeListHead(&m_EventList); KeInitializeSpinLock(&m_EventListLock); - /* set up subdevice descriptor */ - RtlZeroMemory(&m_Descriptor, sizeof(SUBDEVICE_DESCRIPTOR)); - m_Descriptor.FilterPropertySet = PinWaveCyclicPropertySet; - m_Descriptor.FilterPropertySetCount = sizeof(PinWaveCyclicPropertySet) / sizeof(KSPROPERTY_SET); - m_Descriptor.UnknownStream = (PUNKNOWN)m_Stream; - m_Descriptor.DeviceDescriptor = SubDeviceDescriptor->DeviceDescriptor; - m_Descriptor.UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; - m_Descriptor.PortPin = (PVOID)this; - m_Descriptor.EventSetCount = sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET); - m_Descriptor.EventSet = PinWaveCyclicEventSet; - m_Descriptor.EventList = &m_EventList; - m_Descriptor.EventListLock = &m_EventListLock; + Status = PcCreateSubdeviceDescriptor(&m_Descriptor, + SubDeviceDescriptor->InterfaceCount, + SubDeviceDescriptor->Interfaces, + 0, /* FIXME KSINTERFACE_STANDARD with KSINTERFACE_STANDARD_STREAMING / KSINTERFACE_STANDARD_LOOPED_STREAMING */ + NULL, + sizeof(PinWaveCyclicPropertySet) / sizeof(KSPROPERTY_SET), + PinWaveCyclicPropertySet, + 0, + 0, + 0, + NULL, + sizeof(PinWaveCyclicEventSet) / sizeof(KSEVENT_SET), + PinWaveCyclicEventSet, + SubDeviceDescriptor->DeviceDescriptor); + + m_Descriptor->UnknownStream = (PUNKNOWN)m_Stream; + m_Descriptor->UnknownMiniport = SubDeviceDescriptor->UnknownMiniport; + m_Descriptor->PortPin = (PVOID)this; + m_Descriptor->EventList = &m_EventList; + m_Descriptor->EventListLock = &m_EventListLock; // initialize reset state m_ResetState = KSRESET_END; @@ -1247,9 +1290,7 @@ CPortPinWaveCyclic::Init( PC_ASSERT(NT_SUCCESS(Status)); PC_ASSERT(m_FrameSize); - SilenceBuffer = AllocateItem(NonPagedPool, m_FrameSize, TAG_PORTCLASS); - if (!SilenceBuffer) - return STATUS_INSUFFICIENT_RESOURCES; + DPRINT1("Bits %u Samples %u Channels %u Tag %u FrameSize %u CommonBufferSize %lu\n", ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wBitsPerSample, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nSamplesPerSec, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.nChannels, ((PKSDATAFORMAT_WAVEFORMATEX)(DataFormat))->WaveFormatEx.wFormatTag, m_FrameSize, m_CommonBufferSize); /* set up allocator framing */ @@ -1260,10 +1301,9 @@ CPortPinWaveCyclic::Init( m_AllocatorFraming.Reserved = 0; m_AllocatorFraming.FrameSize = m_FrameSize; - m_Stream->Silence(SilenceBuffer, m_FrameSize); m_Stream->Silence(m_CommonBuffer, m_CommonBufferSize); - Status = m_IrpQueue->Init(ConnectDetails, m_FrameSize, 0, SilenceBuffer); + Status = m_IrpQueue->Init(ConnectDetails, m_FrameSize, 0); if (!NT_SUCCESS(Status)) { m_IrpQueue->Release(); @@ -1282,9 +1322,6 @@ CPortPinWaveCyclic::Init( m_Port = Port; m_Filter = Filter; - //DPRINT("Setting state to acquire %x\n", m_Stream->SetState(KSSTATE_ACQUIRE)); - //DPRINT("Setting state to pause %x\n", m_Stream->SetState(KSSTATE_PAUSE)); - return STATUS_SUCCESS; } diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp index a2b89a4408f..9a1cc75613b 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp @@ -919,7 +919,7 @@ CPortPinWavePci::Init( } // initialize irp queue - Status = m_IrpQueue->Init(ConnectDetails, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment, NULL); + Status = m_IrpQueue->Init(ConnectDetails, m_AllocatorFraming.FrameSize, m_AllocatorFraming.FileAlignment); if (!NT_SUCCESS(Status)) { // this should never happen diff --git a/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp b/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp index 7c3d0367123..fd6be3cc28f 100644 --- a/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp +++ b/drivers/wdm/audio/backpln/portcls/pin_wavert.cpp @@ -587,7 +587,7 @@ CPortPinWaveRT::Init( goto cleanup; } - Status = m_IrpQueue->Init(ConnectDetails, 0, 0, NULL); + Status = m_IrpQueue->Init(ConnectDetails, 0, 0); if (!NT_SUCCESS(Status)) { goto cleanup; diff --git a/drivers/wdm/audio/backpln/portcls/private.hpp b/drivers/wdm/audio/backpln/portcls/private.hpp index 17adc4c8af5..e2e600bd75e 100644 --- a/drivers/wdm/audio/backpln/portcls/private.hpp +++ b/drivers/wdm/audio/backpln/portcls/private.hpp @@ -356,6 +356,22 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\ DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(PropPositionHandler, PropPositionHandler)\ } + +#define DEFINE_KSPROPERTY_ITEM_DRMAUDIOSTREAM_CONTENTID(SetHandler)\ + DEFINE_KSPROPERTY_ITEM(\ + KSPROPERTY_DRMAUDIOSTREAM_CONTENTID,\ + NULL,\ + sizeof(KSPROPERTY),\ + sizeof(ULONG),\ + (SetHandler),\ + NULL, 0, NULL, NULL, 0) + +#define DEFINE_KSPROPERTY_DRMSET(PinSet,\ + PropPositionHandler)\ +DEFINE_KSPROPERTY_TABLE(PinSet) {\ + DEFINE_KSPROPERTY_ITEM_DRMAUDIOSTREAM_CONTENTID(PropPositionHandler)\ +} + #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\ PropGeneral, PropInstances, PropIntersection)\ DEFINE_KSPROPERTY_TABLE(PinSet) {\ diff --git a/drivers/wdm/audio/backpln/portcls/undoc.cpp b/drivers/wdm/audio/backpln/portcls/undoc.cpp index f65af7e69a5..2837123897f 100644 --- a/drivers/wdm/audio/backpln/portcls/undoc.cpp +++ b/drivers/wdm/audio/backpln/portcls/undoc.cpp @@ -8,22 +8,6 @@ #include "private.hpp" - -KSPIN_INTERFACE PinInterfaces[] = -{ - { - {STATIC_KSINTERFACESETID_Standard}, - KSINTERFACE_STANDARD_STREAMING, - 0 - }, - { - {STATIC_KSINTERFACESETID_Standard}, - KSINTERFACE_STANDARD_LOOPED_STREAMING, - 0 - } -}; - - NTSTATUS NTAPI KsoDispatchCreateWithGenericFactory( @@ -87,334 +71,429 @@ PcHandleDisableEventWithTable( } NTSTATUS -PcHandleGuidNullRequest( - IN OUT PIRP Irp, +NTAPI +PcHandlePropertyWithTable( + IN PIRP Irp, + IN ULONG PropertySetCount, + IN PKSPROPERTY_SET PropertySet, IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) { - PPCNODE_DESCRIPTOR Node; - PPCPROPERTY_ITEM PropertyItem; PIO_STACK_LOCATION IoStack; - PKSP_NODE Property; - LPGUID Buffer; - ULONG Count = 0, SubIndex, Index; // get current irp stack location IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; - - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) + if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSPROPERTY)) { - // request is out of bounds - Irp->IoStatus.Information = 0; + // certainly an invalid request return STATUS_INVALID_PARAMETER; } - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); + // store device descriptor + KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; - if (!Node->AutomationTable) - { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_INVALID_PARAMETER; - } + // then try KsPropertyHandler + return KsPropertyHandler(Irp, PropertySetCount, PropertySet); +} - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); - - Buffer = (LPGUID)AllocateItem(NonPagedPool, sizeof (GUID) * Node->AutomationTable->PropertyCount, TAG_PORTCLASS); - if (!Buffer) - return STATUS_INSUFFICIENT_RESOURCES; - - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; - for (Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) - { - BOOL Found = FALSE; - for (SubIndex = 0; SubIndex < Count; SubIndex++) - { - if (IsEqualGUIDAligned(Buffer[SubIndex], *PropertyItem->Set)) - { - Found = TRUE; - break; - } - } - if (!Found) - { - RtlMoveMemory(&Buffer[Count], PropertyItem->Set, sizeof (GUID)); - Count++; - } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); - } - - // store result length - Irp->IoStatus.Information = sizeof (GUID) * Count; - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof (GUID) * Count) - { - // buffer too small - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_MORE_ENTRIES; - } - - RtlMoveMemory(Irp->UserBuffer, Buffer, sizeof (GUID) * Count); - FreeItem(Buffer, TAG_PORTCLASS); - return STATUS_SUCCESS; +VOID +NTAPI +PcAcquireFormatResources( + LONG Unknown, + LONG Unknown2, + LONG Unknown3, + LONG Unknown4) +{ + UNIMPLEMENTED; +} + +NTSTATUS +PcAddToEventTable( + PVOID Ptr, + LONG Unknown2, + ULONG Length, + LONG Unknown3, + LONG Unknown4, + LONG Unknown5, + LONG Unknown6, + LONG Unknown7) +{ + UNIMPLEMENTED; + return STATUS_NOT_IMPLEMENTED; } NTSTATUS -PcFindNodePropertyHandler( - PIRP Irp, - PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, - OUT PPCPROPERTY_ITEM * OutPropertyItem) +NTAPI +PropertyItemDispatch( + IN PIRP Irp, + IN PKSIDENTIFIER Request, + IN OUT PVOID Data) { - PPCNODE_DESCRIPTOR Node; + 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; - PKSP_NODE Property; - ULONG Index; + ULONG InstanceSize, ValueSize, Index; + PVOID Instance; + NTSTATUS Status; - // get current irp stack location + // 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); - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + // get input property request + Property = (PKSPROPERTY)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + + // 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 = Data; + ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; + + // initialize property request + PropertyRequest->MajorTarget = Descriptor->UnknownMiniport; + PropertyRequest->MinorTarget = Descriptor->UnknownStream; + PropertyRequest->Irp = Irp; + PropertyRequest->Verb = Property->Flags; - if (Property->NodeId >= SubDeviceDescriptor->DeviceDescriptor->NodeCount) + + // check if this is filter / pin property request + if (!(Property->Flags & KSPROPERTY_TYPE_TOPOLOGY)) { - // request is out of bounds - DPRINT("InvalidIndex %u %u\n", Property->NodeId, SubDeviceDescriptor->DeviceDescriptor->NodeCount); - return STATUS_INVALID_PARAMETER; + // 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)); - Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); + // cast node property request + NodeProperty = (PKSNODEPROPERTY)Request; - if (!Node->AutomationTable) + // store node id + PropertyRequest->Node = NodeProperty->NodeId; + } + else { - // request is out of bounds - Irp->IoStatus.Information = 0; - return STATUS_NOT_FOUND; + // invalid buffer size + return STATUS_INVALID_BUFFER_SIZE; } - // sanity checks - PC_ASSERT(Node->AutomationTable); - PC_ASSERT(Node->AutomationTable->PropertyCount); - PC_ASSERT(Node->AutomationTable->PropertyItemSize); + // store instance size + PropertyRequest->InstanceSize = InstanceSize; + PropertyRequest->Instance = (InstanceSize != 0 ? Instance : NULL); - PropertyItem = (PCPROPERTY_ITEM*)Node->AutomationTable->Properties; + // store value size + PropertyRequest->ValueSize = ValueSize; + PropertyRequest->Value = (ValueSize != 0 ? Irp->UserBuffer : NULL); - DPRINT("NodeId %u PropertyCount %u\n", Property->NodeId, Node->AutomationTable->PropertyCount); - for(Index = 0; Index < Node->AutomationTable->PropertyCount; Index++) + // now scan the property set for the attached property set item stored in Relations member + if (PropertySet) { - if (IsEqualGUIDAligned(*PropertyItem->Set, Property->Property.Set) && PropertyItem->Id == Property->Property.Id) + // sanity check + PC_ASSERT(IsEqualGUIDAligned(Property->Set, *PropertySet->Set)); + + for(Index = 0; Index < PropertySet->PropertiesCount; Index++) { - //found property handler - *OutPropertyItem = PropertyItem; - return STATUS_SUCCESS; + // 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; + } } - PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + Node->AutomationTable->PropertyItemSize); } - // no handler yet found - DPRINT("NotFound\n"); - return STATUS_NOT_FOUND; + // 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; + + // 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); + DPRINT1("Calling Node %lu MajorTarget %p MinorTarget %p PropertySet %S PropertyId %lu PropertyFlags %lx InstanceSize %lu ValueSize %lu Handler %p PropertyRequest %p\n", + PropertyRequest->Node, PropertyRequest->MajorTarget, PropertyRequest->MinorTarget, GuidBuffer.Buffer, Property->Id, Property->Flags, PropertyRequest->InstanceSize, PropertyRequest->ValueSize, + PropertyRequest->PropertyItem->Handler, PropertyRequest); + Status = PropertyRequest->PropertyItem->Handler(PropertyRequest); + + 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 -PcNodeBasicSupportHandler( - PIRP Irp, - PPCPROPERTY_ITEM PropertyItem) +PcAddToPropertyTable( + IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor, + IN PPCPROPERTY_ITEM PropertyItem, + IN ULONG bNode) { - PULONG Flags; - PIO_STACK_LOCATION IoStack; - PKSPROPERTY_DESCRIPTION Description; - PKSP_NODE Property; + ULONG bFound = FALSE; + ULONG Index, PropertySetIndex, PropertySetItemIndex; + PKSPROPERTY_SET NewPropertySet; + PKSPROPERTY_ITEM FilterPropertyItem, NewFilterPropertyItem; + LPGUID Guid; + //UNICODE_STRING GuidBuffer; - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); - - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; +ASSERT(PropertyItem->Set); + // RtlStringFromGUID(*PropertyItem->Set, &GuidBuffer); + // DPRINT1("PcAddToPropertyTable Adding Item Set %S Id %lu Flags %lx\n", GuidBuffer.Buffer, PropertyItem->Id, PropertyItem->Flags); - PC_ASSERT(IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(ULONG)); - Flags= (PULONG)Irp->UserBuffer; - // reset flags - *Flags = 0; - if (PropertyItem->Flags & KSPROPERTY_TYPE_SET) - *Flags |= KSPROPERTY_TYPE_SET; + //DPRINT1("FilterPropertySetCount %lu\n", SubDeviceDescriptor->FilterPropertySetCount); + // first step check if the property set is present already + for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySetCount; Index++) + { - if (PropertyItem->Flags & KSPROPERTY_TYPE_GET) - *Flags |= KSPROPERTY_TYPE_GET; + //RtlStringFromGUID(*SubDeviceDescriptor->FilterPropertySet[Index].Set, &GuidBuffer); + //DPRINT1("FilterProperty Set %S PropertyCount %lu\n", GuidBuffer.Buffer, SubDeviceDescriptor->FilterPropertySet[Index].PropertiesCount); + if (IsEqualGUIDAligned(*SubDeviceDescriptor->FilterPropertySet[Index].Set, *PropertyItem->Set)) + { + // property set is already present + bFound = TRUE; + PropertySetIndex = Index; - // store result length - Irp->IoStatus.Information = sizeof(ULONG); + // break out + break; + } + } - if (IoStack->Parameters.DeviceIoControl.OutputBufferLength >= sizeof(KSPROPERTY_DESCRIPTION)) + // is the property set present + if (!bFound) { - // get output buffer - Description = (PKSPROPERTY_DESCRIPTION)Irp->UserBuffer; - - // store result - Description->DescriptionSize = sizeof(KSPROPERTY_DESCRIPTION); - Description->PropTypeSet.Set = KSPROPTYPESETID_General; - Description->PropTypeSet.Id = 0; - Description->PropTypeSet.Flags = 0; - Description->MembersListCount = 0; - Description->Reserved = 0; - - Irp->IoStatus.Information = sizeof(KSPROPERTY_DESCRIPTION); - } - return STATUS_SUCCESS; -} + // need to allocate a property set + NewPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySetCount + 1) * sizeof(KSPROPERTY_SET), TAG_PORTCLASS); + if (!NewPropertySet) + { + // out of memory + return STATUS_INSUFFICIENT_RESOURCES; + } + // need to allocate property set guid + Guid = (LPGUID)AllocateItem(NonPagedPool, sizeof(GUID), TAG_PORTCLASS); + if (!Guid) + { + // out of memory + FreeItem(NewPropertySet, TAG_PORTCLASS); + return STATUS_INSUFFICIENT_RESOURCES; + } -NTSTATUS -PcHandleNodePropertyRequest( - PIRP Irp, - IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) -{ - PIO_STACK_LOCATION IoStack; - PPCPROPERTY_ITEM PropertyItem; - PPCPROPERTY_REQUEST PropertyRequest; - PKSP_NODE Property; - NTSTATUS Status; + // are any existing property sets + if (SubDeviceDescriptor->FilterPropertySetCount) + { + // copy property sets + RtlMoveMemory(NewPropertySet, SubDeviceDescriptor->FilterPropertySet, SubDeviceDescriptor->FilterPropertySetCount * sizeof(KSPROPERTY_SET)); - // get current irp stack location - IoStack = IoGetCurrentIrpStackLocation(Irp); + // release memory + FreeItem(SubDeviceDescriptor->FilterPropertySet, TAG_PORTCLASS); + } - if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSP_NODE)) - { - // certainly not a node property request - return STATUS_NOT_FOUND; - } + // store new property set descriptors + SubDeviceDescriptor->FilterPropertySet = NewPropertySet; - // access property - Property = (PKSP_NODE)IoStack->Parameters.DeviceIoControl.Type3InputBuffer; + // store index + PropertySetIndex = SubDeviceDescriptor->FilterPropertySetCount; - if (IsEqualGUIDAligned(Property->Property.Set, GUID_NULL) && Property->Property.Id == 0 && Property->Property.Flags == (KSPROPERTY_TYPE_SETSUPPORT | KSPROPERTY_TYPE_TOPOLOGY)) - { - return PcHandleGuidNullRequest(Irp, SubDeviceDescriptor); + // increment property set count + SubDeviceDescriptor->FilterPropertySetCount++; + + // copy property guid + RtlMoveMemory(Guid, PropertyItem->Set, sizeof(GUID)); + + // initialize property set + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].Set = Guid; + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount = 0; } - // find property handler - Status = PcFindNodePropertyHandler(Irp, SubDeviceDescriptor, &PropertyItem); + // as the property set has been indentified, now search for duplicate property set item entries + FilterPropertyItem = (PKSPROPERTY_ITEM)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem; + bFound = FALSE; - // check for success - if (!NT_SUCCESS(Status)) + for(Index = 0; Index < SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; Index++) { - // might not be a node property request - DPRINT("NotFound\n"); - return STATUS_NOT_FOUND; + // now search for an equal property set item + if (FilterPropertyItem->PropertyId == PropertyItem->Id) + { + // found existing property set item + bFound = TRUE; + PropertySetItemIndex = Index; + break; + } + + // move to next entry + FilterPropertyItem++; } - if (Property->Property.Flags & KSPROPERTY_TYPE_BASICSUPPORT) + if (!bFound) { - // caller issued a basic property request - if (!(PropertyItem->Flags & KSPROPERTY_TYPE_BASICSUPPORT)) + // need to allocate memory for new property set item + NewFilterPropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount + 1) * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); + if (!NewFilterPropertyItem) { - // driver does not have a basic support handler - return PcNodeBasicSupportHandler(Irp, PropertyItem); + // out of memory + return STATUS_INSUFFICIENT_RESOURCES; } - } - // sanity check - PC_ASSERT(SubDeviceDescriptor->UnknownMiniport); + // are any existing property set items + if (SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount) + { + // copy property item sets + RtlMoveMemory(NewFilterPropertyItem, + (PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount * sizeof(KSPROPERTY_ITEM)); - // allocate a property request - PropertyRequest = (PPCPROPERTY_REQUEST)AllocateItem(NonPagedPool, sizeof(PCPROPERTY_REQUEST), TAG_PORTCLASS); - if (!PropertyRequest) - return STATUS_INSUFFICIENT_RESOURCES; + // release old descriptors + FreeItem((PVOID)SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem, TAG_PORTCLASS); + } - // initialize property request - PropertyRequest->MajorTarget = SubDeviceDescriptor->UnknownMiniport; - PropertyRequest->MinorTarget = SubDeviceDescriptor->UnknownStream; - PropertyRequest->Irp = Irp; - PropertyRequest->Node = Property->NodeId; - PropertyRequest->PropertyItem = PropertyItem; - PropertyRequest->Verb = Property->Property.Flags; - PropertyRequest->InstanceSize = IoStack->Parameters.DeviceIoControl.InputBufferLength - sizeof(KSNODEPROPERTY); - PropertyRequest->Instance = (PVOID)((ULONG_PTR)IoStack->Parameters.DeviceIoControl.Type3InputBuffer + sizeof(KSNODEPROPERTY)); - PropertyRequest->ValueSize = IoStack->Parameters.DeviceIoControl.OutputBufferLength; - PropertyRequest->Value = Irp->UserBuffer; - - Status = PropertyItem->Handler(PropertyRequest); - - if (Status != STATUS_PENDING) - { - //request completed - Irp->IoStatus.Information = PropertyRequest->ValueSize; - FreeItem(PropertyRequest, TAG_PORTCLASS); - } + // store new descriptor + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem = NewFilterPropertyItem; - // done - DPRINT("Status %x\n", Status); - return Status; -} + // store index + PropertySetItemIndex = SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount; -NTSTATUS -NTAPI -PcHandlePropertyWithTable( - IN PIRP Irp, - IN ULONG PropertySetCount, - IN PKSPROPERTY_SET PropertySet, - IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor) -{ - NTSTATUS Status; + // increment property item set count + SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertiesCount++; - // try handle it as node property request - Status = PcHandleNodePropertyRequest(Irp, SubDeviceDescriptor); + // now initialize property item + FilterPropertyItem = (PKSPROPERTY_ITEM)&SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex]; + FilterPropertyItem->PropertyId = PropertyItem->Id; + FilterPropertyItem->MinProperty = sizeof(KSPROPERTY); + FilterPropertyItem->MinData = 0; - if (Status == STATUS_NOT_FOUND) - { - // store device descriptor - KSPROPERTY_ITEM_IRP_STORAGE(Irp) = (PKSPROPERTY_ITEM)SubDeviceDescriptor; + // are any set operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_SET) + { + // setup handler + FilterPropertyItem->SetPropertyHandler = PropertyItemDispatch; + } - /* then try KsPropertyHandler */ - Status = KsPropertyHandler(Irp, PropertySetCount, PropertySet); - } + // are set operation supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) + { + // setup handler + FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; + } - return Status; -} + // are get operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_GET) + { + // setup handler + FilterPropertyItem->GetPropertyHandler = PropertyItemDispatch; + } -VOID -NTAPI -PcAcquireFormatResources( - LONG Unknown, - LONG Unknown2, - LONG Unknown3, - LONG Unknown4) -{ - UNIMPLEMENTED; -} + // are basic support operations supported + if (PropertyItem->Flags & PCPROPERTY_ITEM_FLAG_BASICSUPPORT) + { + // setup handler + FilterPropertyItem->SupportHandler = PropertyItemDispatch; + } -NTSTATUS -PcAddToEventTable( - PVOID Ptr, - LONG Unknown2, - ULONG Length, - LONG Unknown3, - LONG Unknown4, - LONG Unknown5, - LONG Unknown6, - LONG Unknown7) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; -} + if (!bNode) + { + // store property item in relations + // only store property item of filter properties / pin properties + // because filter & pin properties do not require a specific context + // on the other hand node properties are specifically bound to a node + + FilterPropertyItem->Relations = (const KSPROPERTY*)PropertyItem; + } + } + else + { + // property set item handler already present -NTSTATUS -PcAddToPropertyTable( - PVOID Ptr, - LONG Unknown, - LONG Unknown2, - LONG Unknown3, - CHAR Unknown4) -{ - UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + if (bNode) + { + // filter & pin properties should not be exposed on a node + ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations == NULL); + } + else + { + // node properties should not be exposed on a filter & pin + ASSERT(SubDeviceDescriptor->FilterPropertySet[PropertySetIndex].PropertyItem[PropertySetItemIndex].Relations != NULL); + } + } + + // done + return STATUS_SUCCESS; } NTSTATUS @@ -491,6 +570,15 @@ DumpFilterDescriptor( EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + NodeDescriptor->AutomationTable->EventItemSize); } + DPRINT1(" Index %u PropertyCount %u\n", Index, NodeDescriptor->AutomationTable->PropertyCount); + PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties; + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + RtlStringFromGUID(*PropertyItem->Set, &GuidString); + DPRINT1(" PropertyIndex %u GUID %S Id %u Flags %x\n", SubIndex, GuidString.Buffer, PropertyItem->Id, PropertyItem->Flags); + + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize); + } } @@ -539,10 +627,13 @@ PcCreateSubdeviceDescriptor( IN PPCFILTER_DESCRIPTOR FilterDescription) { SUBDEVICE_DESCRIPTOR * Descriptor; - ULONG Index; + ULONG Index, SubIndex; NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES; PPCPIN_DESCRIPTOR SrcDescriptor; + PPCNODE_DESCRIPTOR NodeDescriptor; + PPCPROPERTY_ITEM PropertyItem; + // allocate subdevice descriptor Descriptor = (PSUBDEVICE_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(SUBDEVICE_DESCRIPTOR), TAG_PORTCLASS); if (!Descriptor) return STATUS_INSUFFICIENT_RESOURCES; @@ -551,6 +642,7 @@ PcCreateSubdeviceDescriptor( InitializeListHead(&Descriptor->SymbolicLinkList); InitializeListHead(&Descriptor->PhysicalConnectionList); + //FIXME add driver category guids Descriptor->Interfaces = (GUID*)AllocateItem(NonPagedPool, sizeof(GUID) * InterfaceCount, TAG_PORTCLASS); if (!Descriptor->Interfaces) goto cleanup; @@ -559,98 +651,215 @@ PcCreateSubdeviceDescriptor( RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount); Descriptor->InterfaceCount = InterfaceCount; + //DumpFilterDescriptor(FilterDescription); + + // are any property sets supported by the portcls if (FilterPropertiesCount) { - /// FIXME - /// handle driver properties - - DumpFilterDescriptor(FilterDescription); - + // first allocate filter properties set Descriptor->FilterPropertySet = (PKSPROPERTY_SET)AllocateItem(NonPagedPool, sizeof(KSPROPERTY_SET) * FilterPropertiesCount, TAG_PORTCLASS); if (! Descriptor->FilterPropertySet) goto cleanup; + // now copy all filter property sets Descriptor->FilterPropertySetCount = FilterPropertiesCount; for(Index = 0; Index < FilterPropertiesCount; Index++) { + // copy property set RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_SET)); - } - } - - Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); - if (!Descriptor->Topology) - goto cleanup; - if (FilterDescription->ConnectionCount) - { - Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyConnections) - goto cleanup; - - RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR)); - Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount; + if (Descriptor->FilterPropertySet[Index].PropertiesCount) + { + // copy property items to make sure they are dynamically allocated + Descriptor->FilterPropertySet[Index].PropertyItem = (PKSPROPERTY_ITEM)AllocateItem(NonPagedPool, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM), TAG_PORTCLASS); + if (!Descriptor->FilterPropertySet[Index].PropertyItem) + { + // no memory + goto cleanup; + } + + // copy filter property items + RtlMoveMemory((PVOID)Descriptor->FilterPropertySet[Index].PropertyItem, FilterProperties[Index].PropertyItem, FilterProperties[Index].PropertiesCount * sizeof(KSPROPERTY_ITEM)); + } + } } - if (FilterDescription->NodeCount) + // now check if the filter descriptor supports filter properties + if (FilterDescription->AutomationTable) { - Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyNodes) - goto cleanup; + // get first entry + PropertyItem = (PPCPROPERTY_ITEM)FilterDescription->AutomationTable->Properties; - Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); - if (!Descriptor->Topology->TopologyNodesNames) - goto cleanup; - - for(Index = 0; Index < FilterDescription->NodeCount; Index++) + // copy driver filter property sets + for(Index = 0; Index < FilterDescription->AutomationTable->PropertyCount; Index++) { - if (FilterDescription->Nodes[Index].Type) - { - RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], FilterDescription->Nodes[Index].Type, sizeof(GUID)); - } - if (FilterDescription->Nodes[Index].Name) + // add the property item + Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); + + // check for success + if (Status != STATUS_SUCCESS) { - RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], FilterDescription->Nodes[Index].Name, sizeof(GUID)); + // goto cleanup + goto cleanup; } + + // move to next entry + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + FilterDescription->AutomationTable->PropertyItemSize); } - Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; } + // check if the filter has pins if (FilterDescription->PinCount) { + // allocate pin factory descriptors Descriptor->Factory.KsPinDescriptor = (PKSPIN_DESCRIPTOR)AllocateItem(NonPagedPool, sizeof(KSPIN_DESCRIPTOR) * FilterDescription->PinCount, TAG_PORTCLASS); if (!Descriptor->Factory.KsPinDescriptor) goto cleanup; + // allocate pin instance info Descriptor->Factory.Instances = (PPIN_INSTANCE_INFO)AllocateItem(NonPagedPool, FilterDescription->PinCount * sizeof(PIN_INSTANCE_INFO), TAG_PORTCLASS); if (!Descriptor->Factory.Instances) goto cleanup; + // initialize pin factory descriptor Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount; Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR); + // grab first entry SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins; - DPRINT("Size %u Expected %u\n", FilterDescription->PinSize, sizeof(PCPIN_DESCRIPTOR)); // copy pin factories for(Index = 0; Index < FilterDescription->PinCount; Index++) { + // copy pin descriptor RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_DESCRIPTOR)); - Descriptor->Factory.KsPinDescriptor[Index].Interfaces = PinInterfaces; - Descriptor->Factory.KsPinDescriptor[Index].InterfacesCount = sizeof(PinInterfaces) / sizeof(KSPIN_INTERFACE); - - DPRINT("Index %u DataRangeCount %u\n", Index, SrcDescriptor->KsPinDescriptor.DataRangesCount); - + // initialize pin factory instance data Descriptor->Factory.Instances[Index].CurrentPinInstanceCount = 0; Descriptor->Factory.Instances[Index].MaxFilterInstanceCount = SrcDescriptor->MaxFilterInstanceCount; Descriptor->Factory.Instances[Index].MaxGlobalInstanceCount = SrcDescriptor->MaxGlobalInstanceCount; Descriptor->Factory.Instances[Index].MinFilterInstanceCount = SrcDescriptor->MinFilterInstanceCount; + + // check if the descriptor has an automation table + if (SrcDescriptor->AutomationTable) + { + // it has, grab first entry + PropertyItem = (PPCPROPERTY_ITEM)SrcDescriptor->AutomationTable->Properties; + + // now add all supported property items + for(SubIndex = 0; SubIndex < SrcDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + // add the property item to the table + Status = PcAddToPropertyTable(Descriptor, PropertyItem, FALSE); + + // check for success + if (Status != STATUS_SUCCESS) + { + // goto cleanup + goto cleanup; + } + + // move to next entry + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + SrcDescriptor->AutomationTable->PropertyItemSize); + } + } + + // move to next entry SrcDescriptor = (PPCPIN_DESCRIPTOR)((ULONG_PTR)SrcDescriptor + FilterDescription->PinSize); } } + // allocate topology descriptor + Descriptor->Topology = (PKSTOPOLOGY)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY), TAG_PORTCLASS); + if (!Descriptor->Topology) + goto cleanup; + + // are there any connections + if (FilterDescription->ConnectionCount) + { + // allocate connection descriptor + Descriptor->Topology->TopologyConnections = (PKSTOPOLOGY_CONNECTION)AllocateItem(NonPagedPool, sizeof(KSTOPOLOGY_CONNECTION) * FilterDescription->ConnectionCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyConnections) + goto cleanup; + + // copy connection descriptor + RtlMoveMemory((PVOID)Descriptor->Topology->TopologyConnections, FilterDescription->Connections, FilterDescription->ConnectionCount * sizeof(PCCONNECTION_DESCRIPTOR)); + + // store connection count + Descriptor->Topology->TopologyConnectionsCount = FilterDescription->ConnectionCount; + } + + // does the filter have nodes + if (FilterDescription->NodeCount) + { + // allocate topology node types array + Descriptor->Topology->TopologyNodes = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodes) + goto cleanup; + + // allocate topology node names array + Descriptor->Topology->TopologyNodesNames = (const GUID *)AllocateItem(NonPagedPool, sizeof(GUID) * FilterDescription->NodeCount, TAG_PORTCLASS); + if (!Descriptor->Topology->TopologyNodesNames) + goto cleanup; + + // grab first entry + NodeDescriptor = (PPCNODE_DESCRIPTOR)FilterDescription->Nodes; + + // iterate all nodes and copy node types / names and node properties + for(Index = 0; Index < FilterDescription->NodeCount; Index++) + { + // does it have a type + if (NodeDescriptor->Type) + { + // copy node type + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodes[Index], NodeDescriptor->Type, sizeof(GUID)); + } + + // does it have a node name + if (NodeDescriptor->Name) + { + // copy node name + RtlMoveMemory((PVOID)&Descriptor->Topology->TopologyNodesNames[Index], NodeDescriptor->Name, sizeof(GUID)); + } + + // check if has an automation table + if (NodeDescriptor->AutomationTable) + { + // grab first entry + PropertyItem = (PPCPROPERTY_ITEM)NodeDescriptor->AutomationTable->Properties; + + // copy all node properties into the global property set + for(SubIndex = 0; SubIndex < NodeDescriptor->AutomationTable->PropertyCount; SubIndex++) + { + // add to property set + Status = PcAddToPropertyTable(Descriptor, PropertyItem, TRUE); + + // check for success + if (Status != STATUS_SUCCESS) + { + // failed + goto cleanup; + } + + // move to next property item + PropertyItem = (PPCPROPERTY_ITEM)((ULONG_PTR)PropertyItem + NodeDescriptor->AutomationTable->PropertyItemSize); + } + } + + // move to next descriptor + NodeDescriptor = (PPCNODE_DESCRIPTOR)((ULONG_PTR)NodeDescriptor + FilterDescription->NodeSize); + } + + // now store the topology node count + Descriptor->Topology->TopologyNodesCount = FilterDescription->NodeCount; + } + + // store descriptor Descriptor->DeviceDescriptor = FilterDescription; + + // store result *OutSubdeviceDescriptor = Descriptor; + // done return STATUS_SUCCESS; cleanup: diff --git a/hal/halx86/generic/usage.c b/hal/halx86/generic/usage.c index c35df96c3e5..be6710d73fd 100644 --- a/hal/halx86/generic/usage.c +++ b/hal/halx86/generic/usage.c @@ -235,8 +235,9 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName, if (!HalpGetInfoFromACPI) { /* No, so use our local table */ - Port = HalpComPortIrqMapping[0][0]; - for (i = 0; Port; i++) + for (i = 0, Port = HalpComPortIrqMapping[i][0]; + Port; + i++, Port = HalpComPortIrqMapping[i][0]) { /* Is this the port we want? */ if (Port == (ULONG_PTR)KdComPortInUse) @@ -248,9 +249,6 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName, PRIMARY_VECTOR_BASE, HIGH_LEVEL); } - - /* Next port */ - Port = HalpComPortIrqMapping[i][0]; } } } @@ -509,6 +507,9 @@ HalpEnableInterruptHandler(IN UCHAR Flags, IN PVOID Handler, IN KINTERRUPT_MODE Mode) { + /* Set the IDT_LATCHED flag for latched interrupts */ + if (Mode == Latched) Flags |= IDT_LATCHED; + /* Register the vector */ HalpRegisterVector(Flags, BusVector, SystemVector, Irql); diff --git a/include/psdk/ks.h b/include/psdk/ks.h index 62357d623a1..7f99f136077 100644 --- a/include/psdk/ks.h +++ b/include/psdk/ks.h @@ -1005,11 +1005,6 @@ DEFINE_GUIDSTRUCT("97E99BA0-BDEA-11CF-A5D6-28DB04C10000", KSPROPTYPESETID_Genera KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY */ -#define KSPROPSETID_DrmAudioStream -/* - KSPROPERTY_DRMAUDIOSTREAM_CONTENTID -*/ - #define KSPROPSETID_Hrtf3d /* KSPROPERTY_HRTF3D_FILTER_FORMAT diff --git a/include/psdk/ksmedia.h b/include/psdk/ksmedia.h index 32e5e3e5269..5a34bba37e6 100644 --- a/include/psdk/ksmedia.h +++ b/include/psdk/ksmedia.h @@ -565,6 +565,15 @@ typedef struct { #endif // !_NTDDK_ } LOOPEDSTREAMING_POSITION_EVENT_DATA, *PLOOPEDSTREAMING_POSITION_EVENT_DATA ; +#define STATIC_KSPROPSETID_DrmAudioStream\ + 0x2f2c8ddd, 0x4198, 0x4fac, 0xba, 0x29, 0x61, 0xbb, 0x5, 0xb7, 0xde, 0x6 +DEFINE_GUIDSTRUCT("2F2C8DDD-4198-4fac-BA29-61BB05B7DE06", KSPROPSETID_DrmAudioStream); +#define KSPROPSETID_DrmAudioStream DEFINE_GUIDNAMED(KSPROPSETID_DrmAudioStream) + +typedef enum { + KSPROPERTY_DRMAUDIOSTREAM_CONTENTID +} KSPROPERTY_DRMAUDIOSTREAM; + /* SysAudio Properties diff --git a/ntoskrnl/include/internal/io.h b/ntoskrnl/include/internal/io.h index 28bc779111c..bf676b610f1 100644 --- a/ntoskrnl/include/internal/io.h +++ b/ntoskrnl/include/internal/io.h @@ -514,6 +514,21 @@ IopAssignDeviceResources( IN PDEVICE_NODE DeviceNode ); +NTSTATUS +NTAPI +IopCreateResourceListFromRequirements( + IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, + OUT PCM_RESOURCE_LIST *ResourceList +); + +NTSTATUS +NTAPI +IopDetectResourceConflict( + IN PCM_RESOURCE_LIST ResourceList, + IN BOOLEAN Silent, + OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor +); + // // PNP Routines // diff --git a/ntoskrnl/io/iomgr/iorsrce.c b/ntoskrnl/io/iomgr/iorsrce.c index af5913146c6..9d52881ce12 100644 --- a/ntoskrnl/io/iomgr/iorsrce.c +++ b/ntoskrnl/io/iomgr/iorsrce.c @@ -841,7 +841,7 @@ IoGetConfigurationInformation(VOID) } /* - * @unimplemented + * @halfplemented */ NTSTATUS NTAPI IoReportResourceUsage(PUNICODE_STRING DriverClassName, @@ -876,13 +876,48 @@ IoReportResourceUsage(PUNICODE_STRING DriverClassName, * a conflict is detected with another driver. */ { - UNIMPLEMENTED; - *ConflictDetected = FALSE; - return STATUS_SUCCESS; + NTSTATUS Status; + PCM_RESOURCE_LIST ResourceList; + + DPRINT1("IoReportResourceUsage is halfplemented!\n"); + + if (!DriverList && !DeviceList) + return STATUS_INVALID_PARAMETER; + + if (DeviceList) + ResourceList = DeviceList; + else + ResourceList = DriverList; + + Status = IopDetectResourceConflict(ResourceList, FALSE, NULL); + if (Status == STATUS_CONFLICTING_ADDRESSES) + { + *ConflictDetected = TRUE; + + if (!OverrideConflict) + { + DPRINT1("Denying an attempt to claim resources currently in use by another device!\n"); + return STATUS_CONFLICTING_ADDRESSES; + } + else + { + DPRINT1("Proceeding with conflicting resources\n"); + } + } + else if (!NT_SUCCESS(Status)) + { + return Status; + } + + /* TODO: Claim resources in registry */ + + *ConflictDetected = FALSE; + + return STATUS_SUCCESS; } /* - * @unimplemented + * @halfplemented */ NTSTATUS NTAPI IoAssignResources(PUNICODE_STRING RegistryPath, @@ -892,8 +927,23 @@ IoAssignResources(PUNICODE_STRING RegistryPath, PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources, PCM_RESOURCE_LIST* AllocatedResources) { - UNIMPLEMENTED; - return(STATUS_NOT_IMPLEMENTED); + NTSTATUS Status; + + DPRINT1("IoAssignResources is halfplemented!\n"); + + Status = IopCreateResourceListFromRequirements(RequestedResources, + AllocatedResources); + if (!NT_SUCCESS(Status)) + { + if (Status == STATUS_CONFLICTING_ADDRESSES) + DPRINT1("Denying an attempt to claim resources currently in use by another device!\n"); + + return Status; + } + + /* TODO: Claim resources in registry */ + + return STATUS_SUCCESS; } /* diff --git a/ntoskrnl/io/pnpmgr/pnpreport.c b/ntoskrnl/io/pnpmgr/pnpreport.c index 165b0b06f59..94a20dc18ce 100644 --- a/ntoskrnl/io/pnpmgr/pnpreport.c +++ b/ntoskrnl/io/pnpmgr/pnpreport.c @@ -38,9 +38,6 @@ NTSTATUS IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode, PVOID Context); -NTSTATUS -IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList); - NTSTATUS PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject, IN OUT PKEVENT SyncEvent OPTIONAL, @@ -379,7 +376,7 @@ IoReportResourceForDetection(IN PDRIVER_OBJECT DriverObject, ResourceList = DriverList; /* Look for a resource conflict */ - Status = IopDetectResourceConflict(ResourceList); + Status = IopDetectResourceConflict(ResourceList, FALSE, NULL); if (Status == STATUS_CONFLICTING_ADDRESSES) { /* Oh noes */ diff --git a/ntoskrnl/io/pnpmgr/pnpres.c b/ntoskrnl/io/pnpmgr/pnpres.c index 71319f8abd1..733440dd5fb 100644 --- a/ntoskrnl/io/pnpmgr/pnpres.c +++ b/ntoskrnl/io/pnpmgr/pnpres.c @@ -12,12 +12,6 @@ #define NDEBUG #include -NTSTATUS -IopDetectResourceConflict( - IN PCM_RESOURCE_LIST ResourceList, - IN BOOLEAN Silent, - OUT OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor); - static BOOLEAN IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor) @@ -187,8 +181,8 @@ IopFindInterruptResource( return FALSE; } -static -NTSTATUS + +NTSTATUS NTAPI IopCreateResourceListFromRequirements( IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList, OUT PCM_RESOURCE_LIST *ResourceList) @@ -336,9 +330,6 @@ IopCheckResourceDescriptor( ULONG i, ii; BOOLEAN Result = FALSE; - if (ResDesc->ShareDisposition == CmResourceShareShared) - return FALSE; - for (i = 0; i < ResourceList->Count; i++) { PCM_PARTIAL_RESOURCE_LIST ResList = &ResourceList->List[i].PartialResourceList; @@ -615,40 +606,61 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 if (DeviceNode->ResourceList) { - PWCHAR DeviceName = NULL; UNICODE_STRING NameU; - UNICODE_STRING Suffix; + UNICODE_STRING RawSuffix, TranslatedSuffix; ULONG OldLength = 0; ASSERT(DeviceNode->ResourceListTranslated); + + RtlInitUnicodeString(&TranslatedSuffix, L".Translated"); + RtlInitUnicodeString(&RawSuffix, L".Raw"); Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, DevicePropertyPhysicalDeviceObjectName, 0, NULL, &OldLength); - if ((OldLength != 0) && (Status == STATUS_BUFFER_TOO_SMALL)) - { - DeviceName = ExAllocatePool(NonPagedPool, OldLength); - ASSERT(DeviceName); - - IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, - DevicePropertyPhysicalDeviceObjectName, - OldLength, - DeviceName, - &OldLength); - - RtlInitUnicodeString(&NameU, DeviceName); - } - else - { - /* Some failure */ - ASSERT(!NT_SUCCESS(Status)); - return Status; - } - - RtlInitUnicodeString(&Suffix, L".Raw"); - RtlAppendUnicodeStringToString(&NameU, &Suffix); + if (Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) + { + ASSERT(OldLength); + + NameU.Buffer = ExAllocatePool(PagedPool, OldLength + TranslatedSuffix.Length); + if (!NameU.Buffer) + { + ZwClose(PnpMgrLevel2); + return STATUS_INSUFFICIENT_RESOURCES; + } + + NameU.Length = 0; + NameU.MaximumLength = OldLength + TranslatedSuffix.Length; + + Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject, + DevicePropertyPhysicalDeviceObjectName, + NameU.MaximumLength, + NameU.Buffer, + &OldLength); + if (!NT_SUCCESS(Status)) + { + ZwClose(PnpMgrLevel2); + ExFreePool(NameU.Buffer); + return Status; + } + } + else if (!NT_SUCCESS(Status)) + { + /* Some failure */ + ZwClose(PnpMgrLevel2); + return Status; + } + else + { + /* This should never happen */ + ASSERT(FALSE); + } + + NameU.Length = OldLength; + + RtlAppendUnicodeStringToString(&NameU, &RawSuffix); Status = ZwSetValueKey(PnpMgrLevel2, &NameU, @@ -659,14 +671,14 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 if (!NT_SUCCESS(Status)) { ZwClose(PnpMgrLevel2); + ExFreePool(NameU.Buffer); return Status; } /* "Remove" the suffix by setting the length back to what it used to be */ - NameU.Length = (USHORT)OldLength; + NameU.Length = OldLength; - RtlInitUnicodeString(&Suffix, L".Translated"); - RtlAppendUnicodeStringToString(&NameU, &Suffix); + RtlAppendUnicodeStringToString(&NameU, &TranslatedSuffix); Status = ZwSetValueKey(PnpMgrLevel2, &NameU, @@ -675,8 +687,8 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2 DeviceNode->ResourceListTranslated, PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated)); ZwClose(PnpMgrLevel2); - ASSERT(DeviceName); - ExFreePool(DeviceName); + ExFreePool(NameU.Buffer); + if (!NT_SUCCESS(Status)) return Status; } @@ -718,7 +730,7 @@ IopTranslateDeviceResources( DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize); if (!DeviceNode->ResourceListTranslated) { - Status =STATUS_NO_MEMORY; + Status = STATUS_NO_MEMORY; goto cleanup; } RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize); @@ -743,6 +755,7 @@ IopTranslateDeviceResources( &DescriptorTranslated->u.Port.Start)) { Status = STATUS_UNSUCCESSFUL; + DPRINT1("Failed to translate port resource (Start: 0xI64x)\n", DescriptorRaw->u.Port.Start.QuadPart); goto cleanup; } break; @@ -756,6 +769,14 @@ IopTranslateDeviceResources( DescriptorRaw->u.Interrupt.Vector, (PKIRQL)&DescriptorTranslated->u.Interrupt.Level, &DescriptorTranslated->u.Interrupt.Affinity); + + if (!DescriptorTranslated->u.Interrupt.Vector) + { + Status = STATUS_UNSUCCESSFUL; + DPRINT1("Failed to translate interrupt resource (Vector: 0x%x | Level: 0x%x)\n", DescriptorRaw->u.Interrupt.Vector, + DescriptorRaw->u.Interrupt.Level); + goto cleanup; + } break; } case CmResourceTypeMemory: @@ -769,6 +790,7 @@ IopTranslateDeviceResources( &DescriptorTranslated->u.Memory.Start)) { Status = STATUS_UNSUCCESSFUL; + DPRINT1("Failed to translate memory resource (Start: 0xI64x)\n", DescriptorRaw->u.Memory.Start.QuadPart); goto cleanup; } } @@ -864,16 +886,21 @@ IopAssignDeviceResources( Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements, &DeviceNode->ResourceList); if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to create a resource list from supplied resources for %wZ\n", &DeviceNode->InstancePath); goto ByeBye; + } - Status = IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL); - if (!NT_SUCCESS(Status)) - goto ByeBye; + /* IopCreateResourceListFromRequirements should NEVER succeed with a conflicting list */ + ASSERT(IopDetectResourceConflict(DeviceNode->ResourceList, FALSE, NULL) != STATUS_CONFLICTING_ADDRESSES); Finish: Status = IopTranslateDeviceResources(DeviceNode); if (!NT_SUCCESS(Status)) + { + DPRINT1("Failed to translate resources for %wZ\n", &DeviceNode->InstancePath); goto ByeBye; + } Status = IopUpdateResourceMapForPnPDevice(DeviceNode); if (!NT_SUCCESS(Status)) @@ -935,7 +962,7 @@ ByeBye: return Result; } -NTSTATUS +NTSTATUS NTAPI IopDetectResourceConflict( IN PCM_RESOURCE_LIST ResourceList, IN BOOLEAN Silent, diff --git a/ntoskrnl/mm/ARM3/virtual.c b/ntoskrnl/mm/ARM3/virtual.c index dd0f818e0ca..19cf8aa052e 100644 --- a/ntoskrnl/mm/ARM3/virtual.c +++ b/ntoskrnl/mm/ARM3/virtual.c @@ -2306,7 +2306,7 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle, NTSTATUS Status; PMMVAD Vad = NULL; PVOID Address, NextAddress; - BOOLEAN Found; + BOOLEAN Found = FALSE; ULONG NewProtect, NewState, BaseVpn; MEMORY_BASIC_INFORMATION MemoryInfo; KAPC_STATE ApcState; @@ -2390,11 +2390,44 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle, /* Was a VAD found? */ if (!Found) { - /* We don't handle this yet */ - UNIMPLEMENTED; - while (TRUE); + Address = PAGE_ALIGN(BaseAddress); + + /* Calculate region size */ + if (Vad) + { + /* We don't handle this yet */ + UNIMPLEMENTED; + while (TRUE); + } + else + { + /* Maximum possible region size with that base address */ + MemoryInfo.RegionSize = (PCHAR)MM_HIGHEST_VAD_ADDRESS + 1 - (PCHAR)Address; + } + + /* Check if we were attached */ + if (ProcessHandle != NtCurrentProcess()) + { + /* Detach and derefernece the process */ + KeUnstackDetachProcess(&ApcState); + ObDereferenceObject(TargetProcess); + } + + /* Build the rest of the initial information block */ + MemoryInfo.BaseAddress = Address; + MemoryInfo.AllocationBase = NULL; + MemoryInfo.AllocationProtect = 0; + MemoryInfo.State = MEM_FREE; + MemoryInfo.Protect = PAGE_NOACCESS; + MemoryInfo.Type = 0; + + /* Return the data (FIXME: Use SEH) */ + *(PMEMORY_BASIC_INFORMATION)MemoryInformation = MemoryInfo; + if (ReturnLength) *ReturnLength = sizeof(MEMORY_BASIC_INFORMATION); + + return STATUS_SUCCESS; } - + /* This must be a VM VAD */ ASSERT(Vad->u.VadFlags.PrivateMemory); diff --git a/subsystems/win32/win32k/ntuser/callback.c b/subsystems/win32/win32k/ntuser/callback.c index 997cd4fb8b5..c2e52f85539 100644 --- a/subsystems/win32/win32k/ntuser/callback.c +++ b/subsystems/win32/win32k/ntuser/callback.c @@ -503,7 +503,7 @@ co_IntCallHookProc(INT HookId, RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs, sizeof(CREATESTRUCTW) ); CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter; Extra = (PCHAR) (CbtCreatewndExtra + 1); - CbtCreatewndExtra->Cs.lpszClass = ClassName.Buffer; // if Atom + CbtCreatewndExtra->Cs.lpszClass = CbtCreateWnd->lpcs->lpszClass; // if Atom if (Ansi) { @@ -517,7 +517,7 @@ co_IntCallHookProc(INT HookId, } else { - if (asWindowName.Buffer) + if (WindowName.Buffer) RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length); CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra); Extra += WindowName.Length; @@ -526,7 +526,7 @@ co_IntCallHookProc(INT HookId, Extra += sizeof(WCHAR); } - if (!IS_ATOM(ClassName.Buffer)) + if (!IS_ATOM(CbtCreateWnd->lpcs->lpszClass)) { if (Ansi) { diff --git a/subsystems/win32/win32k/ntuser/hook.c b/subsystems/win32/win32k/ntuser/hook.c index d83c8c90c31..baf633883f4 100644 --- a/subsystems/win32/win32k/ntuser/hook.c +++ b/subsystems/win32/win32k/ntuser/hook.c @@ -582,7 +582,11 @@ UserCallNextHookEx( PHOOK Hook, break; } break; - +/* + Note WH_JOURNALPLAYBACK, + "To have the system wait before processing the message, the return value + must be the amount of time, in clock ticks, that the system should wait." + */ case WH_JOURNALPLAYBACK: case WH_JOURNALRECORD: { @@ -660,8 +664,6 @@ UserCallNextHookEx( PHOOK Hook, DPRINT1("Unsupported HOOK Id -> %d\n",Hook->HookId); break; } - if (Hook->HookId == WH_JOURNALPLAYBACK && lResult == 0) - lResult = -1; return lResult; } @@ -873,8 +875,7 @@ co_HOOK_CallHooks( INT HookId, ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK); - pti = GetW32ThreadInfo(); // Need to call this! - + pti = PsGetCurrentThreadWin32Thread(); if (!pti || !pti->pDeskInfo) goto Exit; // Must have a desktop running for hooks. @@ -1006,8 +1007,6 @@ co_HOOK_CallHooks( INT HookId, DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId,Result); } Exit: - if (HookId == WH_JOURNALPLAYBACK && Result == 0) - Result = -1; return Result; } @@ -1179,6 +1178,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod, HookId == WH_MOUSE_LL || HookId == WH_SYSMSGFILTER) { + DPRINT1("Local hook installing Global HookId: %d\n",HookId); /* these can only be global */ SetLastWin32Error(ERROR_GLOBAL_ONLY_HOOK); RETURN( NULL); @@ -1197,6 +1197,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod, if ( pti->rpdesk != ptiCurrent->rpdesk) // gptiCurrent->rpdesk) { + DPRINT1("Local hook wrong desktop HookId: %d\n",HookId); SetLastWin32Error(ERROR_ACCESS_DENIED); RETURN( NULL); } @@ -1213,6 +1214,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod, HookId == WH_FOREGROUNDIDLE || HookId == WH_CALLWNDPROCRET) ) { + DPRINT1("Local hook needs hMod HookId: %d\n",HookId); SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD); RETURN( NULL); } @@ -1246,6 +1248,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod, HookId == WH_FOREGROUNDIDLE || HookId == WH_CALLWNDPROCRET) ) { + DPRINT1("Global hook needs hMod HookId: %d\n",HookId); SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD); RETURN( NULL); } @@ -1377,6 +1380,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod, else Hook->offPfn = 0; + DPRINT1("Installing: HookId %d Global %s\n", HookId, !ThreadId ? "TRUE" : "FALSE"); RETURN( Handle); CLEANUP: diff --git a/subsystems/win32/win32k/ntuser/msgqueue.c b/subsystems/win32/win32k/ntuser/msgqueue.c index 04694b46286..c1dc8d527de 100644 --- a/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/subsystems/win32/win32k/ntuser/msgqueue.c @@ -1003,9 +1003,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue) KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE); } - /* Call the callback if the message wa - - s sent with SendMessageCallback */ + /* Call the callback if the message was sent with SendMessageCallback */ if (Message->CompletionCallback != NULL) { co_IntCallSentMessageCallback(Message->CompletionCallback, -- 2.17.1