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"
21 struct WINE_MCIDRIVER mciDrv
[MAXMCIDRIVERS
];
23 int mciInstalledCount
;
24 int mciInstalledListLen
;
25 LPSTR lpmciInstallNames
= NULL
;
27 /* The wDevID's returned by wine were originally in the range
28 * 0 - (MAXMCIDRIVERS - 1) and used directly as array indices.
29 * Unfortunately, ms-windows uses wDevID of zero to indicate
30 * errors. Now, multimedia drivers must pass the wDevID through
31 * MCI_DevIDToIndex to get an index in that range. An
32 * arbitrary value, MCI_MAGIC is added to the wDevID seen
33 * by the windows programs.
36 #define MCI_MAGIC 0x0F00
38 MCI_WineDesc MCI_InternalDescriptors
[] = {
39 {MCI_DEVTYPE_CD_AUDIO
, "CDAUDIO", MCICDAUDIO_DriverProc
},
40 {MCI_DEVTYPE_WAVEFORM_AUDIO
, "WAVEAUDIO", MCIWAVE_DriverProc
},
41 {MCI_DEVTYPE_SEQUENCER
, "SEQUENCER", MCIMIDI_DriverProc
},
42 {MCI_DEVTYPE_ANIMATION
, "ANIMATION1", MCIANIM_DriverProc
},
43 {MCI_DEVTYPE_DIGITAL_VIDEO
, "AVIVIDEO", MCIAVI_DriverProc
},
45 {0xFFFF, NULL
, NULL
} /* sentinel */
48 /**************************************************************************
49 * MCI_GetDevTypeString [internal]
51 static LPCSTR
MCI_GetDevTypeString(WORD uDevType
)
53 LPCSTR str
= "??? MCI ???";
56 for (i
= 0; MCI_InternalDescriptors
[i
].uDevType
!= 0xFFFF; i
++) {
57 if (MCI_InternalDescriptors
[i
].uDevType
!= 0 && MCI_InternalDescriptors
[i
].uDevType
== uDevType
) {
58 str
= MCI_InternalDescriptors
[i
].lpstrName
;
62 /* TRACE(mci, "devType=%u => %s\n", uDevType, str);*/
66 /**************************************************************************
67 * MCI_GetProc [internal]
69 static MCIPROC
MCI_GetProc(UINT16 uDevType
)
74 for (i
= 0; MCI_InternalDescriptors
[i
].uDevType
!= 0xFFFF; i
++) {
75 if (MCI_InternalDescriptors
[i
].uDevType
!= 0 &&
76 MCI_InternalDescriptors
[i
].uDevType
== uDevType
) {
77 proc
= MCI_InternalDescriptors
[i
].lpfnProc
;
84 /**************************************************************************
85 * MCI_GetDevType [internal]
87 WORD
MCI_GetDevType(LPCSTR str
)
92 for (i
= 0; MCI_InternalDescriptors
[i
].uDevType
!= 0xFFFF; i
++) {
93 if (MCI_InternalDescriptors
[i
].uDevType
!= 0 &&
94 strcmp(str
, MCI_InternalDescriptors
[i
].lpstrName
) == 0) {
95 uDevType
= MCI_InternalDescriptors
[i
].uDevType
;
102 /**************************************************************************
103 * MCI_DevIDToIndex [internal]
105 int MCI_DevIDToIndex(UINT16 wDevID
)
107 return wDevID
- MCI_MAGIC
;
110 /**************************************************************************
111 * MCI_FirstDevId [internal]
113 UINT16
MCI_FirstDevID(void)
118 /**************************************************************************
119 * MCI_NextDevId [internal]
121 UINT16
MCI_NextDevID(UINT16 wDevID
)
126 /**************************************************************************
127 * MCI_DevIDValid [internal]
129 BOOL
MCI_DevIDValid(UINT16 wDevID
)
131 return wDevID
>= MCI_MAGIC
&& wDevID
< (MCI_MAGIC
+ MAXMCIDRIVERS
);
134 /**************************************************************************
135 * MCI_CommandToString [internal]
137 const char* MCI_CommandToString(UINT16 wMsg
)
139 static char buffer
[100];
141 #define CASE(s) case (s): return #s
146 CASE(MCI_CLOSE_DRIVER
);
155 CASE(MCI_GETDEVCAPS
);
159 CASE(MCI_OPEN_DRIVER
);
178 sprintf(buffer
, "MCI_<<%04X>>", wMsg
);
184 /**************************************************************************
185 * MCI_MapMsg16To32A [internal]
187 int MCI_MapMsg16To32A(WORD uDevType
, WORD wMsg
, DWORD
* lParam
)
191 /* FIXME: to add also (with seg/linear modifications to do):
192 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
193 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
196 /* case MCI_CAPTURE */
198 case MCI_CLOSE_DRIVER
:
199 /* case MCI_CONFIGURE:*/
206 /* case MCI_INDEX: */
208 /* case MCI_MONITOR: */
218 /* case MCI_SETTIMECODE:*/
219 /* case MCI_SIGNAL:*/
221 case MCI_STATUS
: /* FIXME: is wrong for digital video */
228 *lParam
= (DWORD
)PTR_SEG_TO_LIN(*lParam
);
231 /* in fact, I would also need the dwFlags... to see
232 * which members of lParam are effectively used
234 *lParam
= (DWORD
)PTR_SEG_TO_LIN(*lParam
);
235 FIXME(mci
, "Current mapping may be wrong\n");
239 LPMCI_BREAK_PARMS mbp32
= HeapAlloc(SystemHeap
, 0, sizeof(MCI_BREAK_PARMS
));
240 LPMCI_BREAK_PARMS16 mbp16
= PTR_SEG_TO_LIN(*lParam
);
243 mbp32
->dwCallback
= mbp16
->dwCallback
;
244 mbp32
->nVirtKey
= mbp16
->nVirtKey
;
245 mbp32
->hwndBreak
= mbp16
->hwndBreak
;
249 *lParam
= (DWORD
)mbp32
;
254 LPMCI_VD_ESCAPE_PARMSA mvep32a
= HeapAlloc(SystemHeap
, 0, sizeof(MCI_VD_ESCAPE_PARMSA
));
255 LPMCI_VD_ESCAPE_PARMS16 mvep16
= PTR_SEG_TO_LIN(*lParam
);
258 mvep32a
->dwCallback
= mvep16
->dwCallback
;
259 mvep32a
->lpstrCommand
= PTR_SEG_TO_LIN(mvep16
->lpstrCommand
);
263 *lParam
= (DWORD
)mvep32a
;
268 LPMCI_INFO_PARMSA mip32a
= HeapAlloc(SystemHeap
, 0, sizeof(MCI_INFO_PARMSA
));
269 LPMCI_INFO_PARMS16 mip16
= PTR_SEG_TO_LIN(*lParam
);
271 /* FIXME this is wrong if device is of type
272 * MCI_DEVTYPE_DIGITAL_VIDEO, some members are not mapped
275 mip32a
->dwCallback
= mip16
->dwCallback
;
276 mip32a
->lpstrReturn
= PTR_SEG_TO_LIN(mip16
->lpstrReturn
);
277 mip32a
->dwRetSize
= mip16
->dwRetSize
;
281 *lParam
= (DWORD
)mip32a
;
285 case MCI_OPEN_DRIVER
:
287 LPMCI_OPEN_PARMSA mop32a
= HeapAlloc(SystemHeap
, 0, sizeof(LPMCI_OPEN_PARMS16
) + sizeof(MCI_OPEN_PARMSA
) + 2 * sizeof(DWORD
));
288 LPMCI_OPEN_PARMS16 mop16
= PTR_SEG_TO_LIN(*lParam
);
291 *(LPMCI_OPEN_PARMS16
*)(mop32a
) = mop16
;
292 mop32a
= (LPMCI_OPEN_PARMSA
)((char*)mop32a
+ sizeof(LPMCI_OPEN_PARMS16
));
293 mop32a
->dwCallback
= mop16
->dwCallback
;
294 mop32a
->wDeviceID
= mop16
->wDeviceID
;
295 mop32a
->lpstrDeviceType
= PTR_SEG_TO_LIN(mop16
->lpstrDeviceType
);
296 mop32a
->lpstrElementName
= PTR_SEG_TO_LIN(mop16
->lpstrElementName
);
297 mop32a
->lpstrAlias
= PTR_SEG_TO_LIN(mop16
->lpstrAlias
);
298 /* copy extended information if any...
299 * FIXME: this may seg fault if initial structure does not contain them and
300 * the reads after msip16 fail under LDT limits...
301 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
302 * should not take care of extended parameters, and should be used by MCI_Open
303 * to fetch uDevType. When, this is known, the mapping for sending the
304 * MCI_OPEN_DRIVER shall be done depending on uDevType.
306 memcpy(mop32a
+ 1, mop16
+ 1, 2 * sizeof(DWORD
));
310 *lParam
= (DWORD
)mop32a
;
315 LPMCI_SYSINFO_PARMSA msip32a
= HeapAlloc(SystemHeap
, 0, sizeof(MCI_SYSINFO_PARMSA
));
316 LPMCI_SYSINFO_PARMS16 msip16
= PTR_SEG_TO_LIN(*lParam
);
319 msip32a
->dwCallback
= msip16
->dwCallback
;
320 msip32a
->lpstrReturn
= PTR_SEG_TO_LIN(msip16
->lpstrReturn
);
321 msip32a
->dwRetSize
= msip16
->dwRetSize
;
322 msip32a
->dwNumber
= msip16
->dwNumber
;
323 msip32a
->wDeviceType
= msip16
->wDeviceType
;
327 *lParam
= (DWORD
)msip32a
;
337 case DRV_QUERYCONFIGURE
:
340 case DRV_EXITSESSION
:
341 case DRV_EXITAPPLICATION
:
343 FIXME(mci
, "This is a hack\n");
347 WARN(mci
, "Don't know how to map msg=%s\n", MCI_CommandToString(wMsg
));
352 /**************************************************************************
353 * MCI_UnMapMsg16To32A [internal]
355 int MCI_UnMapMsg16To32A(WORD uDevType
, WORD wMsg
, DWORD lParam
)
358 /* case MCI_CAPTURE */
360 case MCI_CLOSE_DRIVER
:
361 /* case MCI_CONFIGURE:*/
368 /* case MCI_INDEX: */
370 /* case MCI_MONITOR: */
380 /* case MCI_SETTIMECODE:*/
381 /* case MCI_SIGNAL:*/
393 /* FIXME ?? see Map function */
400 HeapFree(SystemHeap
, 0, (LPVOID
)lParam
);
403 case MCI_OPEN_DRIVER
:
405 LPMCI_OPEN_PARMSA mop32a
= (LPMCI_OPEN_PARMSA
)lParam
;
406 LPMCI_OPEN_PARMS16 mop16
= *(LPMCI_OPEN_PARMS16
*)((char*)mop32a
- sizeof(LPMCI_OPEN_PARMS16
*));
408 mop16
->wDeviceID
= mop32a
->wDeviceID
;
409 if (!HeapFree(SystemHeap
, 0, (LPVOID
)(lParam
- sizeof(LPMCI_OPEN_PARMS16
))))
410 FIXME(mci
, "bad free line=%d\n", __LINE__
);
420 case DRV_QUERYCONFIGURE
:
423 case DRV_EXITSESSION
:
424 case DRV_EXITAPPLICATION
:
426 FIXME(mci
, "This is a hack\n");
429 FIXME(mci
, "Map/Unmap internal error on msg=%s\n", MCI_CommandToString(wMsg
));
434 /**************************************************************************
435 * MCI_MsgMapper32To16_Create [internal]
437 * Helper for MCI_MapMsg32ATo16.
438 * Maps the 32 bit pointer (*ptr), of size bytes, to an allocated 16 bit segmented pointer.
439 * if keep is TRUE, keeps track of in 32 bit ptr in allocated 16 bit area.
440 * 1 : ok, some memory allocated
441 * -2 : ko, memory problem
443 static int MCI_MsgMapper32To16_Create(void** ptr
, int size
, BOOLEAN keep
)
445 void* lp
= SEGPTR_ALLOC(sizeof(void**) + size
);
452 memcpy((char*)lp
+ sizeof(void**), *ptr
, size
);
453 *ptr
= (char*)SEGPTR_GET(lp
) + sizeof(void**);
455 memcpy((char*)lp
, *ptr
, size
);
456 *ptr
= (void*)SEGPTR_GET(lp
);
462 /**************************************************************************
463 * MCI_MsgMapper32To16_Destroy [internal]
465 * Helper for MCI_UnMapMsg32ATo16.
467 static int MCI_MsgMapper32To16_Destroy(void* ptr
, int size
, BOOLEAN kept
)
470 void* msg16
= PTR_SEG_TO_LIN(ptr
);
474 alloc
= (char*)msg16
- sizeof(void**);
475 memcpy(*(void**)alloc
, msg16
, size
);
480 if (!SEGPTR_FREE(alloc
)) {
481 FIXME(mci
, "bad free\n");
487 /**************************************************************************
488 * MCI_MapMsg32ATo16 [internal]
490 * Map a 32-A bit MCI message to a 16 bit MCI message.
491 * 1 : ok, some memory allocated, need to call MCI_UnMapMsg32ATo16
492 * 0 : ok, no memory allocated
493 * -1 : ko, unknown message
494 * -2 : ko, memory problem
496 int MCI_MapMsg32ATo16(WORD uDevType
, WORD wMsg
, DWORD dwFlags
, DWORD
* lParam
)
499 BOOLEAN keep
= FALSE
;
503 /* FIXME: to add also (with seg/linear modifications to do):
504 * MCI_LIST, MCI_LOAD, MCI_QUALITY, MCI_RESERVE, MCI_RESTORE, MCI_SAVE
505 * MCI_SETAUDIO, MCI_SETTUNER, MCI_SETVIDEO
508 /* case MCI_BREAK: */
509 /* case MCI_CAPTURE */
511 case MCI_CLOSE_DRIVER
:
512 size
= sizeof(MCI_GENERIC_PARMS
);
514 /* case MCI_CONFIGURE:*/
518 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_CUE_PARMS
); break;
519 case MCI_DEVTYPE_VCR
: /*size = sizeof(MCI_VCR_CUE_PARMS); break;*/ FIXME(mci
, "NIY vcr\n"); return -2;
520 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
526 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_DELETE_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
527 case MCI_DEVTYPE_WAVEFORM_AUDIO
:size
= sizeof(MCI_WAVE_DELETE_PARMS
); break;
528 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
531 /* case MCI_ESCAPE: */
534 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_FREEZE_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
535 case MCI_DEVTYPE_OVERLAY
: /*size = sizeof(MCI_OVLY_FREEZE_PARMS); FIXME(mci, "NIY rect\n"); return -2;*/
536 FIXME(mci
, "NIY ovly\n"); return -2;
537 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
542 size
= sizeof(MCI_GETDEVCAPS_PARMS
);
544 /* case MCI_INDEX: */
547 LPMCI_INFO_PARMSA mip32a
= (LPMCI_INFO_PARMSA
)(*lParam
);
549 LPMCI_INFO_PARMS16 mip16
;
552 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_INFO_PARMS16
); break;
553 default: size
= sizeof(MCI_INFO_PARMS16
); break;
555 ptr
= SEGPTR_ALLOC(sizeof(LPMCI_INFO_PARMSA
) + size
);
558 *(LPMCI_INFO_PARMSA
*)ptr
= mip32a
;
559 mip16
= (LPMCI_INFO_PARMS16
)(ptr
+ sizeof(LPMCI_INFO_PARMSA
));
560 mip16
->dwCallback
= mip32a
->dwCallback
;
561 mip16
->lpstrReturn
= (LPSTR
)SEGPTR_GET(SEGPTR_ALLOC(mip32a
->dwRetSize
));
562 mip16
->dwRetSize
= mip32a
->dwRetSize
;
563 if (uDevType
== MCI_DEVTYPE_DIGITAL_VIDEO
) {
564 ((LPMCI_DGV_INFO_PARMS16
)mip16
)->dwItem
= ((LPMCI_DGV_INFO_PARMSA
)mip32a
)->dwItem
;
569 *lParam
= (LPARAM
)SEGPTR_GET(ptr
) + sizeof(LPMCI_INFO_PARMSA
);
573 /* case MCI_MONITOR: */
575 case MCI_OPEN_DRIVER
:
577 LPMCI_OPEN_PARMSA mop32a
= (LPMCI_OPEN_PARMSA
)(*lParam
);
578 char* ptr
= SEGPTR_ALLOC(sizeof(LPMCI_OPEN_PARMSA
) + sizeof(MCI_OPEN_PARMS16
) + 2 * sizeof(DWORD
));
579 LPMCI_OPEN_PARMS16 mop16
;
583 *(LPMCI_OPEN_PARMSA
*)(ptr
) = mop32a
;
584 mop16
= (LPMCI_OPEN_PARMS16
)(ptr
+ sizeof(LPMCI_OPEN_PARMSA
));
585 mop16
->dwCallback
= mop32a
->dwCallback
;
586 mop16
->wDeviceID
= mop32a
->wDeviceID
;
587 if (dwFlags
& MCI_OPEN_TYPE
) {
588 if (dwFlags
& MCI_OPEN_TYPE_ID
) {
589 /* dword "transparent" value */
590 mop16
->lpstrDeviceType
= mop32a
->lpstrDeviceType
;
593 mop16
->lpstrDeviceType
= mop32a
->lpstrDeviceType
? (LPSTR
)SEGPTR_GET(SEGPTR_STRDUP(mop32a
->lpstrDeviceType
)) : 0;
597 mop16
->lpstrDeviceType
= 0;
599 if (dwFlags
& MCI_OPEN_ELEMENT
) {
600 if (dwFlags
& MCI_OPEN_ELEMENT_ID
) {
601 mop16
->lpstrElementName
= mop32a
->lpstrElementName
;
603 mop16
->lpstrElementName
= mop32a
->lpstrElementName
? (LPSTR
)SEGPTR_GET(SEGPTR_STRDUP(mop32a
->lpstrElementName
)) : 0;
606 mop16
->lpstrElementName
= 0;
608 if (dwFlags
& MCI_OPEN_ALIAS
) {
609 mop16
->lpstrAlias
= mop32a
->lpstrAlias
? (LPSTR
)SEGPTR_GET(SEGPTR_STRDUP(mop32a
->lpstrAlias
)) : 0;
611 mop16
->lpstrAlias
= 0;
613 /* copy extended information if any...
614 * FIXME: this may seg fault if initial structure does not contain them and
615 * the reads after msip16 fail under LDT limits...
616 * NOTE: this should be split in two. First pass, while calling MCI_OPEN, and
617 * should not take care of extended parameters, and should be used by MCI_Open
618 * to fetch uDevType. When, this is known, the mapping for sending the
619 * MCI_OPEN_DRIVER shall be done depending on uDevType.
621 memcpy(mop16
+ 1, mop32a
+ 1, 2 * sizeof(DWORD
));
625 *lParam
= (LPARAM
)SEGPTR_GET(ptr
) + sizeof(LPMCI_OPEN_PARMSA
);
630 size
= sizeof(MCI_GENERIC_PARMS
);
634 case MCI_DEVTYPE_OVERLAY
: /*size = sizeof(MCI_OVLY_PLAY_PARMS); break;*/FIXME(mci
, "NIY ovly\n"); return -2;
635 default: size
= sizeof(MCI_PLAY_PARMS
); break;
640 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_PUT_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
641 case MCI_DEVTYPE_OVERLAY
: /*size = sizeof(MCI_OVLY_PUT_PARMS); FIXME(mci, "NIY rect\n"); return -2;*/
642 FIXME(mci
, "NIY ovly\n"); return -2;
643 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
647 size
= sizeof(MCI_GENERIC_PARMS
);
651 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_RECORD_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
652 case MCI_DEVTYPE_VCR
: /*size = sizeof(MCI_VCR_RECORD_PARMS); break;*/FIXME(mci
, "NIY vcr\n"); return -2;
653 default: size
= sizeof(MCI_RECORD_PARMS
); break;
657 size
= sizeof(MCI_GENERIC_PARMS
);
661 case MCI_DEVTYPE_VCR
: /*size = sizeof(MCI_VCR_SEEK_PARMS); break;*/FIXME(mci
, "NIY vcr\n"); return -2;
662 default: size
= sizeof(MCI_SEEK_PARMS
); break;
667 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_SET_PARMS
); break;
668 case MCI_DEVTYPE_VCR
: /*size = sizeof(MCI_VCR_SET_PARMS); break;*/FIXME(mci
, "NIY vcr\n"); return -2;
669 case MCI_DEVTYPE_SEQUENCER
: size
= sizeof(MCI_SEQ_SET_PARMS
); break;
670 /* FIXME: normally the 16 and 32 bit structures are byte by byte aligned,
671 * so not doing anything should work...
673 case MCI_DEVTYPE_WAVEFORM_AUDIO
:size
= sizeof(MCI_WAVE_SET_PARMS
); break;
674 default: size
= sizeof(MCI_SET_PARMS
); break;
677 /* case MCI_SETTIMECODE:*/
678 /* case MCI_SIGNAL:*/
680 size
= sizeof(MCI_SET_PARMS
);
685 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_STATUS_PARMS16
); FIXME(mci
, "NIY lpstrDevice\n");return -2;
686 case MCI_DEVTYPE_VCR
: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME(mci
, "NIY vcr\n"); return -2;
687 default: size
= sizeof(MCI_STATUS_PARMS
); break;
692 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_STEP_PARMS
); break;
693 case MCI_DEVTYPE_VCR
: /*size = sizeof(MCI_VCR_STEP_PARMS); break;*/FIXME(mci
, "NIY vcr\n"); return -2;
694 case MCI_DEVTYPE_VIDEODISC
: size
= sizeof(MCI_VD_STEP_PARMS
); break;
695 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
699 size
= sizeof(MCI_SET_PARMS
);
703 LPMCI_SYSINFO_PARMSA msip32a
= (LPMCI_SYSINFO_PARMSA
)(*lParam
);
704 char* ptr
= SEGPTR_ALLOC(sizeof(LPMCI_SYSINFO_PARMSA
) + sizeof(MCI_SYSINFO_PARMS16
));
705 LPMCI_SYSINFO_PARMS16 msip16
;
708 *(LPMCI_SYSINFO_PARMSA
*)(ptr
) = msip32a
;
709 msip16
= (LPMCI_SYSINFO_PARMS16
)(ptr
+ sizeof(LPMCI_SYSINFO_PARMSA
));
711 msip16
->dwCallback
= msip32a
->dwCallback
;
712 msip16
->lpstrReturn
= (LPSTR
)SEGPTR_GET(SEGPTR_ALLOC(msip32a
->dwRetSize
));
713 msip16
->dwRetSize
= msip32a
->dwRetSize
;
714 msip16
->dwNumber
= msip32a
->dwNumber
;
715 msip16
->wDeviceType
= msip32a
->wDeviceType
;
719 *lParam
= (LPARAM
)SEGPTR_GET(ptr
) + sizeof(LPMCI_SYSINFO_PARMSA
);
725 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_RECT_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
726 case MCI_DEVTYPE_OVERLAY
: size
= sizeof(MCI_OVLY_RECT_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
727 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
732 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_UPDATE_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
733 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
738 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_RECT_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
739 case MCI_DEVTYPE_OVERLAY
: size
= sizeof(MCI_OVLY_RECT_PARMS
); FIXME(mci
, "NIY rect\n"); return -2;
740 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
745 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_WINDOW_PARMS16
); FIXME(mci
, "NIY lpstrText\n"); return -2;
746 case MCI_DEVTYPE_OVERLAY
: /*size = sizeof(MCI_OVLY_WINDOW_PARMS); FIXME(mci, "NIY lpstrText\n"); return -2;*/
747 FIXME(mci
, "NIY ovly\n"); return -2;
748 default: size
= sizeof(MCI_GENERIC_PARMS
); break;
758 case DRV_QUERYCONFIGURE
:
761 case DRV_EXITSESSION
:
762 case DRV_EXITAPPLICATION
:
764 FIXME(mci
, "This is a hack\n");
768 WARN(mci
, "Don't know how to map msg=%s\n", MCI_CommandToString(wMsg
));
771 return MCI_MsgMapper32To16_Create((void**)lParam
, size
, keep
);
774 /**************************************************************************
775 * MCI_UnMapMsg32ATo16 [internal]
777 int MCI_UnMapMsg32ATo16(WORD uDevType
, WORD wMsg
, DWORD dwFlags
, DWORD lParam
)
780 BOOLEAN kept
= FALSE
; /* there is no need to compute size when kept is FALSE */
783 /* case MCI_CAPTURE */
785 case MCI_CLOSE_DRIVER
:
787 /* case MCI_CONFIGURE:*/
794 /* case MCI_ESCAPE: */
799 size
= sizeof(MCI_GETDEVCAPS_PARMS
);
801 /* case MCI_INDEX: */
804 LPMCI_INFO_PARMS16 mip16
= (LPMCI_INFO_PARMS16
)PTR_SEG_TO_LIN(lParam
);
805 LPMCI_INFO_PARMSA mip32a
= *(LPMCI_INFO_PARMSA
*)((char*)mip16
- sizeof(LPMCI_INFO_PARMSA
));
807 memcpy(mip32a
->lpstrReturn
, PTR_SEG_TO_LIN(mip16
->lpstrReturn
), mip32a
->dwRetSize
);
809 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(mip16
->lpstrReturn
)))
810 FIXME(mci
, "bad free line=%d\n", __LINE__
);
811 if (!SEGPTR_FREE((char*)mip16
- sizeof(LPMCI_INFO_PARMSA
)))
812 FIXME(mci
, "bad free line=%d\n", __LINE__
);
816 /* case MCI_MONITOR: */
818 case MCI_OPEN_DRIVER
:
820 LPMCI_OPEN_PARMS16 mop16
= (LPMCI_OPEN_PARMS16
)PTR_SEG_TO_LIN(lParam
);
821 LPMCI_OPEN_PARMSA mop32a
= *(LPMCI_OPEN_PARMSA
*)((char*)mop16
- sizeof(LPMCI_OPEN_PARMSA
));
823 mop32a
->wDeviceID
= mop16
->wDeviceID
;
824 if ((dwFlags
& MCI_OPEN_TYPE
) && !
825 (dwFlags
& MCI_OPEN_TYPE_ID
) &&
826 !SEGPTR_FREE(PTR_SEG_TO_LIN(mop16
->lpstrDeviceType
)))
827 FIXME(mci
, "bad free line=%d\n", __LINE__
);
828 if ((dwFlags
& MCI_OPEN_ELEMENT
) &&
829 !(dwFlags
& MCI_OPEN_ELEMENT_ID
) &&
830 !SEGPTR_FREE(PTR_SEG_TO_LIN(mop16
->lpstrElementName
)))
831 FIXME(mci
, "bad free line=%d\n", __LINE__
);
832 if ((dwFlags
& MCI_OPEN_ALIAS
) &&
833 !SEGPTR_FREE(PTR_SEG_TO_LIN(mop16
->lpstrAlias
)))
834 FIXME(mci
, "bad free line=%d\n", __LINE__
);
836 if (!SEGPTR_FREE((LPVOID
)((char*)mop16
- sizeof(LPMCI_OPEN_PARMSA
))))
837 FIXME(mci
, "bad free line=%d\n", __LINE__
);
857 /* case MCI_SETTIMECODE:*/
858 /* case MCI_SIGNAL:*/
864 case MCI_DEVTYPE_DIGITAL_VIDEO
: size
= sizeof(MCI_DGV_STATUS_PARMS16
); FIXME(mci
, "NIY lpstrDevice\n");return -2;
865 case MCI_DEVTYPE_VCR
: /*size = sizeof(MCI_VCR_STATUS_PARMS); break;*/FIXME(mci
, "NIY vcr\n"); return -2;
866 default: size
= sizeof(MCI_STATUS_PARMS
); break;
875 LPMCI_SYSINFO_PARMS16 msip16
= (LPMCI_SYSINFO_PARMS16
)PTR_SEG_TO_LIN(lParam
);
876 LPMCI_SYSINFO_PARMSA msip32a
= *(LPMCI_SYSINFO_PARMSA
*)((char*)msip16
- sizeof(LPMCI_SYSINFO_PARMSA
));
879 msip16
->dwCallback
= msip32a
->dwCallback
;
880 memcpy(msip32a
->lpstrReturn
, PTR_SEG_TO_LIN(msip16
->lpstrReturn
), msip32a
->dwRetSize
);
881 if (!SEGPTR_FREE(msip16
->lpstrReturn
))
882 FIXME(mci
, "bad free line=%d\n", __LINE__
);
884 if (!SEGPTR_FREE((LPVOID
)(lParam
- sizeof(LPMCI_SYSINFO_PARMSA
))))
885 FIXME(mci
, "bad free line=%d\n", __LINE__
);
899 /* FIXME: see map function */
909 case DRV_QUERYCONFIGURE
:
912 case DRV_EXITSESSION
:
913 case DRV_EXITAPPLICATION
:
915 FIXME(mci
, "This is a hack\n");
918 FIXME(mci
, "Map/Unmap internal error on msg=%s\n", MCI_CommandToString(wMsg
));
921 return MCI_MsgMapper32To16_Destroy((void*)lParam
, size
, kept
);
924 /**************************************************************************
925 * MCI_SendCommand [internal]
927 DWORD
MCI_SendCommand(UINT wDevID
, UINT16 wMsg
, DWORD dwParam1
, DWORD dwParam2
)
929 DWORD dwRet
= MCIERR_DEVICE_NOT_INSTALLED
;
931 if (!MCI_DevIDValid(wDevID
)) {
932 dwRet
= MCIERR_INVALID_DEVICE_ID
;
934 MCIPROC proc
= MCI_GetProc(MCI_GetDrv(wDevID
)->modp
.wType
);
937 dwRet
= (*proc
)(MCI_GetDrv(wDevID
)->modp
.wDeviceID
,
938 MCI_GetDrv(wDevID
)->hDrv
,
939 wMsg
, dwParam1
, dwParam2
);
940 } else if (MCI_GetDrv(wDevID
)->hDrv
) {
941 switch (DRIVER_GetType(MCI_GetDrv(wDevID
)->hDrv
)) {
942 case WINE_DI_TYPE_16
:
946 switch (res
= MCI_MapMsg32ATo16(MCI_GetDrv(wDevID
)->modp
.wType
, wMsg
, dwParam1
, &dwParam2
)) {
948 TRACE(mci
, "Not handled yet (%s)\n", MCI_CommandToString(wMsg
));
949 dwRet
= MCIERR_DRIVER_INTERNAL
;
952 TRACE(mci
, "Problem mapping msg=%s from 16 to 32a\n", MCI_CommandToString(wMsg
));
953 dwRet
= MCIERR_OUT_OF_MEMORY
;
957 dwRet
= SendDriverMessage16(MCI_GetDrv(wDevID
)->hDrv
, wMsg
, dwParam1
, dwParam2
);
959 MCI_UnMapMsg32ATo16(MCI_GetDrv(wDevID
)->modp
.wType
, wMsg
, dwParam1
, dwParam2
);
964 case WINE_DI_TYPE_32
:
965 dwRet
= SendDriverMessage(MCI_GetDrv(wDevID
)->hDrv
, wMsg
, dwParam1
, dwParam2
);
968 WARN(mci
, "Unknown driver type=%u\n", DRIVER_GetType(MCI_GetDrv(wDevID
)->hDrv
));
969 dwRet
= MCIERR_DRIVER_INTERNAL
;
972 WARN(mci
, "unknown device type=%04X !\n", MCI_GetDrv(wDevID
)->modp
.wType
);
978 /**************************************************************************
979 * MCI_Open [internal]
981 DWORD
MCI_Open(DWORD dwParam
, LPMCI_OPEN_PARMSA lpParms
)
985 UINT16 wDevID
= MCI_FirstDevID();
988 TRACE(mci
, "(%08lX, %p)\n", dwParam
, lpParms
);
989 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
991 if ((dwParam
& ~(MCI_OPEN_SHAREABLE
|MCI_OPEN_ELEMENT
|MCI_OPEN_ALIAS
|MCI_OPEN_TYPE
|MCI_OPEN_TYPE_ID
|MCI_NOTIFY
|MCI_WAIT
)) != 0) {
992 FIXME(mci
, "unsupported yet dwFlags=%08lX\n",
993 (dwParam
& ~(MCI_OPEN_SHAREABLE
|MCI_OPEN_ELEMENT
|MCI_OPEN_ALIAS
|MCI_OPEN_TYPE
|MCI_OPEN_TYPE_ID
|MCI_NOTIFY
|MCI_WAIT
)));
996 while (MCI_GetDrv(wDevID
)->modp
.wType
!= 0) {
997 wDevID
= MCI_NextDevID(wDevID
);
998 if (!MCI_DevIDValid(wDevID
)) {
999 TRACE(mci
, "MAXMCIDRIVERS reached !\n");
1000 return MCIERR_OUT_OF_MEMORY
;
1004 TRACE(mci
, "wDevID=%04X \n", wDevID
);
1005 memcpy(MCI_GetOpenDrv(wDevID
), lpParms
, sizeof(*lpParms
));
1009 if (dwParam
& MCI_OPEN_ELEMENT
) {
1012 TRACE(mci
, "lpstrElementName='%s'\n", lpParms
->lpstrElementName
);
1013 t
= strrchr(lpParms
->lpstrElementName
, '.');
1015 GetProfileStringA("mci extensions", t
+1, "*", strDevTyp
, sizeof(strDevTyp
));
1016 if (strcmp(strDevTyp
, "*") == 0) {
1017 TRACE(mci
,"No [mci extensions] entry for %s found.\n", t
);
1018 return MCIERR_EXTENSION_NOT_FOUND
;
1020 TRACE(mci
, "Extension %s is mapped to type %s\n", t
, strDevTyp
);
1021 } else if (GetDriveTypeA(lpParms
->lpstrElementName
) == DRIVE_CDROM
) {
1022 /* FIXME: this will not work if several CDROM drives are installed on the machine */
1023 strcpy(strDevTyp
, "CDAUDIO");
1025 return MCIERR_EXTENSION_NOT_FOUND
;
1029 if (dwParam
& MCI_OPEN_ALIAS
) {
1030 TRACE(mci
, "Alias='%s' !\n", lpParms
->lpstrAlias
);
1031 /* FIXME is there any memory leak here ? */
1032 MCI_GetOpenDrv(wDevID
)->lpstrAlias
= strdup(lpParms
->lpstrAlias
);
1033 /* mplayer does allocate alias to CDAUDIO */
1035 if (dwParam
& MCI_OPEN_TYPE
) {
1036 if (dwParam
& MCI_OPEN_TYPE_ID
) {
1038 TRACE(mci
, "Dev=%08lx!\n", (DWORD
)lpParms
->lpstrDeviceType
);
1039 uDevType
= LOWORD((DWORD
)lpParms
->lpstrDeviceType
);
1040 MCI_GetOpenDrv(wDevID
)->lpstrDeviceType
= lpParms
->lpstrDeviceType
;
1042 if (LOWORD((DWORD
)lpParms
->lpstrDeviceType
) != MCI_DEVTYPE_CD_AUDIO
) {
1043 FIXME(mci
, "MCI_OPEN_TYPE_ID is no longer properly supported\n");
1046 if (lpParms
->lpstrDeviceType
== NULL
)
1047 return MCIERR_NULL_PARAMETER_BLOCK
;
1048 TRACE(mci
, "Dev='%s' !\n", lpParms
->lpstrDeviceType
);
1049 /* FIXME is there any memory leak here ? */
1050 MCI_GetOpenDrv(wDevID
)->lpstrDeviceType
= strdup(lpParms
->lpstrDeviceType
);
1051 strcpy(strDevTyp
, lpParms
->lpstrDeviceType
);
1055 if (uDevType
== 0 && strDevTyp
[0] != 0) {
1056 CharUpperA(strDevTyp
);
1057 /* try Wine internal MCI drivers */
1058 uDevType
= MCI_GetDevType(strDevTyp
);
1059 if (uDevType
== 0) { /* Nope, load external */
1061 MCI_OPEN_DRIVER_PARMSA modp
;
1063 modp
.wDeviceID
= wDevID
;
1064 modp
.lpstrParams
= NULL
;
1066 /* FIXME: this is a hack... some MCI drivers, while being open, call
1067 * mciSetData, which lookup for non empty slots in MCI table list
1068 * Unfortunatly, open slots are known when wType == 0...
1069 * so use a dummy type, just to keep on going. May be wType == 0 is
1070 * not the best solution to indicate empty slot in MCI drivers table
1072 MCI_GetDrv(wDevID
)->modp
.wType
= MCI_DEVTYPE_CD_AUDIO
;
1073 hDrv
= OpenDriverA(strDevTyp
, "mci", (LPARAM
)&modp
);
1076 FIXME(mci
, "Couldn't load driver for type %s.\n", strDevTyp
);
1077 return MCIERR_DEVICE_NOT_INSTALLED
;
1079 uDevType
= modp
.wType
;
1080 MCI_GetDrv(wDevID
)->hDrv
= hDrv
;
1082 TRACE(mci
, "Loaded driver %u (%s), type is %d\n", hDrv
, strDevTyp
, uDevType
);
1085 MCI_GetDrv(wDevID
)->hDrv
= 0;
1088 MCI_GetDrv(wDevID
)->modp
.wType
= uDevType
;
1089 MCI_GetDrv(wDevID
)->modp
.wDeviceID
= 0; /* FIXME? for multiple devices */
1091 lpParms
->wDeviceID
= wDevID
;
1093 TRACE(mci
, "mcidev=%d, uDevType=%04X wDeviceID=%04X !\n",
1094 wDevID
, uDevType
, lpParms
->wDeviceID
);
1096 dwRet
= MCI_SendCommand(wDevID
, MCI_OPEN_DRIVER
, dwParam
, (DWORD
)lpParms
);
1097 MCI_GetDrv(wDevID
)->lpfnYieldProc
= 0;
1098 MCI_GetDrv(wDevID
)->dwYieldData
= 0;
1101 /* only handled devices fall through */
1102 TRACE(mci
, "wDevID = %04X wDeviceID = %d dwRet = %ld\n", wDevID
, lpParms
->wDeviceID
, dwRet
);
1104 TRACE(mci
, "failed to open driver (MCI_OPEN_DRIVER msg) [%08lx], closing\n", dwRet
);
1105 MCI_GetDrv(wDevID
)->modp
.wType
= 0;
1107 if (dwParam
& MCI_NOTIFY
)
1108 mciDriverNotify16(lpParms
->dwCallback
, wDevID
, dwRet
== 0 ? MCI_NOTIFY_SUCCESSFUL
: MCI_NOTIFY_FAILURE
);
1113 /**************************************************************************
1114 * MCI_Close [internal]
1116 DWORD
MCI_Close(UINT16 wDevID
, DWORD dwParam
, LPMCI_GENERIC_PARMS lpParms
)
1120 TRACE(mci
, "(%04x, %08lX, %p)\n", wDevID
, dwParam
, lpParms
);
1122 if (wDevID
== MCI_ALL_DEVICE_ID
) {
1123 FIXME(mci
, "unhandled MCI_ALL_DEVICE_ID\n");
1124 return MCIERR_CANNOT_USE_ALL
;
1127 dwRet
= MCI_SendCommand(wDevID
, MCI_CLOSE_DRIVER
, dwParam
, (DWORD
)lpParms
);
1128 if (MCI_GetDrv(wDevID
)->hDrv
) {
1130 CloseDriver(MCI_GetDrv(wDevID
)->hDrv
, 0, 0);
1133 MCI_GetDrv(wDevID
)->modp
.wType
= 0;
1135 if (dwParam
& MCI_NOTIFY
)
1136 mciDriverNotify16(lpParms
->dwCallback
, wDevID
,
1137 (dwRet
== 0) ? MCI_NOTIFY_SUCCESSFUL
: MCI_NOTIFY_FAILURE
);
1142 /**************************************************************************
1143 * MCI_WriteString [internal]
1145 DWORD
MCI_WriteString(LPSTR lpDstStr
, DWORD dstSize
, LPCSTR lpSrcStr
)
1149 if (dstSize
<= strlen(lpSrcStr
)) {
1150 lstrcpynA(lpDstStr
, lpSrcStr
, dstSize
- 1);
1151 ret
= MCIERR_PARAM_OVERFLOW
;
1153 strcpy(lpDstStr
, lpSrcStr
);
1159 /**************************************************************************
1160 * MCI_Sysinfo [internal]
1162 DWORD
MCI_SysInfo(UINT uDevID
, DWORD dwFlags
, LPMCI_SYSINFO_PARMSA lpParms
)
1164 DWORD ret
= MCIERR_INVALID_DEVICE_ID
;
1166 if (lpParms
== NULL
) return MCIERR_NULL_PARAMETER_BLOCK
;
1168 TRACE(mci
, "(%08x, %08lX, %08lX[num=%ld, wDevTyp=%u])\n",
1169 uDevID
, dwFlags
, (DWORD
)lpParms
, lpParms
->dwNumber
, lpParms
->wDeviceType
);
1171 switch (dwFlags
& ~MCI_SYSINFO_OPEN
) {
1172 case MCI_SYSINFO_QUANTITY
:
1177 if (lpParms
->wDeviceType
< MCI_DEVTYPE_FIRST
|| lpParms
->wDeviceType
> MCI_DEVTYPE_LAST
) {
1178 if (dwFlags
& MCI_SYSINFO_OPEN
) {
1179 TRACE(mci
, "MCI_SYSINFO_QUANTITY: # of open MCI drivers\n");
1180 for (i
= 0; i
< MAXMCIDRIVERS
; i
++) {
1181 if (mciDrv
[i
].modp
.wType
!= 0) cnt
++;
1184 TRACE(mci
, "MCI_SYSINFO_QUANTITY: # of installed MCI drivers\n");
1185 cnt
= mciInstalledCount
;
1188 if (dwFlags
& MCI_SYSINFO_OPEN
) {
1189 TRACE(mci
, "MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n", lpParms
->wDeviceType
);
1190 for (i
= 0; i
< MAXMCIDRIVERS
; i
++) {
1191 if (mciDrv
[i
].modp
.wType
== lpParms
->wDeviceType
) cnt
++;
1194 TRACE(mci
, "MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %u\n", lpParms
->wDeviceType
);
1195 FIXME(mci
, "Don't know how to get # of MCI devices of a given type\n");
1199 *(DWORD
*)lpParms
->lpstrReturn
= cnt
;
1201 TRACE(mci
, "(%ld) => '%ld'\n", lpParms
->dwNumber
, *(DWORD
*)lpParms
->lpstrReturn
);
1204 case MCI_SYSINFO_INSTALLNAME
:
1205 TRACE(mci
, "MCI_SYSINFO_INSTALLNAME \n");
1206 if (MCI_DevIDValid(uDevID
)) {
1207 LPCSTR str
= MCI_GetDevTypeString(MCI_GetDrv(uDevID
)->modp
.wType
);
1208 ret
= MCI_WriteString(lpParms
->lpstrReturn
, lpParms
->dwRetSize
, str
);
1210 *lpParms
->lpstrReturn
= 0;
1211 ret
= MCIERR_INVALID_DEVICE_ID
;
1213 TRACE(mci
, "(%ld) => '%s'\n", lpParms
->dwNumber
, lpParms
->lpstrReturn
);
1215 case MCI_SYSINFO_NAME
:
1216 TRACE(mci
, "MCI_SYSINFO_NAME\n");
1217 if (dwFlags
& MCI_SYSINFO_OPEN
) {
1218 FIXME(mci
, "Don't handle MCI_SYSINFO_NAME|MCI_SYSINFO_OPEN (yet)\n");
1219 ret
= MCIERR_UNRECOGNIZED_COMMAND
;
1220 } else if (lpParms
->dwNumber
> mciInstalledCount
) {
1221 ret
= MCIERR_OUTOFRANGE
;
1223 DWORD count
= lpParms
->dwNumber
;
1224 LPSTR ptr
= lpmciInstallNames
;
1226 while (--count
> 0) ptr
+= strlen(ptr
) + 1;
1227 ret
= MCI_WriteString(lpParms
->lpstrReturn
, lpParms
->dwRetSize
, ptr
);
1229 TRACE(mci
, "(%ld) => '%s'\n", lpParms
->dwNumber
, lpParms
->lpstrReturn
);
1232 TRACE(mci
, "Unsupported flag value=%08lx\n", dwFlags
);
1233 ret
= MCIERR_UNRECOGNIZED_COMMAND
;
1246 DWORD WINAPI
mciSendCommandA(UINT wDevID
, UINT wMsg
, DWORD dwParam1
, DWORD dwParam2
);
1248 /**************************************************************************
1249 * MCI_SCAStarter [internal]
1251 static DWORD WINAPI
MCI_SCAStarter(LPVOID arg
)
1253 struct SCA
* sca
= (struct SCA
*)arg
;
1256 TRACE(mci
, "In thread before async command (%08x,%s,%08lx,%08lx)\n",
1257 sca
->wDevID
, MCI_CommandToString(sca
->wMsg
), sca
->dwParam1
, sca
->dwParam2
);
1258 ret
= mciSendCommandA(sca
->wDevID
, sca
->wMsg
, sca
->dwParam1
| MCI_WAIT
, sca
->dwParam2
);
1259 TRACE(mci
, "In thread after async command (%08x,%s,%08lx,%08lx)\n",
1260 sca
->wDevID
, MCI_CommandToString(sca
->wMsg
), sca
->dwParam1
, sca
->dwParam2
);
1261 if (sca
->allocatedCopy
)
1262 HeapFree(GetProcessHeap(), 0, (LPVOID
)sca
->dwParam2
);
1263 HeapFree(GetProcessHeap(), 0, sca
);
1265 WARN(mci
, "Should not happen ? what's wrong \n");
1266 /* should not go after this point */
1270 /**************************************************************************
1271 * MCI_SendCommandAsync [internal]
1273 DWORD
MCI_SendCommandAsync(UINT wDevID
, UINT wMsg
, DWORD dwParam1
, DWORD dwParam2
, UINT size
)
1275 struct SCA
* sca
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct SCA
));
1278 return MCIERR_OUT_OF_MEMORY
;
1280 sca
->wDevID
= wDevID
;
1282 sca
->dwParam1
= dwParam1
;
1285 sca
->dwParam2
= (DWORD
)HeapAlloc(GetProcessHeap(), 0, size
);
1286 if (sca
->dwParam2
== 0) {
1287 HeapFree(GetProcessHeap(), 0, sca
);
1288 return MCIERR_OUT_OF_MEMORY
;
1290 sca
->allocatedCopy
= TRUE
;
1291 /* copy structure passed by program in dwParam2 to be sure
1292 * we can still use it whatever the program does
1294 memcpy((LPVOID
)sca
->dwParam2
, (LPVOID
)dwParam2
, size
);
1296 sca
->dwParam2
= dwParam2
;
1297 sca
->allocatedCopy
= FALSE
;
1300 if (CreateThread(NULL
, 0, MCI_SCAStarter
, sca
, 0, NULL
) == 0) {
1301 WARN(mci
, "Couldn't allocate thread for async command handling, sending synchonously\n");
1302 return MCI_SCAStarter(&sca
);
1307 /**************************************************************************
1308 * MCI_CleanUp [internal]
1310 * Some MCI commands need to be cleaned-up (when not called from
1311 * mciSendString), because MCI drivers return extra information for string
1312 * transformation. This function gets read of them.
1314 LRESULT
MCI_CleanUp(LRESULT dwRet
, UINT wMsg
, DWORD dwParam2
, BOOL bIs32
)
1317 case MCI_GETDEVCAPS
:
1318 switch (dwRet
& 0xFFFF0000ul
) {
1321 case MCI_RESOURCE_RETURNED
:
1322 case MCI_RESOURCE_RETURNED
|MCI_RESOURCE_DRIVER
:
1323 case MCI_COLONIZED3_RETURN
:
1324 case MCI_COLONIZED4_RETURN
:
1325 case MCI_INTEGER_RETURNED
:
1327 LPMCI_GETDEVCAPS_PARMS lmgp
= (LPMCI_GETDEVCAPS_PARMS
)(bIs32
? (void*)dwParam2
: PTR_SEG_TO_LIN(dwParam2
));
1329 dwRet
= LOWORD(dwRet
);
1330 TRACE(mci
, "Changing %08lx to %08lx\n", lmgp
->dwReturn
, (DWORD
)LOWORD(lmgp
->dwReturn
));
1332 lmgp
->dwReturn
= LOWORD(lmgp
->dwReturn
);
1336 FIXME(mci
, "Unsupported value for hiword (%04x) returned by DriverProc\n", HIWORD(dwRet
));
1340 switch (dwRet
& 0xFFFF0000ul
) {
1343 case MCI_RESOURCE_RETURNED
:
1344 case MCI_RESOURCE_RETURNED
|MCI_RESOURCE_DRIVER
:
1345 case MCI_COLONIZED3_RETURN
:
1346 case MCI_COLONIZED4_RETURN
:
1347 case MCI_INTEGER_RETURNED
:
1349 LPMCI_STATUS_PARMS lsp
= (LPMCI_STATUS_PARMS
)(bIs32
? (void*)dwParam2
: PTR_SEG_TO_LIN(dwParam2
));
1351 dwRet
= LOWORD(dwRet
);
1352 TRACE(mci
, "Changing %08lx to %08lx\n", lsp
->dwReturn
,(DWORD
) LOWORD(lsp
->dwReturn
));
1353 lsp
->dwReturn
= LOWORD(lsp
->dwReturn
);
1357 FIXME(mci
, "Unsupported value for hiword (%04x) returned by DriverProc\n", HIWORD(dwRet
));