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.

483 lines
13 KiB

  1. /*
  2. ** MMSEX.C
  3. **
  4. ** Example applet DLL to be displayed by the Multimedia Control Panel.
  5. **
  6. ** History:
  7. **
  8. ** Wed Apr 18 1990 -by- MichaelE
  9. **
  10. */
  11. #ifndef DEBUG
  12. #define DEBUG
  13. #endif
  14. #include <windows.h>
  15. #include "mmsystem.h"
  16. #include <cpl.h>
  17. #include "mmsysi.h"
  18. #include "mmsex.dlg"
  19. LRESULT FAR PASCAL _loadds _export CPlApplet ( HWND, UINT, LPARAM, LPARAM );
  20. BOOL FAR PASCAL _loadds DebugDlg ( HWND, UINT, WPARAM, LPARAM );
  21. static SZCODE szMenuName[] = "mmse&x";
  22. static SZCODE szInfoName[] = "change mmsystem debug settings 1.01";
  23. static SZCODE szHelpFile[] = "";
  24. #define MAX_TYPE 7
  25. static SZCODE szTypes[] =
  26. "???????\0" // 0
  27. "WaveOut\0" // 1 TYPE_WAVEOUT
  28. "WaveIn \0" // 2 TYPE_WAVEIN
  29. "MidiOut\0" // 3 TYPE_MIDIOUT
  30. "MidiIn \0" // 4 TYPE_MIDIIN
  31. "mmio \0" // 5 TYPE_MMIO
  32. "IOProc \0"; // 6 TYPE_IOPROC
  33. int nLoadedCount = 0;
  34. HDRVR hdrv;
  35. int iNumHandles = 0;
  36. /* This function is exported so CPL.EXE can do a GetProcAddress() on
  37. ** the label and send the messages described below.
  38. ** To make MMCPL.EXE load your DLL, and thus add your applets to its
  39. ** window, add a keyname under the [MMCPL] application in
  40. ** WIN.INI:
  41. **
  42. ** [MMCPL]
  43. ** myapplets=c:\mydir\applet.dll
  44. **
  45. ** CPL.EXE loads the WIN3 Control Panel applets first, followed by the
  46. ** applets named in WIN.INI, then those from the directory it was loaded,
  47. ** and finally those in the WIN3 SYSTEM directory.
  48. **
  49. */
  50. LRESULT FAR PASCAL _loadds _export CPlApplet(
  51. HWND hCPlWnd,
  52. UINT Msg,
  53. LPARAM lParam1,
  54. LPARAM lParam2)
  55. {
  56. LPNEWCPLINFO lpCPlInfo;
  57. int i;
  58. switch( Msg )
  59. {
  60. case CPL_INIT:
  61. if (!hdrv)
  62. hdrv = OpenDriver("mmsystem.dll", NULL, 0);
  63. if (!hdrv)
  64. return (LRESULT)FALSE;
  65. // #if 0
  66. if (!SendDriverMessage(hdrv, MM_GET_DEBUG, 0, 0))
  67. {
  68. CloseDriver(hdrv,0,0);
  69. hdrv = NULL;
  70. return (LRESULT)FALSE;
  71. }
  72. // #endif
  73. nLoadedCount++;
  74. // first message to CPlApplet(), sent once only
  75. return (LRESULT)TRUE;
  76. case CPL_GETCOUNT:
  77. // second message to CPlApplet(), sent once only
  78. return (LRESULT)1;
  79. case CPL_NEWINQUIRE:
  80. /* third message to CPlApplet(). It is sent as many times
  81. as the number of applets returned by CPL_GETCOUNT message
  82. */
  83. lpCPlInfo = (LPNEWCPLINFO)lParam2;
  84. // lParam1 is an index ranging from 0 to (NUM_APPLETS-1)
  85. i = (int)lParam1;
  86. lpCPlInfo->dwSize = sizeof(NEWCPLINFO);
  87. lpCPlInfo->dwFlags = 0;
  88. lpCPlInfo->dwHelpContext = 0; // help context to use
  89. lpCPlInfo->lData = 0; // user defined data
  90. lpCPlInfo->hIcon = LoadIcon(ghInst, MAKEINTATOM(DLG_MMSEX));
  91. lstrcpy(lpCPlInfo->szName, szMenuName);
  92. lstrcpy(lpCPlInfo->szInfo, szInfoName);
  93. lstrcpy(lpCPlInfo->szHelpFile, szHelpFile);
  94. return (LRESULT)TRUE;
  95. case CPL_SELECT:
  96. /* One of your applets has been selected.
  97. lParam1 is an index from 0 to (NUM_APPLETS-1)
  98. lParam2 is the lData value associated with the applet
  99. */
  100. break;
  101. case CPL_DBLCLK:
  102. /* One of your applets has been double-clicked.
  103. lParam1 is an index from 0 to (NUM_APPLETS-1)
  104. lParam2 is the lData value associated with the applet
  105. */
  106. DialogBox(ghInst,MAKEINTRESOURCE(DLG_MMSEX),hCPlWnd,DebugDlg);
  107. break;
  108. case CPL_STOP:
  109. /* Sent once for each applet prior to the CPL_EXIT msg.
  110. lParam1 is an index from 0 to (NUM_APPLETS-1)
  111. lParam2 is the lData value associated with the applet
  112. */
  113. break;
  114. case CPL_EXIT:
  115. /* Last message, sent once only, before MMCPL.EXE calls
  116. FreeLibrary() on your DLL.
  117. */
  118. nLoadedCount--;
  119. if (hdrv && !nLoadedCount)
  120. {
  121. CloseDriver(hdrv,0,0);
  122. hdrv = NULL;
  123. }
  124. break;
  125. default:
  126. break;
  127. }
  128. return( 0L );
  129. }
  130. int QueryRadioButton(HWND hdlg, int idFirst, int idLast)
  131. {
  132. int id;
  133. for (id=idFirst; id<=idLast; id++)
  134. {
  135. if (IsDlgButtonChecked(hdlg, id))
  136. return id;
  137. }
  138. return 0;
  139. }
  140. #if 0 // API in win31
  141. BOOL NEAR PASCAL IsTask(HANDLE hTask)
  142. {
  143. _asm {
  144. ; push si
  145. mov ax,hTask
  146. or ax,ax
  147. jz error
  148. lsl si,ax
  149. jnz error
  150. call GetCurrentTask
  151. lsl ax,ax
  152. cmp si,ax
  153. je exit
  154. error:
  155. xor ax,ax
  156. exit:
  157. ; pop si
  158. }}
  159. #endif
  160. void NEAR PASCAL GetTaskName(HANDLE hTask, LPSTR pname)
  161. {
  162. if (!IsTask(hTask))
  163. {
  164. lstrcpy(pname,"????");
  165. }
  166. else
  167. {
  168. ((LPDWORD)pname)[0] = ((LPDWORD)MAKELONG(0xF2,hTask))[0];
  169. ((LPDWORD)pname)[1] = ((LPDWORD)MAKELONG(0xF2,hTask))[1];
  170. pname[8] = 0;
  171. }
  172. }
  173. #define SLASH(c) ((c) == '/' || (c) == '\\')
  174. LPSTR FileName(LPSTR szPath)
  175. {
  176. LPSTR sz;
  177. for (sz=szPath; *sz; sz++)
  178. ;
  179. for (; sz>=szPath && !SLASH(*sz) && *sz!=':'; sz--)
  180. ;
  181. return ++sz;
  182. }
  183. int fQuestion(LPSTR sz,...)
  184. {
  185. char ach[128];
  186. wvsprintf (ach,sz,(LPSTR)(&sz+1)); /* Format the string */
  187. return MessageBox(NULL,ach,"mmsex",MB_YESNO|MB_ICONQUESTION|MB_TASKMODAL);
  188. }
  189. void GetHandles(HWND hdlg)
  190. {
  191. HLOCAL h;
  192. HTASK hTask;
  193. DWORD wType;
  194. UINT n;
  195. int i;
  196. UINT j;
  197. int iSel;
  198. char ach[80];
  199. char szTask[80];
  200. char szName[80];
  201. HWND hlb;
  202. iNumHandles=0;
  203. hlb = GetDlgItem(hdlg, ID_HANDLES);
  204. iSel = (int)SendMessage(hlb,LB_GETCURSEL,0,0L);
  205. SendMessage(hlb, WM_SETREDRAW, (WPARAM)FALSE, 0);
  206. SendMessage(hlb, LB_RESETCONTENT, 0, 0);
  207. //
  208. // fill listbox with all active handles in system
  209. //
  210. for (h = (HLOCAL)(LONG)SendDriverMessage(hdrv, MM_HINFO_NEXT, NULL, 0);
  211. h;
  212. h = (HLOCAL)(LONG)SendDriverMessage(hdrv, MM_HINFO_NEXT, (LPARAM)(LONG)(UINT)h, 0) )
  213. {
  214. iNumHandles++;
  215. wType = (UINT)SendDriverMessage(hdrv, MM_HINFO_TYPE, (LPARAM)(LONG)(UINT)h, 0);
  216. hTask = (HTASK)(LONG)SendDriverMessage(hdrv, MM_HINFO_TASK, (LPARAM)(LONG)(UINT)h, 0);
  217. if (wType >= MAX_TYPE)
  218. wType = 0;
  219. GetTaskName(hTask, szTask);
  220. wsprintf(ach, "%ls %04X %ls",(LPSTR)szTypes + wType*(sizeof(szTypes)-1)/MAX_TYPE,h,(LPSTR)szTask);
  221. i = (int)(LONG)SendMessage(hlb, LB_ADDSTRING, 0, (LPARAM)(LPSTR)ach);
  222. SendMessage(hlb, LB_SETITEMDATA, (WPARAM)i, MAKELPARAM(h, wType));
  223. }
  224. //
  225. // add to that all MCI handles
  226. //
  227. n = (UINT)(LONG)SendDriverMessage(hdrv, MM_HINFO_MCI, 0, 0);
  228. for (j = 1; j < n; j++)
  229. {
  230. MCI_DEVICE_NODE node;
  231. if (!SendDriverMessage(hdrv, MM_HINFO_MCI, (LPARAM)j, (LPARAM)(LPVOID)&node))
  232. continue;
  233. iNumHandles++;
  234. if (node.lpstrName == NULL)
  235. node.lpstrName = "";
  236. if (node.lpstrInstallName == NULL)
  237. node.lpstrInstallName = "";
  238. GetTaskName(node.hCreatorTask, szTask);
  239. wsprintf(ach, "mci %04X %ls %ls %ls",j,(LPSTR)szTask,node.lpstrInstallName,node.lpstrName);
  240. i = (int)(LONG)SendMessage(hlb, LB_ADDSTRING, 0, (LPARAM)(LPSTR)ach);
  241. SendMessage(hlb, LB_SETITEMDATA, (WPARAM)i, MAKELPARAM(j, TYPE_MCI));
  242. }
  243. //
  244. // add to that all DRV handles
  245. //
  246. for (h=GetNextDriver(NULL, 0); h; h=GetNextDriver(h, 0))
  247. {
  248. if (GetDriverModuleHandle(h))
  249. {
  250. DRIVERINFOSTRUCT di;
  251. di.length = sizeof(di);
  252. di.szAliasName[0] = 0;
  253. GetDriverInfo(h, &di);
  254. iNumHandles++;
  255. GetModuleFileName(GetDriverModuleHandle(h), szName, sizeof(szName));
  256. wsprintf(ach, "Driver %04X %ls (%ls)",h,(LPSTR)di.szAliasName,(LPSTR)FileName(szName));
  257. i = (int)(LONG)SendDlgItemMessage(hdlg, ID_HANDLES, LB_ADDSTRING, 0, (LPARAM)(LPSTR)ach);
  258. SendDlgItemMessage(hdlg, ID_HANDLES, LB_SETITEMDATA, (WPARAM)i, MAKELPARAM(h,TYPE_DRVR));
  259. }
  260. }
  261. SendMessage(hlb,LB_SETCURSEL,(WPARAM)iSel,0L);
  262. SendMessage(hlb,WM_SETREDRAW,(WPARAM)TRUE,0);
  263. InvalidateRect(hlb, NULL, TRUE);
  264. }
  265. int CountHandles(void)
  266. {
  267. HLOCAL h;
  268. int cnt=0;
  269. UINT n;
  270. UINT j;
  271. for (h = (HLOCAL)(LONG)SendDriverMessage(hdrv, MM_HINFO_NEXT, NULL, 0);
  272. h;
  273. h = (HLOCAL)(LONG)SendDriverMessage(hdrv, MM_HINFO_NEXT, (LPARAM)(LONG)(UINT)h, 0) )
  274. {
  275. cnt++;
  276. }
  277. n = (UINT)(LONG)SendDriverMessage(hdrv, MM_HINFO_MCI, 0, 0);
  278. for (j=1; j<n; j++)
  279. {
  280. MCI_DEVICE_NODE node;
  281. if (!SendDriverMessage(hdrv, MM_HINFO_MCI, (LPARAM)j, (LPARAM)(LPVOID)&node))
  282. continue;
  283. cnt++;
  284. }
  285. for (h=GetNextDriver(NULL,0); h; h=GetNextDriver(h, 0))
  286. {
  287. if (GetDriverModuleHandle(h))
  288. cnt++;
  289. }
  290. return cnt;
  291. }
  292. void CloseHandle(DWORD dw)
  293. {
  294. HLOCAL h;
  295. h = (HLOCAL)LOWORD(dw);
  296. switch(HIWORD(dw))
  297. {
  298. case TYPE_WAVEOUT:
  299. if (IDYES == fQuestion("Close WaveOut handle %04X?",h))
  300. {
  301. waveOutReset(h);
  302. waveOutClose(h);
  303. }
  304. break;
  305. case TYPE_WAVEIN:
  306. if (IDYES == fQuestion("Close WaveIn handle %04X?",h))
  307. {
  308. waveInStop(h);
  309. waveInClose(h);
  310. }
  311. break;
  312. case TYPE_MIDIOUT:
  313. if (IDYES == fQuestion("Close MidiOut handle %04X?",h))
  314. {
  315. midiOutReset(h);
  316. midiOutClose(h);
  317. }
  318. break;
  319. case TYPE_MIDIIN:
  320. if (IDYES == fQuestion("Close MidiIn handle %04X?",h))
  321. {
  322. midiInStop(h);
  323. midiInClose(h);
  324. }
  325. break;
  326. case TYPE_MCI:
  327. if (IDYES == fQuestion("Close Mci device %04X?",h))
  328. {
  329. mciSendCommand((UINT)h, MCI_CLOSE, 0, 0);
  330. }
  331. break;
  332. case TYPE_MMIO:
  333. if (IDYES == fQuestion("Close MMIO handle %04X?",h))
  334. {
  335. mmioClose(h,MMIO_FHOPEN);
  336. }
  337. break;
  338. case TYPE_DRVR:
  339. break;
  340. }
  341. }
  342. BOOL FAR PASCAL _loadds DebugDlg(HWND hdlg, UINT msg, WPARAM wParam, LPARAM lParam)
  343. {
  344. DWORD dw;
  345. int i;
  346. switch (msg)
  347. {
  348. case WM_INITDIALOG:
  349. SendDlgItemMessage(hdlg, ID_DEBUG_OUT, CB_ADDSTRING, 0, (LONG)(LPSTR)"(none)");
  350. SendDlgItemMessage(hdlg, ID_DEBUG_OUT, CB_ADDSTRING, 0, (LONG)(LPSTR)"COM1:");
  351. SendDlgItemMessage(hdlg, ID_DEBUG_OUT, CB_ADDSTRING, 0, (LONG)(LPSTR)"Mono Monitor");
  352. SendDlgItemMessage(hdlg, ID_DEBUG_OUT, CB_ADDSTRING, 0, (LONG)(LPSTR)"Windows");
  353. SendDlgItemMessage(hdlg, ID_DEBUG_OUT, CB_SETCURSEL, (int)(LONG)SendDriverMessage(hdrv, MM_GET_DEBUGOUT, 0, 0), 0L);
  354. CheckDlgButton(hdlg, ID_DEBUG_MCI, (int)(LONG)SendDriverMessage(hdrv, MM_GET_MCI_DEBUG, 0, 0));
  355. CheckDlgButton(hdlg, ID_DEBUG_MMSYS, (int)(LONG)SendDriverMessage(hdrv, MM_GET_MM_DEBUG, 0, 0));
  356. iNumHandles = CountHandles();
  357. GetHandles(hdlg);
  358. SetTimer(hdlg, 500, 500, NULL);
  359. return TRUE;
  360. case WM_TIMER:
  361. i = CountHandles();
  362. if (iNumHandles != i)
  363. {
  364. iNumHandles = i;
  365. GetHandles(hdlg);
  366. }
  367. break;
  368. case WM_COMMAND:
  369. switch ((UINT)wParam)
  370. {
  371. case IDOK:
  372. SendDriverMessage(hdrv, MM_SET_DEBUGOUT,
  373. (LPARAM)SendDlgItemMessage(hdlg, ID_DEBUG_OUT, CB_GETCURSEL, 0, 0), 0);
  374. SendDriverMessage(hdrv, MM_SET_MCI_DEBUG,
  375. (LPARAM)IsDlgButtonChecked(hdlg, ID_DEBUG_MCI),0);
  376. SendDriverMessage(hdrv, MM_SET_MM_DEBUG,
  377. (LPARAM)IsDlgButtonChecked(hdlg, ID_DEBUG_MMSYS),0);
  378. // fall through
  379. case IDCANCEL:
  380. EndDialog(hdlg, wParam);
  381. break;
  382. case ID_RESTART:
  383. SendDriverMessage(hdrv, MM_DRV_RESTART, 0, 0);
  384. break;
  385. case ID_HANDLES:
  386. if (HIWORD(lParam) != LBN_DBLCLK)
  387. break;
  388. i = (int)(LONG)SendDlgItemMessage(hdlg,wParam,LB_GETCURSEL,0,0L);
  389. dw = (DWORD)SendDlgItemMessage(hdlg,wParam,LB_GETITEMDATA,(WPARAM)i,0L);
  390. CloseHandle(dw);
  391. GetHandles(hdlg);
  392. break;
  393. }
  394. break;
  395. }
  396. return FALSE;
  397. }