return STATUS_SUCCESS;
}
+
+NTSTATUS
+KspReadMediaCategory(
+ IN LPGUID Category,
+ PKEY_VALUE_PARTIAL_INFORMATION *OutInformation)
+{
+ UNICODE_STRING MediaPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Control\\MediaCategories\\");
+ UNICODE_STRING Name = RTL_CONSTANT_STRING(L"Name");
+ UNICODE_STRING GuidString, Path;
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hKey;
+ ULONG Size;
+ PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+
+ /* convert the guid to string */
+ Status = RtlStringFromGUID(Category, &GuidString);
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* allocate buffer for the registry key */
+ Path.Length = 0;
+ Path.MaximumLength = MediaPath.MaximumLength + GuidString.MaximumLength;
+ Path.Buffer = ExAllocatePool(NonPagedPool, Path.MaximumLength);
+ if (!Path.Buffer)
+ {
+ /* not enough memory */
+ RtlFreeUnicodeString(&GuidString);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ RtlAppendUnicodeStringToString(&Path, &MediaPath);
+ RtlAppendUnicodeStringToString(&Path, &GuidString);
+
+ /* free guid string */
+ RtlFreeUnicodeString(&GuidString);
+
+ /* initialize object attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &Path, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+ /* open the key */
+ Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
+
+ DPRINT1("ZwOpenKey() status 0x%08lx %S\n", Status, Path.Buffer);
+
+ /* free path buffer */
+ ExFreePool(Path.Buffer);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwOpenKey() failed with status 0x%08lx\n", Status);
+ return Status;
+ }
+
+ /* query the name size */
+ Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, NULL, 0, &Size);
+ if (!NT_SUCCESS(Status) && Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ /* failed to query for name key */
+ ZwClose(hKey);
+ return Status;
+ }
+
+ /* allocate buffer to read key info */
+ KeyInfo = (PKEY_VALUE_PARTIAL_INFORMATION) ExAllocatePool(NonPagedPool, Size);
+ if (!KeyInfo)
+ {
+ /* not enough memory */
+ ZwClose(hKey);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* now read the info */
+ Status = ZwQueryValueKey(hKey, &Name, KeyValuePartialInformation, (PVOID)KeyInfo, Size, &Size);
+
+ /* close the key */
+ ZwClose(hKey);
+
+ if (!NT_SUCCESS(Status))
+ {
+ /* failed to read key */
+ ExFreePool(KeyInfo);
+ return Status;
+ }
+
+ /* store key information */
+ *OutInformation = KeyInfo;
+ return Status;
+}
+
/*
@implemented
*/
PVOID Buffer;
PKSDATARANGE_AUDIO *WaveFormatOut;
PKSDATAFORMAT_WAVEFORMATEX WaveFormatIn;
- PULONG GuidBuffer;
- static WCHAR Speaker[] = {L"PC-Speaker"};
+ PKEY_VALUE_PARTIAL_INFORMATION KeyInfo;
+ NTSTATUS Status = STATUS_NOT_SUPPORTED;
IoStack = IoGetCurrentIrpStackLocation(Irp);
Buffer = Irp->UserBuffer;
case KSPROPERTY_PIN_CTYPES:
(*(PULONG)Buffer) = DescriptorsCount;
Irp->IoStatus.Information = sizeof(ULONG);
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
break;
case KSPROPERTY_PIN_DATAFLOW:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_BUFFER_TOO_SMALL;
break;
}
*((KSPIN_DATAFLOW*)Buffer) = Descriptor[Pin->PinId].DataFlow;
Irp->IoStatus.Information = sizeof(KSPIN_DATAFLOW);
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
break;
case KSPROPERTY_PIN_DATARANGES:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
+ Status = STATUS_MORE_ENTRIES;
break;
}
Data = ((PUCHAR)Data + Descriptor[Pin->PinId].DataRanges[Index]->FormatSize);
}
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
break;
case KSPROPERTY_PIN_INTERFACES:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
+ Status = STATUS_MORE_ENTRIES;
break;
}
RtlMoveMemory((PVOID)(Item + 1), &StandardPinInterface, sizeof(KSPIN_INTERFACE));
}
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
break;
case KSPROPERTY_PIN_MEDIUMS:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
+ Status = STATUS_MORE_ENTRIES;
break;
}
RtlMoveMemory((PVOID)(Item + 1), &StandardPinMedium, sizeof(KSPIN_MEDIUM));
}
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
break;
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_BUFFER_TOO_SMALL;
break;
}
*((KSPIN_COMMUNICATION*)Buffer) = Descriptor[Pin->PinId].Communication;
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
break;
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_BUFFER_TOO_SMALL;
break;
}
if (Descriptor[Pin->PinId].Category)
RtlMoveMemory(Buffer, Descriptor[Pin->PinId].Category, sizeof(GUID));
}
- Irp->IoStatus.Status = STATUS_SUCCESS;
+ Status = STATUS_SUCCESS;
Irp->IoStatus.Information = Size;
break;
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
- GuidBuffer = Buffer;
- Size = sizeof(Speaker);
+ if (!Descriptor[Pin->PinId].Category)
+ {
+ Irp->IoStatus.Information = 0;
+ Status = STATUS_SUCCESS;
+ break;
+ }
- if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
+ Status = KspReadMediaCategory((LPGUID)Descriptor[Pin->PinId].Category, &KeyInfo);
+ if (!NT_SUCCESS(Status))
{
- Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_MORE_ENTRIES;
+ Irp->IoStatus.Information = 0;
break;
}
- RtlMoveMemory(GuidBuffer, Speaker, sizeof(Speaker));
+ Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
- //RtlMoveMemory(Buffer, &Descriptor[Pin->PinId].Name, sizeof(GUID));
- Irp->IoStatus.Status = STATUS_SUCCESS;
- Irp->IoStatus.Information = Size;
+
+ if (KeyInfo->DataLength + sizeof(WCHAR) > IoStack->Parameters.DeviceIoControl.OutputBufferLength)
+ {
+ Status = STATUS_MORE_ENTRIES;
+ ExFreePool(KeyInfo);
+ break;
+ }
+
+ RtlMoveMemory(Irp->UserBuffer, &KeyInfo->Data, KeyInfo->DataLength);
+ ((LPWSTR)Irp->UserBuffer)[KeyInfo->DataLength / sizeof(WCHAR)] = L'\0';
+ Irp->IoStatus.Information = KeyInfo->DataLength + sizeof(WCHAR);
+ ExFreePool(KeyInfo);
break;
case KSPROPERTY_PIN_PROPOSEDATAFORMAT:
Pin = (KSP_PIN*)Property;
if (Pin->PinId >= DescriptorsCount)
{
- Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
+ Status = STATUS_INVALID_PARAMETER;
Irp->IoStatus.Information = 0;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < Size)
{
Irp->IoStatus.Information = Size;
- Irp->IoStatus.Status = STATUS_BUFFER_TOO_SMALL;
+ Status = STATUS_BUFFER_TOO_SMALL;
break;
}
if (IoStack->Parameters.DeviceIoControl.OutputBufferLength != sizeof(KSDATAFORMAT_WAVEFORMATEX))
{
UNIMPLEMENTED
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
- return STATUS_NOT_IMPLEMENTED;
+ break;
}
WaveFormatIn = (PKSDATAFORMAT_WAVEFORMATEX)Buffer;
if (!Descriptor[Pin->PinId].DataRanges || !Descriptor[Pin->PinId].DataRangesCount)
{
- Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
+ Status = STATUS_UNSUCCESSFUL;
Irp->IoStatus.Information = 0;
- return STATUS_UNSUCCESSFUL;
+ break;
}
WaveFormatOut = (PKSDATARANGE_AUDIO*)Descriptor[Pin->PinId].DataRanges;
for(Index = 0; Index < Descriptor[Pin->PinId].DataRangesCount; Index++)
return STATUS_SUCCESS;
}
}
- Irp->IoStatus.Status = STATUS_NO_MATCH;
+ Status = STATUS_NO_MATCH;
Irp->IoStatus.Information = 0;
- return STATUS_NO_MATCH;
+ break;
default:
DPRINT1("Unhandled property request %x\n", Property->Id);
- Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
+ Status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Information = 0;
}
- return Irp->IoStatus.Status;
+ return Status;
}
/*