|
|
1.1 root 1: /*++
2:
3: Copyright (c) 1991 Microsoft Corporation
4:
5: Module Name:
6:
7: devcaps.c
8:
9: Abstract:
10:
11: This module contains code for the device capabilities functions.
12:
13: Author:
14:
15: Nigel Thompson (nigelt) 7-Apr-1991
16:
17: Environment:
18:
19: Kernel mode
20:
21: Revision History:
22:
23: Robin Speed (RobinSp) 29-Jan-1992 - Add other devices and rewrite
24: Stephen Estrop (StephenE) 16-Apr-1992 - Converted to Unicode
25:
26: --*/
27:
28: #include <sound.h>
29:
30: // non-localized strings BUGBUG - version is wrong !!!
31: WCHAR STR_SNDBLST10[] = L"Creative Labs Sound Blaster 1.0";
32: WCHAR STR_SNDBLST15[] = L"Creative Labs Sound Blaster 1.5";
33:
34:
35: //
36: // local functions
37: //
38:
39: VOID sndSetUnicodeName(
40: OUT PWSTR pUnicodeString,
41: IN USHORT Size,
42: OUT PUSHORT pUnicodeLength,
43: IN PSZ pAnsiString
44: );
45:
46:
47: NTSTATUS
48: SoundWaveOutGetCaps(
49: IN PLOCAL_DEVICE_INFO pLDI,
50: IN OUT PIRP pIrp,
51: IN PIO_STACK_LOCATION IrpStack
52: )
53:
54: /*++
55:
56: Routine Description:
57:
58: Return device capabilities for wave output device.
59: Data is truncated if not enough space is provided.
60: Irp is always completed.
61:
62:
63: Arguments:
64:
65: pLDI - pointer to local device info
66: pIrp - the Irp
67: IrpStack - the current stack location
68:
69: Return Value:
70:
71: STATUS_SUCCESS - always succeeds
72:
73: --*/
74:
75: {
76: WAVEOUTCAPSW wc;
77: PGLOBAL_DEVICE_INFO pGDI;
78: NTSTATUS status = STATUS_SUCCESS;
79:
80: pGDI = pLDI->pGlobalInfo;
81:
82:
83: //
84: // say how much we're sending back
85: //
86:
87: pIrp->IoStatus.Information =
88: min(sizeof(wc),
89: IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
90:
91: //
92: // fill in the info
93: //
94:
95: wc.wMid = MM_MICROSOFT;
96: wc.wPid = MM_SNDBLST_WAVEOUT;
97: wc.vDriverVersion = DRIVER_VERSION;
98:
99: if (SBPRO(&pGDI->Hw) || pGDI->ProAudioSpectrum) {
100: wc.dwSupport = WAVECAPS_VOLUME |
101: WAVECAPS_LRVOLUME;
102: wc.dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08;
103: } else {
104: wc.dwSupport = 0;
105: wc.dwFormats = WAVE_FORMAT_1M08 | WAVE_FORMAT_2M08;
106: }
107:
108: wc.wChannels = 1;
109:
110: //
111: // Copy across the product name
112: //
113:
114: if (SB1(&pGDI->Hw)) {
115: RtlMoveMemory(wc.szPname, STR_SNDBLST10, sizeof(STR_SNDBLST10));
116: } else {
117: RtlMoveMemory(wc.szPname, STR_SNDBLST15, sizeof(STR_SNDBLST15));
118: }
119:
120: RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer,
121: &wc,
122: pIrp->IoStatus.Information);
123:
124: return status;
125: }
126:
127:
128: NTSTATUS
129: SoundWaveInGetCaps(
130: IN PLOCAL_DEVICE_INFO pLDI,
131: IN OUT PIRP pIrp,
132: IN PIO_STACK_LOCATION IrpStack
133: )
134:
135: /*++
136:
137: Routine Description:
138:
139: Return device capabilities for wave input device.
140: Data is truncated if not enough space is provided.
141: Irp is always completed.
142:
143:
144: Arguments:
145:
146: pLDI - pointer to local device info
147: pIrp - the Irp
148: IrpStack - the current stack location
149:
150: Return Value:
151:
152: STATUS_SUCCESS - always succeeds
153:
154: --*/
155:
156: {
157: WAVEINCAPSW wc;
158: NTSTATUS status = STATUS_SUCCESS;
159: PGLOBAL_DEVICE_INFO pGDI;
160:
161: pGDI = pLDI->pGlobalInfo;
162:
163: //
164: // say how much we're sending back
165: //
166:
167: pIrp->IoStatus.Information =
168: min(sizeof(wc),
169: IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
170:
171: //
172: // fill in the info
173: //
174:
175: wc.wMid = MM_MICROSOFT;
176: wc.wPid = MM_SNDBLST_WAVEIN;
177: wc.vDriverVersion = DRIVER_VERSION;
178: wc.dwFormats = WAVE_FORMAT_1M08;
179: wc.wChannels = 1;
180:
181: //
182: // Copy across unicode name
183: //
184:
185: if (SB1(&pGDI->Hw)) {
186: RtlMoveMemory(wc.szPname, STR_SNDBLST10, sizeof(STR_SNDBLST10));
187: } else {
188: RtlMoveMemory(wc.szPname, STR_SNDBLST15, sizeof(STR_SNDBLST15));
189: }
190:
191:
192: RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer,
193: &wc,
194: pIrp->IoStatus.Information);
195:
196: return status;
197: }
198:
199:
200: NTSTATUS
201: SoundMidiOutGetCaps(
202: IN PLOCAL_DEVICE_INFO pLDI,
203: IN OUT PIRP pIrp,
204: IN PIO_STACK_LOCATION IrpStack
205: )
206:
207: /*++
208:
209: Routine Description:
210:
211: Return device capabilities for midi output device.
212: Data is truncated if not enough space is provided.
213: Irp is always completed.
214:
215:
216: Arguments:
217:
218: pLDI - pointer to local device info
219: pIrp - the Irp
220: IrpStack - the current stack location
221:
222: Return Value:
223:
224: STATUS_SUCCESS - always succeeds
225:
226: --*/
227:
228: {
229: MIDIOUTCAPSW mc;
230: NTSTATUS status = STATUS_SUCCESS;
231: PGLOBAL_DEVICE_INFO pGDI;
232:
233: pGDI = pLDI->pGlobalInfo;
234:
235:
236:
237: //
238: // say how much we're sending back
239: //
240:
241: pIrp->IoStatus.Information =
242: min(sizeof(mc),
243: IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
244:
245: //
246: // fill in the info
247: //
248:
249: mc.wMid = MM_MICROSOFT;
250: mc.wPid = MM_SNDBLST_MIDIOUT;
251: mc.vDriverVersion = DRIVER_VERSION;
252: mc.wTechnology = MOD_MIDIPORT;
253: mc.wVoices = 0; // not used for ports
254: mc.wNotes = 0; // not used for ports
255: mc.wChannelMask = 0xFFFF; // all channels
256: mc.dwSupport = 0L;
257:
258: if (SB1(&pGDI->Hw)) {
259: RtlMoveMemory(mc.szPname, STR_SNDBLST10, sizeof(STR_SNDBLST10));
260: } else {
261: RtlMoveMemory(mc.szPname, STR_SNDBLST15, sizeof(STR_SNDBLST15));
262: }
263:
264:
265: RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer,
266: &mc,
267: pIrp->IoStatus.Information);
268:
269: return status;
270: }
271:
272:
273:
274: NTSTATUS
275: SoundMidiInGetCaps(
276: IN PLOCAL_DEVICE_INFO pLDI,
277: IN OUT PIRP pIrp,
278: IN PIO_STACK_LOCATION IrpStack
279: )
280:
281: /*++
282:
283: Routine Description:
284:
285: Return device capabilities for midi input device.
286: Data is truncated if not enough space is provided.
287: Irp is always completed.
288:
289:
290: Arguments:
291:
292: pLDI - pointer to local device info
293: pIrp - the Irp
294: IrpStack - the current stack location
295:
296: Return Value:
297:
298: STATUS_SUCCESS - always succeeds
299:
300: --*/
301:
302: {
303: MIDIINCAPSW mc;
304: NTSTATUS status = STATUS_SUCCESS;
305: PGLOBAL_DEVICE_INFO pGDI;
306:
307: pGDI = pLDI->pGlobalInfo;
308:
309:
310: //
311: // say how much we're sending back
312: //
313:
314: pIrp->IoStatus.Information =
315: min(sizeof(mc),
316: IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
317:
318: //
319: // fill in the info
320: // BUGBUG - do UNICODE
321:
322: mc.wMid = MM_MICROSOFT;
323: mc.wPid = MM_SNDBLST_MIDIIN;
324: mc.vDriverVersion = DRIVER_VERSION;
325:
326: if (SB1(&pGDI->Hw)) {
327: RtlMoveMemory(mc.szPname, STR_SNDBLST10, sizeof(STR_SNDBLST10));
328: } else {
329: RtlMoveMemory(mc.szPname, STR_SNDBLST15, sizeof(STR_SNDBLST15));
330: }
331:
332:
333: RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer,
334: &mc,
335: pIrp->IoStatus.Information);
336:
337: return status;
338: }
339:
340:
341: NTSTATUS
342: SoundAuxGetCaps(
343: IN PLOCAL_DEVICE_INFO pLDI,
344: IN OUT PIRP pIrp,
345: IN PIO_STACK_LOCATION IrpStack
346: )
347:
348: /*++
349:
350: Routine Description:
351:
352: Return device capabilities for axu devices
353: Data is truncated if not enough space is provided.
354: Irp is always completed.
355:
356:
357: Arguments:
358:
359: pLDI - pointer to local device info
360: pIrp - the Irp
361: IrpStack - the current stack location
362:
363: Return Value:
364:
365: STATUS_SUCCESS - always succeeds
366:
367: --*/
368:
369: {
370: AUXCAPSW auxCaps;
371: NTSTATUS status = STATUS_SUCCESS;
372: PWSTR DeviceName;
373: PGLOBAL_DEVICE_INFO pGDI;
374:
375: pGDI = pLDI->pGlobalInfo;
376:
377:
378: //
379: // Find the device name
380: //
381:
382: switch (pLDI->DeviceIndex) {
383: #ifdef MICMIX
384: case MicDevice:
385: auxCaps.wPid = MM_MSFT_GENERIC_AUX_MIC;
386: break;
387: #endif // MICMIX
388:
389: case LineInDevice:
390: auxCaps.wPid = MM_MSFT_GENERIC_AUX_LINE;
391: break;
392:
393: #ifdef MASTERVOLUME
394: case MasterVolumeDevice:
395: auxCaps.wPid = ????;
396: break;
397: #endif // MASTERVOLUME
398:
399: default:
400: dprintf1(("Getting aux caps for non-aux device!"));
401: return STATUS_INTERNAL_ERROR;
402: }
403: //
404: // say how much we're sending back
405: //
406:
407: pIrp->IoStatus.Information =
408: min(sizeof(auxCaps),
409: IrpStack->Parameters.DeviceIoControl.OutputBufferLength);
410:
411: //
412: // fill in the info
413: //
414:
415: auxCaps.wMid = MM_MICROSOFT;
416: auxCaps.vDriverVersion = DRIVER_VERSION;
417: auxCaps.wTechnology = AUXCAPS_AUXIN;
418: auxCaps.dwSupport = AUXCAPS_LRVOLUME | AUXCAPS_VOLUME;
419: RtlZeroMemory(auxCaps.szPname, sizeof(auxCaps.szPname));
420:
421: if (SB1(&pGDI->Hw)) {
422: RtlMoveMemory(auxCaps.szPname, STR_SNDBLST10, sizeof(STR_SNDBLST10));
423: } else {
424: RtlMoveMemory(auxCaps.szPname, STR_SNDBLST15, sizeof(STR_SNDBLST15));
425: }
426:
427: RtlMoveMemory(pIrp->AssociatedIrp.SystemBuffer,
428: &auxCaps,
429: pIrp->IoStatus.Information);
430:
431: return status;
432: }
433:
434:
435: NTSTATUS SoundQueryFormat(
436: IN PLOCAL_DEVICE_INFO pLDI,
437: IN PPCMWAVEFORMAT pFormat
438: )
439:
440: /*++
441:
442: Routine Description:
443:
444: Tell the caller whether the wave format specified (input or
445: output) is supported
446:
447: Arguments:
448:
449: pLDI - pointer to local device info
450: pFormat - format being queried
451:
452: Return Value:
453:
454: STATUS_SUCCESS - format is supported
455: STATUS_NOT_SUPPORTED - format not supported
456:
457: --*/
458: {
459: PGLOBAL_DEVICE_INFO pGDI;
460:
461: pGDI = pLDI->pGlobalInfo;
462:
463: if (pFormat->wf.wFormatTag != WAVE_FORMAT_PCM ||
464:
465: pFormat->wf.nChannels != 1 ||
466:
467: pFormat->wf.nSamplesPerSec < pGDI->MinHz ||
468:
469: pLDI->DeviceType == WAVE_OUT &&
470: (pFormat->wf.nSamplesPerSec > pGDI->MaxOutHz ||
471: pFormat->wf.nBlockAlign != 1
472: ) ||
473:
474: pLDI->DeviceType == WAVE_IN &&
475: (pFormat->wf.nSamplesPerSec > pGDI->MaxInHz ||
476: pFormat->wf.nBlockAlign < 1
477: ) ||
478:
479: pFormat->wBitsPerSample != 8
480: ) {
481: return STATUS_NOT_SUPPORTED;
482: } else {
483: return STATUS_SUCCESS;
484: }
485: }
486:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.