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.

346 lines
9.9 KiB

  1. /****************************************************************************
  2. *
  3. * mmdrv.c
  4. *
  5. * Multimedia kernel driver support component (mmdrv)
  6. *
  7. * Copyright (c) 1992-1998 Microsoft Corporation
  8. *
  9. * This module contains
  10. *
  11. * -- the entry point and startup code
  12. * -- debug support code
  13. *
  14. * History
  15. * 01-Feb-1992 - Robin Speed (RobinSp) wrote it
  16. * 04-Feb-1992 - Reviewed by SteveDav
  17. *
  18. ***************************************************************************/
  19. #include "mmdrv.h"
  20. #include <stdarg.h>
  21. CRITICAL_SECTION mmDrvCritSec; // Serialize access to device lists
  22. /**************************************************************************
  23. @doc EXTERNAL
  24. @api BOOL | DllInstanceInit | This procedure is called whenever a
  25. process attaches or detaches from the DLL.
  26. @parm PVOID | hModule | Handle of the DLL.
  27. @parm ULONG | Reason | What the reason for the call is.
  28. @parm PCONTEXT | pContext | Some random other information.
  29. @rdesc The return value is TRUE if the initialisation completed ok,
  30. FALSE if not.
  31. **************************************************************************/
  32. BOOL DllInstanceInit(PVOID hModule, ULONG Reason, PCONTEXT pContext)
  33. {
  34. UNREFERENCED_PARAMETER(pContext);
  35. if (Reason == DLL_PROCESS_ATTACH) {
  36. #if DBG
  37. mmdrvDebugLevel = GetProfileInt(L"MMDEBUG", L"MMDRV", 1);
  38. dprintf2 (("Starting, debug level=%d", mmdrvDebugLevel));
  39. #endif
  40. DisableThreadLibraryCalls(hModule);
  41. //
  42. // Create our process DLL heap
  43. //
  44. hHeap = HeapCreate(0, 800, 0);
  45. if (hHeap == NULL) {
  46. return FALSE;
  47. }
  48. InitializeCriticalSection(&mmDrvCritSec);
  49. } else {
  50. if (Reason == DLL_PROCESS_DETACH) {
  51. dprintf2(("Ending"));
  52. TerminateMidi();
  53. TerminateWave();
  54. DeleteCriticalSection(&mmDrvCritSec);
  55. HeapDestroy(hHeap);
  56. }
  57. }
  58. return TRUE;
  59. }
  60. /***************************************************************************
  61. * @doc INTERNAL
  62. *
  63. * @api LONG | DriverProc | The entry point for an installable driver.
  64. *
  65. * @parm DWORD | dwDriverId | For most messages, <p dwDriverId> is the DWORD
  66. * value that the driver returns in response to a <m DRV_OPEN> message.
  67. * Each time that the driver is opened, through the <f DrvOpen> API,
  68. * the driver receives a <m DRV_OPEN> message and can return an
  69. * arbitrary, non-zero value. The installable driver interface
  70. * saves this value and returns a unique driver handle to the
  71. * application. Whenever the application sends a message to the
  72. * driver using the driver handle, the interface routes the message
  73. * to this entry point and passes the corresponding <p dwDriverId>.
  74. * This mechanism allows the driver to use the same or different
  75. * identifiers for multiple opens but ensures that driver handles
  76. * are unique at the application interface layer.
  77. *
  78. * The following messages are not related to a particular open
  79. * instance of the driver. For these messages, the dwDriverId
  80. * will always be zero.
  81. *
  82. * DRV_LOAD, DRV_FREE, DRV_ENABLE, DRV_DISABLE, DRV_OPEN
  83. *
  84. * @parm HANDLE | hDriver | This is the handle returned to the
  85. * application by the driver interface.
  86. *
  87. * @parm UINT | wMessage | The requested action to be performed. Message
  88. * values below <m DRV_RESERVED> are used for globally defined messages.
  89. * Message values from <m DRV_RESERVED> to <m DRV_USER> are used for
  90. * defined driver protocols. Messages above <m DRV_USER> are used
  91. * for driver specific messages.
  92. *
  93. * @parm LONG | lParam1 | Data for this message. Defined separately for
  94. * each message
  95. *
  96. * @parm LONG | lParam2 | Data for this message. Defined separately for
  97. * each message
  98. *
  99. * @rdesc Defined separately for each message.
  100. ***************************************************************************/
  101. LRESULT DriverProc(DWORD_PTR dwDriverID, HANDLE hDriver, UINT wMessage, LPARAM lParam1, LPARAM lParam2)
  102. {
  103. switch (wMessage)
  104. {
  105. case DRV_LOAD:
  106. dprintf2(("DRV_LOAD"));
  107. /*
  108. Sent to the driver when it is loaded. Always the first
  109. message received by a driver.
  110. dwDriverID is 0L.
  111. lParam1 is 0L.
  112. lParam2 is 0L.
  113. Return 0L to fail the load.
  114. DefDriverProc will return NON-ZERO so we don't have to
  115. handle DRV_LOAD
  116. */
  117. return 1L;
  118. case DRV_FREE:
  119. dprintf2(("DRV_FREE"));
  120. /*
  121. Sent to the driver when it is about to be discarded. This
  122. will always be the last message received by a driver before
  123. it is freed.
  124. dwDriverID is 0L.
  125. lParam1 is 0L.
  126. lParam2 is 0L.
  127. Return value is ignored.
  128. */
  129. return 1L;
  130. case DRV_OPEN:
  131. dprintf2(("DRV_OPEN"));
  132. /*
  133. Sent to the driver when it is opened.
  134. dwDriverID is 0L.
  135. lParam1 is a far pointer to a zero-terminated string
  136. containing the name used to open the driver.
  137. lParam2 is passed through from the drvOpen call.
  138. Return 0L to fail the open.
  139. DefDriverProc will return ZERO so we do have to
  140. handle the DRV_OPEN message.
  141. */
  142. return 1L;
  143. case DRV_CLOSE:
  144. dprintf2(("DRV_CLOSE"));
  145. /*
  146. Sent to the driver when it is closed. Drivers are unloaded
  147. when the close count reaches zero.
  148. dwDriverID is the driver identifier returned from the
  149. corresponding DRV_OPEN.
  150. lParam1 is passed through from the drvClose call.
  151. lParam2 is passed through from the drvClose call.
  152. Return 0L to fail the close.
  153. DefDriverProc will return ZERO so we do have to
  154. handle the DRV_CLOSE message.
  155. */
  156. return 1L;
  157. case DRV_ENABLE:
  158. dprintf2(("DRV_ENABLE"));
  159. /*
  160. Sent to the driver when the driver is loaded or reloaded
  161. and whenever Windows is enabled. Drivers should only
  162. hook interrupts or expect ANY part of the driver to be in
  163. memory between enable and disable messages
  164. dwDriverID is 0L.
  165. lParam1 is 0L.
  166. lParam2 is 0L.
  167. Return value is ignored.
  168. */
  169. return 1L;
  170. case DRV_DISABLE:
  171. dprintf2(("DRV_DISABLE"));
  172. /*
  173. Sent to the driver before the driver is freed.
  174. and whenever Windows is disabled
  175. dwDriverID is 0L.
  176. lParam1 is 0L.
  177. lParam2 is 0L.
  178. Return value is ignored.
  179. */
  180. return 1L;
  181. case DRV_QUERYCONFIGURE:
  182. dprintf2(("DRV_QUERYCONFIGURE"));
  183. /*
  184. Sent to the driver so that applications can
  185. determine whether the driver supports custom
  186. configuration. The driver should return a
  187. non-zero value to indicate that configuration
  188. is supported.
  189. dwDriverID is the value returned from the DRV_OPEN
  190. call that must have succeeded before this message
  191. was sent.
  192. lParam1 is passed from the app and is undefined.
  193. lParam2 is passed from the app and is undefined.
  194. Return 0L to indicate configuration NOT supported.
  195. */
  196. return 0L; // we don't do configuration at the moment
  197. case DRV_CONFIGURE:
  198. dprintf2(("DRV_CONFIGURE"));
  199. /*
  200. Sent to the driver so that it can display a custom
  201. configuration dialog box.
  202. lParam1 is passed from the app. and should contain
  203. the parent window handle in the loword.
  204. lParam2 is passed from the app and is undefined.
  205. Return value is undefined.
  206. Drivers should create their own section in system.ini.
  207. The section name should be the driver name.
  208. */
  209. return 0L;
  210. case DRV_INSTALL:
  211. dprintf2(("DRV_INSTALL"));
  212. return DRVCNF_RESTART;
  213. default:
  214. return DefDriverProc(dwDriverID, hDriver, wMessage,lParam1,lParam2);
  215. }
  216. }
  217. #if DBG
  218. int mmdrvDebugLevel = 1;
  219. /***************************************************************************
  220. @doc INTERNAL
  221. @api void | mmdrvDbgOut | This function sends output to the current
  222. debug output device.
  223. @parm LPSTR | lpszFormat | Pointer to a printf style format string.
  224. @parm ??? | ... | Args.
  225. @rdesc There is no return value.
  226. ****************************************************************************/
  227. void mmdrvDbgOut(LPSTR lpszFormat, ...)
  228. {
  229. char buf[256];
  230. va_list va;
  231. OutputDebugStringA("MMDRV: ");
  232. va_start(va, lpszFormat);
  233. vsprintf(buf, lpszFormat, va);
  234. va_end(va);
  235. OutputDebugStringA(buf);
  236. OutputDebugStringA("\n");
  237. }
  238. /***************************************************************************
  239. @doc INTERNAL
  240. @api void | dDbgAssert | This function prints an assertion message.
  241. @parm LPSTR | exp | Pointer to the expression string.
  242. @parm LPSTR | file | Pointer to the file name.
  243. @parm int | line | The line number.
  244. @rdesc There is no return value.
  245. ****************************************************************************/
  246. void dDbgAssert(LPSTR exp, LPSTR file, int line)
  247. {
  248. dprintf1(("Assertion failure:"));
  249. dprintf1((" Exp: %s", exp));
  250. dprintf1((" File: %s, line: %d", file, line));
  251. DebugBreak();
  252. }
  253. #endif // DBG