if (DeviceInfo->DeviceType != WAVE_OUT_DEVICE_TYPE && DeviceInfo->DeviceType != WAVE_IN_DEVICE_TYPE)
{
- DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
- return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
+ DPRINT("FIXME: Unsupported device type %x\n", DeviceInfo->DeviceType);
+ DeviceInfo->DeviceCount = 0;
+ return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
}
Pin.Property.Set = KSPROPSETID_Sysaudio;
/* store result count */
DeviceInfo->DeviceCount = Result;
- DPRINT1("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
+ DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
}
Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status))
{
- DPRINT1("Error: invalid device handle provided %p\n", DeviceInfo->hDevice);
+ DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
}
+PKEY_VALUE_PARTIAL_INFORMATION
+ReadKeyValue(
+ IN HANDLE hSubKey,
+ IN PUNICODE_STRING KeyName)
+{
+ NTSTATUS Status;
+ ULONG Length;
+ PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
+
+ /* now query MatchingDeviceId key */
+ Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, NULL, 0, &Length);
+
+ /* check for success */
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ return NULL;
+
+ /* allocate a buffer for key data */
+ PartialInformation = ExAllocatePool(NonPagedPool, Length);
+
+ if (!PartialInformation)
+ return NULL;
+
+
+ /* now query MatchingDeviceId key */
+ Status = ZwQueryValueKey(hSubKey, KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ ExFreePool(PartialInformation);
+ return NULL;
+ }
+
+ if (PartialInformation->Type != REG_SZ)
+ {
+ /* invalid key type */
+ ExFreePool(PartialInformation);
+ return NULL;
+ }
+
+ return PartialInformation;
+}
+
+
+NTSTATUS
+CompareProductName(
+ IN HANDLE hSubKey,
+ IN LPWSTR PnpName,
+ IN ULONG ProductNameSize,
+ OUT LPWSTR ProductName)
+{
+ PKEY_VALUE_PARTIAL_INFORMATION PartialInformation;
+ UNICODE_STRING DriverDescName = RTL_CONSTANT_STRING(L"DriverDesc");
+ UNICODE_STRING MatchingDeviceIdName = RTL_CONSTANT_STRING(L"MatchingDeviceId");
+ ULONG Length;
+ LPWSTR DeviceName;
+
+ /* read MatchingDeviceId value */
+ PartialInformation = ReadKeyValue(hSubKey, &MatchingDeviceIdName);
+
+ if (!PartialInformation)
+ return STATUS_UNSUCCESSFUL;
+
+
+ /* extract last '&' */
+ DeviceName = wcsrchr((LPWSTR)PartialInformation->Data, L'&');
+ ASSERT(DeviceName);
+ /* terminate it */
+ DeviceName[0] = L'\0';
+
+ Length = wcslen((LPWSTR)PartialInformation->Data);
+
+ DPRINT("DeviceName %S PnpName %S Length %u\n", (LPWSTR)PartialInformation->Data, PnpName, Length);
+
+ if (_wcsnicmp((LPWSTR)PartialInformation->Data, &PnpName[4], Length))
+ {
+ ExFreePool(PartialInformation);
+ return STATUS_NO_MATCH;
+ }
+
+ /* free buffer */
+ ExFreePool(PartialInformation);
+
+ /* read DriverDescName value */
+ PartialInformation = ReadKeyValue(hSubKey, &DriverDescName);
+
+ if (!PartialInformation)
+ {
+ /* failed to read driver desc key */
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ /* copy key name */
+ Length = min(ProductNameSize * sizeof(WCHAR), PartialInformation->DataLength);
+ RtlMoveMemory(ProductName, (PVOID)PartialInformation->Data, Length);
+
+ /* zero terminate it */
+ ProductName[ProductNameSize-1] = L'\0';
+
+ /* free buffer */
+ ExFreePool(PartialInformation);
+
+ return STATUS_SUCCESS;
+}
+
+
+
+NTSTATUS
+FindProductName(
+ IN LPWSTR PnpName,
+ IN ULONG ProductNameSize,
+ OUT LPWSTR ProductName)
+{
+ UNICODE_STRING KeyName = RTL_CONSTANT_STRING(L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
+
+ UNICODE_STRING SubKeyName;
+ WCHAR SubKey[20];
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ HANDLE hKey, hSubKey;
+ NTSTATUS Status;
+ ULONG Length, Index;
+ PKEY_FULL_INFORMATION KeyInformation;
+
+ for(Index = 0; Index < wcslen(PnpName); Index++)
+ {
+ if (PnpName[Index] == '#')
+ PnpName[Index] = L'\\';
+ }
+
+
+ /* initialize key attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &KeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, NULL, NULL);
+
+ /* open the key */
+ Status = ZwOpenKey(&hKey, GENERIC_READ, &ObjectAttributes);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ return Status;
+
+ /* query num of subkeys */
+ Status = ZwQueryKey(hKey, KeyFullInformation, NULL, 0, &Length);
+
+ if (Status != STATUS_BUFFER_TOO_SMALL)
+ {
+ DPRINT1("ZwQueryKey failed with %x\n", Status);
+ /* failed */
+ ZwClose(hKey);
+ return Status;
+ }
+
+ /* allocate key information struct */
+ KeyInformation = ExAllocatePool(NonPagedPool, Length);
+ if (!KeyInformation)
+ {
+ /* no memory */
+ ZwClose(hKey);
+ return STATUS_INSUFFICIENT_RESOURCES;
+ }
+
+ /* query num of subkeys */
+ Status = ZwQueryKey(hKey, KeyFullInformation, (PVOID)KeyInformation, Length, &Length);
+
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("ZwQueryKey failed with %x\n", Status);
+ ExFreePool(KeyInformation);
+ ZwClose(hKey);
+ return Status;
+ }
+
+ /* now iterate through all subkeys */
+ for(Index = 0; Index < KeyInformation->SubKeys; Index++)
+ {
+ /* subkeys are always in the format 0000-XXXX */
+ swprintf(SubKey, L"%04u", Index);
+
+ /* initialize subkey name */
+ RtlInitUnicodeString(&SubKeyName, SubKey);
+
+ /* initialize key attributes */
+ InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, hKey, NULL);
+
+ /* open the sub key */
+ Status = ZwOpenKey(&hSubKey, GENERIC_READ, &ObjectAttributes);
+
+ /* check for success */
+ if (NT_SUCCESS(Status))
+ {
+ /* compare product name */
+ Status = CompareProductName(hSubKey, PnpName, ProductNameSize, ProductName);
+
+ /* close subkey */
+ ZwClose(hSubKey);
+
+ if (NT_SUCCESS(Status))
+ break;
+ }
+ }
+
+ /* free buffer */
+ ExFreePool(KeyInformation);
+
+ /* close key */
+ ZwClose(hKey);
+
+ /* no matching key found */
+ return Status;
+}
+
+
+
NTSTATUS
WdmAudCapabilities(
IN PDEVICE_OBJECT DeviceObject,
ULONG dwSupport = 0;
ULONG FilterId;
ULONG PinId;
+ WCHAR DeviceName[MAX_PATH];
DPRINT("WdmAudCapabilities entered\n");
+ if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
+ {
+ Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo);
+ return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
+ }
+
+
Status = GetFilterIdAndPinId(DeviceObject, DeviceInfo, ClientInfo, &FilterId, &PinId);
if (!NT_SUCCESS(Status))
{
DeviceInfo->u.WaveOutCaps.vDriverVersion = MAKELONG(ComponentId.Version, ComponentId.Revision);
}
+ /* retrieve pnp base name */
+ PinProperty.PinId = FilterId;
+ PinProperty.Property.Set = KSPROPSETID_Sysaudio;
+ PinProperty.Property.Id = KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME;
+ PinProperty.Property.Flags = KSPROPERTY_TYPE_GET;
+
+ Status = KsSynchronousIoControlDevice(DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&PinProperty, sizeof(KSP_PIN), (PVOID)DeviceName, sizeof(DeviceName), &BytesReturned);
+ if (NT_SUCCESS(Status))
+ {
+ /* find product name */
+ Status = FindProductName(DeviceName, MAXPNAMELEN, DeviceInfo->u.WaveOutCaps.szPname);
+
+ /* check for success */
+ if (!NT_SUCCESS(Status))
+ {
+ DeviceInfo->u.WaveOutCaps.szPname[0] = L'\0';
+ }
+ }
+
PinProperty.Reserved = DeviceInfo->DeviceIndex;
PinProperty.PinId = PinId;
PinProperty.Property.Set = KSPROPSETID_Pin;
DeviceInfo->u.WaveOutCaps.dwFormats = dwFormats;
DeviceInfo->u.WaveOutCaps.dwSupport = dwSupport;
DeviceInfo->u.WaveOutCaps.wChannels = wChannels;
- DeviceInfo->u.WaveOutCaps.szPname[0] = L'\0';
-
ExFreePool(MultipleItem);
+
return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
}
IN PIRP LowerIrp,
IN PVOID Context)
{
- PIRP Irp;
+ //PIRP Irp;
ASSERT(LowerIrp->PendingReturned == FALSE);
/* get original irp */
- Irp = (PIRP)Context;
+ //Irp = (PIRP)Context;
/* save status */
- Irp->IoStatus.Status = LowerIrp->IoStatus.Status;
- Irp->IoStatus.Information = LowerIrp->IoStatus.Information;
+ //Irp->IoStatus.Status = LowerIrp->IoStatus.Status;
+ //Irp->IoStatus.Information = LowerIrp->IoStatus.Information;
/* complete request */
- IoCompleteRequest(Irp, IO_SOUND_INCREMENT);
+ //IoCompleteRequest(Irp, IO_SOUND_INCREMENT);
/* return success to free irp */
return STATUS_SUCCESS;
}
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
}
- Packet->Header.FrameExtent = DeviceInfo->BufferSize;
- Packet->Header.DataUsed = DeviceInfo->BufferSize;
+ Packet->Header.FrameExtent = DeviceInfo->Header.FrameExtent;
+ Packet->Header.DataUsed = DeviceInfo->Header.DataUsed;
Packet->Header.Size = sizeof(KSSTREAM_HEADER);
Packet->Header.PresentationTime.Numerator = 1;
Packet->Header.PresentationTime.Denominator = 1;
Packet->Irp = Irp;
- Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->BufferSize);
+ Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->Header.DataUsed);
if (!Buffer)
{
/* no memory */
}
Packet->Header.Data = Buffer;
- Mdl = IoAllocateMdl(DeviceInfo->Buffer, DeviceInfo->BufferSize, FALSE, FALSE, FALSE);
+ Mdl = IoAllocateMdl(DeviceInfo->Header.Data, DeviceInfo->Header.DataUsed, FALSE, FALSE, FALSE);
if (!Mdl)
{
/* no memory */
return SetIrpIoStatus(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
}
- RtlMoveMemory(Buffer, SystemBuffer, DeviceInfo->BufferSize);
+ RtlMoveMemory(Buffer, SystemBuffer, DeviceInfo->Header.DataUsed);
MmUnlockPages(Mdl);
IoFreeMdl(Mdl);
/* now build the irp */
LowerIrp = IoBuildAsynchronousFsdRequest (IRP_MJ_WRITE,
IoGetRelatedDeviceObject(FileObject),
- Packet,
- sizeof(KSSTREAM_HEADER),
+ Packet,
+ sizeof(KSSTREAM_HEADER),
&Offset,
NULL);
return SetIrpIoStatus(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
}
+ /* get next stack location */
+ IoStack = IoGetNextIrpStackLocation(LowerIrp);
+
+ /* attach file object */
+ IoStack->FileObject = FileObject;
+
/* set a completion routine */
IoSetCompletionRoutine(LowerIrp, WdmAudWriteCompletion, (PVOID)Irp, TRUE, TRUE, TRUE);
/* mark irp as pending */
- IoMarkIrpPending(Irp);
-
+ //IoMarkIrpPending(Irp);
+ Irp->IoStatus.Information = DeviceInfo->BufferSize;
+ Irp->IoStatus.Status = STATUS_SUCCESS;
+ IoCompleteRequest(Irp, IO_NO_INCREMENT);
+ DPRINT1("Wrote %u\n", DeviceInfo->BufferSize);
/* call the driver */
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), LowerIrp);
/* dereference file object */
ObDereferenceObject(FileObject);
- return STATUS_PENDING;
+ return STATUS_SUCCESS;
#endif
}