1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * MCI internal functions
6 * Copyright 1998/1999 Eric Pouech
16 #include "multimedia.h"
17 #include "selectors.h"
20 #include "wine/winbase16.h"
22 struct WINE_MCIDRIVER mciDrv[MAXMCIDRIVERS];
24 int mciInstalledCount;
25 int mciInstalledListLen;
26 LPSTR lpmciInstallNames = NULL;
28 /* The wDevID's returned by wine were originally in the range
29 * 0 - (MAXMCIDRIVERS - 1) and used directly as array indices.
30 * Unfortunately, ms-windows uses wDevID of zero to indicate
31 * errors. Now, multimedia drivers must pass the wDevID through
32 * MCI_DevIDToIndex to get an index in that range. An
33 * arbitrary value, MCI_MAGIC is added to the wDevID seen
34 * by the windows programs.
37 #define MCI_MAGIC 0x0F00
39 MCI_WineDesc MCI_InternalDescriptors[] = {
40 {MCI_DEVTYPE_CD_AUDIO, "CDAUDIO", MCICDAUDIO_DriverProc},
41 {MCI_DEVTYPE_WAVEFORM_AUDIO, "WAVEAUDIO", MCIWAVE_DriverProc},
42 {MCI_DEVTYPE_SEQUENCER, "SEQUENCER", MCIMIDI_DriverProc},
43 {MCI_DEVTYPE_ANIMATION, "ANIMATION1", MCIANIM_DriverProc},
44 {MCI_DEVTYPE_DIGITAL_VIDEO, "AVIVIDEO", MCIAVI_DriverProc},
46 {0xFFFF, NULL, NULL} /* sentinel */
49 /**************************************************************************
50 * MCI_GetDevTypeString [internal]
52 static LPCSTR MCI_GetDevTypeString(WORD uDevType)
54 LPCSTR str = "??? MCI ???";
57 for (i = 0; MCI_InternalDescriptors[i].uDevType != 0xFFFF; i++) {
58 if (MCI_InternalDescriptors[i].uDevType != 0 && MCI_InternalDescriptors[i].uDevType == uDevType) {
59 str = MCI_InternalDescriptors[i].lpstrName;
63 /* TRACE(mci, "devType=%u => %s\n", uDevType, str);*/
67 /**************************************************************************
68 * MCI_GetProc [internal]
70 static MCIPROC MCI_GetProc(UINT16 uDevType)
75 for (i = 0; MCI_InternalDescriptors[i].uDevType != 0xFFFF; i++) {
76 if (MCI_InternalDescriptors[i].uDevType != 0 &&
77 MCI_InternalDescriptors[i].uDevType == uDevType) {
78 proc = MCI_InternalDescriptors[i].lpfnProc;
85 /**************************************************************************
86 * MCI_GetDevType [internal]
88 WORD MCI_GetDevType(LPCSTR str)
93 for (i = 0; MCI_InternalDescriptors[i].uDevType != 0xFFFF; i++) {
94 if (MCI_InternalDescriptors[i].uDevType != 0 &&
95 strcmp(str, MCI_InternalDescriptors[i].lpstrName) == 0) {
96 uDevType = MCI_InternalDescriptors[i].uDevType;
103 /**************************************************************************
104 * MCI_DevIDToIndex [internal]
106 int MCI_DevIDToIndex(UINT16 wDevID)
108 return wDevID - MCI_MAGIC;
111 /**************************************************************************
112 * MCI_FirstDevId [internal]
114 UINT16 MCI_FirstDevID(void)
119 /**************************************************************************
120 * MCI_NextDevId [internal]
122 UINT16 MCI_NextDevID(UINT16 wDevID)
127 /**************************************************************************
128 * MCI_DevIDValid [internal]
130 BOOL MCI_DevIDValid(UINT16 wDevID)
132 return wDevID >= MCI_MAGIC && wDevID < (MCI_MAGIC + MAXMCIDRIVERS);
135 /**************************************************************************
136 * MCI_CommandToString [internal]
138 const char* MCI_CommandToString(UINT16 wMsg)
140 static char buffer[100];
142 #define CASE(s) case (s): return #s
147 CASE(MCI_CLOSE_DRIVER);
156 CASE(MCI_GETDEVCAPS);
160 CASE(MCI_OPEN_DRIVER);
179 sprintf(buffer, "MCI_<<%04X>>", wMsg);
185 /**************************************************************************
186 * MCI_MapMsg16To32A [internal]
188 int MCI_MapMsg16To32A(WORD uDevType, WORD wMsg, DWORD* lParam)
192 /* FIXME: to add also (with seg/linear modifications to do):
193 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
194 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
197 /* case MCI_CAPTURE */
199 case MCI_CLOSE_DRIVER:
200 /* case MCI_CONFIGURE:*/
207 /* case MCI_INDEX: */
209 /* case MCI_MONITOR: */
219 /* case MCI_SETTIMECODE:*/
220 /* case MCI_SIGNAL:*/
222 case MCI_STATUS: /* FIXME: is wrong for digital video */
229 *lParam = (DWORD)PTR_SEG_TO_LIN(*lParam);
232 /* in fact, I would also need the dwFlags... to see
233 * which members of lParam are effectively used
235 *lParam = (DWORD)PTR_SEG_TO_LIN(*lParam);
236 FIXME(mci, "Current mapping may be wrong\n");
240 LPMCI_BREAK_PARMS mbp32 = HeapAlloc(SystemHeap, 0, sizeof(MCI_BREAK_PARMS));
241 LPMCI_BREAK_PARMS16 mbp16 = PTR_SEG_TO_LIN(*lParam);
244 mbp32->dwCallback = mbp16->dwCallback;
245 mbp32->nVirtKey = mbp16->nVirtKey;
246 mbp32->hwndBreak = mbp16->hwndBreak;
250 *lParam = (DWORD)mbp32;
255 LPMCI_VD_ESCAPE_PARMSA mvep32a = HeapAlloc(SystemHeap, 0, sizeof(MCI_VD_ESCAPE_PARMSA));
256 LPMCI_VD_ESCAPE_PARMS16 mvep16 = PTR_SEG_TO_LIN(*lParam);
259 mvep32a->dwCallback = mvep16->dwCallback;
260 mvep32a->lpstrCommand = PTR_SEG_TO_LIN(mvep16->lpstrCommand);
264 *lParam = (DWORD)mvep32a;
269 LPMCI_INFO_PARMSA mip32a = HeapAlloc(SystemHeap, 0, sizeof(MCI_INFO_PARMSA));
270 LPMCI_INFO_PARMS16 mip16 = PTR_SEG_TO_LIN(*lParam);
272 /* FIXME this is wrong if device is of type
273 * MCI_DEVTYPE_DIGITAL_VIDEO, some members are not mapped
276 mip32a->dwCallback = mip16->dwCallback;
277 mip32a->lpstrReturn = PTR_SEG_TO_LIN(mip16->lpstrReturn);
278 mip32a->dwRetSize = mip16->dwRetSize;
282 *lParam = (DWORD)mip32a;
286 case MCI_OPEN_DRIVER:
288 LPMCI_OPEN_PARMSA mop32a = HeapAlloc(SystemHeap, 0, sizeof(LPMCI_OPEN_PARMS16) + sizeof(MCI_OPEN_PARMSA) + 2 * sizeof(DWORD));
289 LPMCI_OPEN_PARMS16 mop16 = PTR_SEG_TO_LIN(*lParam);
292 *(LPMCI_OPEN_PARMS16*)(mop32a) = mop16;
293 mop32a = (LPMCI_OPEN_PARMSA)((char*)mop32a + sizeof(LPMCI_OPEN_PARMS16));
294 mop32a->dwCallback = mop16->dwCallback;
295 mop32a->wDeviceID = mop16->wDeviceID;
296 mop32a->lpstrDeviceType = PTR_SEG_TO_LIN(mop16->lpstrDeviceType);
297 mop32a->lpstrElementName = PTR_SEG_TO_LIN(mop16->lpstrElementName);
298 mop32a->lpstrAlias = PTR_SEG_TO_LIN(mop16->lpstrAlias);
299 /* copy extended information if any...
300 * FIXME: this may seg fault if initial structure does not contain them and
301 * the reads after msip16 fail under LDT limits...
302 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
303 * should not take care of extended parameters, and should be used by MCI_Open
304 * to fetch uDevType. When, this is known, the mapping for sending the
305 * MCI_OPEN_DRIVER shall be done depending on uDevType.
307 memcpy(mop32a + 1, mop16 + 1, 2 * sizeof(DWORD));
311 *lParam = (DWORD)mop32a;
316 LPMCI_SYSINFO_PARMSA msip32a = HeapAlloc(SystemHeap, 0, sizeof(MCI_SYSINFO_PARMSA));
317 LPMCI_SYSINFO_PARMS16 msip16 = PTR_SEG_TO_LIN(*lParam);
320 msip32a->dwCallback = msip16->dwCallback;
321 msip32a->lpstrReturn = PTR_SEG_TO_LIN(msip16->lpstrReturn);
322 msip32a->dwRetSize = msip16->dwRetSize;
323 msip32a->dwNumber = msip16->dwNumber;
324 msip32a->wDeviceType = msip16->wDeviceType;
328 *lParam = (DWORD)msip32a;
338 case DRV_QUERYCONFIGURE:
341 case DRV_EXITSESSION:
342 case DRV_EXITAPPLICATION:
344 FIXME(mci, "This is a hack\n");
348 WARN(mci, "Don't know how to map msg=%s\n", MCI_CommandToString(wMsg));
353 /**************************************************************************
354 * MCI_UnMapMsg16To32A [internal]
356 int MCI_UnMapMsg16To32A(WORD uDevType, WORD wMsg, DWORD lParam)
359 /* case MCI_CAPTURE */
361 case MCI_CLOSE_DRIVER:
362 /* case MCI_CONFIGURE:*/
369 /* case MCI_INDEX: */
371 /* case MCI_MONITOR: */
381 /* case MCI_SETTIMECODE:*/
382 /* case MCI_SIGNAL:*/
394 /* FIXME ?? see Map function */
401 HeapFree(SystemHeap, 0, (LPVOID)lParam);
404 case MCI_OPEN_DRIVER:
406 LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)lParam;
407 LPMCI_OPEN_PARMS16 mop16 = *(LPMCI_OPEN_PARMS16*)((char*)mop32a - sizeof(LPMCI_OPEN_PARMS16*));
409 mop16->wDeviceID = mop32a->wDeviceID;
410 if (!HeapFree(SystemHeap, 0, (LPVOID)(lParam - sizeof(LPMCI_OPEN_PARMS16))))
411 FIXME(mci, "bad free line=%d\n", __LINE__);
421 case DRV_QUERYCONFIGURE:
424 case DRV_EXITSESSION:
425 case DRV_EXITAPPLICATION:
427 FIXME(mci, "This is a hack\n");
430 FIXME(mci, "Map/Unmap internal error on msg=%s\n", MCI_CommandToString(wMsg));
435 /**************************************************************************
436 * MCI_MsgMapper32To16_Create [internal]
438 * Helper for MCI_MapMsg32ATo16.
439 * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit segmented pointer.
440 * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
441 * 1 : ok, some memory allocated
442 * -2 : ko, memory problem
444 static int MCI_MsgMapper32To16_Create(void** ptr, int size, BOOLEAN keep)
446 void* lp = SEGPTR_ALLOC(sizeof(void**) + size);
453 memcpy((char*)lp + sizeof(void**), *ptr, size);
454 *ptr = (char*)SEGPTR_GET(lp) + sizeof(void**);
456 memcpy((char*)lp, *ptr, size);
457 *ptr = (void*)SEGPTR_GET(lp);
463 /**************************************************************************
464 * MCI_MsgMapper32To16_Destroy [internal]
466 * Helper for MCI_UnMapMsg32ATo16.
468 static int MCI_MsgMapper32To16_Destroy(void* ptr, int size, BOOLEAN kept)
471 void* msg16 = PTR_SEG_TO_LIN(ptr);
475 alloc = (char*)msg16 - sizeof(void**);
476 memcpy(*(void**)alloc, msg16, size);
481 if (!SEGPTR_FREE(alloc)) {
482 FIXME(mci, "bad free\n");
488 /**************************************************************************
489 * MCI_MapMsg32ATo16 [internal]
491 * Map a 32-A bit MCI message to a 16 bit MCI message.
492 * 1 : ok, some memory allocated, need to call MCI_UnMapMsg32ATo16
493 * 0 : ok, no memory allocated
494 * -1 : ko, unknown message
495 * -2 : ko, memory problem
497 int MCI_MapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD* lParam)
500 BOOLEAN keep = FALSE;
504 /* FIXME: to add also (with seg/linear modifications to do):
505 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
506 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
509 /* case MCI_BREAK: */
510 /* case MCI_CAPTURE */
512 case MCI_CLOSE_DRIVER:
513 size = sizeof(MCI_GENERIC_PARMS);
515 /* case MCI_CONFIGURE:*/
519 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_CUE_PARMS); break;
520 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_CUE_PARMS); break;*/ FIXME(mci, "NIY vcr\n"); return -2;
521 default: size = sizeof(MCI_GENERIC_PARMS); break;
527 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_DELETE_PARMS); FIXME(mci, "NIY rect\n"); return -2;
528 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_DELETE_PARMS); break;
529 default: size = sizeof(MCI_GENERIC_PARMS); break;
532 /* case MCI_ESCAPE: */
535 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_FREEZE_PARMS); FIXME(mci, "NIY rect\n"); return -2;
536 case MCI_DEVTYPE_OVERLAY: /*size = sizeof(MCI_OVLY_FREEZE_PARMS); FIXME(mci, "NIY rect\n"); return -2;*/
537 FIXME(mci, "NIY ovly\n"); return -2;
538 default: size = sizeof(MCI_GENERIC_PARMS); break;
543 size = sizeof(MCI_GETDEVCAPS_PARMS);
545 /* case MCI_INDEX: */
548 LPMCI_INFO_PARMSA mip32a = (LPMCI_INFO_PARMSA)(*lParam);
550 LPMCI_INFO_PARMS16 mip16;
553 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_INFO_PARMS16); break;
554 default: size = sizeof(MCI_INFO_PARMS16); break;
556 ptr = SEGPTR_ALLOC(sizeof(LPMCI_INFO_PARMSA) + size);
559 *(LPMCI_INFO_PARMSA*)ptr = mip32a;
560 mip16 = (LPMCI_INFO_PARMS16)(ptr + sizeof(LPMCI_INFO_PARMSA));
561 mip16->dwCallback = mip32a->dwCallback;
562 mip16->lpstrReturn = (LPSTR)SEGPTR_GET(SEGPTR_ALLOC(mip32a->dwRetSize));
563 mip16->dwRetSize = mip32a->dwRetSize;
564 if (uDevType == MCI_DEVTYPE_DIGITAL_VIDEO) {
565 ((LPMCI_DGV_INFO_PARMS16)mip16)->dwItem = ((LPMCI_DGV_INFO_PARMSA)mip32a)->dwItem;
570 *lParam = (LPARAM)SEGPTR_GET(ptr) + sizeof(LPMCI_INFO_PARMSA);
574 /* case MCI_MONITOR: */
576 case MCI_OPEN_DRIVER:
578 LPMCI_OPEN_PARMSA mop32a = (LPMCI_OPEN_PARMSA)(*lParam);
579 char* ptr = SEGPTR_ALLOC(sizeof(LPMCI_OPEN_PARMSA) + sizeof(MCI_OPEN_PARMS16) + 2 * sizeof(DWORD));
580 LPMCI_OPEN_PARMS16 mop16;
584 *(LPMCI_OPEN_PARMSA*)(ptr) = mop32a;
585 mop16 = (LPMCI_OPEN_PARMS16)(ptr + sizeof(LPMCI_OPEN_PARMSA));
586 mop16->dwCallback = mop32a->dwCallback;
587 mop16->wDeviceID = mop32a->wDeviceID;
588 if (dwFlags & MCI_OPEN_TYPE) {
589 if (dwFlags & MCI_OPEN_TYPE_ID) {
590 /* dword "transparent" value */
591 mop16->lpstrDeviceType = mop32a->lpstrDeviceType;
594 mop16->lpstrDeviceType = mop32a->lpstrDeviceType ? (LPSTR)SEGPTR_GET(SEGPTR_STRDUP(mop32a->lpstrDeviceType)) : 0;
598 mop16->lpstrDeviceType = 0;
600 if (dwFlags & MCI_OPEN_ELEMENT) {
601 if (dwFlags & MCI_OPEN_ELEMENT_ID) {
602 mop16->lpstrElementName = mop32a->lpstrElementName;
604 mop16->lpstrElementName = mop32a->lpstrElementName ? (LPSTR)SEGPTR_GET(SEGPTR_STRDUP(mop32a->lpstrElementName)) : 0;
607 mop16->lpstrElementName = 0;
609 if (dwFlags & MCI_OPEN_ALIAS) {
610 mop16->lpstrAlias = mop32a->lpstrAlias ? (LPSTR)SEGPTR_GET(SEGPTR_STRDUP(mop32a->lpstrAlias)) : 0;
612 mop16->lpstrAlias = 0;
614 /* copy extended information if any...
615 * FIXME: this may seg fault if initial structure does not contain them and
616 * the reads after msip16 fail under LDT limits...
617 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
618 * should not take care of extended parameters, and should be used by MCI_Open
619 * to fetch uDevType. When, this is known, the mapping for sending the
620 * MCI_OPEN_DRIVER shall be done depending on uDevType.
622 memcpy(mop16 + 1, mop32a + 1, 2 * sizeof(DWORD));
626 *lParam = (LPARAM)SEGPTR_GET(ptr) + sizeof(LPMCI_OPEN_PARMSA);
631 size = sizeof(MCI_GENERIC_PARMS);
635 case MCI_DEVTYPE_OVERLAY: /*size = sizeof(MCI_OVLY_PLAY_PARMS); break;*/FIXME(mci, "NIY ovly\n"); return -2;
636 default: size = sizeof(MCI_PLAY_PARMS); break;
641 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_PUT_PARMS); FIXME(mci, "NIY rect\n"); return -2;
642 case MCI_DEVTYPE_OVERLAY: /*size = sizeof(MCI_OVLY_PUT_PARMS); FIXME(mci, "NIY rect\n"); return -2;*/
643 FIXME(mci, "NIY ovly\n"); return -2;
644 default: size = sizeof(MCI_GENERIC_PARMS); break;
648 size = sizeof(MCI_GENERIC_PARMS);
652 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECORD_PARMS); FIXME(mci, "NIY rect\n"); return -2;
653 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_RECORD_PARMS); break;*/FIXME(mci, "NIY vcr\n"); return -2;
654 default: size = sizeof(MCI_RECORD_PARMS); break;
658 size = sizeof(MCI_GENERIC_PARMS);
662 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SEEK_PARMS); break;*/FIXME(mci, "NIY vcr\n"); return -2;
663 default: size = sizeof(MCI_SEEK_PARMS); break;
668 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_SET_PARMS); break;
669 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_SET_PARMS); break;*/FIXME(mci, "NIY vcr\n"); return -2;
670 case MCI_DEVTYPE_SEQUENCER: size = sizeof(MCI_SEQ_SET_PARMS); break;
671 /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
672 * so not doing anything should work...
674 case MCI_DEVTYPE_WAVEFORM_AUDIO:size = sizeof(MCI_WAVE_SET_PARMS); break;
675 default: size = sizeof(MCI_SET_PARMS); break;
678 /* case MCI_SETTIMECODE:*/
679 /* case MCI_SIGNAL:*/
681 size = sizeof(MCI_SET_PARMS);
686 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16); FIXME(mci, "NIY lpstrDevice\n");return -2;
687 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME(mci, "NIY vcr\n"); return -2;
688 default: size = sizeof(MCI_STATUS_PARMS); break;
693 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STEP_PARMS); break;
694 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STEP_PARMS); break;*/FIXME(mci, "NIY vcr\n"); return -2;
695 case MCI_DEVTYPE_VIDEODISC: size = sizeof(MCI_VD_STEP_PARMS); break;
696 default: size = sizeof(MCI_GENERIC_PARMS); break;
700 size = sizeof(MCI_SET_PARMS);
704 LPMCI_SYSINFO_PARMSA msip32a = (LPMCI_SYSINFO_PARMSA)(*lParam);
705 char* ptr = SEGPTR_ALLOC(sizeof(LPMCI_SYSINFO_PARMSA) + sizeof(MCI_SYSINFO_PARMS16));
706 LPMCI_SYSINFO_PARMS16 msip16;
709 *(LPMCI_SYSINFO_PARMSA*)(ptr) = msip32a;
710 msip16 = (LPMCI_SYSINFO_PARMS16)(ptr + sizeof(LPMCI_SYSINFO_PARMSA));
712 msip16->dwCallback = msip32a->dwCallback;
713 msip16->lpstrReturn = (LPSTR)SEGPTR_GET(SEGPTR_ALLOC(msip32a->dwRetSize));
714 msip16->dwRetSize = msip32a->dwRetSize;
715 msip16->dwNumber = msip32a->dwNumber;
716 msip16->wDeviceType = msip32a->wDeviceType;
720 *lParam = (LPARAM)SEGPTR_GET(ptr) + sizeof(LPMCI_SYSINFO_PARMSA);
726 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS); FIXME(mci, "NIY rect\n"); return -2;
727 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); FIXME(mci, "NIY rect\n"); return -2;
728 default: size = sizeof(MCI_GENERIC_PARMS); break;
733 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_UPDATE_PARMS); FIXME(mci, "NIY rect\n"); return -2;
734 default: size = sizeof(MCI_GENERIC_PARMS); break;
739 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_RECT_PARMS); FIXME(mci, "NIY rect\n"); return -2;
740 case MCI_DEVTYPE_OVERLAY: size = sizeof(MCI_OVLY_RECT_PARMS); FIXME(mci, "NIY rect\n"); return -2;
741 default: size = sizeof(MCI_GENERIC_PARMS); break;
746 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_WINDOW_PARMS16); FIXME(mci, "NIY lpstrText\n"); return -2;
747 case MCI_DEVTYPE_OVERLAY: /*size = sizeof(MCI_OVLY_WINDOW_PARMS); FIXME(mci, "NIY lpstrText\n"); return -2;*/
748 FIXME(mci, "NIY ovly\n"); return -2;
749 default: size = sizeof(MCI_GENERIC_PARMS); break;
759 case DRV_QUERYCONFIGURE:
762 case DRV_EXITSESSION:
763 case DRV_EXITAPPLICATION:
765 FIXME(mci, "This is a hack\n");
769 WARN(mci, "Don't know how to map msg=%s\n", MCI_CommandToString(wMsg));
772 return MCI_MsgMapper32To16_Create((void**)lParam, size, keep);
775 /**************************************************************************
776 * MCI_UnMapMsg32ATo16 [internal]
778 int MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD lParam)
781 BOOLEAN kept = FALSE; /* there is no need to compute size when kept is FALSE */
784 /* case MCI_CAPTURE */
786 case MCI_CLOSE_DRIVER:
788 /* case MCI_CONFIGURE:*/
795 /* case MCI_ESCAPE: */
800 size = sizeof(MCI_GETDEVCAPS_PARMS);
802 /* case MCI_INDEX: */
805 LPMCI_INFO_PARMS16 mip16 = (LPMCI_INFO_PARMS16)PTR_SEG_TO_LIN(lParam);
806 LPMCI_INFO_PARMSA mip32a = *(LPMCI_INFO_PARMSA*)((char*)mip16 - sizeof(LPMCI_INFO_PARMSA));
808 memcpy(mip32a->lpstrReturn, PTR_SEG_TO_LIN(mip16->lpstrReturn), mip32a->dwRetSize);
810 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(mip16->lpstrReturn)))
811 FIXME(mci, "bad free line=%d\n", __LINE__);
812 if (!SEGPTR_FREE((char*)mip16 - sizeof(LPMCI_INFO_PARMSA)))
813 FIXME(mci, "bad free line=%d\n", __LINE__);
817 /* case MCI_MONITOR: */
819 case MCI_OPEN_DRIVER:
821 LPMCI_OPEN_PARMS16 mop16 = (LPMCI_OPEN_PARMS16)PTR_SEG_TO_LIN(lParam);
822 LPMCI_OPEN_PARMSA mop32a = *(LPMCI_OPEN_PARMSA*)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSA));
824 mop32a->wDeviceID = mop16->wDeviceID;
825 if ((dwFlags & MCI_OPEN_TYPE) && !
826 (dwFlags & MCI_OPEN_TYPE_ID) &&
827 !SEGPTR_FREE(PTR_SEG_TO_LIN(mop16->lpstrDeviceType)))
828 FIXME(mci, "bad free line=%d\n", __LINE__);
829 if ((dwFlags & MCI_OPEN_ELEMENT) &&
830 !(dwFlags & MCI_OPEN_ELEMENT_ID) &&
831 !SEGPTR_FREE(PTR_SEG_TO_LIN(mop16->lpstrElementName)))
832 FIXME(mci, "bad free line=%d\n", __LINE__);
833 if ((dwFlags & MCI_OPEN_ALIAS) &&
834 !SEGPTR_FREE(PTR_SEG_TO_LIN(mop16->lpstrAlias)))
835 FIXME(mci, "bad free line=%d\n", __LINE__);
837 if (!SEGPTR_FREE((LPVOID)((char*)mop16 - sizeof(LPMCI_OPEN_PARMSA))))
838 FIXME(mci, "bad free line=%d\n", __LINE__);
858 /* case MCI_SETTIMECODE:*/
859 /* case MCI_SIGNAL:*/
865 case MCI_DEVTYPE_DIGITAL_VIDEO: size = sizeof(MCI_DGV_STATUS_PARMS16); FIXME(mci, "NIY lpstrDevice\n");return -2;
866 case MCI_DEVTYPE_VCR: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME(mci, "NIY vcr\n"); return -2;
867 default: size = sizeof(MCI_STATUS_PARMS); break;
876 LPMCI_SYSINFO_PARMS16 msip16 = (LPMCI_SYSINFO_PARMS16)PTR_SEG_TO_LIN(lParam);
877 LPMCI_SYSINFO_PARMSA msip32a = *(LPMCI_SYSINFO_PARMSA*)((char*)msip16 - sizeof(LPMCI_SYSINFO_PARMSA));
880 msip16->dwCallback = msip32a->dwCallback;
881 memcpy(msip32a->lpstrReturn, PTR_SEG_TO_LIN(msip16->lpstrReturn), msip32a->dwRetSize);
882 if (!SEGPTR_FREE(msip16->lpstrReturn))
883 FIXME(mci, "bad free line=%d\n", __LINE__);
885 if (!SEGPTR_FREE((LPVOID)(lParam - sizeof(LPMCI_SYSINFO_PARMSA))))
886 FIXME(mci, "bad free line=%d\n", __LINE__);
900 /* FIXME: see map function */
910 case DRV_QUERYCONFIGURE:
913 case DRV_EXITSESSION:
914 case DRV_EXITAPPLICATION:
916 FIXME(mci, "This is a hack\n");
919 FIXME(mci, "Map/Unmap internal error on msg=%s\n", MCI_CommandToString(wMsg));
922 return MCI_MsgMapper32To16_Destroy((void*)lParam, size, kept);
925 /**************************************************************************
926 * MCI_SendCommand [internal]
928 DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
930 DWORD dwRet = MCIERR_DEVICE_NOT_INSTALLED;
932 if (!MCI_DevIDValid(wDevID)) {
933 dwRet = MCIERR_INVALID_DEVICE_ID;
935 MCIPROC proc = MCI_GetProc(MCI_GetDrv(wDevID)->modp.wType);
938 dwRet = (*proc)(MCI_GetDrv(wDevID)->modp.wDeviceID,
939 MCI_GetDrv(wDevID)->hDrv,
940 wMsg, dwParam1, dwParam2);
941 } else if (MCI_GetDrv(wDevID)->hDrv) {
942 switch (DRIVER_GetType(MCI_GetDrv(wDevID)->hDrv)) {
943 case WINE_DI_TYPE_16:
947 switch (res = MCI_MapMsg32ATo16(MCI_GetDrv(wDevID)->modp.wType, wMsg, dwParam1, &dwParam2)) {
949 TRACE(mci, "Not handled yet (%s)\n", MCI_CommandToString(wMsg));
950 dwRet = MCIERR_DRIVER_INTERNAL;
953 TRACE(mci, "Problem mapping msg=%s from 16 to 32a\n", MCI_CommandToString(wMsg));
954 dwRet = MCIERR_OUT_OF_MEMORY;
958 dwRet = SendDriverMessage16(MCI_GetDrv(wDevID)->hDrv, wMsg, dwParam1, dwParam2);
960 MCI_UnMapMsg32ATo16(MCI_GetDrv(wDevID)->modp.wType, wMsg, dwParam1, dwParam2);
965 case WINE_DI_TYPE_32:
966 dwRet = SendDriverMessage(MCI_GetDrv(wDevID)->hDrv, wMsg, dwParam1, dwParam2);
969 WARN(mci, "Unknown driver type=%u\n", DRIVER_GetType(MCI_GetDrv(wDevID)->hDrv));
970 dwRet = MCIERR_DRIVER_INTERNAL;
973 WARN(mci, "unknown device type=%04X !\n", MCI_GetDrv(wDevID)->modp.wType);
979 /**************************************************************************
980 * MCI_Open [internal]
982 DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSA lpParms)
986 UINT16 wDevID = MCI_FirstDevID();
989 TRACE(mci, "(%08lX, %p)\n", dwParam, lpParms);
990 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
992 if ((dwParam & ~(MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT|MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_NOTIFY|MCI_WAIT)) != 0) {
993 FIXME(mci, "unsupported yet dwFlags=%08lX\n",
994 (dwParam & ~(MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT|MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID|MCI_NOTIFY|MCI_WAIT)));
997 while (MCI_GetDrv(wDevID)->modp.wType != 0) {
998 wDevID = MCI_NextDevID(wDevID);
999 if (!MCI_DevIDValid(wDevID)) {
1000 TRACE(mci, "MAXMCIDRIVERS reached !\n");
1001 return MCIERR_OUT_OF_MEMORY;
1005 TRACE(mci, "wDevID=%04X \n", wDevID);
1006 memcpy(MCI_GetOpenDrv(wDevID), lpParms, sizeof(*lpParms));
1010 if (dwParam & MCI_OPEN_ELEMENT) {
1013 TRACE(mci, "lpstrElementName='%s'\n", lpParms->lpstrElementName);
1014 t = strrchr(lpParms->lpstrElementName, '.');
1016 GetProfileStringA("mci extensions", t+1, "*", strDevTyp, sizeof(strDevTyp));
1017 if (strcmp(strDevTyp, "*") == 0) {
1018 TRACE(mci,"No [mci extensions] entry for %s found.\n", t);
1019 return MCIERR_EXTENSION_NOT_FOUND;
1021 TRACE(mci, "Extension %s is mapped to type %s\n", t, strDevTyp);
1022 } else if (GetDriveTypeA(lpParms->lpstrElementName) == DRIVE_CDROM) {
1023 /* FIXME: this will not work if several CDROM drives are installed on the machine */
1024 strcpy(strDevTyp, "CDAUDIO");
1026 return MCIERR_EXTENSION_NOT_FOUND;
1030 if (dwParam & MCI_OPEN_ALIAS) {
1031 TRACE(mci, "Alias='%s' !\n", lpParms->lpstrAlias);
1032 /* FIXME is there any memory leak here ? */
1033 MCI_GetOpenDrv(wDevID)->lpstrAlias = strdup(lpParms->lpstrAlias);
1034 /* mplayer does allocate alias to CDAUDIO */
1036 if (dwParam & MCI_OPEN_TYPE) {
1037 if (dwParam & MCI_OPEN_TYPE_ID) {
1039 TRACE(mci, "Dev=%08lx!\n", (DWORD)lpParms->lpstrDeviceType);
1040 uDevType = LOWORD((DWORD)lpParms->lpstrDeviceType);
1041 MCI_GetOpenDrv(wDevID)->lpstrDeviceType = lpParms->lpstrDeviceType;
1043 if (LOWORD((DWORD)lpParms->lpstrDeviceType) != MCI_DEVTYPE_CD_AUDIO) {
1044 FIXME(mci, "MCI_OPEN_TYPE_ID is no longer properly supported\n");
1046 uDevType = LOWORD((DWORD)lpParms->lpstrDeviceType);
1048 if (lpParms->lpstrDeviceType == NULL)
1049 return MCIERR_NULL_PARAMETER_BLOCK;
1050 TRACE(mci, "Dev='%s' !\n", lpParms->lpstrDeviceType);
1051 /* FIXME is there any memory leak here ? */
1052 MCI_GetOpenDrv(wDevID)->lpstrDeviceType = strdup(lpParms->lpstrDeviceType);
1053 strcpy(strDevTyp, lpParms->lpstrDeviceType);
1057 if (uDevType == 0 && strDevTyp[0] != 0) {
1058 CharUpperA(strDevTyp);
1059 /* try Wine internal MCI drivers */
1060 uDevType = MCI_GetDevType(strDevTyp);
1061 if (uDevType == 0) { /* Nope, load external */
1063 MCI_OPEN_DRIVER_PARMSA modp;
1065 modp.wDeviceID = wDevID;
1066 modp.lpstrParams = NULL;
1068 /* FIXME: this is a hack... some MCI drivers, while being open, call
1069 * mciSetData, which lookup for non empty slots in MCI table list
1070 * Unfortunatly, open slots are known when wType == 0...
1071 * so use a dummy type, just to keep on going. May be wType == 0 is
1072 * not the best solution to indicate empty slot in MCI drivers table
1074 MCI_GetDrv(wDevID)->modp.wType = MCI_DEVTYPE_CD_AUDIO;
1075 hDrv = OpenDriverA(strDevTyp, "mci", (LPARAM)&modp);
1078 FIXME(mci, "Couldn't load driver for type %s.\n", strDevTyp);
1079 return MCIERR_DEVICE_NOT_INSTALLED;
1081 uDevType = modp.wType;
1082 MCI_GetDrv(wDevID)->hDrv = hDrv;
1084 TRACE(mci, "Loaded driver %u (%s), type is %d\n", hDrv, strDevTyp, uDevType);
1087 MCI_GetDrv(wDevID)->hDrv = 0;
1090 MCI_GetDrv(wDevID)->modp.wType = uDevType;
1091 MCI_GetDrv(wDevID)->modp.wDeviceID = 0; /* FIXME? for multiple devices */
1093 lpParms->wDeviceID = wDevID;
1095 TRACE(mci, "mcidev=%d, uDevType=%04X wDeviceID=%04X !\n",
1096 wDevID, uDevType, lpParms->wDeviceID);
1098 dwRet = MCI_SendCommand(wDevID, MCI_OPEN_DRIVER, dwParam, (DWORD)lpParms);
1099 MCI_GetDrv(wDevID)->lpfnYieldProc = 0;
1100 MCI_GetDrv(wDevID)->dwYieldData = 0;
1101 MCI_GetDrv(wDevID)->hCreatorTask = GetCurrentTask();
1104 /* only handled devices fall through */
1105 TRACE(mci, "wDevID = %04X wDeviceID = %d dwRet = %ld\n", wDevID, lpParms->wDeviceID, dwRet);
1107 TRACE(mci, "failed to open driver (MCI_OPEN_DRIVER msg) [%08lx], closing\n", dwRet);
1108 MCI_GetDrv(wDevID)->modp.wType = 0;
1110 if (dwParam & MCI_NOTIFY)
1111 mciDriverNotify16(lpParms->dwCallback, wDevID, dwRet == 0 ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
1116 /**************************************************************************
1117 * MCI_Close [internal]
1119 DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
1123 TRACE(mci, "(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms);
1125 if (wDevID == MCI_ALL_DEVICE_ID) {
1126 FIXME(mci, "unhandled MCI_ALL_DEVICE_ID\n");
1127 return MCIERR_CANNOT_USE_ALL;
1130 dwRet = MCI_SendCommand(wDevID, MCI_CLOSE_DRIVER, dwParam, (DWORD)lpParms);
1131 if (MCI_GetDrv(wDevID)->hDrv) {
1133 CloseDriver(MCI_GetDrv(wDevID)->hDrv, 0, 0);
1136 MCI_GetDrv(wDevID)->modp.wType = 0;
1138 if (dwParam & MCI_NOTIFY)
1139 mciDriverNotify16(lpParms->dwCallback, wDevID,
1140 (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
1145 /**************************************************************************
1146 * MCI_WriteString [internal]
1148 DWORD MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr)
1152 if (dstSize <= strlen(lpSrcStr)) {
1153 lstrcpynA(lpDstStr, lpSrcStr, dstSize - 1);
1154 ret = MCIERR_PARAM_OVERFLOW;
1156 strcpy(lpDstStr, lpSrcStr);
1162 /**************************************************************************
1163 * MCI_Sysinfo [internal]
1165 DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParms)
1167 DWORD ret = MCIERR_INVALID_DEVICE_ID;
1169 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1171 TRACE(mci, "(%08x, %08lX, %08lX[num=%ld, wDevTyp=%u])\n",
1172 uDevID, dwFlags, (DWORD)lpParms, lpParms->dwNumber, lpParms->wDeviceType);
1174 switch (dwFlags & ~MCI_SYSINFO_OPEN) {
1175 case MCI_SYSINFO_QUANTITY:
1180 if (lpParms->wDeviceType < MCI_DEVTYPE_FIRST || lpParms->wDeviceType > MCI_DEVTYPE_LAST) {
1181 if (dwFlags & MCI_SYSINFO_OPEN) {
1182 TRACE(mci, "MCI_SYSINFO_QUANTITY: # of open MCI drivers\n");
1183 for (i = 0; i < MAXMCIDRIVERS; i++) {
1184 if (mciDrv[i].modp.wType != 0) cnt++;
1187 TRACE(mci, "MCI_SYSINFO_QUANTITY: # of installed MCI drivers\n");
1188 cnt = mciInstalledCount;
1191 if (dwFlags & MCI_SYSINFO_OPEN) {
1192 TRACE(mci, "MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n", lpParms->wDeviceType);
1193 for (i = 0; i < MAXMCIDRIVERS; i++) {
1194 if (mciDrv[i].modp.wType == lpParms->wDeviceType) cnt++;
1197 TRACE(mci, "MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %u\n", lpParms->wDeviceType);
1198 FIXME(mci, "Don't know how to get # of MCI devices of a given type\n");
1202 *(DWORD*)lpParms->lpstrReturn = cnt;
1204 TRACE(mci, "(%ld) => '%ld'\n", lpParms->dwNumber, *(DWORD*)lpParms->lpstrReturn);
1207 case MCI_SYSINFO_INSTALLNAME:
1208 TRACE(mci, "MCI_SYSINFO_INSTALLNAME \n");
1209 if (MCI_DevIDValid(uDevID)) {
1210 LPCSTR str = MCI_GetDevTypeString(MCI_GetDrv(uDevID)->modp.wType);
1211 ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, str);
1213 *lpParms->lpstrReturn = 0;
1214 ret = MCIERR_INVALID_DEVICE_ID;
1216 TRACE(mci, "(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
1218 case MCI_SYSINFO_NAME:
1219 TRACE(mci, "MCI_SYSINFO_NAME\n");
1220 if (dwFlags & MCI_SYSINFO_OPEN) {
1221 FIXME(mci, "Don't handle MCI_SYSINFO_NAME|MCI_SYSINFO_OPEN (yet)\n");
1222 ret = MCIERR_UNRECOGNIZED_COMMAND;
1223 } else if (lpParms->dwNumber > mciInstalledCount) {
1224 ret = MCIERR_OUTOFRANGE;
1226 DWORD count = lpParms->dwNumber;
1227 LPSTR ptr = lpmciInstallNames;
1229 while (--count > 0) ptr += strlen(ptr) + 1;
1230 ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, ptr);
1232 TRACE(mci, "(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
1235 TRACE(mci, "Unsupported flag value=%08lx\n", dwFlags);
1236 ret = MCIERR_UNRECOGNIZED_COMMAND;
1249 DWORD WINAPI mciSendCommandA(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2);
1251 /**************************************************************************
1252 * MCI_SCAStarter [internal]
1254 static DWORD WINAPI MCI_SCAStarter(LPVOID arg)
1256 struct SCA* sca = (struct SCA*)arg;
1259 TRACE(mci, "In thread before async command (%08x,%s,%08lx,%08lx)\n",
1260 sca->wDevID, MCI_CommandToString(sca->wMsg), sca->dwParam1, sca->dwParam2);
1261 ret = mciSendCommandA(sca->wDevID, sca->wMsg, sca->dwParam1 | MCI_WAIT, sca->dwParam2);
1262 TRACE(mci, "In thread after async command (%08x,%s,%08lx,%08lx)\n",
1263 sca->wDevID, MCI_CommandToString(sca->wMsg), sca->dwParam1, sca->dwParam2);
1264 if (sca->allocatedCopy)
1265 HeapFree(GetProcessHeap(), 0, (LPVOID)sca->dwParam2);
1266 HeapFree(GetProcessHeap(), 0, sca);
1268 WARN(mci, "Should not happen ? what's wrong \n");
1269 /* should not go after this point */
1273 /**************************************************************************
1274 * MCI_SendCommandAsync [internal]
1276 DWORD MCI_SendCommandAsync(UINT wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2, UINT size)
1278 struct SCA* sca = HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA));
1281 return MCIERR_OUT_OF_MEMORY;
1283 sca->wDevID = wDevID;
1285 sca->dwParam1 = dwParam1;
1288 sca->dwParam2 = (DWORD)HeapAlloc(GetProcessHeap(), 0, size);
1289 if (sca->dwParam2 == 0) {
1290 HeapFree(GetProcessHeap(), 0, sca);
1291 return MCIERR_OUT_OF_MEMORY;
1293 sca->allocatedCopy = TRUE;
1294 /* copy structure passed by program in dwParam2 to be sure
1295 * we can still use it whatever the program does
1297 memcpy((LPVOID)sca->dwParam2, (LPVOID)dwParam2, size);
1299 sca->dwParam2 = dwParam2;
1300 sca->allocatedCopy = FALSE;
1303 if (CreateThread(NULL, 0, MCI_SCAStarter, sca, 0, NULL) == 0) {
1304 WARN(mci, "Couldn't allocate thread for async command handling, sending synchonously\n");
1305 return MCI_SCAStarter(&sca);
1310 /**************************************************************************
1311 * MCI_CleanUp [internal]
1313 * Some MCI commands need to be cleaned-up (when not called from
1314 * mciSendString), because MCI drivers return extra information for string
1315 * transformation. This function gets read of them.
1317 LRESULT MCI_CleanUp(LRESULT dwRet, UINT wMsg, DWORD dwParam2, BOOL bIs32)
1320 case MCI_GETDEVCAPS:
1321 switch (dwRet & 0xFFFF0000ul) {
1324 case MCI_RESOURCE_RETURNED:
1325 case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
1326 case MCI_COLONIZED3_RETURN:
1327 case MCI_COLONIZED4_RETURN:
1328 case MCI_INTEGER_RETURNED:
1330 LPMCI_GETDEVCAPS_PARMS lmgp = (LPMCI_GETDEVCAPS_PARMS)(bIs32 ? (void*)dwParam2 : PTR_SEG_TO_LIN(dwParam2));
1332 dwRet = LOWORD(dwRet);
1333 TRACE(mci, "Changing %08lx to %08lx\n", lmgp->dwReturn, (DWORD)LOWORD(lmgp->dwReturn));
1335 lmgp->dwReturn = LOWORD(lmgp->dwReturn);
1339 FIXME(mci, "Unsupported value for hiword (%04x) returned by DriverProc\n", HIWORD(dwRet));
1343 switch (dwRet & 0xFFFF0000ul) {
1346 case MCI_RESOURCE_RETURNED:
1347 case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
1348 case MCI_COLONIZED3_RETURN:
1349 case MCI_COLONIZED4_RETURN:
1350 case MCI_INTEGER_RETURNED:
1352 LPMCI_STATUS_PARMS lsp = (LPMCI_STATUS_PARMS)(bIs32 ? (void*)dwParam2 : PTR_SEG_TO_LIN(dwParam2));
1354 dwRet = LOWORD(dwRet);
1355 TRACE(mci, "Changing %08lx to %08lx\n", lsp->dwReturn,(DWORD) LOWORD(lsp->dwReturn));
1356 lsp->dwReturn = LOWORD(lsp->dwReturn);
1360 FIXME(mci, "Unsupported value for hiword (%04x) returned by DriverProc\n", HIWORD(dwRet));