Leaked source code of windows server 2003
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.

205 lines
5.4 KiB

  1. /* Copyright (c) 1998 Microsoft Corporation */
  2. /*
  3. * @Doc DMusic
  4. *
  5. * @Module DMusic16.c - Startup code |
  6. *
  7. * 16-bit Dll for DirectMusic sequencing on legacy devices (Win95/Win98 non-WDM drivers)
  8. *
  9. * This Dll is the 16-bit thunk peer for DMusic32.Dll
  10. *
  11. * @globalv HINSTANCE | ghInst | The instance handle for the DLL.
  12. *
  13. */
  14. #include <windows.h>
  15. #include <windowsx.h>
  16. #include <mmsystem.h>
  17. #include "dmusic16.h"
  18. #include "debug.h"
  19. HINSTANCE ghInst;
  20. HDRVR ghDrvr;
  21. UINT guReferenceCount = 0;
  22. /* @func LibMain system entry point
  23. *
  24. * @comm
  25. *
  26. * This entry point is called when the DLL is first loaded (NOT every time).
  27. *
  28. * Saves the global instance handle and initializes all the other modules.
  29. *
  30. */
  31. int PASCAL
  32. LibMain(
  33. HINSTANCE hInst, /* @parm Instance handle for the DLL */
  34. WORD cbHeap, /* @parm Initial size of the local heap */
  35. LPSTR lpszCmdLine) /* @parm Command-line parameters */
  36. {
  37. UINT uLev;
  38. char szFilename[260];
  39. if (GetModuleFileName(hInst, szFilename, sizeof(szFilename)))
  40. {
  41. DPF(2, "%s", (LPSTR)szFilename);
  42. }
  43. ghDrvr = OpenDriver(szFilename, NULL, 0L);
  44. DPF(1, "DMusic16.DLL task %04X hdrvr %04X", GetCurrentTask(), (WORD)ghDrvr);
  45. ghInst = hInst;
  46. uLev = DbgInitialize(TRUE);
  47. DPF(0, "DMusic16: Debug level is %u", uLev);
  48. if (uLev > 2)
  49. {
  50. DPF(0, "DMusic16: Break in LibMain");
  51. DebugBreak();
  52. }
  53. DeviceOnLoad();
  54. AllocOnLoad();
  55. MidiOutOnLoad();
  56. #if 0
  57. // This causes problems at terminate time. Find out later if we really need it.
  58. //
  59. if (!CreateTimerTask())
  60. {
  61. DPF(0, "CreateTimerTask() failed");
  62. }
  63. if (NULL == (LoadLibrary("dmusic16")))
  64. {
  65. DPF(0, "Could not LoadLibrary ourselves!");
  66. }
  67. #endif
  68. return 1;
  69. }
  70. /* @func LibExit system call
  71. *
  72. * @comm
  73. *
  74. * This entry point is called just before the DLL is unloaded.
  75. *
  76. * Uninitialize all the other modules
  77. */
  78. VOID PASCAL __loadds
  79. LibExit(VOID)
  80. {
  81. DPF(2, "LibExit start");
  82. #if 0
  83. DestroyTimerTask();
  84. #endif
  85. MidiOutOnExit();
  86. AllocOnExit();
  87. DPF(2, "LibExit end, going away now.");
  88. }
  89. extern BOOL FAR PASCAL dmthunk_ThunkConnect16(LPCSTR, LPCSTR, HINSTANCE, DWORD);
  90. STATIC char pszDll16[] = "DMUSIC16.DLL";
  91. STATIC char pszDll32[] = "DMUSIC.DLL";
  92. /* @func DLLEntryPoint system entry point
  93. *
  94. * @comm
  95. *
  96. * This entry point is called each time the DLL is loaded or unloaded
  97. *
  98. * It is used here to initialize the peer connection for the thunk layer.
  99. */
  100. #define PROCESS_DETACH 0
  101. #define PROCESS_ATTACH 1
  102. BOOL WINAPI
  103. DllEntryPoint(
  104. DWORD dwReason, /* @parm Is the DLL being loaded or unloaded? */
  105. HINSTANCE hi, /* @parm The instance handle */
  106. HGLOBAL hgDS, /* @parm The global handle of the DLL's (shared) DS */
  107. WORD wHeapSize, /* @parm The initial size of the local heap */
  108. LPCSTR lszCmdLine, /* @parm The command line (always NULL) */
  109. WORD wCmdLine) /* @parm Unused */
  110. {
  111. // DllEntryPoint is called before LibEntry in a 4.x dll, so we have to LocalInit here if we're
  112. // going to use LocalAlloc
  113. //
  114. if (guReferenceCount == 0 && wHeapSize)
  115. {
  116. LocalInit(0, 0, wHeapSize);
  117. }
  118. switch(dwReason)
  119. {
  120. case PROCESS_ATTACH:
  121. DPF(2, "ProcessAttach task %04X", GetCurrentTask());
  122. ++guReferenceCount;
  123. dmthunk_ThunkConnect16(pszDll16, pszDll32, ghInst, 1);
  124. break;
  125. case PROCESS_DETACH:
  126. DPF(2, "ProcessDetach task %04X", GetCurrentTask());
  127. /* Clean up after them if they didn't close handles. We must do this here as well as
  128. * in DriverProc because on the last exit, we will go away before the DriverProc cleanup
  129. * gets called if the process termination is normal.
  130. */
  131. CloseDevicesForTask(GetCurrentTask());
  132. /* NOTE: We close on reference count of 1 since the initial OpenDriver call
  133. causes one more PROCESS_ATTACH to happen. */
  134. if (1 == --guReferenceCount)
  135. {
  136. CloseDriver(ghDrvr, 0, 0);
  137. }
  138. break;
  139. }
  140. return TRUE;
  141. }
  142. /* @func DriverProc entry point for ourselves as a loadable driver.
  143. *
  144. * @comm This entry points allows us to know when a task has gone away and therefore to clean
  145. * up after it even though we don't properly get notified that our thunk peer has gone away.
  146. */
  147. LRESULT WINAPI DriverProc(
  148. DWORD dwID,
  149. HDRVR hdrvr,
  150. UINT umsg,
  151. LPARAM lParam1,
  152. LPARAM lParam2)
  153. {
  154. //
  155. // NOTE DS is not valid here.
  156. //
  157. switch (umsg)
  158. {
  159. case DRV_LOAD:
  160. return(1L);
  161. case DRV_FREE:
  162. return(0L);
  163. case DRV_OPEN:
  164. case DRV_CLOSE:
  165. return(1L);
  166. case DRV_EXITAPPLICATION:
  167. DPF(2, "Cleaning up handles for task %04X", GetCurrentTask());
  168. CloseDevicesForTask(GetCurrentTask());
  169. break;
  170. default:
  171. return(DefDriverProc(dwID, hdrvr, umsg, lParam1, lParam2));
  172. }
  173. } //** DriverProc()