Merge trunk head (r49270) backups/reactos-yarotows@57446
authorTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 25 Oct 2010 15:26:06 +0000 (15:26 +0000)
committerTimo Kreuzer <timo.kreuzer@reactos.org>
Mon, 25 Oct 2010 15:26:06 +0000 (15:26 +0000)
svn path=/branches/reactos-yarotows/; revision=49272

22 files changed:
base/system/services/rpcserver.c
dll/win32/user32/include/user32.h
drivers/wdm/audio/backpln/portcls/guids.cpp
drivers/wdm/audio/backpln/portcls/interfaces.hpp
drivers/wdm/audio/backpln/portcls/irpstream.cpp
drivers/wdm/audio/backpln/portcls/pin_dmus.cpp
drivers/wdm/audio/backpln/portcls/pin_wavecyclic.cpp
drivers/wdm/audio/backpln/portcls/pin_wavepci.cpp
drivers/wdm/audio/backpln/portcls/pin_wavert.cpp
drivers/wdm/audio/backpln/portcls/private.hpp
drivers/wdm/audio/backpln/portcls/undoc.cpp
hal/halx86/generic/usage.c
include/psdk/ks.h
include/psdk/ksmedia.h
ntoskrnl/include/internal/io.h
ntoskrnl/io/iomgr/iorsrce.c
ntoskrnl/io/pnpmgr/pnpreport.c
ntoskrnl/io/pnpmgr/pnpres.c
ntoskrnl/mm/ARM3/virtual.c
subsystems/win32/win32k/ntuser/callback.c
subsystems/win32/win32k/ntuser/hook.c
subsystems/win32/win32k/ntuser/msgqueue.c

index b4b5bb8..30df18d 100644 (file)
@@ -31,9 +31,6 @@ typedef struct _SCMGR_HANDLE
 typedef struct _MANAGER_HANDLE
 {
     SCMGR_HANDLE Handle;
 typedef struct _MANAGER_HANDLE
 {
     SCMGR_HANDLE Handle;
-
-    /* FIXME: Insert more data here */
-
     WCHAR DatabaseName[1];
 } MANAGER_HANDLE, *PMANAGER_HANDLE;
 
     WCHAR DatabaseName[1];
 } MANAGER_HANDLE, *PMANAGER_HANDLE;
 
@@ -41,11 +38,7 @@ typedef struct _MANAGER_HANDLE
 typedef struct _SERVICE_HANDLE
 {
     SCMGR_HANDLE Handle;
 typedef struct _SERVICE_HANDLE
 {
     SCMGR_HANDLE Handle;
-
     PSERVICE ServiceEntry;
     PSERVICE ServiceEntry;
-
-    /* FIXME: Insert more data here */
-
 } SERVICE_HANDLE, *PSERVICE_HANDLE;
 
 
 } SERVICE_HANDLE, *PSERVICE_HANDLE;
 
 
@@ -149,7 +142,7 @@ ScmCreateManagerHandle(LPWSTR lpDatabaseName,
     if (lpDatabaseName == NULL)
         lpDatabaseName = SERVICES_ACTIVE_DATABASEW;
 
     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;
     {
         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;
 
 
     Ptr->Handle.Tag = MANAGER_TAG;
 
-    /* FIXME: initialize more data here */
-
     wcscpy(Ptr->DatabaseName, lpDatabaseName);
 
     *Handle = (SC_HANDLE)Ptr;
     wcscpy(Ptr->DatabaseName, lpDatabaseName);
 
     *Handle = (SC_HANDLE)Ptr;
@@ -192,7 +183,6 @@ ScmCreateServiceHandle(PSERVICE lpServiceEntry,
 
     Ptr->Handle.Tag = SERVICE_TAG;
 
 
     Ptr->Handle.Tag = SERVICE_TAG;
 
-    /* FIXME: initialize more data here */
     Ptr->ServiceEntry = lpServiceEntry;
 
     *Handle = (SC_HANDLE)Ptr;
     Ptr->ServiceEntry = lpServiceEntry;
 
     *Handle = (SC_HANDLE)Ptr;
@@ -453,9 +443,10 @@ DWORD RCloseServiceHandle(
     if (*hSCObject == 0)
         return ERROR_INVALID_HANDLE;
 
     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");
 
     {
         DPRINT("Found manager handle\n");
 
@@ -467,7 +458,7 @@ DWORD RCloseServiceHandle(
         DPRINT("RCloseServiceHandle() done\n");
         return ERROR_SUCCESS;
     }
         DPRINT("RCloseServiceHandle() done\n");
         return ERROR_SUCCESS;
     }
-    else if (hService->Handle.Tag == SERVICE_TAG)
+    else if (hService != NULL)
     {
         DPRINT("Found service handle\n");
 
     {
         DPRINT("Found service handle\n");
 
@@ -561,6 +552,8 @@ DWORD RControlService(
     DWORD dwError = ERROR_SUCCESS;
     DWORD pcbBytesNeeded = 0;
     DWORD dwServicesReturned = 0;
     DWORD dwError = ERROR_SUCCESS;
     DWORD pcbBytesNeeded = 0;
     DWORD dwServicesReturned = 0;
+    DWORD dwControlsAccepted;
+    DWORD dwCurrentState;
     HKEY hServicesKey = NULL;
 
     DPRINT("RControlService() called\n");
     HKEY hServicesKey = NULL;
 
     DPRINT("RControlService() called\n");
@@ -662,6 +655,49 @@ DWORD RControlService(
     }
     else
     {
     }
     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);
         /* Send control code to the service */
         dwError = ScmControlService(lpService,
                                     dwControl);
index c6dbbc7..a0472b3 100644 (file)
@@ -169,7 +169,7 @@ SharedPtrToKernel(PVOID Ptr)
 static __inline BOOL
 IsThreadHooked(PCLIENTINFO pci)
 {
 static __inline BOOL
 IsThreadHooked(PCLIENTINFO pci)
 {
-    return pci->fsHooks != 0;
+    return (pci->fsHooks|pci->pDeskInfo->fsHooks) != 0;
 }
 
 static __inline PDESKTOPINFO
 }
 
 static __inline PDESKTOPINFO
index 457868d..34fed48 100644 (file)
@@ -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_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}};
 
 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}};
index 6caebb9..248bcbe 100644 (file)
@@ -321,8 +321,7 @@ DECLARE_INTERFACE_(IIrpQueue, IUnknown)
     STDMETHOD_(NTSTATUS, Init)(THIS_
         IN KSPIN_CONNECT *ConnectDetails,
         IN ULONG FrameSize,
     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,
 
     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,                            \
     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,                                   \
                                                        \
     STDMETHODIMP_(NTSTATUS) AddMapping(THIS_           \
         IN PIRP Irp,                                   \
index aa6f392..a19a6da 100644 (file)
@@ -43,7 +43,6 @@ protected:
     LIST_ENTRY m_IrpList;
     LIST_ENTRY m_FreeIrpList;
     PIRP m_Irp;
     LIST_ENTRY m_IrpList;
     LIST_ENTRY m_FreeIrpList;
     PIRP m_Irp;
-    PVOID m_SilenceBuffer;
 
     ULONG m_OutOfMapping;
     ULONG m_MaxFrameSize;
 
     ULONG m_OutOfMapping;
     ULONG m_MaxFrameSize;
@@ -84,12 +83,10 @@ NTAPI
 CIrpQueue::Init(
     IN KSPIN_CONNECT *ConnectDetails,
     IN ULONG FrameSize,
 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_ConnectDetails = ConnectDetails;
     m_MaxFrameSize = FrameSize;
-    m_SilenceBuffer = SilenceBuffer;
     m_Alignment = Alignment;
 
     InitializeListHead(&m_IrpList);
     m_Alignment = Alignment;
 
     InitializeListHead(&m_IrpList);
@@ -259,22 +256,13 @@ CIrpQueue::GetMapping(
         m_CurrentOffset = Offset = 0;
     }
 
         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
     if (!Irp)
     {
         // no irp buffer available
+        DPRINT("NoIrp\n");
         return STATUS_UNSUCCESSFUL;
     }
 
         return STATUS_UNSUCCESSFUL;
     }
 
-
     // get stream header
     StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2];
 
     // get stream header
     StreamHeader = (PKSSTREAM_HEADER)Irp->Tail.Overlay.DriverContext[2];
 
index 4bcad8c..5a616f3 100644 (file)
@@ -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);
     if (!NT_SUCCESS(Status))
     {
         DPRINT("IrpQueue_Init failed with %x\n", Status);
index e615413..226457c 100644 (file)
@@ -73,7 +73,7 @@ protected:
     ULONG m_StopCount;
     KSAUDIO_POSITION m_Position;
     KSALLOCATOR_FRAMING m_AllocatorFraming;
     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;
 
     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 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_CONNECTIONSET(PinWaveCyclicConnectionSet, PinWaveCyclicState, PinWaveCyclicDataFormat, PinWaveCyclicAllocatorFraming);
 DEFINE_KSPROPERTY_AUDIOSET(PinWaveCyclicAudioSet, PinWaveCyclicAudioPosition);
+DEFINE_KSPROPERTY_DRMSET(PinWaveCyclicDRMSet, PinWaveCyclicDRMHandler);
 
 KSEVENT_ITEM PinWaveCyclicConnectionEventSet =
 {
 
 KSEVENT_ITEM PinWaveCyclicConnectionEventSet =
 {
@@ -146,6 +148,13 @@ KSPROPERTY_SET PinWaveCyclicPropertySet[] =
         (const KSPROPERTY_ITEM*)&PinWaveCyclicAudioSet,
         0,
         NULL
         (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;
 }
 
     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(
 NTSTATUS
 NTAPI
 PinWaveCyclicAddEndOfStreamEvent(
@@ -448,12 +470,14 @@ PinWaveCyclicState(
             {
                 // FIXME
                 // complete with successful state
             {
                 // 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_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;
                 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 BufferLength;
     ULONG BytesToCopy;
     ULONG BufferSize;
+    ULONG Gap;
     PUCHAR Buffer;
     NTSTATUS Status;
 
     PUCHAR Buffer;
     NTSTATUS Status;
 
@@ -672,7 +697,18 @@ CPortPinWaveCyclic::UpdateCommonBuffer(
     {
         Status = m_IrpQueue->GetMapping(&Buffer, &BufferSize);
         if (!NT_SUCCESS(Status))
     {
         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);
 
 
         BytesToCopy = min(BufferLength, BufferSize);
 
@@ -688,7 +724,7 @@ CPortPinWaveCyclic::UpdateCommonBuffer(
         m_IrpQueue->UpdateMapping(BytesToCopy);
         m_CommonBufferOffset += BytesToCopy;
 
         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)
         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))
     {
         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);
 
 
         BytesToCopy = min(BufferLength, BufferSize);
 
@@ -741,7 +788,7 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap(
         m_CommonBufferOffset += BytesToCopy;
         m_Position.PlayOffset += BytesToCopy;
 
         m_CommonBufferOffset += BytesToCopy;
         m_Position.PlayOffset += BytesToCopy;
 
-        BufferLength = m_CommonBufferSize - m_CommonBufferOffset;
+        BufferLength -=BytesToCopy;
 
         if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
         {
 
         if (m_ConnectDetails->Interface.Id == KSINTERFACE_STANDARD_LOOPED_STREAMING)
         {
@@ -751,7 +798,6 @@ CPortPinWaveCyclic::UpdateCommonBufferOverlap(
                 m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset;
             }
         }
                 m_Position.PlayOffset = m_Position.PlayOffset % m_Position.WriteOffset;
             }
         }
-
     }
 
     if (Gap == Length)
     }
 
     if (Gap == Length)
@@ -773,22 +819,13 @@ CPortPinWaveCyclic::RequestService()
 {
     ULONG Position;
     NTSTATUS Status;
 {
     ULONG Position;
     NTSTATUS Status;
-    PUCHAR Buffer;
-    ULONG BufferSize;
     ULONGLONG OldOffset, NewOffset;
 
     PC_ASSERT_IRQL(DISPATCH_LEVEL);
 
     if (m_State == KSSTATE_RUN)
     {
     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);
         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;
 
 
         OldOffset = m_Position.PlayOffset;
 
@@ -841,7 +878,7 @@ CPortPinWaveCyclic::DeviceIoControl(
     if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY)
     {
         /* handle property with subdevice descriptor */
     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)
         {
 
         if (Status == STATUS_NOT_FOUND)
         {
@@ -854,11 +891,11 @@ CPortPinWaveCyclic::DeviceIoControl(
     }
     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_ENABLE_EVENT)
     {
     }
     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)
     {
     }
     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)
     {
     }
     else if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE)
     {
@@ -1120,7 +1157,6 @@ CPortPinWaveCyclic::Init(
     PKSDATAFORMAT DataFormat;
     PDEVICE_OBJECT DeviceObject;
     BOOLEAN Capture;
     PKSDATAFORMAT DataFormat;
     PDEVICE_OBJECT DeviceObject;
     BOOLEAN Capture;
-    PVOID SilenceBuffer;
     PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor = NULL;
     //IDrmAudioStream * DrmAudio = NULL;
 
     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);
 #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;
 
     if (!NT_SUCCESS(Status))
         return Status;
@@ -1203,18 +1238,26 @@ CPortPinWaveCyclic::Init(
     InitializeListHead(&m_EventList);
     KeInitializeSpinLock(&m_EventListLock);
 
     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;
 
     // initialize reset state
     m_ResetState = KSRESET_END;
@@ -1247,9 +1290,7 @@ CPortPinWaveCyclic::Init(
     PC_ASSERT(NT_SUCCESS(Status));
     PC_ASSERT(m_FrameSize);
 
     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 */
 
 
     /* set up allocator framing */
@@ -1260,10 +1301,9 @@ CPortPinWaveCyclic::Init(
     m_AllocatorFraming.Reserved = 0;
     m_AllocatorFraming.FrameSize = m_FrameSize;
 
     m_AllocatorFraming.Reserved = 0;
     m_AllocatorFraming.FrameSize = m_FrameSize;
 
-    m_Stream->Silence(SilenceBuffer, m_FrameSize);
     m_Stream->Silence(m_CommonBuffer, m_CommonBufferSize);
 
     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();
     if (!NT_SUCCESS(Status))
     {
        m_IrpQueue->Release();
@@ -1282,9 +1322,6 @@ CPortPinWaveCyclic::Init(
     m_Port = Port;
     m_Filter = Filter;
 
     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;
 }
 
     return STATUS_SUCCESS;
 }
 
index a2b89a4..9a1cc75 100644 (file)
@@ -919,7 +919,7 @@ CPortPinWavePci::Init(
     }
 
     // initialize irp queue
     }
 
     // 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
     if (!NT_SUCCESS(Status))
     {
         // this should never happen
index 7c3d036..fd6be3c 100644 (file)
@@ -587,7 +587,7 @@ CPortPinWaveRT::Init(
         goto cleanup;
     }
 
         goto cleanup;
     }
 
-    Status = m_IrpQueue->Init(ConnectDetails, 0, 0, NULL);
+    Status = m_IrpQueue->Init(ConnectDetails, 0, 0);
     if (!NT_SUCCESS(Status))
     {
         goto cleanup;
     if (!NT_SUCCESS(Status))
     {
         goto cleanup;
index 17adc4c..e2e600b 100644 (file)
@@ -356,6 +356,22 @@ DEFINE_KSPROPERTY_TABLE(PinSet) {\
     DEFINE_KSPROPERTY_ITEM_AUDIO_POSITION(PropPositionHandler, PropPositionHandler)\
 }
 
     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) {\
 #define DEFINE_KSPROPERTY_PINPROPOSEDATAFORMAT(PinSet,\
     PropGeneral, PropInstances, PropIntersection)\
 DEFINE_KSPROPERTY_TABLE(PinSet) {\
index f65af7e..2837123 100644 (file)
@@ -8,22 +8,6 @@
 
 #include "private.hpp"
 
 
 #include "private.hpp"
 
-
-KSPIN_INTERFACE PinInterfaces[] = 
-{
-    {
-        {STATIC_KSINTERFACESETID_Standard},
-        KSINTERFACE_STANDARD_STREAMING,
-        0
-    },
-    {
-        {STATIC_KSINTERFACESETID_Standard},
-        KSINTERFACE_STANDARD_LOOPED_STREAMING,
-        0
-    }
-};
-
-
 NTSTATUS
 NTAPI
 KsoDispatchCreateWithGenericFactory(
 NTSTATUS
 NTAPI
 KsoDispatchCreateWithGenericFactory(
@@ -87,334 +71,429 @@ PcHandleDisableEventWithTable(
 }
 
 NTSTATUS
 }
 
 NTSTATUS
-PcHandleGuidNullRequest(
-    IN OUT PIRP Irp,
+NTAPI
+PcHandlePropertyWithTable(
+    IN PIRP Irp,
+    IN ULONG PropertySetCount,
+    IN PKSPROPERTY_SET PropertySet,
     IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
 {
     IN PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor)
 {
-    PPCNODE_DESCRIPTOR Node;
-    PPCPROPERTY_ITEM PropertyItem;
     PIO_STACK_LOCATION IoStack;
     PIO_STACK_LOCATION IoStack;
-    PKSP_NODE Property;
-    LPGUID Buffer;
-    ULONG Count = 0, SubIndex, Index;
 
     // get current irp stack location
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
 
     // 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;
     }
 
         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
 }
 
 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;
     PPCPROPERTY_ITEM PropertyItem;
+    PPCAUTOMATION_TABLE NodeAutomation;
     PIO_STACK_LOCATION IoStack;
     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);
 
     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
 }
 
 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
 }
 
 NTSTATUS
@@ -491,6 +570,15 @@ DumpFilterDescriptor(
                     EventItem = (PPCEVENT_ITEM)((ULONG_PTR)EventItem + NodeDescriptor->AutomationTable->EventItemSize);
                 }
 
                     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;
     IN PPCFILTER_DESCRIPTOR FilterDescription)
 {
     SUBDEVICE_DESCRIPTOR * Descriptor;
-    ULONG Index;
+    ULONG Index, SubIndex;
     NTSTATUS Status = STATUS_INSUFFICIENT_RESOURCES;
     PPCPIN_DESCRIPTOR SrcDescriptor;
     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;
     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);
 
     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;
     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;
 
     RtlCopyMemory(Descriptor->Interfaces, InterfaceGuids, sizeof(GUID) * InterfaceCount);
     Descriptor->InterfaceCount = InterfaceCount;
 
+    //DumpFilterDescriptor(FilterDescription);
+
+    // are any property sets supported by the portcls
     if (FilterPropertiesCount)
     {
     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;
 
        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++)
        {
        Descriptor->FilterPropertySetCount = FilterPropertiesCount;
        for(Index = 0; Index < FilterPropertiesCount; Index++)
        {
+           // copy property set
            RtlMoveMemory(&Descriptor->FilterPropertySet[Index], &FilterProperties[Index], sizeof(KSPROPERTY_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)
     {
     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;
 
         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;
 
         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);
 
         Descriptor->Factory.PinDescriptorCount = FilterDescription->PinCount;
         Descriptor->Factory.PinDescriptorSize = sizeof(KSPIN_DESCRIPTOR);
 
+        // grab first entry
         SrcDescriptor = (PPCPIN_DESCRIPTOR)FilterDescription->Pins;
         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 factories
         for(Index = 0; Index < FilterDescription->PinCount; Index++)
         {
+            // copy pin descriptor
             RtlMoveMemory(&Descriptor->Factory.KsPinDescriptor[Index], &SrcDescriptor->KsPinDescriptor, sizeof(KSPIN_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;
             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);
         }
     }
 
             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;
     Descriptor->DeviceDescriptor = FilterDescription;
+
+    // store result
     *OutSubdeviceDescriptor = Descriptor;
     *OutSubdeviceDescriptor = Descriptor;
+    // done
     return STATUS_SUCCESS;
 
 cleanup:
     return STATUS_SUCCESS;
 
 cleanup:
index c35df96..be6710d 100644 (file)
@@ -235,8 +235,9 @@ HalpReportResourceUsage(IN PUNICODE_STRING HalName,
         if (!HalpGetInfoFromACPI)
         {
             /* No, so use our local table */
         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)
             {
                 /* 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);
                 }
                                        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)
 {
                            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);
 
     /* Register the vector */
     HalpRegisterVector(Flags, BusVector, SystemVector, Irql);
 
index 62357d6..7f99f13 100644 (file)
@@ -1005,11 +1005,6 @@ DEFINE_GUIDSTRUCT("97E99BA0-BDEA-11CF-A5D6-28DB04C10000", KSPROPTYPESETID_Genera
     KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY
 */
 
     KSPROPERTY_DIRECTSOUND3DLISTENER_VELOCITY
 */
 
-#define KSPROPSETID_DrmAudioStream
-/*
-    KSPROPERTY_DRMAUDIOSTREAM_CONTENTID
-*/
-
 #define KSPROPSETID_Hrtf3d
 /*
     KSPROPERTY_HRTF3D_FILTER_FORMAT
 #define KSPROPSETID_Hrtf3d
 /*
     KSPROPERTY_HRTF3D_FILTER_FORMAT
index 32e5e3e..5a34bba 100644 (file)
@@ -565,6 +565,15 @@ typedef struct {
 #endif // !_NTDDK_
 } LOOPEDSTREAMING_POSITION_EVENT_DATA, *PLOOPEDSTREAMING_POSITION_EVENT_DATA ;
 
 #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
 
 /*
     SysAudio Properties
index 28bc779..bf676b6 100644 (file)
@@ -514,6 +514,21 @@ IopAssignDeviceResources(
     IN PDEVICE_NODE DeviceNode
 );
 
     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
 //
 //
 // PNP Routines
 //
index af59131..9d52881 100644 (file)
@@ -841,7 +841,7 @@ IoGetConfigurationInformation(VOID)
 }
 
 /*
 }
 
 /*
- * @unimplemented
+ * @halfplemented
  */
 NTSTATUS NTAPI
 IoReportResourceUsage(PUNICODE_STRING DriverClassName,
  */
 NTSTATUS NTAPI
 IoReportResourceUsage(PUNICODE_STRING DriverClassName,
@@ -876,13 +876,48 @@ IoReportResourceUsage(PUNICODE_STRING DriverClassName,
       *       a conflict is detected with another driver.
       */
 {
       *       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,
  */
 NTSTATUS NTAPI
 IoAssignResources(PUNICODE_STRING RegistryPath,
@@ -892,8 +927,23 @@ IoAssignResources(PUNICODE_STRING RegistryPath,
                  PIO_RESOURCE_REQUIREMENTS_LIST RequestedResources,
                  PCM_RESOURCE_LIST* AllocatedResources)
 {
                  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;
 }
 
 /*
 }
 
 /*
index 165b0b0..94a20dc 100644 (file)
@@ -38,9 +38,6 @@ NTSTATUS
 IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
                                 PVOID Context);
 
 IopActionInterrogateDeviceStack(PDEVICE_NODE DeviceNode,
                                 PVOID Context);
 
-NTSTATUS
-IopDetectResourceConflict(IN PCM_RESOURCE_LIST ResourceList);
-
 NTSTATUS
 PpSetCustomTargetEvent(IN PDEVICE_OBJECT DeviceObject,
                        IN OUT PKEVENT SyncEvent OPTIONAL,
 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 */
         ResourceList = DriverList;
 
     /* Look for a resource conflict */
-    Status = IopDetectResourceConflict(ResourceList);
+    Status = IopDetectResourceConflict(ResourceList, FALSE, NULL);
     if (Status == STATUS_CONFLICTING_ADDRESSES)
     {
         /* Oh noes */
     if (Status == STATUS_CONFLICTING_ADDRESSES)
     {
         /* Oh noes */
index 71319f8..733440d 100644 (file)
 #define NDEBUG
 #include <debug.h>
 
 #define NDEBUG
 #include <debug.h>
 
-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)
 static
 BOOLEAN
 IopCheckDescriptorForConflict(PCM_PARTIAL_RESOURCE_DESCRIPTOR CmDesc, OPTIONAL PCM_PARTIAL_RESOURCE_DESCRIPTOR ConflictingDescriptor)
@@ -187,8 +181,8 @@ IopFindInterruptResource(
    return FALSE;
 }
 
    return FALSE;
 }
 
-static
-NTSTATUS
+
+NTSTATUS NTAPI
 IopCreateResourceListFromRequirements(
    IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
    OUT PCM_RESOURCE_LIST *ResourceList)
 IopCreateResourceListFromRequirements(
    IN PIO_RESOURCE_REQUIREMENTS_LIST RequirementsList,
    OUT PCM_RESOURCE_LIST *ResourceList)
@@ -336,9 +330,6 @@ IopCheckResourceDescriptor(
    ULONG i, ii;
    BOOLEAN Result = FALSE;
 
    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;
    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)
   {
 
   if (DeviceNode->ResourceList)
   {
-      PWCHAR DeviceName = NULL;
       UNICODE_STRING NameU;
       UNICODE_STRING NameU;
-      UNICODE_STRING Suffix;
+      UNICODE_STRING RawSuffix, TranslatedSuffix;
       ULONG OldLength = 0;
 
       ASSERT(DeviceNode->ResourceListTranslated);
       ULONG OldLength = 0;
 
       ASSERT(DeviceNode->ResourceListTranslated);
+      
+      RtlInitUnicodeString(&TranslatedSuffix, L".Translated");
+      RtlInitUnicodeString(&RawSuffix, L".Raw");
 
       Status = IoGetDeviceProperty(DeviceNode->PhysicalDeviceObject,
                                    DevicePropertyPhysicalDeviceObjectName,
                                    0,
                                    NULL,
                                    &OldLength);
 
       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,
 
       Status = ZwSetValueKey(PnpMgrLevel2,
                              &NameU,
@@ -659,14 +671,14 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
       if (!NT_SUCCESS(Status))
       {
           ZwClose(PnpMgrLevel2);
       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 */
           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,
 
       Status = ZwSetValueKey(PnpMgrLevel2,
                              &NameU,
@@ -675,8 +687,8 @@ IopUpdateResourceMap(IN PDEVICE_NODE DeviceNode, PWCHAR Level1Key, PWCHAR Level2
                              DeviceNode->ResourceListTranslated,
                              PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated));
       ZwClose(PnpMgrLevel2);
                              DeviceNode->ResourceListTranslated,
                              PnpDetermineResourceListSize(DeviceNode->ResourceListTranslated));
       ZwClose(PnpMgrLevel2);
-      ASSERT(DeviceName);
-      ExFreePool(DeviceName);
+      ExFreePool(NameU.Buffer);
+
       if (!NT_SUCCESS(Status))
           return Status;
   }
       if (!NT_SUCCESS(Status))
           return Status;
   }
@@ -718,7 +730,7 @@ IopTranslateDeviceResources(
    DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize);
    if (!DeviceNode->ResourceListTranslated)
    {
    DeviceNode->ResourceListTranslated = ExAllocatePool(PagedPool, ListSize);
    if (!DeviceNode->ResourceListTranslated)
    {
-      Status =STATUS_NO_MEMORY;
+      Status = STATUS_NO_MEMORY;
       goto cleanup;
    }
    RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize);
       goto cleanup;
    }
    RtlCopyMemory(DeviceNode->ResourceListTranslated, DeviceNode->ResourceList, ListSize);
@@ -743,6 +755,7 @@ IopTranslateDeviceResources(
                   &DescriptorTranslated->u.Port.Start))
                {
                   Status = STATUS_UNSUCCESSFUL;
                   &DescriptorTranslated->u.Port.Start))
                {
                   Status = STATUS_UNSUCCESSFUL;
+                  DPRINT1("Failed to translate port resource (Start: 0xI64x)\n", DescriptorRaw->u.Port.Start.QuadPart);
                   goto cleanup;
                }
                break;
                   goto cleanup;
                }
                break;
@@ -756,6 +769,14 @@ IopTranslateDeviceResources(
                   DescriptorRaw->u.Interrupt.Vector,
                   (PKIRQL)&DescriptorTranslated->u.Interrupt.Level,
                   &DescriptorTranslated->u.Interrupt.Affinity);
                   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:
                break;
             }
             case CmResourceTypeMemory:
@@ -769,6 +790,7 @@ IopTranslateDeviceResources(
                   &DescriptorTranslated->u.Memory.Start))
                {
                   Status = STATUS_UNSUCCESSFUL;
                   &DescriptorTranslated->u.Memory.Start))
                {
                   Status = STATUS_UNSUCCESSFUL;
+                  DPRINT1("Failed to translate memory resource (Start: 0xI64x)\n", DescriptorRaw->u.Memory.Start.QuadPart);
                   goto cleanup;
                }
             }
                   goto cleanup;
                }
             }
@@ -864,16 +886,21 @@ IopAssignDeviceResources(
    Status = IopCreateResourceListFromRequirements(DeviceNode->ResourceRequirements,
                                                   &DeviceNode->ResourceList);
    if (!NT_SUCCESS(Status))
    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;
        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))
 
 Finish:
    Status = IopTranslateDeviceResources(DeviceNode);
    if (!NT_SUCCESS(Status))
+   {
+       DPRINT1("Failed to translate resources for %wZ\n", &DeviceNode->InstancePath);
        goto ByeBye;
        goto ByeBye;
+   }
 
    Status = IopUpdateResourceMapForPnPDevice(DeviceNode);
    if (!NT_SUCCESS(Status))
 
    Status = IopUpdateResourceMapForPnPDevice(DeviceNode);
    if (!NT_SUCCESS(Status))
@@ -935,7 +962,7 @@ ByeBye:
    return Result;
 }
 
    return Result;
 }
 
-NTSTATUS
+NTSTATUS NTAPI
 IopDetectResourceConflict(
    IN PCM_RESOURCE_LIST ResourceList,
    IN BOOLEAN Silent,
 IopDetectResourceConflict(
    IN PCM_RESOURCE_LIST ResourceList,
    IN BOOLEAN Silent,
index dd0f818..19cf8aa 100644 (file)
@@ -2306,7 +2306,7 @@ NtQueryVirtualMemory(IN HANDLE ProcessHandle,
     NTSTATUS Status;
     PMMVAD Vad = NULL;
     PVOID Address, NextAddress;
     NTSTATUS Status;
     PMMVAD Vad = NULL;
     PVOID Address, NextAddress;
-    BOOLEAN Found;
+    BOOLEAN Found = FALSE;
     ULONG NewProtect, NewState, BaseVpn;
     MEMORY_BASIC_INFORMATION MemoryInfo;
     KAPC_STATE ApcState;
     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)
     {
     /* 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);
    
     /* This must be a VM VAD */
     ASSERT(Vad->u.VadFlags.PrivateMemory);
    
index 997cd4f..c2e52f8 100644 (file)
@@ -503,7 +503,7 @@ co_IntCallHookProc(INT HookId,
                RtlCopyMemory( &CbtCreatewndExtra->Cs, CbtCreateWnd->lpcs, sizeof(CREATESTRUCTW) );
                CbtCreatewndExtra->WndInsertAfter = CbtCreateWnd->hwndInsertAfter;
                Extra = (PCHAR) (CbtCreatewndExtra + 1);
                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)
                {
 
                if (Ansi)
                {
@@ -517,7 +517,7 @@ co_IntCallHookProc(INT HookId,
                }
                else
                {
                }
                else
                {
-                 if (asWindowName.Buffer)
+                 if (WindowName.Buffer)
                     RtlCopyMemory(Extra, WindowName.Buffer, WindowName.Length);
                  CbtCreatewndExtra->Cs.lpszName = (LPCWSTR) (Extra - (PCHAR) CbtCreatewndExtra);
                  Extra += WindowName.Length;
                     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);
                }
 
                  Extra += sizeof(WCHAR);
                }
 
-               if (!IS_ATOM(ClassName.Buffer))
+               if (!IS_ATOM(CbtCreateWnd->lpcs->lpszClass))
                {
                   if (Ansi)
                   {
                {
                   if (Ansi)
                   {
index d83c8c9..baf6338 100644 (file)
@@ -582,7 +582,11 @@ UserCallNextHookEx( PHOOK Hook,
                     break;
             }
             break;
                     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:
         {
         case WH_JOURNALPLAYBACK:
         case WH_JOURNALRECORD:
         {
@@ -660,8 +664,6 @@ UserCallNextHookEx( PHOOK Hook,
             DPRINT1("Unsupported HOOK Id -> %d\n",Hook->HookId);
             break;
     }
             DPRINT1("Unsupported HOOK Id -> %d\n",Hook->HookId);
             break;
     }
-    if (Hook->HookId == WH_JOURNALPLAYBACK && lResult == 0)
-       lResult = -1;
     return lResult; 
 }
 
     return lResult; 
 }
 
@@ -873,8 +875,7 @@ co_HOOK_CallHooks( INT HookId,
 
     ASSERT(WH_MINHOOK <= HookId && HookId <= WH_MAXHOOK);
 
 
     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.
 
     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:
        DPRINT("Ret: Global HookId %d Result 0x%x\n", HookId,Result);
     }
 Exit:
-    if (HookId == WH_JOURNALPLAYBACK && Result == 0)
-       Result = -1;
     return Result;
 }
 
     return Result;
 }
 
@@ -1179,6 +1178,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
             HookId == WH_MOUSE_LL ||
             HookId == WH_SYSMSGFILTER)
        {
             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);
            /* 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)
        {
 
        if ( pti->rpdesk != ptiCurrent->rpdesk) // gptiCurrent->rpdesk)
        {
+          DPRINT1("Local hook wrong desktop HookId: %d\n",HookId);
           SetLastWin32Error(ERROR_ACCESS_DENIED);
           RETURN( NULL);
        }
           SetLastWin32Error(ERROR_ACCESS_DENIED);
           RETURN( NULL);
        }
@@ -1213,6 +1214,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
                HookId == WH_FOREGROUNDIDLE ||
                HookId == WH_CALLWNDPROCRET) )
           {
                HookId == WH_FOREGROUNDIDLE ||
                HookId == WH_CALLWNDPROCRET) )
           {
+             DPRINT1("Local hook needs hMod HookId: %d\n",HookId);
              SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD);
              RETURN( NULL);
           }
              SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD);
              RETURN( NULL);
           }
@@ -1246,6 +1248,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
              HookId == WH_FOREGROUNDIDLE ||
              HookId == WH_CALLWNDPROCRET) )
        {
              HookId == WH_FOREGROUNDIDLE ||
              HookId == WH_CALLWNDPROCRET) )
        {
+          DPRINT1("Global hook needs hMod HookId: %d\n",HookId);
           SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD);
           RETURN( NULL);
        }
           SetLastWin32Error(ERROR_HOOK_NEEDS_HMOD);
           RETURN( NULL);
        }
@@ -1377,6 +1380,7 @@ NtUserSetWindowsHookEx( HINSTANCE Mod,
     else
        Hook->offPfn = 0;
 
     else
        Hook->offPfn = 0;
 
+    DPRINT1("Installing: HookId %d Global %s\n", HookId, !ThreadId ? "TRUE" : "FALSE");
     RETURN( Handle);
 
 CLEANUP:
     RETURN( Handle);
 
 CLEANUP:
index 04694b4..c1dc8d5 100644 (file)
@@ -1003,9 +1003,7 @@ co_MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
       KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
    }
 
       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,
    if (Message->CompletionCallback != NULL)
    {
       co_IntCallSentMessageCallback(Message->CompletionCallback,