source: trunk/src/winmm/mci.cpp

Last change on this file was 21916, checked in by dmik, 14 years ago

Merge branch gcc-kmk to trunk.

File size: 40.3 KB
RevLine 
[10410]1/* $Id: mci.cpp,v 1.10 2004-01-20 18:09:42 sandervl Exp $ */
[95]2
[4]3/*
[4748]4 * MCI functions
[4]5 *
6 * Copyright 1998 Joel Troster
[4748]7 * Copyright 1998/1999 Eric Pouech
8 * Copyright 2000 Chris Wohlgemuth
[10410]9 *
10 * Contains portions of Wine (dlls\winmm\mci.c, winmm.c)
11 * Copyright 1998/1999 Eric Pouech
[4]12 *
13 * Project Odin Software License can be found in LICENSE.TXT
14 *
15 */
[588]16
17
18/****************************************************************************
19 * Includes *
20 ****************************************************************************/
21
[4748]22#define INCL_BASE
23#define INCL_OS2MM
24
[4]25#include <os2win.h>
26#include <mmsystem.h>
[588]27#include <odinwrap.h>
[4]28#include <string.h>
29#include <stdio.h>
[10173]30#include "debugtools.h"
[4]31
32#include <misc.h>
33#include <unicode.h>
34
[4748]35#include "mcimm.h"
36
[4]37#include "winmm.h"
38
[10173]39#define DBG_LOCALLOG DBG_mci
[2812]40#include "dbglocal.h"
41
[4748]42
43/****************************************************************************
44 * Local functions *
45 ****************************************************************************/
46
47/* forward declaration */
48static DWORD MCI_SendCommand(UINT mciId,
49 UINT16 uMsg,
50 DWORD dwParam1,
[10410]51 DWORD dwParam2);
[4748]52
[10173]53static LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID) ;
54static UINT MCI_GetDriverFromString(LPCSTR lpstrName);
[4748]55
56/****************************************************************************/
57
[588]58
[8470]59BOOL WINAPI mciDriverNotify(HWND hwndCallback, UINT uDeviceID, UINT uStatus)
[4]60{
[4748]61 TRACE("Entering mciDriverNotify (%08X, %04x, %04X)\n", hwndCallback, uDeviceID, uStatus);
[10173]62
[4748]63 if (!IsWindow(hwndCallback)) {
[10173]64 WARN("bad hwnd for call back (0x%04x)\n", hwndCallback);
65 return FALSE;
[4748]66 }
67 TRACE("before PostMessage\n");
68 PostMessageA(hwndCallback, MM_MCINOTIFY, uStatus, uDeviceID);
69 return TRUE;
[4]70}
71
[8470]72UINT WINAPI mciDriverYield(UINT uDeviceID)
[4]73{
74 dprintf(("WINMM:mciDriverYield - stub\n"));
75 return 0;
76}
77
[8470]78BOOL WINAPI mciExecute(LPCSTR pszCommand)
[4]79{
80 dprintf(("WINMM:mciExecute(%s) - stub\n", pszCommand));
81 return FALSE;
82}
83
[8470]84BOOL WINAPI mciFreeCommandResource(UINT uTable)
[4]85{
86 dprintf(("WINMM:mciFreeCommandResource - stub\n"));
87 return FALSE;
88}
89
[8470]90HTASK mciGetCreatorTask(MCIDEVICEID mciId)
[4]91{
92 dprintf(("WINMM:mciGetCreatorTask - stub\n"));
93 return 0;
94}
95
[8470]96MCIDEVICEID WINAPI mciGetDeviceIDA(LPCSTR pszDevice)
[4]97{
[4748]98 WARN(("WINMM:mciGetDeviceIDA - untested\n"));
99 return MCI_GetDriverFromString(pszDevice);
[4]100}
101
[8470]102MCIDEVICEID WINAPI mciGetDeviceIDW(LPCWSTR pszDevice)
[4]103{
104 dprintf(("WINMM:mciGetDeviceIDW - stub\n"));
105 return 0;
106}
107
[8470]108MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDA(DWORD dwElementID, LPCSTR lpstrType)
[4]109{
110 dprintf(("WINMM:mciGetDeviceIDFromElementIDA - stub\n"));
111 return 0;
112}
113
[8470]114MCIDEVICEID WINAPI mciGetDeviceIDFromElementIDW(DWORD dwElementID, LPCWSTR lpstrType)
[4]115{
116 dprintf(("WINMM:mciGetDeviceIDFromElementIDW - stub\n"));
117 return 0;
118}
119
[4748]120/*****************************************************************************
121 * Queries driver data
122 * Parameters: UINT uDeviceID
123 * Variables :
124 * @return : Pointer to driver data (as a DWORD)
125 * Remark :
126 * @status : Completely
127 *
128 * @author : Chris Wohlgemuth [Sun, 2000/11/19]
129 *****************************************************************************/
[8470]130DWORD WINAPI mciGetDriverData(UINT uDeviceID)
[4]131{
[10173]132 LPWINE_MCIDRIVER wmd;
133
[4748]134 wmd = MCI_GetDriver(uDeviceID);
[10173]135
[4748]136 if (!wmd) {
[10173]137 dprintf(("WARNING: Bad uDeviceID (mciGetDriverData (mci.cpp line %d)\n",__LINE__));
[4748]138 return 0L; /* Error */
139 }
[10173]140
[4748]141 return wmd->dwPrivate;
[4]142}
143
[4748]144/*****************************************************************************
145 * Converts an error to an error string
146 * Parameters: MCIERROR mcierr,
147 * LPSTR pszText,
148 * UINT cchText
149 * Variables :
150 * @return : API returncode (TRUE/FALSE)
151 * Remark :
152 * @status : Completely
153 *
154 * @author : Wine
155 *****************************************************************************/
[8470]156BOOL WINAPI mciGetErrorStringA(MCIERROR mcierr, LPSTR pszText, UINT cchText)
[4]157{
158 dprintf(("WINMM:mciGetErrorStringA(%d)\n", mcierr ));
[21916]159 const char * theMsg = getWinmmMsg( mcierr );
[4]160 if ( theMsg )
161 strncpy( pszText, theMsg, cchText );
162 else
163 {
164 char errMsg[100];
165 sprintf( errMsg, "Unknown error number %d", mcierr );
166 strncpy( pszText, errMsg, cchText );
167 }
168 return TRUE;
169}
170
[4748]171/*****************************************************************************
172 * Converts an error to an error string
173 * Parameters: MCIERROR mcierr,
174 * LPSTR pszText,
175 * UINT cchText
176 * Variables :
177 * @return : API returncode (TRUE/FALSE)
178 * Remark :
179 * @status : Completely
180 *
181 * @author : Wine
182 *****************************************************************************/
[8470]183BOOL WINAPI mciGetErrorStringW(MCIERROR mcierr, LPWSTR pszText, UINT cchText)
[4]184{
185 dprintf(("WINMM:mciGetErrorStringW(%d)\n", mcierr ));
[21916]186 const char * theMsg = getWinmmMsg( mcierr );
[4]187 if ( theMsg )
[10173]188 AsciiToUnicodeN( theMsg, pszText, cchText );
[4]189 else
190 {
191 char errMsg[100];
192 sprintf( errMsg, "Unknown error number %d", mcierr );
[10173]193 AsciiToUnicodeN( errMsg, pszText, cchText );
[4]194 }
195 return TRUE;
196}
197
[4748]198/*****************************************************************************
199 * Converts an error to an error string
200 * Parameters: MCIERROR mcierr,
201 * LPSTR pszText,
202 * UINT cchText
203 * Variables :
204 * @return : API returncode
205 * Remark :
206 * @status : Completely
207 *
208 * @author : Wine
209 *****************************************************************************/
[8470]210YIELDPROC WINAPI mciGetYieldProc(MCIDEVICEID mciId, LPDWORD pdwYieldData)
[4]211{
[10173]212 LPWINE_MCIDRIVER wmd;
213
[4748]214 TRACE("Entering mciGetYieldProc (%u, %p) - untested\n", mciId, pdwYieldData);
215
216 if (!(wmd = MCI_GetDriver(mciId))) {
[10173]217 WARN("Bad uDeviceID\n");
218 return NULL;
[4748]219 }
220 if (!wmd->lpfnYieldProc) {
[10173]221 WARN("No proc set\n");
222 return NULL;
[4748]223 }
224 if (!wmd->bIs32) {
[10173]225 WARN("Proc is 32 bit\n");
226 return NULL;
[4748]227 }
228 return wmd->lpfnYieldProc;
[4]229}
230
[8470]231UINT WINAPI mciLoadCommandResource(HINSTANCE hInstance, LPCWSTR lpResName,
232 UINT uType)
[4]233{
234 dprintf(("WINMM:mciLoadCOmmandResource - stub\n"));
235 return 0;
236}
237
[4748]238
[8470]239MCIERROR WINAPI mciSendCommandA(MCIDEVICEID mciId, UINT uMsg, DWORD dwParam1,
240 DWORD dwParam2)
[4]241{
[4748]242 DWORD dwRet;
243 // dprintf(("WINMM:mciSendCommandA - entering %X %X %X %X\n", mciId, uMsg, dwParam1, dwParam2));
[10173]244 dwRet= MCI_SendCommand((UINT) mciId, uMsg, dwParam1, dwParam2) & 0xFFFF;
[4748]245 return(dwRet);
[4]246}
247
[4748]248
[10410]249/**************************************************************************
250 * MCI_MessageToString [internal]
251 */
252const char* MCI_MessageToString(UINT16 wMsg)
[4]253{
[10410]254 static char buffer[100];
255
256#define CASE(s) case (s): return #s
257
258 switch (wMsg) {
259 CASE(MCI_BREAK);
260 CASE(MCI_CLOSE);
261 CASE(MCI_CLOSE_DRIVER);
262 CASE(MCI_COPY);
263 CASE(MCI_CUE);
264 CASE(MCI_CUT);
265 CASE(MCI_DELETE);
266 CASE(MCI_ESCAPE);
267 CASE(MCI_FREEZE);
268 CASE(MCI_PAUSE);
269 CASE(MCI_PLAY);
270 CASE(MCI_GETDEVCAPS);
271 CASE(MCI_INFO);
272 CASE(MCI_LOAD);
273 CASE(MCI_OPEN);
274 CASE(MCI_OPEN_DRIVER);
275 CASE(MCI_PASTE);
276 CASE(MCI_PUT);
277 CASE(MCI_REALIZE);
278 CASE(MCI_RECORD);
279 CASE(MCI_RESUME);
280 CASE(MCI_SAVE);
281 CASE(MCI_SEEK);
282 CASE(MCI_SET);
283 CASE(MCI_SPIN);
284 CASE(MCI_STATUS);
285 CASE(MCI_STEP);
286 CASE(MCI_STOP);
287 CASE(MCI_SYSINFO);
288 CASE(MCI_UNFREEZE);
289 CASE(MCI_UPDATE);
290 CASE(MCI_WHERE);
291 CASE(MCI_WINDOW);
292 /* constants for digital video */
293 /*
294 CASE(MCI_CAPTURE);
295 CASE(MCI_MONITOR);
296 CASE(MCI_RESERVE);
297 CASE(MCI_SETAUDIO);
298 CASE(MCI_SIGNAL);
299 CASE(MCI_SETVIDEO);
300 CASE(MCI_QUALITY);
301 CASE(MCI_LIST);
302 CASE(MCI_UNDO);
303 CASE(MCI_CONFIGURE);
304 CASE(MCI_RESTORE);
305 */
306#undef CASE
307 default:
308 sprintf(buffer, "MCI_<<%04X>>", wMsg);
309 return buffer;
310 }
[4]311}
312
[10410]313inline static LPSTR strdupWtoA( LPCWSTR str )
314{
315 LPSTR ret;
316 INT len;
317
318 if (!str) return NULL;
319 len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
320 ret = (LPSTR)HeapAlloc( GetProcessHeap(), 0, len );
321 if(ret) WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
322 return ret;
323}
324
325static int MCI_MapMsgWtoA(UINT msg, DWORD dwParam1, DWORD *dwParam2)
326{
327 switch(msg)
328 {
329 case MCI_CLOSE:
330 case MCI_PLAY:
331 case MCI_SEEK:
332 case MCI_STOP:
333 case MCI_PAUSE:
334 case MCI_GETDEVCAPS:
335 case MCI_SPIN:
336 case MCI_SET:
337 case MCI_STEP:
338 case MCI_RECORD:
339 case MCI_BREAK:
340 case MCI_SOUND:
341 case MCI_STATUS:
342 case MCI_CUE:
343 case MCI_REALIZE:
344 case MCI_PUT:
345 case MCI_WHERE:
346 case MCI_FREEZE:
347 case MCI_UNFREEZE:
348 case MCI_CUT:
349 case MCI_COPY:
350 case MCI_PASTE:
351 case MCI_UPDATE:
352 case MCI_RESUME:
353 case MCI_DELETE:
354 return 0;
355
356 case MCI_OPEN:
357 {
358 MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*dwParam2;
359 MCI_OPEN_PARMSA *mci_openA;
360 DWORD *ptr;
361
362 ptr = (DWORD *)HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_openA) + sizeof(DWORD));
363 if (!ptr) return -1;
364
365 *ptr++ = *dwParam2; /* save the previous pointer */
366 *dwParam2 = (DWORD)ptr;
367 mci_openA = (MCI_OPEN_PARMSA *)ptr;
368
369 if (dwParam1 & MCI_NOTIFY)
370 mci_openA->dwCallback = mci_openW->dwCallback;
371
372 if (dwParam1 & MCI_OPEN_TYPE)
373 {
374 if (dwParam1 & MCI_OPEN_TYPE_ID)
375 mci_openA->lpstrDeviceType = (LPSTR)mci_openW->lpstrDeviceType;
376 else
377 mci_openA->lpstrDeviceType = strdupWtoA(mci_openW->lpstrDeviceType);
378 }
379 if (dwParam1 & MCI_OPEN_ELEMENT)
380 {
381 if (dwParam1 & MCI_OPEN_ELEMENT_ID)
382 mci_openA->lpstrElementName = (LPSTR)mci_openW->lpstrElementName;
383 else
384 mci_openA->lpstrElementName = strdupWtoA(mci_openW->lpstrElementName);
385 }
386 if (dwParam1 & MCI_OPEN_ALIAS)
387 mci_openA->lpstrAlias = strdupWtoA(mci_openW->lpstrAlias);
388 }
389 return 1;
390
391 case MCI_WINDOW:
392 if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
393 {
394 MCI_ANIM_WINDOW_PARMSW *mci_windowW = (MCI_ANIM_WINDOW_PARMSW *)*dwParam2;
395 MCI_ANIM_WINDOW_PARMSA *mci_windowA;
396
397 mci_windowA = (MCI_ANIM_WINDOW_PARMSA *)HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_windowA));
398 if (!mci_windowA) return -1;
399
400 *dwParam2 = (DWORD)mci_windowA;
401
402 mci_windowA->lpstrText = strdupWtoA(mci_windowW->lpstrText);
403
404 if (dwParam1 & MCI_NOTIFY)
405 mci_windowA->dwCallback = mci_windowW->dwCallback;
406 if (dwParam1 & MCI_ANIM_WINDOW_HWND)
407 mci_windowA->hWnd = mci_windowW->hWnd;
408 if (dwParam1 & MCI_ANIM_WINDOW_STATE)
409 mci_windowA->nCmdShow = mci_windowW->nCmdShow;
410
411 return 1;
412 }
413 return 0;
414
415 case MCI_SYSINFO:
416 {
417 MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)*dwParam2;
418 MCI_SYSINFO_PARMSA *mci_sysinfoA;
419 DWORD *ptr;
420
421 ptr = (DWORD *)HeapAlloc(GetProcessHeap(), 0, sizeof(*mci_sysinfoA) + sizeof(DWORD));
422 if (!ptr) return -1;
423
424 *ptr++ = *dwParam2; /* save the previous pointer */
425 *dwParam2 = (DWORD)ptr;
426 mci_sysinfoA = (MCI_SYSINFO_PARMSA *)ptr;
427
428 if (dwParam1 & MCI_NOTIFY)
429 mci_sysinfoA->dwCallback = mci_sysinfoW->dwCallback;
430
431 mci_sysinfoA->dwRetSize = mci_sysinfoW->dwRetSize; /* FIXME */
432 mci_sysinfoA->lpstrReturn = (CHAR *)HeapAlloc(GetProcessHeap(), 0, mci_sysinfoA->dwRetSize);
433
434 return 1;
435 }
436
437 case MCI_INFO:
438 case MCI_SAVE:
439 case MCI_LOAD:
440 case MCI_ESCAPE:
441 default:
442 FIXME("Message 0x%04x needs translation\n", msg);
443 return -1;
444 }
445 return 0;
446}
447
448static DWORD MCI_UnmapMsgWtoA(UINT msg, DWORD dwParam1, DWORD dwParam2,
449 DWORD result)
450{
451 switch(msg)
452 {
453 case MCI_OPEN:
454 {
455 DWORD *ptr = (DWORD *)dwParam2 - 1;
456 MCI_OPEN_PARMSW *mci_openW = (MCI_OPEN_PARMSW *)*ptr;
457 MCI_OPEN_PARMSA *mci_openA = (MCI_OPEN_PARMSA *)(ptr + 1);
458
459 mci_openW->wDeviceID = mci_openA->wDeviceID;
460
461 if (dwParam1 & MCI_OPEN_TYPE)
462 {
463 if (!(dwParam1 & MCI_OPEN_TYPE_ID))
464 HeapFree(GetProcessHeap(), 0, (LPVOID)mci_openA->lpstrDeviceType);
465 }
466 if (dwParam1 & MCI_OPEN_ELEMENT)
467 {
468 if (!(dwParam1 & MCI_OPEN_ELEMENT_ID))
469 HeapFree(GetProcessHeap(), 0, (LPVOID)mci_openA->lpstrElementName);
470 }
471 if (dwParam1 & MCI_OPEN_ALIAS)
472 HeapFree(GetProcessHeap(), 0, (LPVOID)mci_openA->lpstrAlias);
473 HeapFree(GetProcessHeap(), 0, ptr);
474 }
475 break;
476
477 case MCI_WINDOW:
478 if (dwParam1 & MCI_ANIM_WINDOW_TEXT)
479 {
480 MCI_ANIM_WINDOW_PARMSA *mci_windowA = (MCI_ANIM_WINDOW_PARMSA *)dwParam2;
481
482 HeapFree(GetProcessHeap(), 0, (void *)mci_windowA->lpstrText);
483 HeapFree(GetProcessHeap(), 0, mci_windowA);
484 }
485 break;
486
487 case MCI_SYSINFO:
488 {
489 DWORD *ptr = (DWORD *)dwParam2 - 1;
490 MCI_SYSINFO_PARMSW *mci_sysinfoW = (MCI_SYSINFO_PARMSW *)*ptr;
491 MCI_SYSINFO_PARMSA *mci_sysinfoA = (MCI_SYSINFO_PARMSA *)(ptr + 1);
492
493 if (!result)
494 {
495 mci_sysinfoW->dwNumber = mci_sysinfoA->dwNumber;
496 mci_sysinfoW->wDeviceType = mci_sysinfoA->wDeviceType;
497 MultiByteToWideChar(CP_ACP, 0,
498 mci_sysinfoA->lpstrReturn, mci_sysinfoA->dwRetSize,
499 mci_sysinfoW->lpstrReturn, mci_sysinfoW->dwRetSize);
500 }
501
502 HeapFree(GetProcessHeap(), 0, mci_sysinfoA->lpstrReturn);
503 HeapFree(GetProcessHeap(), 0, ptr);
504 }
505 break;
506
507 default:
508 FIXME("Message 0x%04x needs unmapping\n", msg);
509 break;
510 }
511
512 return result;
513}
514
515
516/**************************************************************************
517 * mciSendCommandW [WINMM.@]
518 *
519 * FIXME: we should do the things other way around, but since our
520 * MM subsystem is not unicode aware...
521 */
522DWORD WINAPI mciSendCommandW(MCIDEVICEID wDevID, UINT wMsg, DWORD dwParam1, DWORD dwParam2)
523{
524 DWORD ret;
525 int mapped;
526
527 dprintf(("(%08x, %s, %08lx, %08lx)\n", wDevID, MCI_MessageToString(wMsg), dwParam1, dwParam2));
528
529 mapped = MCI_MapMsgWtoA(wMsg, dwParam1, &dwParam2);
530 if (mapped == -1)
531 {
532 dprintf(("message %04x mapping failed\n", wMsg));
533 return MMSYSERR_NOMEM;
534 }
535 ret = mciSendCommandA(wDevID, wMsg, dwParam1, dwParam2);
536 if (mapped)
537 MCI_UnmapMsgWtoA(wMsg, dwParam1, dwParam2, ret);
538 return ret;
539}
540
541
[8470]542MCIERROR WINAPI mciSendStringA(LPCSTR lpstrCommand, LPSTR lpstrReturnString,
543 UINT uReturnLength, HWND hwndCallback)
[4]544{
545 dprintf(("WINMM:mciSendStringA - stub\n"));
[4748]546 if(lpstrCommand)
547 dprintf(("WINMM:mciSendStringA command: %s\n",lpstrCommand));
[4]548 return(MMSYSERR_NODRIVER);
549}
550
[8470]551MCIERROR WINAPI mciSendStringW(LPCWSTR lpstrCommand, LPWSTR lpstrReturnString,
552 UINT uReturnLength, HWND hwndCallback)
[4]553{
554 dprintf(("WINMM:mciSendStringW - stub\n"));
555 return(MMSYSERR_NODRIVER);
556}
557
[8470]558BOOL WINAPI mciSetDriverData(UINT uDeviceID, DWORD dwData)
[4]559{
[10173]560 LPWINE_MCIDRIVER wmd;
561
[4748]562 wmd = MCI_GetDriver(uDeviceID);
563
564 if (!wmd) {
[10173]565 dprintf(("WARNING: Bad uDeviceID (mciSetDriverData line %d)\n",__LINE__));
566 return FALSE;
[4748]567 }
[10173]568
[4748]569 wmd->dwPrivate = dwData;
570 return TRUE;
[4]571}
572
[4748]573
[8470]574BOOL WINAPI mciSetYieldProc(MCIDEVICEID mciId, YIELDPROC fpYieldProc, DWORD dwYieldData)
[4]575{
[10173]576 LPWINE_MCIDRIVER wmd;
577
[4748]578 TRACE("WINMM:mciSetYieldProc (%u, %p, %08lx) - untested\n", mciId, fpYieldProc, dwYieldData);
[10173]579
[4748]580 if (!(wmd = MCI_GetDriver(mciId))) {
[10173]581 WARN("Bad uDeviceID\n");
582 return FALSE;
[4748]583 }
[10173]584
[4748]585 wmd->lpfnYieldProc = fpYieldProc;
586 wmd->dwYieldData = dwYieldData;
587 wmd->bIs32 = TRUE;
[10173]588
[4748]589 return TRUE;
[4]590}
591
[588]592
[4748]593/**************************************************************************/
594/* heap.c */
595/**************************************************************************/
596
597#ifdef __GNUC__
598#define GET_EIP() (__builtin_return_address(0))
599#define SET_EIP(ptr) ((ARENA_INUSE*)(ptr) - 1)->callerEIP = GET_EIP()
600#else
601#define GET_EIP() 0
602#define SET_EIP(ptr) /* nothing */
603#endif /* __GNUC__ */
604
605
606/**************************************************************************/
607/* mmmsystem.c */
608/**************************************************************************/
609
[10173]610static LPWINE_MM_IDATA lpFirstIData = NULL;
[4748]611
[10173]612static LPWINE_MM_IDATA MULTIMEDIA_GetIDataNoCheck(void)
[4748]613{
[10173]614 DWORD pid = GetCurrentProcessId();
615 LPWINE_MM_IDATA iData;
[4748]616
617 for (iData = lpFirstIData; iData; iData = iData->lpNextIData) {
618 if (iData->dwThisProcess == pid)
[10173]619 break;
[4748]620 }
621 return iData;
622}
623
624/**************************************************************************
[10173]625 * MULTIMEDIA_GetIData [internal]
[4748]626 */
[10173]627LPWINE_MM_IDATA MULTIMEDIA_GetIData(void)
[4748]628{
[10173]629 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck();
[4748]630
631 if (!iData) {
632 dprintf(("MULTIMEDIA_GetIData: IData not found for pid=%08lx. Suicide !!!\n", GetCurrentProcessId()));
633 ExitProcess(0);
634 }
635 return iData;
636}
637
638
639/**************************************************************************
[10173]640 * MULTIMEDIA_CreateIData [internal]
[4748]641 */
642BOOL MULTIMEDIA_CreateIData(HINSTANCE hInstDLL)
643{
[10173]644 LPWINE_MM_IDATA iData;
645
[4748]646 iData = (LPWINE_MM_IDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MM_IDATA));
647
648 if (!iData)
649 return FALSE;
650 iData->hWinMM32Instance = hInstDLL;
651 iData->dwThisProcess = GetCurrentProcessId();
652 iData->lpNextIData = lpFirstIData;
653 lpFirstIData = iData;
654 InitializeCriticalSection(&iData->cs);
655 dprintf(("Created IData (%p) for pid %08lx\n", iData, iData->dwThisProcess));
656 return TRUE;
657}
658
659
660/**************************************************************************
[10173]661 * MULTIMEDIA_DeleteIData [internal]
[4748]662 */
663void MULTIMEDIA_DeleteIData(void)
664{
[10173]665 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIDataNoCheck();
666 LPWINE_MM_IDATA* ppid;
667
[4748]668 if (iData) {
[10173]669 for (ppid = &lpFirstIData; *ppid; ppid = &(*ppid)->lpNextIData) {
670 if (*ppid == iData) {
671 *ppid = iData->lpNextIData;
672 break;
673 }
[4748]674 }
[10173]675 /* FIXME: should also free content and resources allocated
676 * inside iData */
677 HeapFree(GetProcessHeap(), 0, iData);
678 }
[4748]679}
680
681
682/**************************************************************************/
683/* mmmsystem.c */
684/**************************************************************************/
685
686
[10173]687static int MCI_InstalledCount;
688static LPSTR MCI_lpInstallNames = NULL;
[4748]689
690
691/* First MCI valid device ID (0 means error) */
692#define MCI_MAGIC 0x0001
693
694
695/**************************************************************************
[10173]696 * MCI_GetDriver [internal]
[4748]697 */
[10173]698static LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID)
[4748]699{
[10173]700 LPWINE_MCIDRIVER wmd = 0;
701 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
[4748]702
703 EnterCriticalSection(&iData->cs);
704 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
[10173]705 if (wmd->wDeviceID == wDevID)
706 break;
[4748]707 }
708 LeaveCriticalSection(&iData->cs);
709 return wmd;
710}
711
712/**************************************************************************
[10173]713 * MCI_GetDriverFromString [internal]
[4748]714 */
[10173]715static UINT MCI_GetDriverFromString(LPCSTR lpstrName)
[4748]716{
[10173]717 LPWINE_MCIDRIVER wmd;
718 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
719 UINT ret = 0;
[4748]720
721 if (!lpstrName)
722 return 0;
[10173]723
[4748]724 if (!lstrcmpiA(lpstrName, "ALL"))
725 return MCI_ALL_DEVICE_ID;
[10173]726
[4748]727 EnterCriticalSection(&iData->cs);
728 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
729 if (wmd->lpstrElementName && strcmp(wmd->lpstrElementName, lpstrName) == 0) {
[10173]730 ret = wmd->wDeviceID;
731 break;
[4748]732 }
[10173]733
[4748]734 if (wmd->lpstrDeviceType && strcmp(wmd->lpstrDeviceType, lpstrName) == 0) {
[10173]735 ret = wmd->wDeviceID;
736 break;
[4748]737 }
[10173]738
[4748]739 if (wmd->lpstrAlias && strcmp(wmd->lpstrAlias, lpstrName) == 0) {
[10173]740 ret = wmd->wDeviceID;
741 break;
[4748]742 }
743 }
744 LeaveCriticalSection(&iData->cs);
[10173]745
[4748]746 return ret;
747}
748
749
750/**************************************************************************
[10173]751 * MCI_GetDevTypeFromFileName [internal]
[4748]752 */
[10173]753static DWORD MCI_GetDevTypeFromFileName(LPCSTR fileName, LPSTR buf, UINT len)
[4748]754{
[10173]755 LPSTR tmp;
[4748]756
757 if ((tmp = strrchr(fileName, '.'))) {
758 GetProfileStringA("mci extensions", tmp + 1, "*", buf, len);
759 if (strcmp(buf, "*") != 0) {
[10173]760 return 0;
[4748]761 }
762 dprintf(("No [mci extensions] entry for '%s' found. MCI_GetDevTypeFromFileName: line %d, file 'mci.cpp'\n", tmp, __LINE__));
763 }
764 return MCIERR_EXTENSION_NOT_FOUND;
765}
766
767
[10173]768#define MAX_MCICMDTABLE 20
769#define MCI_COMMAND_TABLE_NOT_LOADED 0xFFFE
[4748]770
771
772
773/**************************************************************************
[10173]774 * MCI_DefYieldProc [internal]
[4748]775 */
776//UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data)
777
778UINT16 WINAPI MCI_DefYieldProc(UINT16 wDevID, DWORD data)
779{
[10173]780 INT16 ret;
[4748]781
[10173]782#if 0
[4748]783 dprintf(("(0x%04x, 0x%08lx)\n", wDevID, data));
[10173]784#endif
[4748]785 if ((HIWORD(data) != 0 && GetActiveWindow() != HIWORD(data)) ||
786 (GetAsyncKeyState(LOWORD(data)) & 1) == 0) {
[10173]787 /* WINE stuff removed: UserYield16();*/
788 ret = 0;
[4748]789 } else {
[10173]790 MSG msg;
791
792 msg.hwnd = HIWORD(data);
793 while (!PeekMessageA(&msg, HIWORD(data), WM_KEYFIRST, WM_KEYLAST, PM_REMOVE));
794 ret = -1;
[4748]795 }
796 return ret;
797}
798
799
800/**************************************************************************
[10173]801 * MCI_UnLoadMciDriver [internal]
[4748]802 */
[10173]803static BOOL MCI_UnLoadMciDriver(LPWINE_MM_IDATA iData, LPWINE_MCIDRIVER wmd)
[4748]804{
[10173]805 LPWINE_MCIDRIVER* tmp;
[4748]806
807#if 0
808 dprintf(("Entering MCI_UnLoadMciDriver...\n"));
809#endif
810 if (!wmd)
811 return TRUE;
812
[10173]813 if (wmd->hDrv)
[4748]814 CloseDriver(wmd->hDrv, 0, 0);
815
816 if (wmd->dwPrivate != 0)
817 dprintf(("Unloading mci driver with non nul dwPrivate field\n"));
818
819 EnterCriticalSection(&iData->cs);
820 for (tmp = &iData->lpMciDrvs; *tmp; tmp = &(*tmp)->lpNext) {
821 if (*tmp == wmd) {
[10173]822 *tmp = wmd->lpNext;
823 break;
[4748]824 }
825 }
826 LeaveCriticalSection(&iData->cs);
827
828 HeapFree(GetProcessHeap(), 0, wmd->lpstrDeviceType);
829 HeapFree(GetProcessHeap(), 0, wmd->lpstrAlias);
830 HeapFree(GetProcessHeap(), 0, wmd->lpstrElementName);
831
832 HeapFree(GetProcessHeap(), 0, wmd);
833 //dprintf(("Leaving MCI_UnLoadMciDriver...\n"));
834 return TRUE;
835}
836
837/**************************************************************************
[10173]838 * MCI_LoadMciDriver [internal]
[4748]839 */
[10173]840static DWORD MCI_LoadMciDriver(LPWINE_MM_IDATA iData, LPCSTR _strDevTyp,
841 LPWINE_MCIDRIVER* lpwmd)
[4748]842{
[10173]843 LPSTR strDevTyp = CharUpperA(HEAP_strdupA(GetProcessHeap(), 0, _strDevTyp));
844 LPWINE_MCIDRIVER wmd = (LPWINE_MCIDRIVER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wmd));
845 MCI_OPEN_DRIVER_PARMSA modp;
846 DWORD dwRet = 0;
847 HDRVR hDrv = 0;
[4748]848
849
850 dprintf(("Entering MCI_LoadMciDriver...\n"));
[10173]851
[4748]852 if (!wmd || !strDevTyp) {
853 dwRet = MCIERR_OUT_OF_MEMORY;
854 goto errCleanUp;
855 }
856
857 wmd->lpstrDeviceType = strDevTyp;
858 wmd->lpfnYieldProc = MCI_DefYieldProc;
859 wmd->dwYieldData = VK_CANCEL;
860 wmd->hCreatorTask = NULL;
861
862
863 EnterCriticalSection(&iData->cs);
864 /* wmd must be inserted in list before sending opening the driver, coz' it
865 * may want to lookup at wDevID
866 */
867 wmd->lpNext = iData->lpMciDrvs;
868 iData->lpMciDrvs = wmd;
869
[10173]870 for (modp.wDeviceID = MCI_MAGIC;
871 MCI_GetDriver(modp.wDeviceID) != 0;
[4748]872 modp.wDeviceID++);
873
874 wmd->wDeviceID = modp.wDeviceID;
875
876 LeaveCriticalSection(&iData->cs);
877
878 dprintf(("wDevID=%04X strDevTyp: %s\n", modp.wDeviceID, strDevTyp));
879
880 modp.lpstrParams = NULL;
881
882 hDrv = OpenDriverA(strDevTyp, "mci", (LPARAM)&modp);
[10173]883
[4748]884 if (!hDrv) {
885 dprintf(("Couldn't load driver for type %s.\n"
886 "If you don't have a windows installation accessible from Wine,\n"
887 "you perhaps forgot to create a [mci] section in system.ini\n",
888 strDevTyp));
889 dwRet = MCIERR_DEVICE_NOT_INSTALLED;
890 goto errCleanUp;
[10173]891 }
[4748]892
893 /* FIXME: should also check that module's description is of the form
894 * MODULENAME:[MCI] comment
895 */
896
897 wmd->hDrv = hDrv;
898 /* some drivers will return 0x0000FFFF, some others 0xFFFFFFFF */
899 wmd->uSpecificCmdTable = LOWORD(modp.wCustomCommandTable);
900 wmd->uTypeCmdTable = MCI_COMMAND_TABLE_NOT_LOADED;
901
[10173]902 dprintf(("Loaded driver %x (%s), type is %d, cmdTable=%08x\n",
903 hDrv, strDevTyp, modp.wType, modp.wCustomCommandTable));
904
905
[4748]906 wmd->wType = modp.wType;
907
[10173]908#if 0
909 dprintf(("mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n",
[4748]910 modp.wDeviceID, modp.wType, modp.wDeviceID));
911#endif
912
913 *lpwmd = wmd;
914#if 0
915 dprintf(("Leaving MCI_LoadMciDriver succesful...\n"));
916#endif
917 return 0;
918errCleanUp:
919 MCI_UnLoadMciDriver(iData, wmd);
920 // HeapFree(GetProcessHeap(), 0, strDevTyp);<-- done in MCI_UnloadMciDriver
921 *lpwmd = 0;
922 dprintf(("Leaving MCI_LoadMciDriver on error...\n"));
923 return dwRet;
924}
925
926
927/**************************************************************************
[10173]928 * MCI_SendCommandFrom32 [internal]
[4748]929 */
930static DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
931{
[10173]932 DWORD dwRet = MCIERR_DEVICE_NOT_INSTALLED;
933 LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID);
[4748]934
935 if (!wmd) {
936 dwRet = MCIERR_INVALID_DEVICE_ID;
937 } else {
938 switch (GetDriverFlags(wmd->hDrv) & (WINE_GDF_EXIST)) {
939 case WINE_GDF_EXIST:
[10173]940 dwRet = SendDriverMessage(wmd->hDrv, wMsg, dwParam1, dwParam2);
941 break;
[4748]942 default:
[10173]943 dprintf(("Unknown driver %u\n", wmd->hDrv));
944 dwRet = MCIERR_DRIVER_INTERNAL;
[4748]945 }
946 }
947 return dwRet;
948}
[10173]949
[4748]950/**************************************************************************
[10173]951 * MCI_FinishOpen [internal]
[4748]952 */
[10173]953static DWORD MCI_FinishOpen(LPWINE_MCIDRIVER wmd, LPMCI_OPEN_PARMSA lpParms,
[4748]954 DWORD dwParam)
955{
956 if (dwParam & MCI_OPEN_ELEMENT)
[10173]957 wmd->lpstrElementName = HEAP_strdupA(GetProcessHeap(), 0,
[4748]958 lpParms->lpstrElementName);
[10173]959
[4748]960 if (dwParam & MCI_OPEN_ALIAS)
[10173]961 wmd->lpstrAlias = HEAP_strdupA(GetProcessHeap(), 0, lpParms->lpstrAlias);
962
[4748]963 lpParms->wDeviceID = wmd->wDeviceID;
[10173]964
965 return MCI_SendCommandFrom32(wmd->wDeviceID, MCI_OPEN_DRIVER, dwParam,
[4748]966 (DWORD)lpParms);
967}
968
969/**************************************************************************
[10173]970 * MCI_Open [internal]
[4748]971 */
[10173]972static DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSA lpParms)
[4748]973{
[10173]974 char strDevTyp[128];
975 DWORD dwRet;
976 LPWINE_MCIDRIVER wmd = NULL;
[4748]977
[10173]978 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
[4748]979
980 dprintf(("Entering MCI_OPEN...\n"));
981
982 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
983
984 /* only two low bytes are generic, the other ones are dev type specific */
[10173]985#define WINE_MCIDRIVER_SUPP (0xFFFF0000|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT| \
[4748]986 MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID| \
987 MCI_NOTIFY|MCI_WAIT)
988 if ((dwParam & ~WINE_MCIDRIVER_SUPP) != 0) {
[10173]989 dprintf(("Unsupported yet dwFlags=%08lX\n", dwParam & ~WINE_MCIDRIVER_SUPP));
[4748]990 }
991#undef WINE_MCIDRIVER_SUPP
992
993 strDevTyp[0] = 0;
994
995 if (dwParam & MCI_OPEN_TYPE) {
996 if (dwParam & MCI_OPEN_TYPE_ID) {
[10173]997 WORD uDevType = LOWORD((DWORD)lpParms->lpstrDeviceType);
[4748]998 if (uDevType < MCI_DEVTYPE_FIRST ||
999 uDevType > MCI_DEVTYPE_LAST ||
1000 !LoadStringA(iData->hWinMM32Instance, uDevType, strDevTyp, sizeof(strDevTyp))) /* This gets a name for the device e.g 'cdaudio' */
1001 {
1002 dwRet = MCIERR_BAD_INTEGER;
1003 goto errCleanUp;
1004 }
1005 } else {
[10173]1006 LPSTR ptr;
1007 if (lpParms->lpstrDeviceType == NULL) {
[4748]1008 dwRet = MCIERR_NULL_PARAMETER_BLOCK;
[10173]1009 goto errCleanUp;
1010 }
1011 strcpy(strDevTyp, lpParms->lpstrDeviceType);
1012 ptr = strchr(strDevTyp, '!');
1013 if (ptr) {
1014 /* this behavior is not documented in windows. However, since, in
1015 * some occasions, MCI_OPEN handling is translated by WinMM into
1016 * a call to mciSendString("open <type>"); this code shall be correct
1017 */
1018 if (dwParam & MCI_OPEN_ELEMENT) {
1019 dprintf(("Both MCI_OPEN_ELEMENT(%s) and %s are used\n",
1020 lpParms->lpstrElementName, strDevTyp));
1021 dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
1022 goto errCleanUp;
1023 }
1024 dwParam |= MCI_OPEN_ELEMENT;
1025 *ptr++ = 0;
1026 /* FIXME: not a good idea to write in user supplied buffer */
1027 lpParms->lpstrElementName = ptr;
1028 }
1029
[4748]1030 }
1031 dprintf(("MCI_OPEN (MCI_OPEN_TYPE): devType='%s' !\n", strDevTyp));
1032 }
[10173]1033
[4748]1034 if (dwParam & MCI_OPEN_ELEMENT) {
1035 dprintf(("lpstrElementName='%s'\n", lpParms->lpstrElementName));
1036
1037 if (dwParam & MCI_OPEN_ELEMENT_ID) {
[10173]1038 dprintf(("Unsupported yet flag MCI_OPEN_ELEMENT_ID\n"));
1039 dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
1040 goto errCleanUp;
[4748]1041 }
1042
1043 if (!lpParms->lpstrElementName) {
[10173]1044 dwRet = MCIERR_NULL_PARAMETER_BLOCK;
1045 goto errCleanUp;
[4748]1046 }
1047
1048#if 0
1049 /* Only working on my machine!! CW */
1050 if(lpParms->lpstrElementName[0]=='N') {
[10173]1051 dprintf(("Discarding drive N:\n"));
[4748]1052 dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
[10173]1053 goto errCleanUp;
[4748]1054 }
1055#endif
[10173]1056
[4748]1057 /* type, if given as a parameter, supersedes file extension */
[10173]1058 if (!strDevTyp[0] &&
1059 MCI_GetDevTypeFromFileName(lpParms->lpstrElementName,
[4748]1060 strDevTyp, sizeof(strDevTyp))) {
[10410]1061 if (GetDriveTypeA(lpParms->lpstrElementName) == DRIVE_CDROM) {
1062 /* FIXME: this will not work if several CDROM drives are installed on the machine */
1063 strcpy(strDevTyp, "CDAUDIO");
1064 }
1065 else
1066 if (GetFileAttributesA(lpParms->lpstrElementName) != INVALID_FILE_ATTRIBUTES) {
1067 // TODO: Assuming wave file here
1068 strcpy(strDevTyp, "WAVEAUDIO");
1069 }
1070 else {
[4748]1071 dwRet = MCIERR_EXTENSION_NOT_FOUND;
1072 goto errCleanUp;
1073 }
1074 }
1075 }
[10173]1076
[4748]1077 if (strDevTyp[0] == 0) {
1078 dprintf(("Couldn't load driver (MCI_Open line %d)\n",__LINE__));
1079 dwRet = MCIERR_INVALID_DEVICE_NAME;
1080 goto errCleanUp;
1081 }
1082
1083 if (dwParam & MCI_OPEN_ALIAS) {
1084 dprintf(("MCI_OPEN_ALIAS requested\n"));
1085 if (!lpParms->lpstrAlias) {
[10173]1086 dwRet = MCIERR_NULL_PARAMETER_BLOCK;
1087 goto errCleanUp;
[4748]1088 }
1089 dprintf(("Alias='%s' !\n", lpParms->lpstrAlias));
1090 }
[10173]1091
[4748]1092 if ((dwRet = MCI_LoadMciDriver(iData, strDevTyp, &wmd))) {
1093 goto errCleanUp;
1094 }
1095
1096
1097 if ((dwRet = MCI_FinishOpen(wmd, lpParms, dwParam))) {
1098 dprintf(("Failed to open driver (MCI_OPEN_DRIVER) [%08lx], closing\n", dwRet));
1099 /* FIXME: is dwRet the correct ret code ? */
1100 goto errCleanUp;
1101 }
1102
1103
1104 /* only handled devices fall through */
1105 dprintf(("wDevID=%04X wDeviceID=%d dwRet=%ld\n", wmd->wDeviceID, lpParms->wDeviceID, dwRet));
1106
1107 if (dwParam & MCI_NOTIFY)
1108 // mciDriverNotify16(lpParms->dwCallback, wmd->wDeviceID, MCI_NOTIFY_SUCCESSFUL);
1109 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Open (line %d)\n",__LINE__));
1110
1111 return 0;
1112
1113errCleanUp:
1114
1115 if (wmd) MCI_UnLoadMciDriver(iData, wmd);
1116
1117 if (dwParam & MCI_NOTIFY)
1118 // mciDriverNotify16(lpParms->dwCallback, 0, MCI_NOTIFY_FAILURE);
1119 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Open (line %d)\n",__LINE__));
[10173]1120
[4748]1121 dprintf(("Leaving MCI_Open on error...\n"));
1122 return dwRet;
1123}
1124
1125
1126/**************************************************************************
[10173]1127 * MCI_Close [internal]
[4748]1128 */
[10173]1129static DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
[4748]1130{
[10173]1131 DWORD dwRet;
1132 LPWINE_MCIDRIVER wmd;
1133 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
1134
[4748]1135 //dprintf(("(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms));
1136
1137 if (wDevID == MCI_ALL_DEVICE_ID) {
[10173]1138 LPWINE_MCIDRIVER next;
[4748]1139
[10173]1140 EnterCriticalSection(&iData->cs);
1141 /* FIXME: shall I notify once after all is done, or for
1142 * each of the open drivers ? if the latest, which notif
1143 * to return when only one fails ?
1144 */
1145 for (wmd = iData->lpMciDrvs; wmd; ) {
[4748]1146 next = wmd->lpNext;
1147 MCI_Close(wmd->wDeviceID, dwParam, lpParms);
1148 wmd = next;
[10173]1149 }
1150 LeaveCriticalSection(&iData->cs);
1151 return 0;
[4748]1152 }
1153
1154 if (!(wmd = MCI_GetDriver(wDevID))) {
[10173]1155 return MCIERR_INVALID_DEVICE_ID;
[4748]1156 }
1157
1158 dwRet = MCI_SendCommandFrom32(wDevID, MCI_CLOSE_DRIVER, dwParam, (DWORD)lpParms);
[10173]1159
[4748]1160 MCI_UnLoadMciDriver(iData, wmd);
[10173]1161
[4748]1162 if (dwParam & MCI_NOTIFY)
1163 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Close (line %d)\n",__LINE__));
[10173]1164 // mciDriverNotify16(lpParms->dwCallback, wDevID,
[4748]1165 // (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
[10173]1166
[4748]1167 return dwRet;
1168}
1169
1170
1171/**************************************************************************
[10173]1172 * MCI_WriteString [internal]
[4748]1173 */
[10173]1174DWORD MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr)
[4748]1175{
[10173]1176 DWORD ret = 0;
[4748]1177
1178 if (lpSrcStr) {
[10173]1179 if (dstSize <= strlen(lpSrcStr)) {
1180 lstrcpynA(lpDstStr, lpSrcStr, dstSize - 1);
1181 ret = MCIERR_PARAM_OVERFLOW;
[4748]1182 } else {
[10173]1183 strcpy(lpDstStr, lpSrcStr);
[4748]1184 }
[10173]1185 } else {
1186 *lpDstStr = 0;
1187 }
[4748]1188 return ret;
1189}
1190
1191
1192/**************************************************************************
[10173]1193 * MCI_Sysinfo [internal]
[4748]1194 */
[10173]1195static DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParms)
[4748]1196{
[10173]1197 DWORD ret = MCIERR_INVALID_DEVICE_ID;
1198 LPWINE_MCIDRIVER wmd;
1199 LPWINE_MM_IDATA iData = MULTIMEDIA_GetIData();
[4748]1200
[10173]1201 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
[4748]1202
[10173]1203 TRACE("(%08x, %08lX, %08lX[num=%ld, wDevTyp=%u])\n",
1204 uDevID, dwFlags, (DWORD)lpParms, lpParms->dwNumber, lpParms->wDeviceType);
1205
[4748]1206 switch (dwFlags & ~MCI_SYSINFO_OPEN) {
1207 case MCI_SYSINFO_QUANTITY:
1208 {
[10173]1209 DWORD cnt = 0;
1210
1211 if (lpParms->wDeviceType < MCI_DEVTYPE_FIRST ||
[4748]1212 lpParms->wDeviceType > MCI_DEVTYPE_LAST) {
1213 if (dwFlags & MCI_SYSINFO_OPEN) {
[10173]1214 TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers\n");
1215 EnterCriticalSection(&iData->cs);
1216 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
[4748]1217 cnt++;
[10173]1218 }
1219 LeaveCriticalSection(&iData->cs);
[4748]1220 } else {
[10173]1221 TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers\n");
1222 cnt = MCI_InstalledCount;
[4748]1223 }
[10173]1224 } else {
[4748]1225 if (dwFlags & MCI_SYSINFO_OPEN) {
[10173]1226 TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n",
[4748]1227 lpParms->wDeviceType);
[10173]1228 EnterCriticalSection(&iData->cs);
1229 for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
[4748]1230 if (wmd->wType == lpParms->wDeviceType)
[10173]1231 cnt++;
1232 }
1233 LeaveCriticalSection(&iData->cs);
[4748]1234 } else {
[10173]1235 TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %u\n",
[4748]1236 lpParms->wDeviceType);
[10173]1237 FIXME("Don't know how to get # of MCI devices of a given type\n");
1238 cnt = 1;
[4748]1239 }
[10173]1240 }
1241 *(DWORD*)lpParms->lpstrReturn = cnt;
[4748]1242 }
1243 TRACE("(%ld) => '%ld'\n", lpParms->dwNumber, *(DWORD*)lpParms->lpstrReturn);
1244 ret = MCI_INTEGER_RETURNED;
1245 break;
1246 case MCI_SYSINFO_INSTALLNAME:
1247 TRACE("MCI_SYSINFO_INSTALLNAME \n");
1248 if ((wmd = MCI_GetDriver(uDevID))) {
[10173]1249 ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize,
[4748]1250 wmd->lpstrDeviceType);
1251 } else {
[10173]1252 *lpParms->lpstrReturn = 0;
1253 ret = MCIERR_INVALID_DEVICE_ID;
[4748]1254 }
1255 TRACE("(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
1256 break;
1257 case MCI_SYSINFO_NAME:
1258 TRACE("MCI_SYSINFO_NAME\n");
1259 if (dwFlags & MCI_SYSINFO_OPEN) {
[10173]1260 FIXME("Don't handle MCI_SYSINFO_NAME|MCI_SYSINFO_OPEN (yet)\n");
1261 ret = MCIERR_UNRECOGNIZED_COMMAND;
[4748]1262 } else if (lpParms->dwNumber > MCI_InstalledCount) {
[10173]1263 ret = MCIERR_OUTOFRANGE;
[4748]1264 } else {
[10173]1265 DWORD count = lpParms->dwNumber;
1266 LPSTR ptr = MCI_lpInstallNames;
1267
1268 while (--count > 0) ptr += strlen(ptr) + 1;
1269 ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, ptr);
[4748]1270 }
1271 TRACE("(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
1272 break;
1273 default:
1274 TRACE("Unsupported flag value=%08lx\n", dwFlags);
1275 ret = MCIERR_UNRECOGNIZED_COMMAND;
1276 }
1277 return ret;
1278}
1279
1280
1281/**************************************************************************
[10173]1282 * MCI_Break [internal]
[4748]1283 */
[10173]1284static DWORD MCI_Break(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms)
[4748]1285{
[10173]1286 DWORD dwRet = 0;
[4748]1287
[10173]1288 if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
1289
[4748]1290 if (dwFlags & MCI_NOTIFY)
1291 dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Break (line %d)\n",__LINE__));
[10173]1292 // mciDriverNotify16(lpParms->dwCallback, wDevID,
1293 // (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
[4748]1294
1295 return dwRet;
1296}
1297
[10173]1298
[4748]1299/**************************************************************************
[10173]1300 * MCI_SendCommand [internal]
[4748]1301 */
[10173]1302static DWORD MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1,
1303 DWORD dwParam2)
[4748]1304{
[10173]1305 DWORD dwRet = MCIERR_UNRECOGNIZED_COMMAND;
[4748]1306
1307 switch (wMsg) {
1308 case MCI_OPEN:
1309 dwRet = MCI_Open(dwParam1, (LPMCI_OPEN_PARMSA)dwParam2);
1310 break;
1311 case MCI_CLOSE:
1312 dwRet = MCI_Close(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
1313 break;
1314 case MCI_SYSINFO:
1315 dwRet = MCI_SysInfo(wDevID, dwParam1, (LPMCI_SYSINFO_PARMSA)dwParam2);
1316 break;
1317 case MCI_BREAK:
1318 dwRet = MCI_Break(wDevID, dwParam1, (LPMCI_BREAK_PARMS)dwParam2);
1319 break;
1320 // case MCI_SOUND:
1321 /* FIXME: it seems that MCI_SOUND needs the same handling as MCI_BREAK
1322 * but I couldn't get any doc on this MCI message
1323 */
1324 // break;
1325 default:
1326 if (wDevID == MCI_ALL_DEVICE_ID) {
[10173]1327 dprintf(("MCI_SendCommand: unhandled MCI_ALL_DEVICE_ID\n"));
1328 dwRet = MCIERR_CANNOT_USE_ALL;
[4748]1329 } else {
1330 dwRet=MCI_SendCommandFrom32(wDevID, wMsg, dwParam1, dwParam2);
[10173]1331 }
[4748]1332 break;
1333 }
1334 return dwRet;
1335}
1336
1337
1338
1339
1340/**************************************************************************
[10173]1341 * MULTIMEDIA_MciInit [internal]
[4748]1342 *
1343 * Initializes the MCI internal variables.
1344 *
1345 */
1346BOOL MULTIMEDIA_MciInit(void)
1347{
[10173]1348 LPSTR ptr1, ptr2;
1349 HKEY hWineConf;
1350 HKEY hkey;
1351 DWORD err;
1352 DWORD type;
1353 DWORD count = 2048;
[4748]1354
1355 MCI_InstalledCount = 0;
1356 ptr1 = MCI_lpInstallNames = (char*) HeapAlloc(GetProcessHeap(), 0, count);
1357
1358 if (!MCI_lpInstallNames)
1359 return FALSE;
1360
1361#if 0
1362 /* FIXME: should do also some registry diving here ? */
1363 if (!(err = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config", &hWineConf)) &&
1364 !(err = RegOpenKeyA(hWineConf, "options", &hkey))) {
1365 err = RegQueryValueExA(hkey, "mci", 0, &type, MCI_lpInstallNames, &count);
1366 RegCloseKey(hkey);
1367 FIXME("Registry handling for mci drivers not changed for odin yet. Verbatim copy from WINE (line %d)",__LINE__);
1368 }
1369 FIXME("No Registry querying for mci drivers yet! (line %d)",__LINE__);
1370 err=1;
1371 if (!err) {
1372 TRACE("Wine => '%s' \n", ptr1);
1373 while ((ptr2 = strchr(ptr1, ':')) != 0) {
[10173]1374 *ptr2++ = 0;
1375 TRACE("---> '%s' \n", ptr1);
1376 MCI_InstalledCount++;
1377 ptr1 = ptr2;
[4748]1378 }
1379 MCI_InstalledCount++;
1380 TRACE("---> '%s' \n", ptr1);
1381 ptr1 += strlen(ptr1) + 1;
1382 } else {
1383 GetPrivateProfileStringA("mci", NULL, "", MCI_lpInstallNames, count, "SYSTEM.INI");
1384 while (strlen(ptr1) > 0) {
[10173]1385 TRACE("---> '%s' \n", ptr1);
1386 ptr1 += strlen(ptr1) + 1;
1387 MCI_InstalledCount++;
[4748]1388 }
1389 }
1390 //RegCloseKey(hWineConf);
[10410]1391#else
1392 //Just used hardcoded names here
1393 strcpy(MCI_lpInstallNames, "CDAUDIO=MCICDA");
1394 strcpy(MCI_lpInstallNames+strlen(MCI_lpInstallNames)+1, "WAVEAUDIO=MCIWAVE");
1395 MCI_InstalledCount = 2;
1396#endif
[4748]1397 return TRUE;
1398}
Note: See TracBrowser for help on using the repository browser.