Ignore:
Timestamp:
Dec 3, 2000, 11:19:43 PM (25 years ago)
Author:
sandervl
Message:

CW: Ported Wine MCI code

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/winmm/mci.cpp

    r2812 r4748  
    1 /* $Id: mci.cpp,v 1.5 2000-02-17 14:09:31 sandervl Exp $ */
     1/* $Id: mci.cpp,v 1.6 2000-12-03 22:18:17 sandervl Exp $ */
    22
    33/*
    4  * MCI stubs
     4 * MCI functions
    55 *
    66 * Copyright 1998 Joel Troster
    7  *
     7 * Copyright 1998/1999 Eric Pouech
     8 * Copyright 2000 Chris Wohlgemuth
    89 *
    910 * Project Odin Software License can be found in LICENSE.TXT
     
    1516 * Includes                                                                 *
    1617 ****************************************************************************/
     18
     19#define  INCL_BASE
     20#define  INCL_OS2MM
    1721
    1822#include <os2win.h>
     
    2125#include <string.h>
    2226#include <stdio.h>
     27#include "debugtools.h"
    2328
    2429#include <misc.h>
    2530#include <unicode.h>
    2631
     32#include "mcimm.h"
     33
    2734#include "winmm.h"
    2835
    2936#define DBG_LOCALLOG    DBG_mci
     37
    3038#include "dbglocal.h"
     39
     40
     41/****************************************************************************
     42 * Local functions                                                          *
     43 ****************************************************************************/
     44
     45/* forward declaration */
     46static DWORD  MCI_SendCommand(UINT mciId,
     47              UINT16 uMsg,
     48              DWORD dwParam1,
     49              DWORD dwParam2);
     50
     51static LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID) ;
     52static UINT     MCI_GetDriverFromString(LPCSTR lpstrName);
     53
     54/****************************************************************************/
    3155
    3256ODINDEBUGCHANNEL(WINMM-MCI)
     
    3862              UINT, uStatus)
    3963{
    40   dprintf(("WINMM:mciDriverNotify - stub\n"));
    41   return FALSE;
     64  TRACE("Entering mciDriverNotify (%08X, %04x, %04X)\n", hwndCallback, uDeviceID, uStatus);
     65 
     66  if (!IsWindow(hwndCallback)) {
     67        WARN("bad hwnd for call back (0x%04x)\n", hwndCallback);
     68        return FALSE;
     69  }
     70  TRACE("before PostMessage\n");
     71  PostMessageA(hwndCallback, MM_MCINOTIFY, uStatus, uDeviceID);
     72  return TRUE;
    4273}
    4374
     
    73104              LPCSTR, pszDevice)
    74105{
    75   dprintf(("WINMM:mciGetDeviceIDA - stub\n"));
    76   return 0;
     106  WARN(("WINMM:mciGetDeviceIDA - untested\n"));
     107  return MCI_GetDriverFromString(pszDevice);
    77108}
    78109
     
    100131}
    101132
     133/*****************************************************************************
     134 *             Queries driver data
     135 * Parameters: UINT uDeviceID
     136 * Variables :
     137 * @return   :  Pointer to driver data (as a DWORD)
     138 * Remark    :
     139 * @status   : Completely
     140 *
     141 * @author   : Chris Wohlgemuth [Sun, 2000/11/19]
     142 *****************************************************************************/
    102143ODINFUNCTION1(DWORD, mciGetDriverData,
    103144              UINT, uDeviceID)
    104145{
    105   dprintf(("WINMM:mciGetDriverData - stub\n"));
    106   return 0;
    107 }
    108 
     146  LPWINE_MCIDRIVER      wmd;
     147 
     148  wmd = MCI_GetDriver(uDeviceID);
     149 
     150  if (!wmd) {
     151        dprintf(("WARNING: Bad uDeviceID (mciGetDriverData (mci.cpp line %d)\n",__LINE__));
     152    return 0L; /* Error */
     153  }
     154   
     155  return wmd->dwPrivate;
     156}
     157
     158/*****************************************************************************
     159 *             Converts an error to an error string
     160 * Parameters: MCIERROR mcierr,
     161 *             LPSTR pszText,
     162 *             UINT cchText
     163 * Variables :
     164 * @return   : API returncode (TRUE/FALSE)
     165 * Remark    :
     166 * @status   : Completely
     167 *
     168 * @author   : Wine
     169 *****************************************************************************/
    109170ODINFUNCTION3(BOOL, mciGetErrorStringA,
    110171              MCIERROR, mcierr,
     
    125186}
    126187
     188/*****************************************************************************
     189 *             Converts an error to an error string
     190 * Parameters: MCIERROR mcierr,
     191 *             LPSTR pszText,
     192 *             UINT cchText
     193 * Variables :
     194 * @return   : API returncode (TRUE/FALSE)
     195 * Remark    :
     196 * @status   : Completely
     197 *
     198 * @author   : Wine
     199 *****************************************************************************/
    127200ODINFUNCTION3(BOOL, mciGetErrorStringW,
    128201              MCIERROR, mcierr,
     
    143216}
    144217
     218/*****************************************************************************
     219 *             Converts an error to an error string
     220 * Parameters: MCIERROR mcierr,
     221 *             LPSTR pszText,
     222 *             UINT cchText
     223 * Variables :
     224 * @return    : API returncode
     225 * Remark    :
     226 * @status    : Completely
     227 *
     228 * @author    : Wine
     229 *****************************************************************************/
    145230ODINFUNCTION2(YIELDPROC, mciGetYieldProc,
    146231              MCIDEVICEID, mciId,
    147232              LPDWORD, pdwYieldData)
    148233{
    149   dprintf(("WINMM:mciGetYieldProc - stub\n"));
    150   return 0;
     234  LPWINE_MCIDRIVER      wmd;
     235 
     236  TRACE("Entering mciGetYieldProc (%u, %p) - untested\n", mciId, pdwYieldData);
     237
     238  if (!(wmd = MCI_GetDriver(mciId))) {
     239        WARN("Bad uDeviceID\n");
     240        return NULL;
     241  }
     242  if (!wmd->lpfnYieldProc) {
     243        WARN("No proc set\n");
     244        return NULL;
     245  }
     246  if (!wmd->bIs32) {
     247        WARN("Proc is 32 bit\n");
     248        return NULL;
     249  }
     250  return wmd->lpfnYieldProc;
    151251}
    152252
     
    159259  return 0;
    160260}
     261
    161262
    162263ODINFUNCTION4(MCIERROR, mciSendCommandA,
     
    166267              DWORD, dwParam2)
    167268{
    168   dprintf(("WINMM:mciSendCommandA - stub %X %X %X %X\n", mciId, uMsg, dwParam1, dwParam2));
    169   return(MMSYSERR_NODRIVER);
    170 }
     269  DWORD dwRet;
     270  //  dprintf(("WINMM:mciSendCommandA - entering %X %X %X %X\n", mciId, uMsg, dwParam1, dwParam2));
     271  dwRet= MCI_SendCommand((UINT) mciId,  uMsg,  dwParam1, dwParam2) & 0xFFFF;     
     272  return(dwRet);
     273}
     274
    171275
    172276ODINFUNCTION4(MCIERROR, mciSendCommandW,
     
    187291{
    188292  dprintf(("WINMM:mciSendStringA - stub\n"));
     293  if(lpstrCommand)
     294    dprintf(("WINMM:mciSendStringA command: %s\n",lpstrCommand));
    189295  return(MMSYSERR_NODRIVER);
    190296}
     
    204310              DWORD, dwData)
    205311{
    206   dprintf(("WINMM:mciSetDriverData - stub\n"));
    207   return FALSE;
    208 }
     312  LPWINE_MCIDRIVER      wmd;
     313 
     314  wmd = MCI_GetDriver(uDeviceID);
     315
     316  if (!wmd) {
     317        dprintf(("WARNING: Bad uDeviceID (mciSetDriverData line %d)\n",__LINE__));
     318        return FALSE;
     319  }
     320 
     321  wmd->dwPrivate = dwData;
     322  return TRUE;
     323}
     324
    209325
    210326ODINFUNCTION3(BOOL, mciSetYieldProc,
     
    213329              DWORD, dwYieldData)
    214330{
    215   dprintf(("WINMM:mciSetYieldProc - stub\n"));
    216   return FALSE;
    217 }
    218 
    219 
     331  LPWINE_MCIDRIVER      wmd;
     332 
     333  TRACE("WINMM:mciSetYieldProc (%u, %p, %08lx) - untested\n", mciId, fpYieldProc, dwYieldData);
     334 
     335  if (!(wmd = MCI_GetDriver(mciId))) {
     336        WARN("Bad uDeviceID\n");
     337        return FALSE;
     338  }
     339 
     340  wmd->lpfnYieldProc = fpYieldProc;
     341  wmd->dwYieldData   = dwYieldData;
     342  wmd->bIs32         = TRUE;
     343 
     344  return TRUE;
     345}
     346
     347
     348/**************************************************************************/
     349/*                       heap.c                                           */
     350/**************************************************************************/
     351
     352#ifdef __GNUC__
     353#define GET_EIP()    (__builtin_return_address(0))
     354#define SET_EIP(ptr) ((ARENA_INUSE*)(ptr) - 1)->callerEIP = GET_EIP()
     355#else
     356#define GET_EIP()    0
     357#define SET_EIP(ptr) /* nothing */
     358#endif  /* __GNUC__ */
     359
     360/***********************************************************************
     361 *           HEAP_strdupA
     362 */
     363static LPSTR HEAP_strdupA( HANDLE heap, DWORD flags, LPCSTR str )
     364{
     365    LPSTR p = (LPSTR) HeapAlloc( heap, flags, strlen(str) + 1 );
     366    if(p) {
     367      //SET_EIP(p);
     368      strcpy( p, str );
     369    }
     370    return p;
     371}
     372
     373
     374/**************************************************************************/
     375/*                     mmmsystem.c                                        */
     376/**************************************************************************/
     377
     378static LPWINE_MM_IDATA          lpFirstIData = NULL;
     379
     380static  LPWINE_MM_IDATA MULTIMEDIA_GetIDataNoCheck(void)
     381{
     382    DWORD               pid = GetCurrentProcessId();
     383    LPWINE_MM_IDATA     iData;
     384
     385    for (iData = lpFirstIData; iData; iData = iData->lpNextIData) {
     386      if (iData->dwThisProcess == pid)
     387            break;
     388    }
     389    return iData;
     390}
     391
     392/**************************************************************************
     393 *                      MULTIMEDIA_GetIData                     [internal]
     394 */
     395LPWINE_MM_IDATA MULTIMEDIA_GetIData(void)
     396{
     397    LPWINE_MM_IDATA     iData = MULTIMEDIA_GetIDataNoCheck();
     398
     399    if (!iData) {
     400      dprintf(("MULTIMEDIA_GetIData: IData not found for pid=%08lx. Suicide !!!\n", GetCurrentProcessId()));
     401      ExitProcess(0);
     402    }
     403    return iData;
     404}
     405
     406
     407/**************************************************************************
     408 *                      MULTIMEDIA_CreateIData                  [internal]
     409 */
     410BOOL MULTIMEDIA_CreateIData(HINSTANCE hInstDLL)
     411{
     412    LPWINE_MM_IDATA     iData;
     413       
     414    iData = (LPWINE_MM_IDATA) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WINE_MM_IDATA));
     415
     416    if (!iData)
     417      return FALSE;
     418    iData->hWinMM32Instance = hInstDLL;
     419    iData->dwThisProcess = GetCurrentProcessId();
     420    iData->lpNextIData = lpFirstIData;
     421    lpFirstIData = iData;
     422    InitializeCriticalSection(&iData->cs);
     423    dprintf(("Created IData (%p) for pid %08lx\n", iData, iData->dwThisProcess));
     424    return TRUE;
     425}
     426
     427
     428/**************************************************************************
     429 *                      MULTIMEDIA_DeleteIData                  [internal]
     430 */
     431void MULTIMEDIA_DeleteIData(void)
     432{
     433    LPWINE_MM_IDATA     iData = MULTIMEDIA_GetIDataNoCheck();
     434    LPWINE_MM_IDATA*    ppid;
     435           
     436    if (iData) {
     437        for (ppid = &lpFirstIData; *ppid; ppid = &(*ppid)->lpNextIData) {
     438            if (*ppid == iData) {
     439                *ppid = iData->lpNextIData;
     440                break;
     441            }
     442        }
     443        /* FIXME: should also free content and resources allocated
     444         * inside iData */
     445        HeapFree(GetProcessHeap(), 0, iData);
     446    }
     447}
     448
     449
     450/**************************************************************************/
     451/*                     mmmsystem.c                                        */
     452/**************************************************************************/
     453
     454
     455static  int                     MCI_InstalledCount;
     456static  LPSTR                   MCI_lpInstallNames = NULL;
     457
     458
     459/* First MCI valid device ID (0 means error) */
     460#define MCI_MAGIC 0x0001
     461
     462
     463/**************************************************************************
     464 *                              MCI_GetDriver                   [internal]
     465 */
     466static LPWINE_MCIDRIVER MCI_GetDriver(UINT16 wDevID)
     467{
     468    LPWINE_MCIDRIVER    wmd = 0;
     469    LPWINE_MM_IDATA     iData = MULTIMEDIA_GetIData();
     470
     471    EnterCriticalSection(&iData->cs);
     472    for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
     473        if (wmd->wDeviceID == wDevID)
     474            break;
     475    }
     476    LeaveCriticalSection(&iData->cs);
     477    return wmd;
     478}
     479
     480/**************************************************************************
     481 *                              MCI_GetDriverFromString         [internal]
     482 */
     483static UINT     MCI_GetDriverFromString(LPCSTR lpstrName)
     484{
     485    LPWINE_MCIDRIVER    wmd;
     486    LPWINE_MM_IDATA     iData = MULTIMEDIA_GetIData();
     487    UINT                ret = 0;
     488
     489    if (!lpstrName)
     490      return 0;
     491   
     492    if (!lstrcmpiA(lpstrName, "ALL"))
     493      return MCI_ALL_DEVICE_ID;
     494   
     495    EnterCriticalSection(&iData->cs);
     496    for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
     497      if (wmd->lpstrElementName && strcmp(wmd->lpstrElementName, lpstrName) == 0) {
     498            ret = wmd->wDeviceID;
     499            break;
     500      }
     501     
     502      if (wmd->lpstrDeviceType && strcmp(wmd->lpstrDeviceType, lpstrName) == 0) {
     503            ret = wmd->wDeviceID;
     504            break;
     505      }
     506     
     507      if (wmd->lpstrAlias && strcmp(wmd->lpstrAlias, lpstrName) == 0) {
     508            ret = wmd->wDeviceID;
     509            break;
     510      }
     511    }
     512    LeaveCriticalSection(&iData->cs);
     513   
     514    return ret;
     515}
     516
     517
     518/**************************************************************************
     519 *                              MCI_GetDevTypeFromFileName      [internal]
     520 */
     521static  DWORD   MCI_GetDevTypeFromFileName(LPCSTR fileName, LPSTR buf, UINT len)
     522{
     523    LPSTR       tmp;
     524
     525    if ((tmp = strrchr(fileName, '.'))) {
     526      GetProfileStringA("mci extensions", tmp + 1, "*", buf, len);
     527      if (strcmp(buf, "*") != 0) {
     528            return 0;
     529      }
     530      dprintf(("No [mci extensions] entry for '%s' found. MCI_GetDevTypeFromFileName: line %d, file 'mci.cpp'\n", tmp, __LINE__));
     531    }
     532    return MCIERR_EXTENSION_NOT_FOUND;
     533}
     534
     535
     536#define MAX_MCICMDTABLE                 20
     537#define MCI_COMMAND_TABLE_NOT_LOADED    0xFFFE
     538
     539
     540
     541/**************************************************************************
     542 *                              MCI_DefYieldProc                [internal]
     543 */
     544//UINT WINAPI MCI_DefYieldProc(MCIDEVICEID wDevID, DWORD data)
     545
     546UINT16 WINAPI MCI_DefYieldProc(UINT16 wDevID, DWORD data)
     547{
     548  INT16 ret;
     549
     550#if 0 
     551  dprintf(("(0x%04x, 0x%08lx)\n", wDevID, data));
     552#endif 
     553  if ((HIWORD(data) != 0 && GetActiveWindow() != HIWORD(data)) ||
     554      (GetAsyncKeyState(LOWORD(data)) & 1) == 0) {
     555        /* WINE stuff removed: UserYield16();*/
     556        ret = 0;
     557  } else {
     558        MSG             msg;
     559   
     560        msg.hwnd = HIWORD(data);
     561        while (!PeekMessageA(&msg, HIWORD(data), WM_KEYFIRST, WM_KEYLAST, PM_REMOVE));
     562        ret = -1;
     563  }
     564  return ret;
     565}
     566
     567
     568/**************************************************************************
     569 *                              MCI_UnLoadMciDriver             [internal]
     570 */
     571static  BOOL    MCI_UnLoadMciDriver(LPWINE_MM_IDATA iData, LPWINE_MCIDRIVER wmd)
     572{
     573    LPWINE_MCIDRIVER*           tmp;
     574
     575#if 0
     576    dprintf(("Entering MCI_UnLoadMciDriver...\n"));
     577#endif
     578    if (!wmd)
     579      return TRUE;
     580
     581    if (wmd->hDrv)
     582      CloseDriver(wmd->hDrv, 0, 0);
     583
     584    if (wmd->dwPrivate != 0)
     585      dprintf(("Unloading mci driver with non nul dwPrivate field\n"));
     586
     587    EnterCriticalSection(&iData->cs);
     588    for (tmp = &iData->lpMciDrvs; *tmp; tmp = &(*tmp)->lpNext) {
     589      if (*tmp == wmd) {
     590            *tmp = wmd->lpNext;
     591            break;
     592      }
     593    }
     594    LeaveCriticalSection(&iData->cs);
     595
     596    HeapFree(GetProcessHeap(), 0, wmd->lpstrDeviceType);
     597    HeapFree(GetProcessHeap(), 0, wmd->lpstrAlias);
     598    HeapFree(GetProcessHeap(), 0, wmd->lpstrElementName);
     599
     600    HeapFree(GetProcessHeap(), 0, wmd);
     601    //dprintf(("Leaving MCI_UnLoadMciDriver...\n"));
     602    return TRUE;
     603}
     604
     605/**************************************************************************
     606 *                              MCI_LoadMciDriver               [internal]
     607 */
     608static  DWORD   MCI_LoadMciDriver(LPWINE_MM_IDATA iData, LPCSTR _strDevTyp,
     609                                  LPWINE_MCIDRIVER* lpwmd)
     610{
     611    LPSTR                       strDevTyp = CharUpperA(HEAP_strdupA(GetProcessHeap(), 0, _strDevTyp));
     612    LPWINE_MCIDRIVER            wmd = (LPWINE_MCIDRIVER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wmd));
     613    MCI_OPEN_DRIVER_PARMSA      modp;
     614    DWORD                       dwRet = 0;
     615    HDRVR                       hDrv = 0;
     616
     617
     618    dprintf(("Entering MCI_LoadMciDriver...\n"));
     619 
     620    if (!wmd || !strDevTyp) {
     621      dwRet = MCIERR_OUT_OF_MEMORY;
     622      goto errCleanUp;
     623    }
     624
     625    wmd->lpstrDeviceType = strDevTyp;
     626    wmd->lpfnYieldProc = MCI_DefYieldProc;
     627    wmd->dwYieldData = VK_CANCEL;
     628    wmd->hCreatorTask = NULL;
     629
     630
     631    EnterCriticalSection(&iData->cs);
     632    /* wmd must be inserted in list before sending opening the driver, coz' it
     633     * may want to lookup at wDevID
     634     */
     635    wmd->lpNext = iData->lpMciDrvs;
     636    iData->lpMciDrvs = wmd;
     637
     638    for (modp.wDeviceID = MCI_MAGIC;
     639         MCI_GetDriver(modp.wDeviceID) != 0;
     640         modp.wDeviceID++);
     641
     642    wmd->wDeviceID = modp.wDeviceID;
     643
     644    LeaveCriticalSection(&iData->cs);
     645
     646    dprintf(("wDevID=%04X strDevTyp: %s\n", modp.wDeviceID, strDevTyp));
     647
     648    modp.lpstrParams = NULL;
     649
     650    hDrv = OpenDriverA(strDevTyp, "mci", (LPARAM)&modp);
     651   
     652    if (!hDrv) {
     653      dprintf(("Couldn't load driver for type %s.\n"
     654               "If you don't have a windows installation accessible from Wine,\n"
     655               "you perhaps forgot to create a [mci] section in system.ini\n",
     656               strDevTyp));
     657      dwRet = MCIERR_DEVICE_NOT_INSTALLED;
     658      goto errCleanUp;
     659    }                           
     660
     661    /* FIXME: should also check that module's description is of the form
     662     * MODULENAME:[MCI] comment
     663     */
     664
     665    wmd->hDrv = hDrv;
     666    /* some drivers will return 0x0000FFFF, some others 0xFFFFFFFF */
     667    wmd->uSpecificCmdTable = LOWORD(modp.wCustomCommandTable);
     668    wmd->uTypeCmdTable = MCI_COMMAND_TABLE_NOT_LOADED;
     669
     670    dprintf(("Loaded driver %x (%s), type is %d, cmdTable=%08x\n",
     671          hDrv, strDevTyp, modp.wType, modp.wCustomCommandTable));
     672   
     673   
     674    wmd->wType = modp.wType;
     675
     676#if 0   
     677    dprintf(("mcidev=%d, uDevTyp=%04X wDeviceID=%04X !\n",
     678             modp.wDeviceID, modp.wType, modp.wDeviceID));
     679#endif
     680
     681    *lpwmd = wmd;
     682#if 0
     683    dprintf(("Leaving MCI_LoadMciDriver succesful...\n"));
     684#endif
     685    return 0;
     686errCleanUp:
     687    MCI_UnLoadMciDriver(iData, wmd);
     688    //  HeapFree(GetProcessHeap(), 0, strDevTyp);<-- done in MCI_UnloadMciDriver
     689    *lpwmd = 0;
     690    dprintf(("Leaving MCI_LoadMciDriver on error...\n"));
     691    return dwRet;
     692}
     693
     694
     695/**************************************************************************
     696 *                      MCI_SendCommandFrom32                   [internal]
     697 */
     698static DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
     699{
     700    DWORD               dwRet = MCIERR_DEVICE_NOT_INSTALLED;
     701    LPWINE_MCIDRIVER    wmd = MCI_GetDriver(wDevID);
     702
     703    if (!wmd) {
     704      dwRet = MCIERR_INVALID_DEVICE_ID;
     705    } else {
     706      switch (GetDriverFlags(wmd->hDrv) & (WINE_GDF_EXIST)) {
     707      case WINE_GDF_EXIST:
     708            dwRet = SendDriverMessage(wmd->hDrv, wMsg, dwParam1, dwParam2);
     709            break;
     710      default:
     711            dprintf(("Unknown driver %u\n", wmd->hDrv));
     712            dwRet = MCIERR_DRIVER_INTERNAL;
     713      }
     714    }
     715    return dwRet;
     716}
     717   
     718/**************************************************************************
     719 *                      MCI_FinishOpen                          [internal]
     720 */
     721static  DWORD   MCI_FinishOpen(LPWINE_MCIDRIVER wmd, LPMCI_OPEN_PARMSA lpParms,
     722                               DWORD dwParam)
     723{
     724  if (dwParam & MCI_OPEN_ELEMENT)
     725        wmd->lpstrElementName = HEAP_strdupA(GetProcessHeap(), 0,
     726                                         lpParms->lpstrElementName);
     727 
     728  if (dwParam & MCI_OPEN_ALIAS)
     729        wmd->lpstrAlias = HEAP_strdupA(GetProcessHeap(), 0, lpParms->lpstrAlias);
     730 
     731  lpParms->wDeviceID = wmd->wDeviceID;
     732 
     733  return MCI_SendCommandFrom32(wmd->wDeviceID, MCI_OPEN_DRIVER, dwParam,
     734                               (DWORD)lpParms);
     735}
     736
     737/**************************************************************************
     738 *                      MCI_Open                                [internal]
     739 */
     740static  DWORD MCI_Open(DWORD dwParam, LPMCI_OPEN_PARMSA lpParms)
     741{
     742    char                        strDevTyp[128];
     743    DWORD                       dwRet;
     744    LPWINE_MCIDRIVER            wmd = NULL;
     745
     746    LPWINE_MM_IDATA             iData = MULTIMEDIA_GetIData();
     747
     748    dprintf(("Entering MCI_OPEN...\n"));
     749
     750    if (lpParms == NULL) return MCIERR_NULL_PARAMETER_BLOCK;
     751
     752    /* only two low bytes are generic, the other ones are dev type specific */
     753#define WINE_MCIDRIVER_SUPP     (0xFFFF0000|MCI_OPEN_SHAREABLE|MCI_OPEN_ELEMENT| \
     754                         MCI_OPEN_ALIAS|MCI_OPEN_TYPE|MCI_OPEN_TYPE_ID| \
     755                         MCI_NOTIFY|MCI_WAIT)
     756    if ((dwParam & ~WINE_MCIDRIVER_SUPP) != 0) {
     757        dprintf(("Unsupported yet dwFlags=%08lX\n", dwParam & ~WINE_MCIDRIVER_SUPP));
     758    }
     759#undef WINE_MCIDRIVER_SUPP
     760
     761    strDevTyp[0] = 0;
     762
     763    if (dwParam & MCI_OPEN_TYPE) {
     764      if (dwParam & MCI_OPEN_TYPE_ID) {
     765            WORD uDevType = LOWORD((DWORD)lpParms->lpstrDeviceType);
     766        if (uDevType < MCI_DEVTYPE_FIRST ||
     767            uDevType > MCI_DEVTYPE_LAST ||
     768            !LoadStringA(iData->hWinMM32Instance, uDevType, strDevTyp, sizeof(strDevTyp))) /* This gets a name for the device e.g 'cdaudio' */
     769          {
     770            dwRet = MCIERR_BAD_INTEGER;
     771            goto errCleanUp;
     772          }
     773      } else {
     774            LPSTR       ptr;
     775            if (lpParms->lpstrDeviceType == NULL) {
     776          dwRet = MCIERR_NULL_PARAMETER_BLOCK;
     777                goto errCleanUp;
     778            }
     779            strcpy(strDevTyp, lpParms->lpstrDeviceType);
     780            ptr = strchr(strDevTyp, '!');
     781            if (ptr) {
     782                /* this behavior is not documented in windows. However, since, in
     783                 * some occasions, MCI_OPEN handling is translated by WinMM into
     784                 * a call to mciSendString("open <type>"); this code shall be correct
     785                 */
     786                if (dwParam & MCI_OPEN_ELEMENT) {
     787                    dprintf(("Both MCI_OPEN_ELEMENT(%s) and %s are used\n",
     788                        lpParms->lpstrElementName, strDevTyp));
     789                    dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
     790                    goto errCleanUp;
     791                }
     792                dwParam |= MCI_OPEN_ELEMENT;
     793                *ptr++ = 0;
     794                /* FIXME: not a good idea to write in user supplied buffer */
     795                lpParms->lpstrElementName = ptr;
     796            }
     797               
     798      }
     799      dprintf(("MCI_OPEN (MCI_OPEN_TYPE): devType='%s' !\n", strDevTyp));
     800    }
     801   
     802    if (dwParam & MCI_OPEN_ELEMENT) {
     803      dprintf(("lpstrElementName='%s'\n", lpParms->lpstrElementName));
     804
     805      if (dwParam & MCI_OPEN_ELEMENT_ID) {
     806            dprintf(("Unsupported yet flag MCI_OPEN_ELEMENT_ID\n"));
     807            dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
     808            goto errCleanUp;
     809      }
     810
     811      if (!lpParms->lpstrElementName) {
     812            dwRet = MCIERR_NULL_PARAMETER_BLOCK;
     813            goto errCleanUp;
     814      }
     815
     816#if 0
     817      /* Only working on my machine!! CW */
     818      if(lpParms->lpstrElementName[0]=='N') {
     819            dprintf(("Discarding drive N:\n"));
     820        dwRet = MCIERR_UNRECOGNIZED_KEYWORD;
     821            goto errCleanUp;
     822      }
     823#endif
     824     
     825      /* type, if given as a parameter, supersedes file extension */
     826      if (!strDevTyp[0] &&
     827          MCI_GetDevTypeFromFileName(lpParms->lpstrElementName,
     828                                     strDevTyp, sizeof(strDevTyp))) {
     829        if (GetDriveTypeA(lpParms->lpstrElementName) != DRIVE_CDROM) {
     830          dwRet = MCIERR_EXTENSION_NOT_FOUND;
     831          goto errCleanUp;
     832        }
     833        /* FIXME: this will not work if several CDROM drives are installed on the machine */
     834        strcpy(strDevTyp, "CDAUDIO");
     835      }
     836    }
     837   
     838    if (strDevTyp[0] == 0) {
     839      dprintf(("Couldn't load driver (MCI_Open line %d)\n",__LINE__));
     840      dwRet = MCIERR_INVALID_DEVICE_NAME;
     841      goto errCleanUp;
     842    }
     843
     844    if (dwParam & MCI_OPEN_ALIAS) {
     845      dprintf(("MCI_OPEN_ALIAS requested\n"));
     846      if (!lpParms->lpstrAlias) {
     847            dwRet = MCIERR_NULL_PARAMETER_BLOCK;
     848            goto errCleanUp;
     849      }
     850      dprintf(("Alias='%s' !\n", lpParms->lpstrAlias));
     851    }
     852   
     853    if ((dwRet = MCI_LoadMciDriver(iData, strDevTyp, &wmd))) {
     854      goto errCleanUp;
     855    }
     856
     857
     858    if ((dwRet = MCI_FinishOpen(wmd, lpParms, dwParam))) {
     859      dprintf(("Failed to open driver (MCI_OPEN_DRIVER) [%08lx], closing\n", dwRet));
     860      /* FIXME: is dwRet the correct ret code ? */
     861      goto errCleanUp;
     862    }
     863
     864
     865    /* only handled devices fall through */
     866    dprintf(("wDevID=%04X wDeviceID=%d dwRet=%ld\n", wmd->wDeviceID, lpParms->wDeviceID, dwRet));
     867
     868    if (dwParam & MCI_NOTIFY)
     869      // mciDriverNotify16(lpParms->dwCallback, wmd->wDeviceID, MCI_NOTIFY_SUCCESSFUL);
     870      dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Open (line %d)\n",__LINE__));
     871
     872    return 0;
     873
     874errCleanUp:
     875
     876    if (wmd) MCI_UnLoadMciDriver(iData, wmd);
     877
     878    if (dwParam & MCI_NOTIFY)
     879      //  mciDriverNotify16(lpParms->dwCallback, 0, MCI_NOTIFY_FAILURE);
     880      dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Open (line %d)\n",__LINE__));
     881 
     882    dprintf(("Leaving MCI_Open on error...\n"));
     883    return dwRet;
     884}
     885
     886
     887/**************************************************************************
     888 *                      MCI_Close                               [internal]
     889 */
     890static  DWORD MCI_Close(UINT16 wDevID, DWORD dwParam, LPMCI_GENERIC_PARMS lpParms)
     891{
     892  DWORD         dwRet;
     893  LPWINE_MCIDRIVER      wmd;
     894  LPWINE_MM_IDATA       iData = MULTIMEDIA_GetIData();
     895 
     896  //dprintf(("(%04x, %08lX, %p)\n", wDevID, dwParam, lpParms));
     897
     898  if (wDevID == MCI_ALL_DEVICE_ID) {
     899        LPWINE_MCIDRIVER        next;
     900
     901        EnterCriticalSection(&iData->cs);
     902        /* FIXME: shall I notify once after all is done, or for
     903         * each of the open drivers ? if the latest, which notif
     904         * to return when only one fails ?
     905         */
     906        for (wmd = iData->lpMciDrvs; wmd; ) {
     907      next = wmd->lpNext;
     908      MCI_Close(wmd->wDeviceID, dwParam, lpParms);
     909      wmd = next;
     910        }       
     911        LeaveCriticalSection(&iData->cs);
     912        return 0;
     913  }
     914
     915  if (!(wmd = MCI_GetDriver(wDevID))) {
     916        return MCIERR_INVALID_DEVICE_ID;
     917  }
     918
     919  dwRet = MCI_SendCommandFrom32(wDevID, MCI_CLOSE_DRIVER, dwParam, (DWORD)lpParms);
     920 
     921  MCI_UnLoadMciDriver(iData, wmd);
     922 
     923  if (dwParam & MCI_NOTIFY)
     924    dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Close (line %d)\n",__LINE__));
     925    //  mciDriverNotify16(lpParms->dwCallback, wDevID,
     926    //                (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
     927 
     928  return dwRet;
     929}
     930
     931
     932/**************************************************************************
     933 *                      MCI_WriteString                         [internal]
     934 */
     935DWORD   MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr)
     936{
     937    DWORD       ret = 0;
     938
     939    if (lpSrcStr) {
     940        if (dstSize <= strlen(lpSrcStr)) {
     941            lstrcpynA(lpDstStr, lpSrcStr, dstSize - 1);
     942            ret = MCIERR_PARAM_OVERFLOW;
     943        } else {
     944            strcpy(lpDstStr, lpSrcStr);
     945        }       
     946    } else {
     947        *lpDstStr = 0;
     948    }
     949    return ret;
     950}
     951
     952
     953/**************************************************************************
     954 *                      MCI_Sysinfo                             [internal]
     955 */
     956static  DWORD MCI_SysInfo(UINT uDevID, DWORD dwFlags, LPMCI_SYSINFO_PARMSA lpParms)
     957{
     958    DWORD               ret = MCIERR_INVALID_DEVICE_ID;
     959    LPWINE_MCIDRIVER    wmd;
     960    LPWINE_MM_IDATA     iData = MULTIMEDIA_GetIData();
     961
     962    if (lpParms == NULL)                        return MCIERR_NULL_PARAMETER_BLOCK;
     963
     964    TRACE("(%08x, %08lX, %08lX[num=%ld, wDevTyp=%u])\n",
     965          uDevID, dwFlags, (DWORD)lpParms, lpParms->dwNumber, lpParms->wDeviceType);
     966   
     967    switch (dwFlags & ~MCI_SYSINFO_OPEN) {
     968    case MCI_SYSINFO_QUANTITY:
     969      {
     970            DWORD       cnt = 0;
     971           
     972            if (lpParms->wDeviceType < MCI_DEVTYPE_FIRST ||
     973            lpParms->wDeviceType > MCI_DEVTYPE_LAST) {
     974          if (dwFlags & MCI_SYSINFO_OPEN) {
     975                    TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers\n");
     976                    EnterCriticalSection(&iData->cs);
     977                    for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
     978              cnt++;
     979                    }
     980                    LeaveCriticalSection(&iData->cs);
     981          } else {
     982                    TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers\n");
     983                    cnt = MCI_InstalledCount;
     984          }
     985            } else {
     986          if (dwFlags & MCI_SYSINFO_OPEN) {
     987                    TRACE("MCI_SYSINFO_QUANTITY: # of open MCI drivers of type %u\n",
     988                  lpParms->wDeviceType);
     989                    EnterCriticalSection(&iData->cs);
     990                    for (wmd = iData->lpMciDrvs; wmd; wmd = wmd->lpNext) {
     991              if (wmd->wType == lpParms->wDeviceType)
     992                            cnt++;
     993                    }
     994                    LeaveCriticalSection(&iData->cs);
     995          } else {
     996                    TRACE("MCI_SYSINFO_QUANTITY: # of installed MCI drivers of type %u\n",
     997                  lpParms->wDeviceType);
     998                    FIXME("Don't know how to get # of MCI devices of a given type\n");
     999                    cnt = 1;
     1000          }
     1001            }
     1002            *(DWORD*)lpParms->lpstrReturn = cnt;
     1003      }
     1004      TRACE("(%ld) => '%ld'\n", lpParms->dwNumber, *(DWORD*)lpParms->lpstrReturn);
     1005      ret = MCI_INTEGER_RETURNED;
     1006      break;
     1007    case MCI_SYSINFO_INSTALLNAME:
     1008      TRACE("MCI_SYSINFO_INSTALLNAME \n");
     1009      if ((wmd = MCI_GetDriver(uDevID))) {
     1010            ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize,
     1011                              wmd->lpstrDeviceType);
     1012      } else {
     1013            *lpParms->lpstrReturn = 0;
     1014            ret = MCIERR_INVALID_DEVICE_ID;
     1015      }
     1016      TRACE("(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
     1017      break;
     1018    case MCI_SYSINFO_NAME:
     1019      TRACE("MCI_SYSINFO_NAME\n");
     1020      if (dwFlags & MCI_SYSINFO_OPEN) {
     1021            FIXME("Don't handle MCI_SYSINFO_NAME|MCI_SYSINFO_OPEN (yet)\n");
     1022            ret = MCIERR_UNRECOGNIZED_COMMAND;
     1023      } else if (lpParms->dwNumber > MCI_InstalledCount) {
     1024            ret = MCIERR_OUTOFRANGE;
     1025      } else {
     1026            DWORD       count = lpParms->dwNumber;
     1027            LPSTR       ptr = MCI_lpInstallNames;
     1028       
     1029            while (--count > 0) ptr += strlen(ptr) + 1;
     1030            ret = MCI_WriteString(lpParms->lpstrReturn, lpParms->dwRetSize, ptr);
     1031      }
     1032      TRACE("(%ld) => '%s'\n", lpParms->dwNumber, lpParms->lpstrReturn);
     1033      break;
     1034    default:
     1035      TRACE("Unsupported flag value=%08lx\n", dwFlags);
     1036      ret = MCIERR_UNRECOGNIZED_COMMAND;
     1037    }
     1038    return ret;
     1039}
     1040
     1041
     1042/**************************************************************************
     1043 *                      MCI_Break                               [internal]
     1044 */
     1045static  DWORD MCI_Break(UINT wDevID, DWORD dwFlags, LPMCI_BREAK_PARMS lpParms)
     1046{
     1047    DWORD       dwRet = 0;
     1048   
     1049    if (lpParms == NULL)        return MCIERR_NULL_PARAMETER_BLOCK;
     1050
     1051    if (dwFlags & MCI_NOTIFY)
     1052      dprintf(("FIXME: MCI_NOTIFY not implemented yet! MCI_Break (line %d)\n",__LINE__));
     1053    //  mciDriverNotify16(lpParms->dwCallback, wDevID,
     1054    //    (dwRet == 0) ? MCI_NOTIFY_SUCCESSFUL : MCI_NOTIFY_FAILURE);
     1055
     1056    return dwRet;
     1057}
     1058
     1059   
     1060/**************************************************************************
     1061 *                      MCI_SendCommand                         [internal]
     1062 */
     1063static DWORD    MCI_SendCommand(UINT wDevID, UINT16 wMsg, DWORD dwParam1,
     1064                        DWORD dwParam2)
     1065{
     1066    DWORD               dwRet = MCIERR_UNRECOGNIZED_COMMAND;
     1067
     1068    switch (wMsg) {
     1069    case MCI_OPEN:
     1070      dwRet = MCI_Open(dwParam1, (LPMCI_OPEN_PARMSA)dwParam2);
     1071      break;
     1072    case MCI_CLOSE:
     1073      dwRet = MCI_Close(wDevID, dwParam1, (LPMCI_GENERIC_PARMS)dwParam2);
     1074      break;
     1075    case MCI_SYSINFO:
     1076      dwRet = MCI_SysInfo(wDevID, dwParam1, (LPMCI_SYSINFO_PARMSA)dwParam2);
     1077      break;
     1078    case MCI_BREAK:
     1079      dwRet = MCI_Break(wDevID, dwParam1, (LPMCI_BREAK_PARMS)dwParam2);
     1080      break;
     1081      // case MCI_SOUND:
     1082      /* FIXME: it seems that MCI_SOUND needs the same handling as MCI_BREAK
     1083       * but I couldn't get any doc on this MCI message
     1084       */
     1085      // break;
     1086    default:
     1087      if (wDevID == MCI_ALL_DEVICE_ID) {
     1088            dprintf(("MCI_SendCommand: unhandled MCI_ALL_DEVICE_ID\n"));
     1089            dwRet = MCIERR_CANNOT_USE_ALL;
     1090      } else {
     1091        dwRet=MCI_SendCommandFrom32(wDevID, wMsg, dwParam1, dwParam2);
     1092      }     
     1093      break;
     1094    }
     1095    return dwRet;
     1096}
     1097
     1098
     1099
     1100
     1101/**************************************************************************
     1102 *                      MULTIMEDIA_MciInit                      [internal]
     1103 *
     1104 * Initializes the MCI internal variables.
     1105 *
     1106 */
     1107BOOL MULTIMEDIA_MciInit(void)
     1108{
     1109    LPSTR       ptr1, ptr2;
     1110    HKEY        hWineConf;
     1111    HKEY        hkey;
     1112    DWORD       err;
     1113    DWORD       type;
     1114    DWORD       count = 2048;
     1115
     1116    MCI_InstalledCount = 0;
     1117    ptr1 = MCI_lpInstallNames = (char*) HeapAlloc(GetProcessHeap(), 0, count);
     1118
     1119    if (!MCI_lpInstallNames)
     1120      return FALSE;
     1121
     1122#if 0
     1123    /* FIXME: should do also some registry diving here ? */
     1124    if (!(err = RegOpenKeyA(HKEY_LOCAL_MACHINE, "Software\\Wine\\Wine\\Config", &hWineConf)) &&
     1125        !(err = RegOpenKeyA(hWineConf, "options", &hkey))) {
     1126      err = RegQueryValueExA(hkey, "mci", 0, &type, MCI_lpInstallNames, &count);
     1127      RegCloseKey(hkey);
     1128      FIXME("Registry handling for mci drivers not changed for odin yet. Verbatim copy from WINE (line %d)",__LINE__);
     1129    }
     1130#endif
     1131    FIXME("No Registry querying for mci drivers yet! (line %d)",__LINE__);
     1132    err=1;
     1133    if (!err) {
     1134      TRACE("Wine => '%s' \n", ptr1);
     1135      while ((ptr2 = strchr(ptr1, ':')) != 0) {
     1136            *ptr2++ = 0;
     1137            TRACE("---> '%s' \n", ptr1);
     1138            MCI_InstalledCount++;
     1139            ptr1 = ptr2;
     1140      }
     1141      MCI_InstalledCount++;
     1142      TRACE("---> '%s' \n", ptr1);
     1143      ptr1 += strlen(ptr1) + 1;
     1144    } else {
     1145      GetPrivateProfileStringA("mci", NULL, "", MCI_lpInstallNames, count, "SYSTEM.INI");
     1146      while (strlen(ptr1) > 0) {
     1147            TRACE("---> '%s' \n", ptr1);
     1148            ptr1 += strlen(ptr1) + 1;
     1149            MCI_InstalledCount++;
     1150      }
     1151    }
     1152    //RegCloseKey(hWineConf);
     1153    return TRUE;
     1154}
Note: See TracChangeset for help on using the changeset viewer.