Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

368 lines
11 KiB

  1. /************************************************************************/
  2. /*
  3. ** Copyright (c) 1985-1994 Microsoft Corporation
  4. **
  5. ** Title: mwinfo.c - Multimedia Systems Media Control Interface
  6. ** waveform digital audio driver for RIFF wave files.
  7. **
  8. ** Version: 1.00
  9. **
  10. ** Date: 18-Apr-1990
  11. **
  12. ** Author: ROBWI
  13. */
  14. /************************************************************************/
  15. /*
  16. ** Change log:
  17. **
  18. ** DATE REV DESCRIPTION
  19. ** ----------- ----- ------------------------------------------
  20. ** 18-APR-1990 ROBWI Original
  21. ** 19-JUN-1990 ROBWI Added wave in
  22. ** 10-Jan-1992 MikeTri Ported to NT
  23. ** @@@ Change slash slash comments to slash star
  24. */
  25. /************************************************************************/
  26. #define UNICODE
  27. #define NOGDICAPMASKS
  28. #define NOVIRTUALKEYCODES
  29. #define NOWINSTYLES
  30. #define NOSYSMETRICS
  31. #define NOMENUS
  32. #define NOICONS
  33. #define NOKEYSTATES
  34. #define NOSYSCOMMANDS
  35. #define NORASTEROPS
  36. #define NOSHOWWINDOW
  37. #define OEMRESOURCE
  38. #define NOATOM
  39. #define NOCLIPBOARD
  40. #define NOCOLOR
  41. #define NOCTLMGR
  42. #define NODRAWTEXT
  43. #define NOGDI
  44. #define NOKERNEL
  45. #define NONLS
  46. #define NOMB
  47. #define NOMEMMGR
  48. #define NOMETAFILE
  49. #define NOOPENFILE
  50. #define NOSCROLL
  51. #define NOTEXTMETRIC
  52. #define NOWH
  53. #define NOWINOFFSETS
  54. #define NOCOMM
  55. #define NOKANJI
  56. #define NOHELP
  57. #define NOPROFILER
  58. #define NODEFERWINDOWPOS
  59. #include <windows.h>
  60. #include "mciwave.h"
  61. #include <mmddk.h>
  62. #include <wchar.h>
  63. /************************************************************************/
  64. /*
  65. ** The following two constants are used to describe the mask of flags
  66. ** that are dealt with in the Info and Capability commands.
  67. */
  68. #define MCI_WAVE_INFO_MASK (MCI_INFO_FILE | MCI_INFO_PRODUCT | \
  69. MCI_WAVE_INPUT | MCI_WAVE_OUTPUT)
  70. #define MCI_WAVE_CAPS_MASK (MCI_WAVE_GETDEVCAPS_INPUTS | \
  71. MCI_WAVE_GETDEVCAPS_OUTPUTS | MCI_GETDEVCAPS_CAN_RECORD | \
  72. MCI_GETDEVCAPS_CAN_PLAY | MCI_GETDEVCAPS_CAN_SAVE | \
  73. MCI_GETDEVCAPS_HAS_AUDIO | MCI_GETDEVCAPS_USES_FILES | \
  74. MCI_GETDEVCAPS_COMPOUND_DEVICE | MCI_GETDEVCAPS_HAS_VIDEO | \
  75. MCI_GETDEVCAPS_CAN_EJECT | MCI_GETDEVCAPS_DEVICE_TYPE)
  76. /************************************************************************/
  77. /*
  78. @doc INTERNAL MCIWAVE
  79. @api DWORD | mwInfo |
  80. Respond to info command. The function tries to thoroughly check
  81. the <p>dFlags<d> parameter by masking out unrecognized commands
  82. and comparing against the original. It then makes sure that only
  83. one command is present by doing a switch() on the flags, and returning
  84. an error condition if some combination of flags is present.
  85. @parm <t>PWAVEDESC<d> | pwd |
  86. Pointer to the wave device descriptor.
  87. @parm DWORD | dFlags |
  88. Command flags.
  89. @flag MCI_INFO_FILE |
  90. Return the file name associated with the MCI wave device instance.
  91. The instance must have file information attached, that is, not just
  92. opened for configuration or capabilities checking. The file name
  93. returned might be zero length if a name has not been associated with
  94. a new file.
  95. @flag MCI_INFO_PRODUCT |
  96. Return the product name of the driver.
  97. @flag MCI_WAVE_OUTPUT |
  98. Return the product name of the current wave output device. This
  99. function also requires file information to be attached. If any
  100. output can be used and playback is not currently in progress, then
  101. no device is currently selected. Else the specific device in use
  102. is returned.
  103. @flag MCI_WAVE_INPUT |
  104. Return the product name of the current wave input device. This
  105. function also requires file information to be attached. If any
  106. input can be used and recording is not currently in progress, then
  107. no device is currently selected. Else the specific device in use
  108. is returned.
  109. @parm <t>LPMCI_INFO_PARMS<d> | lpInfo |
  110. Info parameters.
  111. @rdesc Returns zero on success, or an MCI error code.
  112. */
  113. PUBLIC DWORD PASCAL FAR mwInfo(
  114. PWAVEDESC pwd,
  115. DWORD dFlags,
  116. LPMCI_INFO_PARMS lpInfo)
  117. {
  118. UINT wReturnLength;
  119. UINT wReturnBufferLength;
  120. UINT wErrorRet;
  121. wReturnBufferLength = lpInfo->dwRetSize; // Win 16 only uses the loword
  122. if (!lpInfo->lpstrReturn || !wReturnBufferLength)
  123. return MCIERR_PARAM_OVERFLOW;
  124. // Turn off the uninteresting flags
  125. dFlags &= ~(MCI_NOTIFY | MCI_WAIT);
  126. // See if the user wants anything
  127. if (!dFlags)
  128. return MCIERR_MISSING_PARAMETER;
  129. if (dFlags != (dFlags & MCI_WAVE_INFO_MASK))
  130. return MCIERR_UNRECOGNIZED_KEYWORD;
  131. *(lpInfo->lpstrReturn + wReturnBufferLength - 1) = '\0';
  132. switch (dFlags) {
  133. case MCI_INFO_FILE:
  134. if (!pwd)
  135. return MCIERR_UNSUPPORTED_FUNCTION;
  136. if (!*pwd->aszFile)
  137. return MCIERR_NONAPPLICABLE_FUNCTION;
  138. // BYTE!!CHARACTER count ??
  139. wcsncpy(lpInfo->lpstrReturn, pwd->aszFile, wReturnBufferLength);
  140. // Note: the return length may be BIGGER than the buffer provided
  141. wReturnLength = lstrlen(pwd->aszFile);
  142. break;
  143. case MCI_INFO_PRODUCT:
  144. wReturnLength = LoadString(hModuleInstance, IDS_PRODUCTNAME, lpInfo->lpstrReturn, wReturnBufferLength);
  145. break;
  146. case MCI_WAVE_OUTPUT:
  147. if (pwd) {
  148. WAVEOUTCAPS waveOutCaps;
  149. UINT idOut;
  150. if ((pwd->idOut == WAVE_MAPPER) && ISMODE(pwd, MODE_PLAYING))
  151. waveOutGetID(pwd->hWaveOut, &idOut);
  152. else
  153. idOut = pwd->idOut;
  154. if (0 != (wErrorRet = waveOutGetDevCaps(idOut, &waveOutCaps, sizeof(WAVEOUTCAPS)))) {
  155. if (idOut == WAVE_MAPPER)
  156. wReturnLength = LoadString(hModuleInstance, IDS_MAPPER, lpInfo->lpstrReturn, wReturnBufferLength);
  157. else
  158. return wErrorRet;
  159. } else {
  160. wcsncpy(lpInfo->lpstrReturn, waveOutCaps.szPname, wReturnBufferLength);
  161. wReturnLength = lstrlen(waveOutCaps.szPname);
  162. wReturnLength = min(wReturnLength, wReturnBufferLength);
  163. }
  164. } else
  165. return MCIERR_UNSUPPORTED_FUNCTION;
  166. break;
  167. case MCI_WAVE_INPUT:
  168. if (pwd) {
  169. WAVEINCAPS waveInCaps;
  170. UINT idIn;
  171. if ((pwd->idIn == WAVE_MAPPER) && ISMODE(pwd, MODE_INSERT | MODE_OVERWRITE))
  172. waveInGetID(pwd->hWaveIn, &idIn);
  173. else
  174. idIn = pwd->idIn;
  175. if (0 != (wErrorRet = waveInGetDevCaps(idIn, &waveInCaps, sizeof(WAVEINCAPS)))) {
  176. if (idIn == WAVE_MAPPER)
  177. wReturnLength = LoadString(hModuleInstance, (UINT)IDS_MAPPER, lpInfo->lpstrReturn, wReturnBufferLength);
  178. else
  179. return wErrorRet;
  180. } else {
  181. wcsncpy(lpInfo->lpstrReturn, waveInCaps.szPname, wReturnBufferLength);
  182. wReturnLength = lstrlen(waveInCaps.szPname);
  183. wReturnLength = min(wReturnLength, wReturnBufferLength);
  184. }
  185. } else
  186. return MCIERR_UNSUPPORTED_FUNCTION;
  187. break;
  188. default:
  189. return MCIERR_FLAGS_NOT_COMPATIBLE;
  190. }
  191. lpInfo->dwRetSize = (DWORD)wReturnLength;
  192. if (*(lpInfo->lpstrReturn + wReturnBufferLength - 1) != '\0')
  193. return MCIERR_PARAM_OVERFLOW;
  194. return 0;
  195. }
  196. /************************************************************************/
  197. /*
  198. @doc INTERNAL MCIWAVE
  199. @api DWORD | mwGetDevCaps |
  200. Respond to device capabilities command. The function tries to
  201. thoroughly check the <p>dFlags<d> parameter by masking out
  202. unrecognized commands and comparing against the original. It then
  203. makes sure that only one command is present by doing a switch() on the
  204. flags, and returning an error condition if some combination of flags
  205. is present.
  206. @parm <t>PWAVEDESC<d> | pwd |
  207. Pointer to the wave device descriptor.
  208. @parm UINT | dFlags |
  209. Command flags.
  210. @flag MCI_WAVE_GETDEVCAPS_INPUTS |
  211. Queries the number of wave audio input devices.
  212. @flag MCI_WAVE_GETDEVCAPS_OUTPUTS |
  213. Queries the number of wave audio output devices.
  214. @flag MCI_GETDEVCAPS_CAN_RECORD |
  215. Queries whether or not recording can be done. This depends upon if
  216. there are any wave audio input devices.
  217. @flag MCI_GETDEVCAPS_CAN_PLAY |
  218. Queries whether or not playback can be done. This depends upon if
  219. there are any wave audio output devices.
  220. @flag MCI_GETDEVCAPS_CAN_SAVE |
  221. Queries as to whether audio can be saved. This returns TRUE.
  222. @flag MCI_GETDEVCAPS_HAS_AUDIO |
  223. Queries as to whether the device has audio. As this is an audio
  224. device, this returns TRUE.
  225. @flag MCI_GETDEVCAPS_USES_FILES |
  226. Queries as to whether the device uses file to play or record. This
  227. returns TRUE.
  228. @flag MCI_GETDEVCAPS_COMPOUND_DEVICE |
  229. Queries as to whether the device can deal with compound files. This
  230. returns TRUE.
  231. @flag MCI_GETDEVCAPS_HAS_VIDEO |
  232. Queries as to whether the device has video capability. This returns
  233. FALSE.
  234. @flag MCI_GETDEVCAPS_CAN_EJECT |
  235. Queries as to whether the device can eject media. This returns FALSE.
  236. @flag MCI_GETDEVCAPS_DEVICE_TYPE |
  237. Queries the type of device. This returns the wave audio device
  238. string resource identifier.
  239. @parm <t>LPMCI_GETDEVCAPS_PARMS<d> | lpCaps |
  240. Capability parameters.
  241. @rdesc Returns zero on success, or an MCI error code.
  242. */
  243. PUBLIC DWORD PASCAL FAR mwGetDevCaps(
  244. PWAVEDESC pwd,
  245. DWORD dFlags,
  246. LPMCI_GETDEVCAPS_PARMS lpCaps)
  247. {
  248. DWORD dRet;
  249. dFlags &= ~(MCI_NOTIFY | MCI_WAIT);
  250. if (!dFlags || !lpCaps->dwItem)
  251. return MCIERR_MISSING_PARAMETER;
  252. if ((dFlags != MCI_GETDEVCAPS_ITEM) || (lpCaps->dwItem != (lpCaps->dwItem & MCI_WAVE_CAPS_MASK)))
  253. return MCIERR_UNRECOGNIZED_KEYWORD;
  254. switch (lpCaps->dwItem) {
  255. case MCI_WAVE_GETDEVCAPS_INPUTS:
  256. lpCaps->dwReturn = cWaveInMax;
  257. dRet = 0L;
  258. break;
  259. case MCI_WAVE_GETDEVCAPS_OUTPUTS:
  260. lpCaps->dwReturn = cWaveOutMax;
  261. dRet = 0L;
  262. break;
  263. case MCI_GETDEVCAPS_CAN_RECORD:
  264. if (cWaveInMax)
  265. lpCaps->dwReturn = MAKELONG(TRUE, MCI_TRUE);
  266. else
  267. lpCaps->dwReturn = MAKELONG(FALSE, MCI_FALSE);
  268. dRet = MCI_RESOURCE_RETURNED;
  269. break;
  270. case MCI_GETDEVCAPS_CAN_PLAY:
  271. if (cWaveOutMax)
  272. lpCaps->dwReturn = MAKELONG(TRUE, MCI_TRUE);
  273. else
  274. lpCaps->dwReturn = MAKELONG(FALSE, MCI_FALSE);
  275. dRet = MCI_RESOURCE_RETURNED;
  276. break;
  277. case MCI_GETDEVCAPS_CAN_SAVE:
  278. case MCI_GETDEVCAPS_HAS_AUDIO:
  279. case MCI_GETDEVCAPS_USES_FILES:
  280. case MCI_GETDEVCAPS_COMPOUND_DEVICE:
  281. lpCaps->dwReturn = MAKELONG(TRUE, MCI_TRUE);
  282. dRet = MCI_RESOURCE_RETURNED;
  283. break;
  284. case MCI_GETDEVCAPS_HAS_VIDEO:
  285. case MCI_GETDEVCAPS_CAN_EJECT:
  286. lpCaps->dwReturn = MAKELONG(FALSE, MCI_FALSE);
  287. dRet = MCI_RESOURCE_RETURNED;
  288. break;
  289. case MCI_GETDEVCAPS_DEVICE_TYPE:
  290. lpCaps->dwReturn = MAKELONG(MCI_DEVTYPE_WAVEFORM_AUDIO, MCI_DEVTYPE_WAVEFORM_AUDIO);
  291. dRet = MCI_RESOURCE_RETURNED;
  292. break;
  293. default:
  294. dRet = MCIERR_UNSUPPORTED_FUNCTION;
  295. break;
  296. }
  297. return dRet;
  298. }
  299. /************************************************************************/