2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Configuration of network devices
4 * FILE: dll/directx/dsound_new/misc.c
5 * PURPOSE: Misc support routines
7 * PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
12 const GUID KSPROPSETID_Pin
= {0x8C134960L
, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
13 const GUID KSPROPSETID_Topology
= {0x720D4AC0L
, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
14 const GUID KSPROPSETID_Audio
= {0x45FFAAA0L
, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
20 LPWAVEFORMATEX WaveFormatEx
,
25 PKSPIN_CONNECT PinConnect
;
26 PKSDATAFORMAT_WAVEFORMATEX DataFormat
;
28 /* calculate request size */
29 Size
= sizeof(KSPIN_CONNECT
) + sizeof(KSDATAFORMAT_WAVEFORMATEX
);
31 PinConnect
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, Size
);
34 /* not enough memory */
35 return DSERR_OUTOFMEMORY
;
37 /* build pin request */
38 PinConnect
->Interface
.Set
= KSINTERFACESETID_Standard
;
41 PinConnect
->Interface
.Id
= KSINTERFACE_STANDARD_LOOPED_STREAMING
;
43 PinConnect
->Interface
.Id
= KSINTERFACE_STANDARD_STREAMING
;
45 PinConnect
->Interface
.Flags
= 0;
46 PinConnect
->Medium
.Set
= KSMEDIUMSETID_Standard
;
47 PinConnect
->Medium
.Id
= KSMEDIUM_TYPE_ANYINSTANCE
;
48 PinConnect
->Medium
.Flags
= 0;
49 PinConnect
->PinToHandle
= NULL
;
50 PinConnect
->PinId
= PinId
;
51 PinConnect
->Priority
.PriorityClass
= KSPRIORITY_NORMAL
;
52 PinConnect
->Priority
.PrioritySubClass
= 1;
54 DataFormat
= (PKSDATAFORMAT_WAVEFORMATEX
) (PinConnect
+ 1);
56 /* initialize data format */
57 DataFormat
->WaveFormatEx
.wFormatTag
= WaveFormatEx
->wFormatTag
;
58 DataFormat
->WaveFormatEx
.nChannels
= WaveFormatEx
->nChannels
;
59 DataFormat
->WaveFormatEx
.nSamplesPerSec
= WaveFormatEx
->nSamplesPerSec
;
60 DataFormat
->WaveFormatEx
.nBlockAlign
= WaveFormatEx
->nBlockAlign
;
61 DataFormat
->WaveFormatEx
.nAvgBytesPerSec
= WaveFormatEx
->nAvgBytesPerSec
;
62 DataFormat
->WaveFormatEx
.wBitsPerSample
= WaveFormatEx
->wBitsPerSample
;
63 DataFormat
->WaveFormatEx
.cbSize
= 0;
64 DataFormat
->DataFormat
.FormatSize
= sizeof(KSDATAFORMAT
) + sizeof(WAVEFORMATEX
);
65 DataFormat
->DataFormat
.Flags
= 0;
66 DataFormat
->DataFormat
.Reserved
= 0;
67 DataFormat
->DataFormat
.MajorFormat
= KSDATAFORMAT_TYPE_AUDIO
;
69 DataFormat
->DataFormat
.SubFormat
= KSDATAFORMAT_SUBTYPE_PCM
;
70 DataFormat
->DataFormat
.Specifier
= KSDATAFORMAT_SPECIFIER_WAVEFORMATEX
;
71 DataFormat
->DataFormat
.SampleSize
= 4;
73 Result
= KsCreatePin(hFilter
, PinConnect
, GENERIC_READ
| GENERIC_WRITE
, hPin
);
75 HeapFree(GetProcessHeap(), 0, PinConnect
);
83 IN LPCWSTR lpFileName
,
89 Handle
= CreateFileW(lpFileName
, GENERIC_WRITE
| GENERIC_READ
, 0, NULL
, OPEN_EXISTING
, FILE_ATTRIBUTE_NORMAL
| FILE_FLAG_OVERLAPPED
, NULL
);
91 /* check for success */
92 if (Handle
== INVALID_HANDLE_VALUE
)
94 DPRINT("Failed to open Filter %ws\n", lpFileName
);
95 return GetLastError();
103 SyncOverlappedDeviceIoControl(
105 IN DWORD IoControlCode
,
107 IN DWORD InBufferSize
,
108 OUT LPVOID OutBuffer
,
109 IN DWORD OutBufferSize
,
110 OUT LPDWORD BytesTransferred OPTIONAL
)
112 OVERLAPPED Overlapped
;
116 /* Overlapped I/O is done here - this is used for waiting for completion */
117 ZeroMemory(&Overlapped
, sizeof(OVERLAPPED
));
118 Overlapped
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
120 if (!Overlapped
.hEvent
)
121 return GetLastError();
123 /* Talk to the device */
124 IoResult
= DeviceIoControl(Handle
,
133 /* If failure occurs, make sure it's not just due to the overlapped I/O */
136 if ( GetLastError() != ERROR_IO_PENDING
)
138 CloseHandle(Overlapped
.hEvent
);
139 return GetLastError();
143 /* Wait for the I/O to complete */
144 IoResult
= GetOverlappedResult(Handle
,
149 /* Don't need this any more */
150 CloseHandle(Overlapped
.hEvent
);
153 return GetLastError();
155 if ( BytesTransferred
)
156 *BytesTransferred
= Transferred
;
158 return ERROR_SUCCESS
;
170 /* setup the pin request */
171 Pin
.Flags
= KSPROPERTY_TYPE_GET
;
172 Pin
.Set
= KSPROPSETID_Pin
;
173 Pin
.Id
= KSPROPERTY_PIN_CTYPES
;
175 /* query the device */
176 return SyncOverlappedDeviceIoControl(hFilter
, IOCTL_KS_PROPERTY
, (LPVOID
)&Pin
, sizeof(KSPROPERTY
), (PVOID
)NumPins
, sizeof(ULONG
), NULL
);
180 GetFilterNodeProperty(
183 OUT PKSMULTIPLE_ITEM
*OutMultipleItem
)
185 DWORD Status
, BytesReturned
;
186 PKSMULTIPLE_ITEM MultipleItem
;
189 /* setup query request */
190 Property
.Id
= PropertyId
;
191 Property
.Flags
= KSPROPERTY_TYPE_GET
;
192 Property
.Set
= KSPROPSETID_Topology
;
195 Status
= SyncOverlappedDeviceIoControl(hFilter
, IOCTL_KS_PROPERTY
, (LPVOID
)&Property
, sizeof(KSPROPERTY
), NULL
, 0, &BytesReturned
);
197 if (Status
!= ERROR_MORE_DATA
)
200 DPRINT("Failed to query PropertyId %lu ErrorCode %lx\n", PropertyId
, Status
);
204 MultipleItem
= HeapAlloc(GetProcessHeap(), 0, BytesReturned
);
207 /* not enough memory */
208 DPRINT("Failed to allocate %u Bytes\n", BytesReturned
);
209 return ERROR_OUTOFMEMORY
;
212 /* retrieve data ranges */
213 Status
= SyncOverlappedDeviceIoControl(hFilter
, IOCTL_KS_PROPERTY
, (LPVOID
)&Property
, sizeof(KSP_PIN
), (LPVOID
)MultipleItem
, BytesReturned
, &BytesReturned
);
216 if (Status
!= ERROR_SUCCESS
)
218 /* failed to get data ranges */
219 DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status
);
221 HeapFree(GetProcessHeap(), 0, MultipleItem
);
226 *OutMultipleItem
= MultipleItem
;
232 GetFilterPinCommunication(
235 OUT PKSPIN_COMMUNICATION Communication
)
239 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
240 Property
.Property
.Set
= KSPROPSETID_Pin
;
241 Property
.Property
.Id
= KSPROPERTY_PIN_COMMUNICATION
;
242 Property
.PinId
= PinId
;
243 Property
.Reserved
= 0;
245 return SyncOverlappedDeviceIoControl(hFilter
, IOCTL_KS_PROPERTY
, (LPVOID
)&Property
, sizeof(KSP_PIN
), (LPVOID
)Communication
, sizeof(KSPIN_COMMUNICATION
), NULL
);
249 GetFilterPinDataFlow(
252 OUT PKSPIN_DATAFLOW DataFlow
)
256 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
257 Property
.Property
.Set
= KSPROPSETID_Pin
;
258 Property
.Property
.Id
= KSPROPERTY_PIN_DATAFLOW
;
259 Property
.PinId
= PinId
;
260 Property
.Reserved
= 0;
262 return SyncOverlappedDeviceIoControl(hFilter
, IOCTL_KS_PROPERTY
, (LPVOID
)&Property
, sizeof(KSP_PIN
), (LPVOID
)DataFlow
, sizeof(KSPIN_DATAFLOW
), NULL
);
266 GetFilterPinDataRanges(
269 IN OUT PKSMULTIPLE_ITEM
* OutMultipleItem
)
272 ULONG BytesReturned
= 0;
274 PKSMULTIPLE_ITEM MultipleItem
;
276 /* prepare request */
277 Property
.Reserved
= 0;
278 Property
.PinId
= PinId
;
279 Property
.Property
.Set
= KSPROPSETID_Pin
;
280 Property
.Property
.Id
= KSPROPERTY_PIN_DATARANGES
;
281 Property
.Property
.Flags
= KSPROPERTY_TYPE_GET
;
283 /* retrieve size of data ranges buffer */
284 Status
= SyncOverlappedDeviceIoControl(hFilter
, IOCTL_KS_PROPERTY
, (LPVOID
)&Property
, sizeof(KSP_PIN
), NULL
, 0, &BytesReturned
);
286 if (Status
!= ERROR_MORE_DATA
)
288 DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status
);
292 MultipleItem
= HeapAlloc(GetProcessHeap(), 0, BytesReturned
);
295 /* not enough memory */
296 DPRINT("Failed to allocate %u Bytes\n", BytesReturned
);
297 return ERROR_OUTOFMEMORY
;
300 /* retrieve data ranges */
301 Status
= SyncOverlappedDeviceIoControl(hFilter
, IOCTL_KS_PROPERTY
, (LPVOID
)&Property
, sizeof(KSP_PIN
), (LPVOID
)MultipleItem
, BytesReturned
, &BytesReturned
);
304 if (Status
!= ERROR_SUCCESS
)
306 /* failed to get data ranges */
307 DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status
);
309 HeapFree(GetProcessHeap(), 0, MultipleItem
);
314 *OutMultipleItem
= MultipleItem
;