ReactOS 0.4.15-dev-7918-g2a2556c
midi.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: lib/drivers/sound/mmixer/midi.c
5 * PURPOSE: Midi Support Functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9#include "precomp.h"
10
11// #define NDEBUG
12#include <debug.h>
13
17 IN HANDLE hDevice,
18 IN ULONG PinId,
20 OUT PKSPIN_COMMUNICATION Communication)
21{
25
26 /* setup request */
27 Pin.PinId = PinId;
28 Pin.Reserved = 0;
29 Pin.Property.Flags = KSPROPERTY_TYPE_GET;
30 Pin.Property.Id = KSPROPERTY_PIN_DATAFLOW;
31 Pin.Property.Set = KSPROPSETID_Pin;
32
33 /* get pin dataflow */
36 {
37 /* failed to retrieve dataflow */
38 return Status;
39 }
40
41 /* setup communication request */
43
44 /* get pin communication */
45 Status = MixerContext->Control(hDevice, IOCTL_KS_PROPERTY, (PVOID)&Pin, sizeof(KSP_PIN), (PVOID)Communication, sizeof(KSPIN_COMMUNICATION), &BytesReturned);
46
47 return Status;
48}
49
53 IN PMIXER_LIST MixerList,
54 IN ULONG DeviceId,
55 IN ULONG PinId,
56 IN ULONG bInput,
58{
59 LPMIDI_INFO MidiInfo;
60
61 /* allocate midi info */
62 MidiInfo = MixerContext->Alloc(sizeof(MIDI_INFO));
63
64 if (!MidiInfo)
65 {
66 /* no memory */
68 }
69
70 /* initialize midi info */
71 MidiInfo->DeviceId = DeviceId;
72 MidiInfo->PinId = PinId;
73
74 /* sanity check */
76
77 /* copy device name */
78 if (bInput && DeviceName)
79 {
80 wcscpy(MidiInfo->u.InCaps.szPname, DeviceName);
81 }
82 else if (!bInput && DeviceName)
83 {
84 wcscpy(MidiInfo->u.OutCaps.szPname, DeviceName);
85 }
86
87 /* FIXME determine manufacturer / product id */
88 if (bInput)
89 {
90 MidiInfo->u.InCaps.dwSupport = 0;
91 MidiInfo->u.InCaps.wMid = MM_MICROSOFT;
92 MidiInfo->u.InCaps.wPid = MM_PID_UNMAPPED;
93 MidiInfo->u.InCaps.vDriverVersion = 1;
94 }
95 else
96 {
97 MidiInfo->u.OutCaps.dwSupport = 0;
98 MidiInfo->u.OutCaps.wMid = MM_MICROSOFT;
99 MidiInfo->u.OutCaps.wPid = MM_PID_UNMAPPED;
100 MidiInfo->u.OutCaps.vDriverVersion = 1;
101 }
102
103 if (bInput)
104 {
105 /* insert into list */
106 InsertTailList(&MixerList->MidiInList, &MidiInfo->Entry);
107 MixerList->MidiInListCount++;
108 }
109 else
110 {
111 /* insert into list */
112 InsertTailList(&MixerList->MidiOutList, &MidiInfo->Entry);
113 MixerList->MidiOutListCount++;
114 }
115
116 return MM_STATUS_SUCCESS;
117}
118
119VOID
122 IN PMIXER_LIST MixerList,
123 IN LPMIXER_DATA MixerData,
124 IN ULONG PinId,
125 IN PKSMULTIPLE_ITEM MultipleItem,
126 IN LPWSTR szPname)
127{
128 ULONG Index;
129 PKSDATARANGE DataRange;
130 KSPIN_COMMUNICATION Communication;
132
133 /* get first datarange */
134 DataRange = (PKSDATARANGE)(MultipleItem + 1);
135
136 /* alignment assert */
137 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
138
139 /* iterate through all data ranges */
140 for(Index = 0; Index < MultipleItem->Count; Index++)
141 {
145 {
146 /* pin supports midi datarange */
147 if (MMixerGetPinDataFlowAndCommunication(MixerContext, MixerData->hDevice, PinId, &DataFlow, &Communication) == MM_STATUS_SUCCESS)
148 {
149 if (DataFlow == KSPIN_DATAFLOW_IN && Communication == KSPIN_COMMUNICATION_SINK)
150 {
151 MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, FALSE, szPname);
152 }
153 else if (DataFlow == KSPIN_DATAFLOW_OUT && Communication == KSPIN_COMMUNICATION_SOURCE)
154 {
155 MMixerAddMidiPin(MixerContext, MixerList, MixerData->DeviceId, PinId, TRUE, szPname);
156 }
157 }
158 }
159
160 /* move to next datarange */
161 DataRange = (PKSDATARANGE)((ULONG_PTR)DataRange + DataRange->FormatSize);
162
163 /* alignment assert */
164 ASSERT(((ULONG_PTR)DataRange & 0x7) == 0);
165
166 /* data ranges are 64-bit aligned */
167 DataRange = (PVOID)(((ULONG_PTR)DataRange + 0x7) & ~0x7);
168 }
169}
170
171VOID
174 IN PMIXER_LIST MixerList,
175 IN LPMIXER_DATA MixerData,
176 IN PTOPOLOGY Topology)
177{
180 PKSMULTIPLE_ITEM MultipleItem;
181 WCHAR szPname[MAXPNAMELEN];
182
183 /* get filter pin count */
185
186 /* get mixer name */
187 if (MMixerGetDeviceName(MixerContext, szPname, MixerData->hDeviceInterfaceKey) != MM_STATUS_SUCCESS)
188 {
189 /* clear name */
190 szPname[0] = 0;
191 }
192
193 /* iterate all pins and check for KSDATARANGE_MUSIC support */
194 for(Index = 0; Index < PinCount; Index++)
195 {
196 /* get audio pin data ranges */
197 Status = MMixerGetAudioPinDataRanges(MixerContext, MixerData->hDevice, Index, &MultipleItem);
198
199 /* check for success */
201 {
202 /* check if there is support KSDATARANGE_MUSIC */
203 MMixerCheckFilterPinMidiSupport(MixerContext, MixerList, MixerData, Index, MultipleItem, szPname);
204 }
205 }
206}
207
211 IN PMIXER_LIST MixerList,
212 IN ULONG DeviceId,
213 IN ULONG PinId,
215 IN PIN_CREATE_CALLBACK CreateCallback,
217 OUT PHANDLE PinHandle)
218{
219 PKSPIN_CONNECT PinConnect;
221 LPMIXER_DATA MixerData;
223 MIXER_STATUS MixerStatus;
224
225 MixerData = MMixerGetDataByDeviceId(MixerList, DeviceId);
226 if (!MixerData)
228
229 /* allocate pin connect */
231 if (!PinConnect)
232 {
233 /* no memory */
234 return MM_STATUS_NO_MEMORY;
235 }
236
237 /* initialize pin connect struct */
238 MMixerInitializePinConnect(PinConnect, PinId);
239
240 /* get offset to dataformat */
241 DataFormat = (PKSDATAFORMAT) (PinConnect + 1);
242
243 /* initialize data format */
244 RtlMoveMemory(&DataFormat->MajorFormat, &KSDATAFORMAT_TYPE_MUSIC, sizeof(GUID));
247
248 if (CreateCallback)
249 {
250 /* let the callback handle the creation */
251 MixerStatus = CreateCallback(Context, DeviceId, PinId, MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
252 }
253 else
254 {
255 /* now create the pin */
256 Status = KsCreatePin(MixerData->hDevice, PinConnect, DesiredAccess, PinHandle);
257
258 /* normalize status */
259 if (Status == STATUS_SUCCESS)
260 MixerStatus = MM_STATUS_SUCCESS;
261 else
262 MixerStatus = MM_STATUS_UNSUCCESSFUL;
263 }
264
265 /* free create info */
266 MixerContext->Free(PinConnect);
267
268 /* done */
269 return MixerStatus;
270}
271
274 IN PMIXER_LIST MixerList,
275 IN ULONG DeviceIndex,
276 IN ULONG bMidiInputType,
277 OUT LPMIDI_INFO *OutMidiInfo)
278{
279 ULONG Index = 0;
280 PLIST_ENTRY Entry, ListHead;
281 LPMIDI_INFO MidiInfo;
282
283 if (bMidiInputType)
284 ListHead = &MixerList->MidiInList;
285 else
286 ListHead = &MixerList->MidiOutList;
287
288 /* get first entry */
289 Entry = ListHead->Flink;
290
291 while(Entry != ListHead)
292 {
294
295 if (Index == DeviceIndex)
296 {
297 *OutMidiInfo = MidiInfo;
298 return MM_STATUS_SUCCESS;
299 }
300 Index++;
301 Entry = Entry->Flink;
302 }
303
305}
306
310 IN ULONG DeviceIndex,
311 OUT LPMIDIOUTCAPSW Caps)
312{
313 PMIXER_LIST MixerList;
315 LPMIDI_INFO MidiInfo;
316
317 /* verify mixer context */
319
321 {
322 /* invalid context passed */
323 return Status;
324 }
325
326 /* grab mixer list */
328
329 /* find destination midi */
330 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, FALSE, &MidiInfo);
332 {
333 /* failed to find midi info */
335 }
336
337 /* copy capabilities */
338 MixerContext->Copy(Caps, &MidiInfo->u.OutCaps, sizeof(MIDIOUTCAPSW));
339
340 return MM_STATUS_SUCCESS;
341}
342
346 IN ULONG DeviceIndex,
347 OUT LPMIDIINCAPSW Caps)
348{
349 PMIXER_LIST MixerList;
351 LPMIDI_INFO MidiInfo;
352
353 /* verify mixer context */
355
357 {
358 /* invalid context passed */
359 return Status;
360 }
361
362 /* grab mixer list */
364
365 /* find destination midi */
366 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, TRUE, &MidiInfo);
368 {
369 /* failed to find midi info */
371 }
372
373 /* copy capabilities */
374 MixerContext->Copy(Caps, &MidiInfo->u.InCaps, sizeof(MIDIINCAPSW));
375
376 return MM_STATUS_SUCCESS;
377}
378
382 IN ULONG bMidiIn,
383 IN ULONG DeviceId,
384 OUT LPWSTR * DevicePath)
385{
386 PMIXER_LIST MixerList;
387 LPMIXER_DATA MixerData;
388 LPMIDI_INFO MidiInfo;
391
392 /* verify mixer context */
394
396 {
397 /* invalid context passed */
398 return Status;
399 }
400
401 /* grab mixer list */
403
404 /* find destination midi */
405 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceId, bMidiIn, &MidiInfo);
407 {
408 /* failed to find midi info */
410 }
411
412 /* get associated device id */
413 MixerData = MMixerGetDataByDeviceId(MixerList, MidiInfo->DeviceId);
414 if (!MixerData)
416
417 /* calculate length */
418 Length = wcslen(MixerData->DeviceName)+1;
419
420 /* allocate destination buffer */
421 *DevicePath = MixerContext->Alloc(Length * sizeof(WCHAR));
422
423 if (!*DevicePath)
424 {
425 /* no memory */
426 return MM_STATUS_NO_MEMORY;
427 }
428
429 /* copy device path */
430 MixerContext->Copy(*DevicePath, MixerData->DeviceName, Length * sizeof(WCHAR));
431
432 /* done */
433 return MM_STATUS_SUCCESS;
434}
435
439 IN HANDLE PinHandle,
441{
444
445 /* setup property request */
449
450 return MixerContext->Control(PinHandle, IOCTL_KS_PROPERTY, &Property, sizeof(KSPROPERTY), &State, sizeof(KSSTATE), &Length);
451}
452
456 IN ULONG DeviceIndex,
457 IN ULONG bMidiIn,
458 IN PIN_CREATE_CALLBACK CreateCallback,
460 OUT PHANDLE PinHandle)
461{
462 PMIXER_LIST MixerList;
464 LPMIDI_INFO MidiInfo;
466
467 /* verify mixer context */
469
471 {
472 /* invalid context passed */
473 return Status;
474 }
475
476 /* grab mixer list */
478
479 /* find destination midi */
480 Status = MMixerGetMidiInfoByIndexAndType(MixerList, DeviceIndex, bMidiIn, &MidiInfo);
482 {
483 /* failed to find midi info */
485 }
486
487 /* get desired access */
488 if (bMidiIn)
489 {
491 }
492 else
493 {
495 }
496
497 /* now try open the pin */
498 return MMixerOpenMidiPin(MixerContext, MixerList, MidiInfo->DeviceId, MidiInfo->PinId, DesiredAccess, CreateCallback, Context, PinHandle);
499}
500
501ULONG
504{
505 PMIXER_LIST MixerList;
507
508 /* verify mixer context */
510
512 {
513 /* invalid context passed */
514 return Status;
515 }
516
517 /* grab mixer list */
519
520 return MixerList->MidiInListCount;
521}
522
523ULONG
526{
527 PMIXER_LIST MixerList;
529
530 /* verify mixer context */
532
534 {
535 /* invalid context passed */
536 return Status;
537 }
538
539 /* grab mixer list */
541
542 return MixerList->MidiOutListCount;
543}
LONG NTSTATUS
Definition: precomp.h:26
KSDATAFORMAT * PKSDATAFORMAT
DataFlow
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define GENERIC_READ
Definition: compat.h:135
MIXER_CONTEXT MixerContext
Definition: mmixer.c:41
#define KSPROPERTY_TYPE_SET
Definition: dmksctrl.h:43
#define KSPROPERTY_TYPE_GET
Definition: dmksctrl.h:42
#define InsertTailList(ListHead, Entry)
IN PDCB IN VBO IN ULONG IN BOOLEAN Pin
Definition: fatprocs.h:427
Status
Definition: gdiplustypes.h:25
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define KSDATAFORMAT_SPECIFIER_NONE
Definition: ks.h:1157
@ KSPROPERTY_CONNECTION_STATE
Definition: ks.h:349
#define IOCTL_KS_PROPERTY
Definition: ks.h:127
#define KSPROPSETID_Pin
Definition: ks.h:617
@ KSPROPERTY_PIN_COMMUNICATION
Definition: ks.h:632
@ KSPROPERTY_PIN_DATAFLOW
Definition: ks.h:627
KSSTATE
Definition: ks.h:1214
KSPIN_DATAFLOW
Definition: ks.h:1248
@ KSPIN_DATAFLOW_IN
Definition: ks.h:1249
@ KSPIN_DATAFLOW_OUT
Definition: ks.h:1250
enum KSPIN_DATAFLOW * PKSPIN_DATAFLOW
#define KSPROPSETID_Connection
Definition: ks.h:346
KSPIN_COMMUNICATION
Definition: ks.h:1253
@ KSPIN_COMMUNICATION_SOURCE
Definition: ks.h:1256
@ KSPIN_COMMUNICATION_SINK
Definition: ks.h:1255
union KSDATAFORMAT * PKSDATARANGE
enum KSPIN_COMMUNICATION * PKSPIN_COMMUNICATION
#define KSDATAFORMAT_TYPE_MUSIC
Definition: ksmedia.h:1005
#define KSDATAFORMAT_SUBTYPE_MIDI
Definition: ksmedia.h:1016
KSDDKAPI DWORD NTAPI KsCreatePin(HANDLE FilterHandle, PKSPIN_CONNECT Connect, ACCESS_MASK DesiredAccess, PHANDLE ConnectionHandle)
Definition: ksuser.c:192
MIXER_STATUS(* PIN_CREATE_CALLBACK)(IN PVOID Context, IN ULONG DeviceId, IN ULONG PinId, IN HANDLE hFilter, IN PKSPIN_CONNECT PinConnect, IN ACCESS_MASK DesiredAccess, OUT PHANDLE PinHandle)
Definition: mmixer.h:80
MIXER_STATUS
Definition: mmixer.h:4
@ MM_STATUS_UNSUCCESSFUL
Definition: mmixer.h:11
@ MM_STATUS_INVALID_PARAMETER
Definition: mmixer.h:10
@ MM_STATUS_NO_MEMORY
Definition: mmixer.h:12
@ MM_STATUS_SUCCESS
Definition: mmixer.h:5
#define MM_PID_UNMAPPED
Definition: mmreg.h:141
#define MM_MICROSOFT
Definition: mmreg.h:144
#define MAXPNAMELEN
Definition: mmsystem.h:24
#define ASSERT(a)
Definition: mode.c:44
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define GENERIC_WRITE
Definition: nt_native.h:90
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
MIXER_STATUS MMixerMidiInCapabilities(IN PMIXER_CONTEXT MixerContext, IN ULONG DeviceIndex, OUT LPMIDIINCAPSW Caps)
Definition: midi.c:344
MIXER_STATUS MMixerAddMidiPin(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN ULONG DeviceId, IN ULONG PinId, IN ULONG bInput, IN LPWSTR DeviceName)
Definition: midi.c:51
MIXER_STATUS MMixerGetMidiInfoByIndexAndType(IN PMIXER_LIST MixerList, IN ULONG DeviceIndex, IN ULONG bMidiInputType, OUT LPMIDI_INFO *OutMidiInfo)
Definition: midi.c:273
MIXER_STATUS MMixerOpenMidi(IN PMIXER_CONTEXT MixerContext, IN ULONG DeviceIndex, IN ULONG bMidiIn, IN PIN_CREATE_CALLBACK CreateCallback, IN PVOID Context, OUT PHANDLE PinHandle)
Definition: midi.c:454
MIXER_STATUS MMixerGetPinDataFlowAndCommunication(IN PMIXER_CONTEXT MixerContext, IN HANDLE hDevice, IN ULONG PinId, OUT PKSPIN_DATAFLOW DataFlow, OUT PKSPIN_COMMUNICATION Communication)
Definition: midi.c:15
VOID MMixerCheckFilterPinMidiSupport(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN ULONG PinId, IN PKSMULTIPLE_ITEM MultipleItem, IN LPWSTR szPname)
Definition: midi.c:120
ULONG MMixerGetMidiInCount(IN PMIXER_CONTEXT MixerContext)
Definition: midi.c:502
MIXER_STATUS MMixerSetMidiStatus(IN PMIXER_CONTEXT MixerContext, IN HANDLE PinHandle, IN KSSTATE State)
Definition: midi.c:437
MIXER_STATUS MMixerMidiOutCapabilities(IN PMIXER_CONTEXT MixerContext, IN ULONG DeviceIndex, OUT LPMIDIOUTCAPSW Caps)
Definition: midi.c:308
MIXER_STATUS MMixerOpenMidiPin(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN ULONG DeviceId, IN ULONG PinId, IN ACCESS_MASK DesiredAccess, IN PIN_CREATE_CALLBACK CreateCallback, IN PVOID Context, OUT PHANDLE PinHandle)
Definition: midi.c:209
MIXER_STATUS MMixerGetMidiDevicePath(IN PMIXER_CONTEXT MixerContext, IN ULONG bMidiIn, IN ULONG DeviceId, OUT LPWSTR *DevicePath)
Definition: midi.c:380
VOID MMixerInitializeMidiForFilter(IN PMIXER_CONTEXT MixerContext, IN PMIXER_LIST MixerList, IN LPMIXER_DATA MixerData, IN PTOPOLOGY Topology)
Definition: midi.c:172
ULONG MMixerGetMidiOutCount(IN PMIXER_CONTEXT MixerContext)
Definition: midi.c:524
VOID MMixerGetTopologyPinCount(IN PTOPOLOGY Topology, OUT PULONG PinCount)
Definition: topology.c:1004
PKSPIN_CONNECT MMixerAllocatePinConnect(IN PMIXER_CONTEXT MixerContext, ULONG DataFormatSize)
Definition: wave.c:72
VOID MMixerInitializePinConnect(IN OUT PKSPIN_CONNECT PinConnect, IN ULONG PinId)
Definition: sup.c:901
MIXER_STATUS MMixerGetDeviceName(IN PMIXER_CONTEXT MixerContext, OUT LPWSTR DeviceName, IN HANDLE hKey)
Definition: sup.c:852
struct MIXER_LIST * PMIXER_LIST
MIXER_STATUS MMixerVerifyContext(IN PMIXER_CONTEXT MixerContext)
Definition: sup.c:40
struct MIDI_INFO * LPMIDI_INFO
MIXER_STATUS MMixerGetAudioPinDataRanges(IN PMIXER_CONTEXT MixerContext, IN HANDLE hDevice, IN ULONG PinId, IN OUT PKSMULTIPLE_ITEM *OutMultipleItem)
Definition: wave.c:156
LPMIXER_DATA MMixerGetDataByDeviceId(IN PMIXER_LIST MixerList, IN ULONG DeviceId)
Definition: sup.c:735
#define STATUS_SUCCESS
Definition: shellext.h:65
_In_ const GUID _In_ ULONG PinCount
Definition: strmini.h:505
base of all file and directory entries
Definition: entries.h:83
Definition: ks.h:642
union MIDI_INFO::@4336 u
ULONG PinId
Definition: precomp.h:138
MIDIOUTCAPSW OutCaps
Definition: precomp.h:141
MIDIINCAPSW InCaps
Definition: precomp.h:142
LIST_ENTRY Entry
Definition: precomp.h:136
ULONG DeviceId
Definition: precomp.h:137
PMIXER_DEVICE_CONTROL Control
Definition: mmixer.h:95
PMIXER_COPY Copy
Definition: mmixer.h:99
PVOID MixerContext
Definition: mmixer.h:92
PMIXER_FREE Free
Definition: mmixer.h:96
PMIXER_ALLOC Alloc
Definition: mmixer.h:94
HANDLE hDevice
Definition: precomp.h:115
LPWSTR DeviceName
Definition: precomp.h:117
ULONG MidiInListCount
Definition: precomp.h:161
ULONG MidiOutListCount
Definition: precomp.h:164
ULONG Flags
Definition: ntfs.h:536
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
MMVERSION vDriverVersion
Definition: mmsystem.h:1145
DWORD dwSupport
Definition: mmsystem.h:1147
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1146
MMVERSION vDriverVersion
Definition: mmsystem.h:1125
WCHAR szPname[MAXPNAMELEN]
Definition: mmsystem.h:1126
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_opt_ PCUNICODE_STRING DeviceName
Definition: wdfdevice.h:3275
_Must_inspect_result_ _In_ WDFIOTARGET _In_opt_ WDFREQUEST _In_ ULONG _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_MEMORY_DESCRIPTOR _In_opt_ PWDF_REQUEST_SEND_OPTIONS _Out_opt_ PULONG_PTR BytesReturned
Definition: wdfiotarget.h:1052
#define IsEqualGUIDAligned(guid1, guid2)
Definition: wdm.template.h:235
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184