2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/legacy/wdmaud/deviface.c
5 * PURPOSE: System Audio graph builder
6 * PROGRAMMER: Andrew Greenwood
11 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
12 const GUID KSPROPSETID_Connection
= {0x1D58C920L
, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
13 const GUID KSPROPSETID_Sysaudio
= {0xCBE3FAA0L
, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
14 const GUID KSPROPSETID_General
= {0x1464EDA5L
, 0x6A8F, 0x11D1, {0x9A, 0xA7, 0x00, 0xA0, 0xC9, 0x22, 0x31, 0x96}};
15 const GUID KSINTERFACESETID_Standard
= {0x1A8766A0L
, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
16 const GUID KSMEDIUMSETID_Standard
= {0x4747B320L
, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
17 const GUID KSDATAFORMAT_TYPE_AUDIO
= {0x73647561L
, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
18 const GUID KSDATAFORMAT_SUBTYPE_PCM
= {0x00000001L
, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
19 const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
= {0x05589f81L
, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
20 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
28 Irp
->IoStatus
.Information
= Length
;
29 Irp
->IoStatus
.Status
= Status
;
30 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
37 IN PDEVICE_OBJECT DeviceObject
,
38 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
39 IN PWDMAUD_CLIENT ClientInfo
,
44 ULONG Count
, BytesReturned
, Index
, SubIndex
, Result
, NumPins
;
46 KSPIN_COMMUNICATION Communication
;
47 KSPIN_DATAFLOW DataFlow
;
48 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
50 if (DeviceInfo
->DeviceType
!= WAVE_OUT_DEVICE_TYPE
&& DeviceInfo
->DeviceType
!= WAVE_IN_DEVICE_TYPE
)
52 DPRINT1("FIXME: Unsupported device type %x\n", DeviceInfo
->DeviceType
);
53 return STATUS_UNSUCCESSFUL
;
56 Pin
.Property
.Set
= KSPROPSETID_Sysaudio
;
57 Pin
.Property
.Id
= KSPROPERTY_SYSAUDIO_DEVICE_COUNT
;
58 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
60 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
62 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSPROPERTY
), (PVOID
)&Count
, sizeof(ULONG
), &BytesReturned
);
63 if (!NT_SUCCESS(Status
))
64 return STATUS_UNSUCCESSFUL
;
67 for(Index
= 0; Index
< Count
; Index
++)
69 /* query number of pins */
70 Pin
.Reserved
= Index
; // see sysaudio
71 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
72 Pin
.Property
.Set
= KSPROPSETID_Pin
;
73 Pin
.Property
.Id
= KSPROPERTY_PIN_CTYPES
;
76 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&NumPins
, sizeof(ULONG
), &BytesReturned
);
77 if (NT_SUCCESS(Status
))
79 /* enumerate now all pins */
80 for(SubIndex
= 0; SubIndex
< NumPins
; SubIndex
++)
83 Pin
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
84 Communication
= KSPIN_COMMUNICATION_NONE
;
86 /* get pin communication type */
87 KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
89 Pin
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
92 /* get pin dataflow type */
93 KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&DataFlow
, sizeof(KSPIN_DATAFLOW
), &BytesReturned
);
95 if (DeviceInfo
->DeviceType
== WAVE_OUT_DEVICE_TYPE
)
97 if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_IN
)
99 if(DeviceInfo
->DeviceIndex
== Result
)
101 /* found the index */
104 return STATUS_SUCCESS
;
110 else if (DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
)
112 if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_OUT
)
114 if(DeviceInfo
->DeviceIndex
== Result
)
116 /* found the index */
119 return STATUS_SUCCESS
;
128 return STATUS_UNSUCCESSFUL
;
133 IN PDEVICE_OBJECT DeviceObject
,
135 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
136 IN PWDMAUD_CLIENT ClientInfo
)
138 SYSAUDIO_INSTANCE_INFO InstanceInfo
;
139 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
142 ACCESS_MASK DesiredAccess
= 0;
144 KSPIN_CONNECT
* PinConnect
;
146 KSDATAFORMAT_WAVEFORMATEX
* DataFormat
;
151 if (DeviceInfo
->DeviceType
== MIXER_DEVICE_TYPE
)
153 return WdmAudControlOpenMixer(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
156 if (DeviceInfo
->DeviceType
!= WAVE_OUT_DEVICE_TYPE
&& DeviceInfo
->DeviceType
!= WAVE_IN_DEVICE_TYPE
)
158 DPRINT1("FIXME: only waveout / wavein devices are supported\n");
159 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
162 if (DeviceInfo
->u
.WaveFormatEx
.wFormatTag
!= WAVE_FORMAT_PCM
)
164 DPRINT("FIXME: Only WAVE_FORMAT_PCM is supported RequestFormat %x\n", DeviceInfo
->u
.WaveFormatEx
.wFormatTag
);
165 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
168 Status
= GetFilterIdAndPinId(DeviceObject
, DeviceInfo
, ClientInfo
, &FilterId
, &PinId
);
169 if (!NT_SUCCESS(Status
))
171 DPRINT1("Invalid device index %u\n", DeviceInfo
->DeviceIndex
);
172 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
175 /* close pin handle which uses same virtual audio device id and pin id */
176 FreeIndex
= (ULONG
)-1;
177 for(Index
= 0; Index
< ClientInfo
->NumPins
; Index
++)
179 if (ClientInfo
->hPins
[Index
].FilterId
== FilterId
&& ClientInfo
->hPins
[Index
].PinId
== PinId
&& ClientInfo
->hPins
[Index
].Handle
&& ClientInfo
->hPins
[Index
].Type
== DeviceInfo
->DeviceType
)
181 ZwClose(ClientInfo
->hPins
[Index
].Handle
);
182 ClientInfo
->hPins
[Index
].Handle
= NULL
;
188 Length
= sizeof(KSDATAFORMAT_WAVEFORMATEX
) + sizeof(KSPIN_CONNECT
);
189 PinConnect
= ExAllocatePool(NonPagedPool
, Length
);
193 return SetIrpIoStatus(Irp
, STATUS_NO_MEMORY
, 0);
196 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
198 if (DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
||
199 DeviceInfo
->DeviceType
== MIDI_IN_DEVICE_TYPE
||
200 DeviceInfo
->DeviceType
== MIXER_DEVICE_TYPE
)
202 DesiredAccess
|= GENERIC_READ
;
205 if (DeviceInfo
->DeviceType
== WAVE_OUT_DEVICE_TYPE
||
206 DeviceInfo
->DeviceType
== MIDI_OUT_DEVICE_TYPE
||
207 DeviceInfo
->DeviceType
== AUX_DEVICE_TYPE
||
208 DeviceInfo
->DeviceType
== MIXER_DEVICE_TYPE
)
210 DesiredAccess
|= GENERIC_WRITE
;
213 PinConnect
->Interface
.Set
= KSINTERFACESETID_Standard
;
214 PinConnect
->Interface
.Id
= KSINTERFACE_STANDARD_STREAMING
;
215 PinConnect
->Interface
.Flags
= 0;
216 PinConnect
->Medium
.Set
= KSMEDIUMSETID_Standard
;
217 PinConnect
->Medium
.Id
= KSMEDIUM_TYPE_ANYINSTANCE
;
218 PinConnect
->Medium
.Flags
= 0;
219 PinConnect
->PinToHandle
= NULL
;
220 PinConnect
->PinId
= PinId
;
221 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
222 PinConnect
->Priority
.PrioritySubClass
= 1;
225 DataFormat
= (KSDATAFORMAT_WAVEFORMATEX
*) (PinConnect
+ 1);
226 DataFormat
->WaveFormatEx
.wFormatTag
= DeviceInfo
->u
.WaveFormatEx
.wFormatTag
;
227 DataFormat
->WaveFormatEx
.nChannels
= DeviceInfo
->u
.WaveFormatEx
.nChannels
;
228 DataFormat
->WaveFormatEx
.nSamplesPerSec
= DeviceInfo
->u
.WaveFormatEx
.nSamplesPerSec
;
229 DataFormat
->WaveFormatEx
.nBlockAlign
= DeviceInfo
->u
.WaveFormatEx
.nBlockAlign
;
230 DataFormat
->WaveFormatEx
.nAvgBytesPerSec
= DeviceInfo
->u
.WaveFormatEx
.nAvgBytesPerSec
;
231 DataFormat
->WaveFormatEx
.wBitsPerSample
= DeviceInfo
->u
.WaveFormatEx
.wBitsPerSample
;
232 DataFormat
->WaveFormatEx
.cbSize
= 0;
233 DataFormat
->DataFormat
.FormatSize
= sizeof(KSDATAFORMAT
) + sizeof(WAVEFORMATEX
);
234 DataFormat
->DataFormat
.Flags
= 0;
235 DataFormat
->DataFormat
.Reserved
= 0;
236 DataFormat
->DataFormat
.MajorFormat
= KSDATAFORMAT_TYPE_AUDIO
;
238 DataFormat
->DataFormat
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
239 DataFormat
->DataFormat
.Specifier
= KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
;
240 DataFormat
->DataFormat
.SampleSize
= 4;
242 /* setup property request */
243 InstanceInfo
.Property
.Set
= KSPROPSETID_Sysaudio
;
244 InstanceInfo
.Property
.Id
= KSPROPERTY_SYSAUDIO_INSTANCE_INFO
;
245 InstanceInfo
.Property
.Flags
= KSPROPERTY_TYPE_SET
;
246 InstanceInfo
.Flags
= 0;
247 InstanceInfo
.DeviceNumber
= FilterId
;
249 /* first open the virtual device */
250 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&InstanceInfo
, sizeof(SYSAUDIO_INSTANCE_INFO
), NULL
, 0, &BytesReturned
);
252 if (!NT_SUCCESS(Status
))
255 ExFreePool(PinConnect
);
256 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
259 /* now create the pin */
260 Status
= KsCreatePin(DeviceExtension
->hSysAudio
, PinConnect
, DesiredAccess
, &PinHandle
);
262 /* free create info */
263 ExFreePool(PinConnect
);
265 if (NT_SUCCESS(Status
))
267 PWDMAUD_HANDLE Handels
;
269 if (FreeIndex
!= (ULONG
)-1)
271 /* re-use a free index */
272 ClientInfo
->hPins
[Index
].Handle
= PinHandle
;
273 ClientInfo
->hPins
[Index
].FilterId
= FilterId
;
274 ClientInfo
->hPins
[Index
].PinId
= PinId
;
275 ClientInfo
->hPins
[Index
].Type
= DeviceInfo
->DeviceType
;
277 DeviceInfo
->hDevice
= PinHandle
;
278 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
281 Handels
= ExAllocatePool(NonPagedPool
, sizeof(WDMAUD_HANDLE
) * (ClientInfo
->NumPins
+1));
285 if (ClientInfo
->NumPins
)
287 RtlMoveMemory(Handels
, ClientInfo
->hPins
, sizeof(WDMAUD_HANDLE
) * ClientInfo
->NumPins
);
288 ExFreePool(ClientInfo
->hPins
);
291 ClientInfo
->hPins
= Handels
;
292 ClientInfo
->hPins
[ClientInfo
->NumPins
].Handle
= PinHandle
;
293 ClientInfo
->hPins
[ClientInfo
->NumPins
].Type
= DeviceInfo
->DeviceType
;
294 ClientInfo
->hPins
[ClientInfo
->NumPins
].FilterId
= FilterId
;
295 ClientInfo
->hPins
[ClientInfo
->NumPins
].PinId
= PinId
;
296 ClientInfo
->NumPins
++;
298 DeviceInfo
->hDevice
= PinHandle
;
302 DeviceInfo
->hDevice
= NULL
;
305 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
309 WdmAudControlDeviceType(
310 IN PDEVICE_OBJECT DeviceObject
,
312 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
313 IN PWDMAUD_CLIENT ClientInfo
)
316 ULONG Count
, BytesReturned
, Index
, SubIndex
, Result
, NumPins
;
318 KSPIN_COMMUNICATION Communication
;
319 KSPIN_DATAFLOW DataFlow
;
320 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
322 if (DeviceInfo
->DeviceType
== MIXER_DEVICE_TYPE
)
324 DeviceInfo
->DeviceCount
= GetNumOfMixerDevices(DeviceObject
);
325 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
328 if (DeviceInfo
->DeviceType
!= WAVE_OUT_DEVICE_TYPE
&& DeviceInfo
->DeviceType
!= WAVE_IN_DEVICE_TYPE
)
330 DPRINT("FIXME: Unsupported device type %x\n", DeviceInfo
->DeviceType
);
331 DeviceInfo
->DeviceCount
= 0;
332 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
335 Pin
.Property
.Set
= KSPROPSETID_Sysaudio
;
336 Pin
.Property
.Id
= KSPROPERTY_SYSAUDIO_DEVICE_COUNT
;
337 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
339 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
340 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSPROPERTY
), (PVOID
)&Count
, sizeof(ULONG
), &BytesReturned
);
341 if (!NT_SUCCESS(Status
))
343 DPRINT1("KSPROPERTY_SYSAUDIO_DEVICE_COUNT failed with %x\n", Status
);
344 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
347 /* now enumerate all available filters */
348 for(Index
= 0; Index
< Count
; Index
++)
350 /* query number of pins */
351 Pin
.Reserved
= Index
; // see sysaudio
352 Pin
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
353 Pin
.Property
.Set
= KSPROPSETID_Pin
;
354 Pin
.Property
.Id
= KSPROPERTY_PIN_CTYPES
;
357 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&NumPins
, sizeof(ULONG
), &BytesReturned
);
358 if (NT_SUCCESS(Status
))
360 /* enumerate now all pins */
361 for(SubIndex
= 0; SubIndex
< NumPins
; SubIndex
++)
363 Pin
.PinId
= SubIndex
;
364 Pin
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
365 Communication
= KSPIN_COMMUNICATION_NONE
;
367 /* get pin communication type */
368 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&Communication
, sizeof(KSPIN_COMMUNICATION
), &BytesReturned
);
369 if (!NT_SUCCESS(Status
))
372 Pin
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
375 /* get pin dataflow type */
376 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Pin
, sizeof(KSP_PIN
), (PVOID
)&DataFlow
, sizeof(KSPIN_DATAFLOW
), &BytesReturned
);
377 if (!NT_SUCCESS(Status
))
380 if (DeviceInfo
->DeviceType
== WAVE_OUT_DEVICE_TYPE
)
382 if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_IN
)
385 else if (DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
)
387 if (Communication
== KSPIN_COMMUNICATION_SINK
&& DataFlow
== KSPIN_DATAFLOW_OUT
)
394 /* store result count */
395 DeviceInfo
->DeviceCount
= Result
;
397 DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status
, DeviceInfo
->DeviceCount
);
398 return SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
402 WdmAudControlDeviceState(
403 IN PDEVICE_OBJECT DeviceObject
,
405 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
406 IN PWDMAUD_CLIENT ClientInfo
)
412 PFILE_OBJECT FileObject
;
414 //DPRINT1("WdmAudControlDeviceState\n");
416 Status
= ObReferenceObjectByHandle(DeviceInfo
->hDevice
, GENERIC_READ
| GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
417 if (!NT_SUCCESS(Status
))
419 DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo
->hDevice
, DeviceInfo
->DeviceType
);
420 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
423 Property
.Set
= KSPROPSETID_Connection
;
424 Property
.Id
= KSPROPERTY_CONNECTION_STATE
;
425 Property
.Flags
= KSPROPERTY_TYPE_SET
;
427 State
= DeviceInfo
->u
.State
;
429 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&State
, sizeof(KSSTATE
), &BytesReturned
);
431 ObDereferenceObject(FileObject
);
433 //DPRINT1("WdmAudControlDeviceState Status %x\n", Status);
434 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
439 IN PKSDATARANGE_AUDIO DataRangeAudio
,
440 ULONG SampleFrequency
,
448 if (DataRangeAudio
->MinimumSampleFrequency
<= SampleFrequency
&& DataRangeAudio
->MaximumSampleFrequency
>= SampleFrequency
)
450 if (DataRangeAudio
->MinimumBitsPerSample
<= 8 && DataRangeAudio
->MaximumBitsPerSample
>= 8)
453 if (DataRangeAudio
->MaximumChannels
>= 2)
455 Result
|= Stereo8Bit
;
459 if (DataRangeAudio
->MinimumBitsPerSample
<= 16 && DataRangeAudio
->MaximumBitsPerSample
>= 16)
462 if (DataRangeAudio
->MaximumChannels
>= 2)
464 Result
|= Stereo8Bit
;
472 PKEY_VALUE_PARTIAL_INFORMATION
475 IN PUNICODE_STRING KeyName
)
479 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
481 /* now query MatchingDeviceId key */
482 Status
= ZwQueryValueKey(hSubKey
, KeyName
, KeyValuePartialInformation
, NULL
, 0, &Length
);
484 /* check for success */
485 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
488 /* allocate a buffer for key data */
489 PartialInformation
= ExAllocatePool(NonPagedPool
, Length
);
491 if (!PartialInformation
)
495 /* now query MatchingDeviceId key */
496 Status
= ZwQueryValueKey(hSubKey
, KeyName
, KeyValuePartialInformation
, PartialInformation
, Length
, &Length
);
498 /* check for success */
499 if (!NT_SUCCESS(Status
))
501 ExFreePool(PartialInformation
);
505 if (PartialInformation
->Type
!= REG_SZ
)
507 /* invalid key type */
508 ExFreePool(PartialInformation
);
512 return PartialInformation
;
520 IN ULONG ProductNameSize
,
521 OUT LPWSTR ProductName
)
523 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation
;
524 UNICODE_STRING DriverDescName
= RTL_CONSTANT_STRING(L
"DriverDesc");
525 UNICODE_STRING MatchingDeviceIdName
= RTL_CONSTANT_STRING(L
"MatchingDeviceId");
529 /* read MatchingDeviceId value */
530 PartialInformation
= ReadKeyValue(hSubKey
, &MatchingDeviceIdName
);
532 if (!PartialInformation
)
533 return STATUS_UNSUCCESSFUL
;
536 /* extract last '&' */
537 DeviceName
= wcsrchr((LPWSTR
)PartialInformation
->Data
, L
'&');
540 DeviceName
[0] = L
'\0';
542 Length
= wcslen((LPWSTR
)PartialInformation
->Data
);
544 DPRINT("DeviceName %S PnpName %S Length %u\n", (LPWSTR
)PartialInformation
->Data
, PnpName
, Length
);
546 if (_wcsnicmp((LPWSTR
)PartialInformation
->Data
, &PnpName
[4], Length
))
548 ExFreePool(PartialInformation
);
549 return STATUS_NO_MATCH
;
553 ExFreePool(PartialInformation
);
555 /* read DriverDescName value */
556 PartialInformation
= ReadKeyValue(hSubKey
, &DriverDescName
);
558 if (!PartialInformation
)
560 /* failed to read driver desc key */
561 return STATUS_UNSUCCESSFUL
;
565 Length
= min(ProductNameSize
* sizeof(WCHAR
), PartialInformation
->DataLength
);
566 RtlMoveMemory(ProductName
, (PVOID
)PartialInformation
->Data
, Length
);
568 /* zero terminate it */
569 ProductName
[ProductNameSize
-1] = L
'\0';
572 ExFreePool(PartialInformation
);
574 return STATUS_SUCCESS
;
582 IN ULONG ProductNameSize
,
583 OUT LPWSTR ProductName
)
585 UNICODE_STRING KeyName
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\Class\\{4D36E96C-E325-11CE-BFC1-08002BE10318}");
587 UNICODE_STRING SubKeyName
;
589 OBJECT_ATTRIBUTES ObjectAttributes
;
590 HANDLE hKey
, hSubKey
;
593 PKEY_FULL_INFORMATION KeyInformation
;
595 for(Index
= 0; Index
< wcslen(PnpName
); Index
++)
597 if (PnpName
[Index
] == '#')
598 PnpName
[Index
] = L
'\\';
602 /* initialize key attributes */
603 InitializeObjectAttributes(&ObjectAttributes
, &KeyName
, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, NULL
, NULL
);
606 Status
= ZwOpenKey(&hKey
, GENERIC_READ
, &ObjectAttributes
);
608 /* check for success */
609 if (!NT_SUCCESS(Status
))
612 /* query num of subkeys */
613 Status
= ZwQueryKey(hKey
, KeyFullInformation
, NULL
, 0, &Length
);
615 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
617 DPRINT1("ZwQueryKey failed with %x\n", Status
);
623 /* allocate key information struct */
624 KeyInformation
= ExAllocatePool(NonPagedPool
, Length
);
629 return STATUS_INSUFFICIENT_RESOURCES
;
632 /* query num of subkeys */
633 Status
= ZwQueryKey(hKey
, KeyFullInformation
, (PVOID
)KeyInformation
, Length
, &Length
);
635 if (!NT_SUCCESS(Status
))
637 DPRINT1("ZwQueryKey failed with %x\n", Status
);
638 ExFreePool(KeyInformation
);
643 /* now iterate through all subkeys */
644 for(Index
= 0; Index
< KeyInformation
->SubKeys
; Index
++)
646 /* subkeys are always in the format 0000-XXXX */
647 swprintf(SubKey
, L
"%04u", Index
);
649 /* initialize subkey name */
650 RtlInitUnicodeString(&SubKeyName
, SubKey
);
652 /* initialize key attributes */
653 InitializeObjectAttributes(&ObjectAttributes
, &SubKeyName
, OBJ_CASE_INSENSITIVE
| OBJ_OPENIF
, hKey
, NULL
);
655 /* open the sub key */
656 Status
= ZwOpenKey(&hSubKey
, GENERIC_READ
, &ObjectAttributes
);
658 /* check for success */
659 if (NT_SUCCESS(Status
))
661 /* compare product name */
662 Status
= CompareProductName(hSubKey
, PnpName
, ProductNameSize
, ProductName
);
667 if (NT_SUCCESS(Status
))
673 ExFreePool(KeyInformation
);
678 /* no matching key found */
686 IN PDEVICE_OBJECT DeviceObject
,
688 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
689 IN PWDMAUD_CLIENT ClientInfo
)
691 PWDMAUD_DEVICE_EXTENSION DeviceExtension
;
692 NTSTATUS Status
= STATUS_UNSUCCESSFUL
;
694 KSCOMPONENTID ComponentId
;
695 KSMULTIPLE_ITEM
* MultipleItem
;
697 PKSDATARANGE_AUDIO DataRangeAudio
;
698 PKSDATARANGE DataRange
;
705 WCHAR DeviceName
[MAX_PATH
];
707 DPRINT("WdmAudCapabilities entered\n");
709 if (DeviceInfo
->DeviceType
== MIXER_DEVICE_TYPE
)
711 Status
= WdmAudMixerCapabilities(DeviceObject
, DeviceInfo
, ClientInfo
);
712 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
716 Status
= GetFilterIdAndPinId(DeviceObject
, DeviceInfo
, ClientInfo
, &FilterId
, &PinId
);
717 if (!NT_SUCCESS(Status
))
719 DPRINT1("Invalid device index provided %u\n", DeviceInfo
->DeviceIndex
);
720 return SetIrpIoStatus(Irp
, STATUS_INVALID_PARAMETER
, 0);
723 PinProperty
.PinId
= FilterId
;
724 PinProperty
.Property
.Set
= KSPROPSETID_Sysaudio
;
725 PinProperty
.Property
.Id
= KSPROPERTY_SYSAUDIO_COMPONENT_ID
;
726 PinProperty
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
728 RtlZeroMemory(&ComponentId
, sizeof(KSCOMPONENTID
));
730 DeviceExtension
= (PWDMAUD_DEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
731 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)&ComponentId
, sizeof(KSCOMPONENTID
), &BytesReturned
);
732 if (NT_SUCCESS(Status
))
734 DeviceInfo
->u
.WaveOutCaps
.wMid
= ComponentId
.Manufacturer
.Data1
- 0xd5a47fa7;
735 DeviceInfo
->u
.WaveOutCaps
.vDriverVersion
= MAKELONG(ComponentId
.Version
, ComponentId
.Revision
);
738 /* retrieve pnp base name */
739 PinProperty
.PinId
= FilterId
;
740 PinProperty
.Property
.Set
= KSPROPSETID_Sysaudio
;
741 PinProperty
.Property
.Id
= KSPROPERTY_SYSAUDIO_DEVICE_INTERFACE_NAME
;
742 PinProperty
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
744 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)DeviceName
, sizeof(DeviceName
), &BytesReturned
);
745 if (NT_SUCCESS(Status
))
747 /* find product name */
748 Status
= FindProductName(DeviceName
, MAXPNAMELEN
, DeviceInfo
->u
.WaveOutCaps
.szPname
);
750 /* check for success */
751 if (!NT_SUCCESS(Status
))
753 DeviceInfo
->u
.WaveOutCaps
.szPname
[0] = L
'\0';
757 PinProperty
.Reserved
= DeviceInfo
->DeviceIndex
;
758 PinProperty
.PinId
= PinId
;
759 PinProperty
.Property
.Set
= KSPROPSETID_Pin
;
760 PinProperty
.Property
.Id
= KSPROPERTY_PIN_DATARANGES
;
761 PinProperty
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
764 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)NULL
, 0, &BytesReturned
);
765 if (Status
!= STATUS_BUFFER_TOO_SMALL
)
767 return SetIrpIoStatus(Irp
, Status
, 0);
770 MultipleItem
= ExAllocatePool(NonPagedPool
, BytesReturned
);
774 return SetIrpIoStatus(Irp
, STATUS_NO_MEMORY
, 0);
777 Status
= KsSynchronousIoControlDevice(DeviceExtension
->FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&PinProperty
, sizeof(KSP_PIN
), (PVOID
)MultipleItem
, BytesReturned
, &BytesReturned
);
778 if (!NT_SUCCESS(Status
))
780 ExFreePool(MultipleItem
);
781 return SetIrpIoStatus(Irp
, Status
, 0);
784 DataRange
= (PKSDATARANGE
) (MultipleItem
+ 1);
785 for(Index
= 0; Index
< MultipleItem
->Count
; Index
++)
787 if (DeviceInfo
->DeviceType
== WAVE_OUT_DEVICE_TYPE
|| DeviceInfo
->DeviceType
== WAVE_IN_DEVICE_TYPE
)
789 if (DataRange
->FormatSize
== sizeof(KSDATARANGE_AUDIO
))
791 DataRangeAudio
= (PKSDATARANGE_AUDIO
)DataRange
;
793 if (IsEqualGUIDAligned(&DataRangeAudio
->DataRange
.MajorFormat
, &KSDATAFORMAT_TYPE_AUDIO
) &&
794 IsEqualGUIDAligned(&DataRangeAudio
->DataRange
.SubFormat
, &KSDATAFORMAT_SUBTYPE_PCM
) &&
795 IsEqualGUIDAligned(&DataRangeAudio
->DataRange
.Specifier
, &KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
))
797 DPRINT("Min Sample %u Max Sample %u Min Bits %u Max Bits %u Max Channel %u\n", DataRangeAudio
->MinimumSampleFrequency
, DataRangeAudio
->MaximumSampleFrequency
,
798 DataRangeAudio
->MinimumBitsPerSample
, DataRangeAudio
->MaximumBitsPerSample
, DataRangeAudio
->MaximumChannels
);
800 dwFormats
|= CheckFormatSupport(DataRangeAudio
, 11025, WAVE_FORMAT_1M08
, WAVE_FORMAT_1S08
, WAVE_FORMAT_1M16
, WAVE_FORMAT_1S16
);
801 dwFormats
|= CheckFormatSupport(DataRangeAudio
, 22050, WAVE_FORMAT_2M08
, WAVE_FORMAT_2S08
, WAVE_FORMAT_2M16
, WAVE_FORMAT_2S16
);
802 dwFormats
|= CheckFormatSupport(DataRangeAudio
, 44100, WAVE_FORMAT_4M08
, WAVE_FORMAT_4S08
, WAVE_FORMAT_4M16
, WAVE_FORMAT_4S16
);
803 dwFormats
|= CheckFormatSupport(DataRangeAudio
, 48000, WAVE_FORMAT_48M08
, WAVE_FORMAT_48S08
, WAVE_FORMAT_48M16
, WAVE_FORMAT_48S16
);
804 dwFormats
|= CheckFormatSupport(DataRangeAudio
, 96000, WAVE_FORMAT_96M08
, WAVE_FORMAT_96S08
, WAVE_FORMAT_96M16
, WAVE_FORMAT_96S16
);
807 wChannels
= DataRangeAudio
->MaximumChannels
;
808 dwSupport
= WAVECAPS_VOLUME
; //FIXME get info from nodes
812 DataRange
= (PKSDATARANGE
)((PUCHAR
)DataRange
+ DataRange
->FormatSize
);
815 DeviceInfo
->u
.WaveOutCaps
.dwFormats
= dwFormats
;
816 DeviceInfo
->u
.WaveOutCaps
.dwSupport
= dwSupport
;
817 DeviceInfo
->u
.WaveOutCaps
.wChannels
= wChannels
;
819 ExFreePool(MultipleItem
);
821 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
827 IN PDEVICE_OBJECT DeviceObject
,
829 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
830 IN PWDMAUD_CLIENT ClientInfo
)
834 for(Index
= 0; Index
< ClientInfo
->NumPins
; Index
++)
836 if (ClientInfo
->hPins
[Index
].Handle
== DeviceInfo
->hDevice
&& ClientInfo
->hPins
[Index
].Type
!= MIXER_DEVICE_TYPE
)
838 DPRINT1("Closing device %p\n", DeviceInfo
->hDevice
);
839 ZwClose(DeviceInfo
->hDevice
);
840 ClientInfo
->hPins
[Index
].Handle
= NULL
;
841 SetIrpIoStatus(Irp
, STATUS_SUCCESS
, sizeof(WDMAUD_DEVICE_INFO
));
842 return STATUS_SUCCESS
;
845 SetIrpIoStatus(Irp
, STATUS_INVALID_PARAMETER
, sizeof(WDMAUD_DEVICE_INFO
));
846 return STATUS_INVALID_PARAMETER
;
852 IN PDEVICE_OBJECT DeviceObject
,
854 IN PWDMAUD_DEVICE_INFO DeviceInfo
,
855 IN PWDMAUD_CLIENT ClientInfo
)
857 PFILE_OBJECT FileObject
;
860 KSALLOCATOR_FRAMING Framing
;
863 /* Get sysaudio pin file object */
864 Status
= ObReferenceObjectByHandle(DeviceInfo
->hDevice
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
865 if (!NT_SUCCESS(Status
))
867 DPRINT1("Invalid buffer handle %x\n", DeviceInfo
->hDevice
);
868 return SetIrpIoStatus(Irp
, Status
, 0);
871 /* Setup get framing request */
872 Property
.Id
= KSPROPERTY_CONNECTION_ALLOCATORFRAMING
;
873 Property
.Flags
= KSPROPERTY_TYPE_GET
;
874 Property
.Set
= KSPROPSETID_Connection
;
876 Status
= KsSynchronousIoControlDevice(FileObject
, KernelMode
, IOCTL_KS_PROPERTY
, (PVOID
)&Property
, sizeof(KSPROPERTY
), (PVOID
)&Framing
, sizeof(KSALLOCATOR_FRAMING
), &BytesReturned
);
878 if (NT_SUCCESS(Status
))
880 /* Store framesize */
881 DeviceInfo
->u
.FrameSize
= Framing
.FrameSize
;
884 /* Release file object */
885 ObDereferenceObject(FileObject
);
887 return SetIrpIoStatus(Irp
, Status
, sizeof(WDMAUD_DEVICE_INFO
));
895 IN PDEVICE_OBJECT DeviceObject
,
898 PIO_STACK_LOCATION IoStack
;
899 PWDMAUD_DEVICE_INFO DeviceInfo
;
900 PWDMAUD_CLIENT ClientInfo
;
902 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
904 DPRINT("WdmAudDeviceControl entered\n");
906 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(WDMAUD_DEVICE_INFO
))
908 /* invalid parameter */
909 DPRINT1("Input buffer too small size %u expected %u\n", IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
, sizeof(WDMAUD_DEVICE_INFO
));
910 return SetIrpIoStatus(Irp
, STATUS_INVALID_PARAMETER
, 0);
913 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)Irp
->AssociatedIrp
.SystemBuffer
;
915 if (DeviceInfo
->DeviceType
< MIN_SOUND_DEVICE_TYPE
|| DeviceInfo
->DeviceType
> MAX_SOUND_DEVICE_TYPE
)
917 /* invalid parameter */
918 DPRINT1("Error: device type not set\n");
919 return SetIrpIoStatus(Irp
, STATUS_INVALID_PARAMETER
, 0);
922 if (!IoStack
->FileObject
)
924 /* file object parameter */
925 DPRINT1("Error: file object is not attached\n");
926 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
928 ClientInfo
= (PWDMAUD_CLIENT
)IoStack
->FileObject
->FsContext
;
930 DPRINT("WdmAudDeviceControl entered\n");
932 switch(IoStack
->Parameters
.DeviceIoControl
.IoControlCode
)
934 case IOCTL_OPEN_WDMAUD
:
935 return WdmAudControlOpen(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
936 case IOCTL_GETNUMDEVS_TYPE
:
937 return WdmAudControlDeviceType(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
938 case IOCTL_SETDEVICE_STATE
:
939 return WdmAudControlDeviceState(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
940 case IOCTL_GETCAPABILITIES
:
941 return WdmAudCapabilities(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
942 case IOCTL_CLOSE_WDMAUD
:
943 return WdmAudIoctlClose(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
944 case IOCTL_GETFRAMESIZE
:
945 return WdmAudFrameSize(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
946 case IOCTL_GETLINEINFO
:
947 return WdmAudGetLineInfo(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
948 case IOCTL_GETLINECONTROLS
:
949 return WdmAudGetLineControls(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
950 case IOCTL_SETCONTROLDETAILS
:
951 return WdmAudSetControlDetails(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
952 case IOCTL_GETCONTROLDETAILS
:
953 return WdmAudGetControlDetails(DeviceObject
, Irp
, DeviceInfo
, ClientInfo
);
957 case IOCTL_GETVOLUME
:
958 case IOCTL_SETVOLUME
:
960 DPRINT1("Unhandeled %x\n", IoStack
->Parameters
.DeviceIoControl
.IoControlCode
);
964 return SetIrpIoStatus(Irp
, STATUS_NOT_IMPLEMENTED
, 0);
969 WdmAudWriteCompletion(
970 IN PDEVICE_OBJECT DeviceObject
,
975 ASSERT(LowerIrp
->PendingReturned
== FALSE
);
976 /* get original irp */
977 //Irp = (PIRP)Context;
980 //Irp->IoStatus.Status = LowerIrp->IoStatus.Status;
981 //Irp->IoStatus.Information = LowerIrp->IoStatus.Information;
982 /* complete request */
983 //IoCompleteRequest(Irp, IO_SOUND_INCREMENT);
984 /* return success to free irp */
985 return STATUS_SUCCESS
;
992 IN PDEVICE_OBJECT DeviceObject
,
995 PIO_STACK_LOCATION IoStack
;
996 PWDMAUD_DEVICE_INFO DeviceInfo
;
997 PWDMAUD_CLIENT ClientInfo
;
998 NTSTATUS Status
= STATUS_SUCCESS
;
1000 PFILE_OBJECT FileObject
;
1003 PCONTEXT_WRITE Packet
;
1005 //LARGE_INTEGER Offset;
1006 IO_STATUS_BLOCK IoStatusBlock
;
1008 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1010 //DPRINT("WdmAudWrite entered\n");
1012 if (IoStack
->Parameters
.Write
.Length
< sizeof(WDMAUD_DEVICE_INFO
))
1014 /* invalid parameter */
1015 DPRINT1("Input buffer too small size %u expected %u\n", IoStack
->Parameters
.Write
.Length
, sizeof(WDMAUD_DEVICE_INFO
));
1016 return SetIrpIoStatus(Irp
, STATUS_INVALID_PARAMETER
, 0);
1019 DeviceInfo
= (PWDMAUD_DEVICE_INFO
)MmGetMdlVirtualAddress(Irp
->MdlAddress
);
1022 Status
= ObReferenceObjectByHandle(DeviceInfo
->hDevice
, GENERIC_WRITE
, IoFileObjectType
, KernelMode
, (PVOID
*)&FileObject
, NULL
);
1023 if (!NT_SUCCESS(Status
))
1025 DPRINT1("Invalid buffer handle %x\n", DeviceInfo
->hDevice
);
1026 return SetIrpIoStatus(Irp
, Status
, 0);
1030 //DPRINT("DeviceInfo %p %p %p\n", DeviceInfo, Irp->MdlAddress->StartVa, Irp->MdlAddress->MappedSystemVa);
1031 if (DeviceInfo
->DeviceType
< MIN_SOUND_DEVICE_TYPE
|| DeviceInfo
->DeviceType
> MAX_SOUND_DEVICE_TYPE
)
1033 /* invalid parameter */
1034 DPRINT1("Error: device type not set\n");
1035 ObDereferenceObject(FileObject
);
1036 return SetIrpIoStatus(Irp
, STATUS_INVALID_PARAMETER
, 0);
1039 if (!IoStack
->FileObject
)
1041 /* file object parameter */
1042 DPRINT1("Error: file object is not attached\n");
1043 ObDereferenceObject(FileObject
);
1044 return SetIrpIoStatus(Irp
, STATUS_UNSUCCESSFUL
, 0);
1046 ClientInfo
= (PWDMAUD_CLIENT
)IoStack
->FileObject
->FsContext
;
1049 /* setup stream context */
1050 Packet
= (PCONTEXT_WRITE
)ExAllocatePool(NonPagedPool
, sizeof(CONTEXT_WRITE
));
1054 return SetIrpIoStatus(Irp
, STATUS_NO_MEMORY
, 0);
1057 Packet
->Header
.FrameExtent
= DeviceInfo
->Header
.FrameExtent
;
1058 Packet
->Header
.DataUsed
= DeviceInfo
->Header
.DataUsed
;
1059 Packet
->Header
.Size
= sizeof(KSSTREAM_HEADER
);
1060 Packet
->Header
.PresentationTime
.Numerator
= 1;
1061 Packet
->Header
.PresentationTime
.Denominator
= 1;
1064 Buffer
= ExAllocatePool(NonPagedPool
, DeviceInfo
->Header
.DataUsed
);
1069 ObDereferenceObject(FileObject
);
1070 return SetIrpIoStatus(Irp
, STATUS_NO_MEMORY
, 0);
1072 Packet
->Header
.Data
= Buffer
;
1074 Mdl
= IoAllocateMdl(DeviceInfo
->Header
.Data
, DeviceInfo
->Header
.DataUsed
, FALSE
, FALSE
, FALSE
);
1079 ObDereferenceObject(FileObject
);
1081 return SetIrpIoStatus(Irp
, STATUS_NO_MEMORY
, 0);
1086 MmProbeAndLockPages(Mdl
, UserMode
, IoReadAccess
);
1088 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1090 /* Exception, get the error code */
1091 Status
= _SEH2_GetExceptionCode();
1095 if (!NT_SUCCESS(Status
))
1097 DPRINT1("Invalid buffer supplied\n");
1101 ObDereferenceObject(FileObject
);
1102 return SetIrpIoStatus(Irp
, Status
, 0);
1105 SystemBuffer
= MmGetSystemAddressForMdlSafe(Mdl
, NormalPagePriority
);
1108 DPRINT1("Invalid buffer supplied\n");
1112 ObDereferenceObject(FileObject
);
1113 return SetIrpIoStatus(Irp
, STATUS_INSUFFICIENT_RESOURCES
, 0);
1116 RtlMoveMemory(Buffer
, SystemBuffer
, DeviceInfo
->Header
.DataUsed
);
1121 KsStreamIo(FileObject
, NULL
, NULL
, NULL
, NULL
, 0, &IoStatusBlock
, Packet
, sizeof(CONTEXT_WRITE
), KSSTREAM_WRITE
, UserMode
);
1122 /* dereference file object */
1123 ObDereferenceObject(FileObject
);
1124 return IoStatusBlock
.Status
;
1126 Offset
.QuadPart
= 0L;
1128 /* now build the irp */
1129 LowerIrp
= IoBuildAsynchronousFsdRequest (IRP_MJ_WRITE
,
1130 IoGetRelatedDeviceObject(FileObject
),
1132 sizeof(KSSTREAM_HEADER
),
1138 /* failed to create an associated irp */
1141 ObDereferenceObject(FileObject
);
1143 return SetIrpIoStatus(Irp
, STATUS_INSUFFICIENT_RESOURCES
, 0);
1146 /* get next stack location */
1147 IoStack
= IoGetNextIrpStackLocation(LowerIrp
);
1149 /* attach file object */
1150 IoStack
->FileObject
= FileObject
;
1152 /* set a completion routine */
1153 IoSetCompletionRoutine(LowerIrp
, WdmAudWriteCompletion
, (PVOID
)Irp
, TRUE
, TRUE
, TRUE
);
1155 /* mark irp as pending */
1156 //IoMarkIrpPending(Irp);
1157 Irp
->IoStatus
.Information
= DeviceInfo
->BufferSize
;
1158 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1159 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1160 DPRINT1("Wrote %u\n", DeviceInfo
->BufferSize
);
1161 /* call the driver */
1162 Status
= IoCallDriver(IoGetRelatedDeviceObject(FileObject
), LowerIrp
);
1164 /* dereference file object */
1165 ObDereferenceObject(FileObject
);
1167 return STATUS_SUCCESS
;