/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsValidateClockCreateRequest( IN PIRP Irp, OUT PKSCLOCK_CREATE* OutClockCreate) { PKSCLOCK_CREATE ClockCreate; NTSTATUS Status; ULONG Size; /* minimum request size */ Size = sizeof(KSCLOCK_CREATE); /* copy create request */ Status = KspCopyCreateRequest(Irp, KSSTRING_Clock, &Size, (PVOID*)&ClockCreate); if (!NT_SUCCESS(Status)) return Status; if (ClockCreate->CreateFlags != 0) { /* flags must be zero */ FreeItem(ClockCreate); return STATUS_INVALID_PARAMETER; } *OutClockCreate = ClockCreate; return STATUS_SUCCESS; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsValidateAllocatorCreateRequest( IN PIRP Irp, OUT PKSALLOCATOR_FRAMING* OutAllocatorFraming) { PKSALLOCATOR_FRAMING AllocatorFraming; ULONG Size; NTSTATUS Status; ULONG SupportedFlags; /* set minimum request size */ Size = sizeof(KSALLOCATOR_FRAMING); Status = KspCopyCreateRequest(Irp, KSSTRING_Allocator, &Size, (PVOID*)&AllocatorFraming); if (!NT_SUCCESS(Status)) return Status; /* allowed supported flags */ SupportedFlags = (KSALLOCATOR_OPTIONF_COMPATIBLE | KSALLOCATOR_OPTIONF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_INPLACE_MODIFIER | KSALLOCATOR_REQUIREMENTF_SYSTEM_MEMORY | KSALLOCATOR_REQUIREMENTF_FRAME_INTEGRITY | KSALLOCATOR_REQUIREMENTF_MUST_ALLOCATE); if (!AllocatorFraming->FrameSize || (AllocatorFraming->OptionsFlags & (~SupportedFlags))) { FreeItem(AllocatorFraming); return STATUS_INVALID_PARAMETER; } /* store result */ *OutAllocatorFraming = AllocatorFraming; return Status; }
/* @implemented */ KSDDKAPI NTSTATUS NTAPI KsValidateTopologyNodeCreateRequest( IN PIRP Irp, IN PKSTOPOLOGY Topology, OUT PKSNODE_CREATE* OutNodeCreate) { PKSNODE_CREATE NodeCreate; ULONG Size; NTSTATUS Status; /* did the caller miss the topology */ if (!Topology) return STATUS_INVALID_PARAMETER; /* set create param size */ Size = sizeof(KSNODE_CREATE); /* fetch create parameters */ Status = KspCopyCreateRequest(Irp, KSSTRING_TopologyNode, &Size, (PVOID*)&NodeCreate); if (!NT_SUCCESS(Status)) return Status; if (NodeCreate->CreateFlags != 0 || (NodeCreate->Node >= Topology->TopologyNodesCount && NodeCreate->Node != MAXULONG)) { /* invalid node create */ FreeItem(NodeCreate); return STATUS_UNSUCCESSFUL; } /* store result */ *OutNodeCreate = NodeCreate; return Status; }
NTSTATUS KspValidateConnectRequest( IN PIRP Irp, IN ULONG DescriptorsCount, IN PVOID Descriptors, IN ULONG DescriptorSize, OUT PKSPIN_CONNECT* Connect) { PKSPIN_CONNECT ConnectDetails; PKSPIN_INTERFACE Interface; PKSPIN_MEDIUM Medium; ULONG Size; NTSTATUS Status; ULONG Index; ULONG Count; BOOLEAN Found; PKSPIN_DESCRIPTOR Descriptor; UNICODE_STRING GuidString2; /* did the caller miss the connect parameter */ if (!Connect) return STATUS_INVALID_PARAMETER; /* set create param size */ Size = sizeof(KSPIN_CONNECT); /* fetch create parameters */ Status = KspCopyCreateRequest(Irp, KSSTRING_Pin, &Size, (PVOID*)&ConnectDetails); /* check for success */ if (!NT_SUCCESS(Status)) return Status; /* is pin id out of bounds */ if (ConnectDetails->PinId >= DescriptorsCount) { FreeItem(ConnectDetails); return STATUS_INVALID_PARAMETER; } if (DescriptorSize == sizeof(KSPIN_DESCRIPTOR)) { /* standard pin descriptor */ Descriptor = (PKSPIN_DESCRIPTOR)((ULONG_PTR)Descriptors + sizeof(KSPIN_DESCRIPTOR) * ConnectDetails->PinId); } else { /* extended / variable pin descriptor */ Descriptor = &((PKSPIN_DESCRIPTOR_EX)((ULONG_PTR)Descriptors + DescriptorSize * ConnectDetails->PinId))->PinDescriptor; } /* does the pin have interface details filled in */ if (Descriptor->InterfacesCount && Descriptor->Interfaces) { /* use provided pin interface count */ Count = Descriptor->InterfacesCount; Interface = (PKSPIN_INTERFACE)Descriptor->Interfaces; } else { /* use standard pin interface */ Count = 1; Interface = &StandardPinInterface; } /* now check the interface */ Found = FALSE; Index = 0; RtlStringFromGUID(&ConnectDetails->Interface.Set, &GuidString2); do { UNICODE_STRING GuidString; RtlStringFromGUID(&Interface[Index].Set, &GuidString); DPRINT("Driver Interface %S Id %u\n", GuidString.Buffer, Interface[Index].Id); DPRINT("Connect Interface %S Id %u\n", GuidString2.Buffer, ConnectDetails->Interface.Id); RtlFreeUnicodeString(&GuidString); if (IsEqualGUIDAligned(&Interface[Index].Set, &ConnectDetails->Interface.Set) && Interface[Index].Id == ConnectDetails->Interface.Id) { /* found a matching interface */ Found = TRUE; break; } /* iterate to next interface */ Index++; }while(Index < Count); RtlFreeUnicodeString(&GuidString2); if (!Found) { /* pin doesnt support this interface */ FreeItem(ConnectDetails); return STATUS_NO_MATCH; } /* does the pin have medium details filled in */ if (Descriptor->MediumsCount && Descriptor->Mediums) { /* use provided pin interface count */ Count = Descriptor->MediumsCount; Medium = (PKSPIN_MEDIUM)Descriptor->Mediums; } else { /* use standard pin interface */ Count = 1; Medium = &StandardPinMedium; } /* now check the interface */ Found = FALSE; Index = 0; RtlStringFromGUID(&ConnectDetails->Medium.Set, &GuidString2); do { UNICODE_STRING GuidString; RtlStringFromGUID(&Medium[Index].Set, &GuidString); DPRINT("Driver Medium %S Id %u\n", GuidString.Buffer, Medium[Index].Id); DPRINT("Connect Medium %S Id %u\n", GuidString2.Buffer, ConnectDetails->Medium.Id); RtlFreeUnicodeString(&GuidString); if (IsEqualGUIDAligned(&Medium[Index].Set, &ConnectDetails->Medium.Set) && Medium[Index].Id == ConnectDetails->Medium.Id) { /* found a matching interface */ Found = TRUE; break; } /* iterate to next medium */ Index++; }while(Index < Count); RtlFreeUnicodeString(&GuidString2); if (!Found) { /* pin doesnt support this medium */ FreeItem(ConnectDetails); return STATUS_NO_MATCH; } /// FIXME /// implement format checking *Connect = ConnectDetails; return STATUS_SUCCESS; }