ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

lolvldrv.c
Go to the documentation of this file.
00001 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
00002 
00003 /*
00004  * MMSYSTEM low level drivers handling functions
00005  *
00006  * Copyright 1999 Eric Pouech
00007  * Modified for use with ReactOS by Andrew Greenwood, 2007
00008  *
00009  * This library is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 2.1 of the License, or (at your option) any later version.
00013  *
00014  * This library is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00022  */
00023 
00024 #include "config.h"
00025 #include "wine/port.h"
00026 
00027 #include <string.h>
00028 #include <stdarg.h>
00029 #include <stdio.h>
00030 #include <assert.h>
00031 #include "windef.h"
00032 #include "winbase.h"
00033 #include "winreg.h"
00034 #include "winemm.h"
00035 #include "wine/debug.h"
00036 #include "wine/exception.h"
00037 
00038 WINE_DEFAULT_DEBUG_CHANNEL(winmm);
00039 
00040 /* each known type of driver has an instance of this structure */
00041 typedef struct tagWINE_LLTYPE {
00042     /* those attributes depend on the specification of the type */
00043     LPCSTR      typestr;    /* name (for debugging) */
00044     BOOL        bSupportMapper; /* if type is allowed to support mapper */
00045     /* those attributes reflect the loaded/current situation for the type */
00046     UINT        wMaxId;     /* number of loaded devices (sum across all loaded drivers) */
00047     LPWINE_MLD      lpMlds;     /* "static" mlds to access the part though device IDs */
00048     int         nMapper;    /* index to mapper */
00049 } WINE_LLTYPE;
00050 
00051 static int      MMDrvsHi /* = 0 */;
00052 static WINE_MM_DRIVER   MMDrvs[8];
00053 static LPWINE_MLD   MM_MLDrvs[40];
00054 #define MAX_MM_MLDRVS   (sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]))
00055 
00056 #define A(_x,_y) {#_y, _x, 0, NULL, -1}
00057 /* Note: the indices of this array must match the definitions
00058  *   of the MMDRV_???? manifest constants
00059  */
00060 static WINE_LLTYPE  llTypes[MMDRV_MAX] = {
00061     A(TRUE,  Aux),
00062     A(FALSE, Mixer),
00063     A(TRUE,  MidiIn),
00064     A(TRUE,  MidiOut),
00065     A(TRUE,  WaveIn),
00066     A(TRUE,  WaveOut),
00067 };
00068 #undef A
00069 
00070 /**************************************************************************
00071  *          MMDRV_GetNum                [internal]
00072  */
00073 UINT    MMDRV_GetNum(UINT type)
00074 {
00075     TRACE("(%04x)\n", type);
00076     assert(type < MMDRV_MAX);
00077     return llTypes[type].wMaxId;
00078 }
00079 
00080 /**************************************************************************
00081  *              MMDRV_Message           [internal]
00082  */
00083 DWORD  MMDRV_Message(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1,
00084                      DWORD_PTR dwParam2)
00085 {
00086     LPWINE_MM_DRIVER        lpDrv;
00087     DWORD           ret;
00088     WINE_MM_DRIVER_PART*    part;
00089     WINE_LLTYPE*        llType = &llTypes[mld->type];
00090     int             devID;
00091 
00092     TRACE("(%s %u %u 0x%08lx 0x%08lx 0x%08lx)\n",
00093       llTypes[mld->type].typestr, mld->uDeviceID, wMsg,
00094       mld->dwDriverInstance, dwParam1, dwParam2);
00095 
00096     if (mld->uDeviceID == (UINT16)-1) {
00097     if (!llType->bSupportMapper) {
00098         WARN("uDev=-1 requested on non-mappable ll type %s\n",
00099          llTypes[mld->type].typestr);
00100         return MMSYSERR_BADDEVICEID;
00101     }
00102     devID = -1;
00103     } else {
00104     if (mld->uDeviceID >= llType->wMaxId) {
00105         WARN("uDev(%u) requested >= max (%d)\n", mld->uDeviceID, llType->wMaxId);
00106         return MMSYSERR_BADDEVICEID;
00107     }
00108     devID = mld->uDeviceID;
00109     }
00110 
00111     lpDrv = &MMDrvs[mld->mmdIndex];
00112     part = &lpDrv->parts[mld->type];
00113 
00114 #if 0
00115     /* some sanity checks */
00116     if (!(part->nIDMin <= devID))
00117     ERR("!(part->nIDMin(%d) <= devID(%d))\n", part->nIDMin, devID);
00118     if (!(devID < part->nIDMax))
00119     ERR("!(devID(%d) < part->nIDMax(%d))\n", devID, part->nIDMax);
00120 #endif
00121 
00122     assert(part->fnMessage32);
00123 
00124     TRACE("Calling message(dev=%u msg=%u usr=0x%08lx p1=0x%08lx p2=0x%08lx)\n",
00125           mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
00126     ret = part->fnMessage32(mld->uDeviceID, wMsg, mld->dwDriverInstance, dwParam1, dwParam2);
00127     TRACE("=> %s\n", WINMM_ErrorToString(ret));
00128 
00129     return ret;
00130 }
00131 
00132 /**************************************************************************
00133  *              MMDRV_Alloc         [internal]
00134  */
00135 LPWINE_MLD  MMDRV_Alloc(UINT size, UINT type, LPHANDLE hndl, DWORD* dwFlags,
00136                 DWORD_PTR* dwCallback, DWORD_PTR* dwInstance)
00137 {
00138     LPWINE_MLD  mld;
00139     UINT_PTR i;
00140     TRACE("(%d, %04x, %p, %p, %p, %p)\n",
00141           size, type, hndl, dwFlags, dwCallback, dwInstance);
00142 
00143     mld = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size);
00144     if (!mld)   return NULL;
00145 
00146     /* find an empty slot in MM_MLDrvs table */
00147     for (i = 0; i < MAX_MM_MLDRVS; i++) if (!MM_MLDrvs[i]) break;
00148 
00149     if (i == MAX_MM_MLDRVS) {
00150     /* the MM_MLDrvs table could be made growable in the future if needed */
00151     ERR("Too many open drivers\n");
00152         HeapFree(GetProcessHeap(), 0, mld);
00153     return NULL;
00154     }
00155     MM_MLDrvs[i] = mld;
00156     *hndl = (HANDLE)(i | 0x8000);
00157 
00158     mld->type = type;
00159     if ((UINT_PTR)*hndl < MMDRV_GetNum(type) || ((UINT_PTR)*hndl >> 16)) {
00160     /* FIXME: those conditions must be fulfilled so that:
00161      * - we can distinguish between device IDs and handles
00162      * - we can use handles as 16 or 32 bit entities
00163      */
00164     ERR("Shouldn't happen. Bad allocation scheme\n");
00165     }
00166 
00167     mld->dwFlags = HIWORD(*dwFlags);
00168     mld->dwCallback = *dwCallback;
00169     mld->dwClientInstance = *dwInstance;
00170 
00171     return mld;
00172 }
00173 
00174 /**************************************************************************
00175  *              MMDRV_Free          [internal]
00176  */
00177 void    MMDRV_Free(HANDLE hndl, LPWINE_MLD mld)
00178 {
00179     TRACE("(%p, %p)\n", hndl, mld);
00180 
00181     if ((UINT_PTR)hndl & 0x8000) {
00182     UINT_PTR idx = (UINT_PTR)hndl & ~0x8000;
00183     if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
00184         MM_MLDrvs[idx] = NULL;
00185         HeapFree(GetProcessHeap(), 0, mld);
00186         return;
00187     }
00188     }
00189     ERR("Bad Handle %p at %p (not freed)\n", hndl, mld);
00190 }
00191 
00192 /**************************************************************************
00193  *              MMDRV_Open          [internal]
00194  */
00195 DWORD MMDRV_Open(LPWINE_MLD mld, UINT wMsg, DWORD_PTR dwParam1, DWORD dwFlags)
00196 {
00197     DWORD       dwRet = MMSYSERR_BADDEVICEID;
00198     DWORD_PTR       dwInstance;
00199     WINE_LLTYPE*    llType = &llTypes[mld->type];
00200     TRACE("(%p, %04x, 0x%08lx, 0x%08x)\n", mld, wMsg, dwParam1, dwFlags);
00201 
00202     mld->dwDriverInstance = (DWORD_PTR)&dwInstance;
00203 
00204     if (mld->uDeviceID == (UINT)-1 || mld->uDeviceID == (UINT16)-1) {
00205     TRACE("MAPPER mode requested !\n");
00206     /* check if mapper is supported by type */
00207     if (llType->bSupportMapper) {
00208         if (llType->nMapper == -1) {
00209         /* no driver for mapper has been loaded, try a dumb implementation */
00210         TRACE("No mapper loaded, doing it by hand\n");
00211         for (mld->uDeviceID = 0; mld->uDeviceID < llType->wMaxId; mld->uDeviceID++) {
00212             if ((dwRet = MMDRV_Open(mld, wMsg, dwParam1, dwFlags)) == MMSYSERR_NOERROR) {
00213             /* to share this function epilog */
00214             dwInstance = mld->dwDriverInstance;
00215             break;
00216             }
00217         }
00218         } else {
00219         mld->uDeviceID = (UINT16)-1;
00220         mld->mmdIndex = llType->lpMlds[-1].mmdIndex;
00221         TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
00222         dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags);
00223         }
00224     }
00225     } else {
00226     if (mld->uDeviceID < llType->wMaxId) {
00227         mld->mmdIndex = llType->lpMlds[mld->uDeviceID].mmdIndex;
00228         TRACE("Setting mmdIndex to %u\n", mld->mmdIndex);
00229         dwRet = MMDRV_Message(mld, wMsg, dwParam1, dwFlags);
00230     }
00231     }
00232     if (dwRet == MMSYSERR_NOERROR)
00233     mld->dwDriverInstance = dwInstance;
00234     return dwRet;
00235 }
00236 
00237 /**************************************************************************
00238  *              MMDRV_Close         [internal]
00239  */
00240 DWORD   MMDRV_Close(LPWINE_MLD mld, UINT wMsg)
00241 {
00242     TRACE("(%p, %04x)\n", mld, wMsg);
00243     return MMDRV_Message(mld, wMsg, 0L, 0L);
00244 }
00245 
00246 /**************************************************************************
00247  *              MMDRV_GetByID           [internal]
00248  */
00249 static LPWINE_MLD MMDRV_GetByID(UINT uDevID, UINT type)
00250 {
00251     TRACE("(%04x, %04x)\n", uDevID, type);
00252     if (uDevID < llTypes[type].wMaxId)
00253     return &llTypes[type].lpMlds[uDevID];
00254     if ((uDevID == (UINT16)-1 || uDevID == (UINT)-1) && llTypes[type].nMapper != -1)
00255     return &llTypes[type].lpMlds[-1];
00256     return NULL;
00257 }
00258 
00259 /**************************************************************************
00260  *              MMDRV_Get           [internal]
00261  */
00262 LPWINE_MLD  MMDRV_Get(HANDLE _hndl, UINT type, BOOL bCanBeID)
00263 {
00264     LPWINE_MLD  mld = NULL;
00265     UINT_PTR    hndl = (UINT_PTR)_hndl;
00266     TRACE("(%p, %04x, %c)\n", _hndl, type, bCanBeID ? 'Y' : 'N');
00267 
00268     assert(type < MMDRV_MAX);
00269 
00270     if (hndl >= llTypes[type].wMaxId &&
00271     hndl != (UINT16)-1 && hndl != (UINT)-1) {
00272     if (hndl & 0x8000) {
00273         UINT idx = hndl & ~0x8000;
00274         if (idx < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0])) {
00275                 __TRY
00276                 {
00277                     mld = MM_MLDrvs[idx];
00278                     if (mld && mld->type != type) mld = NULL;
00279                 }
00280                 __EXCEPT_PAGE_FAULT
00281                 {
00282                     mld = NULL;
00283                 }
00284                 __ENDTRY;
00285         }
00286     }
00287     }
00288     if (mld == NULL && bCanBeID) {
00289     mld = MMDRV_GetByID(hndl, type);
00290     }
00291     return mld;
00292 }
00293 
00294 /**************************************************************************
00295  *              MMDRV_GetRelated        [internal]
00296  */
00297 LPWINE_MLD  MMDRV_GetRelated(HANDLE hndl, UINT srcType,
00298                  BOOL bSrcCanBeID, UINT dstType)
00299 {
00300     LPWINE_MLD      mld;
00301     TRACE("(%p, %04x, %c, %04x)\n",
00302           hndl, srcType, bSrcCanBeID ? 'Y' : 'N', dstType);
00303 
00304     if ((mld = MMDRV_Get(hndl, srcType, bSrcCanBeID)) != NULL) {
00305     WINE_MM_DRIVER_PART*    part = &MMDrvs[mld->mmdIndex].parts[dstType];
00306     if (part->nIDMin < part->nIDMax)
00307         return MMDRV_GetByID(part->nIDMin, dstType);
00308     }
00309     return NULL;
00310 }
00311 
00312 /**************************************************************************
00313  *              MMDRV_PhysicalFeatures      [internal]
00314  */
00315 UINT    MMDRV_PhysicalFeatures(LPWINE_MLD mld, UINT uMsg,
00316                                DWORD_PTR dwParam1, DWORD_PTR dwParam2)
00317 {
00318     WINE_MM_DRIVER* lpDrv = &MMDrvs[mld->mmdIndex];
00319 
00320     TRACE("(%p, %04x, %08lx, %08lx)\n", mld, uMsg, dwParam1, dwParam2);
00321 
00322     /* all those function calls are undocumented */
00323     switch (uMsg) {
00324     case DRV_QUERYDRVENTRY:
00325         lstrcpynA((LPSTR)dwParam1, lpDrv->drvname, LOWORD(dwParam2));
00326     break;
00327     case DRV_QUERYDEVNODE:
00328         *(LPDWORD)dwParam1 = 0L; /* should be DevNode */
00329     break;
00330     case DRV_QUERYNAME:
00331     WARN("NIY QueryName\n");
00332     break;
00333     case DRV_QUERYDRIVERIDS:
00334     WARN("NIY call VxD\n");
00335     /* should call VxD MMDEVLDR with (DevNode, dwParam1 and dwParam2) as pmts
00336      * dwParam1 is buffer and dwParam2 is sizeof(buffer)
00337      * I don't know where the result is stored though
00338      */
00339     break;
00340     case DRV_QUERYMAPPABLE:
00341     return (lpDrv->bIsMapper) ? 2 : 0;
00342 
00343     case DRVM_MAPPER_PREFERRED_GET:
00344     /* FIXME: get from registry someday */
00345         *((LPDWORD)dwParam1) = -1;      /* No preferred device */
00346         *((LPDWORD)dwParam2) = 0;
00347         break;
00348 
00349     case DRV_QUERYDEVICEINTERFACE:
00350     case DRV_QUERYDEVICEINTERFACESIZE:
00351         return MMDRV_Message(mld, uMsg, dwParam1, dwParam2);
00352 
00353     case DRV_QUERYDSOUNDIFACE: /* Wine-specific: Retrieve DirectSound interface */
00354     case DRV_QUERYDSOUNDDESC: /* Wine-specific: Retrieve DirectSound driver description*/
00355     return MMDRV_Message(mld, uMsg, dwParam1, dwParam2);
00356 
00357     default:
00358     WARN("Unknown call %04x\n", uMsg);
00359     return MMSYSERR_INVALPARAM;
00360     }
00361     return 0L;
00362 }
00363 
00364 /**************************************************************************
00365  *              MMDRV_InitPerType       [internal]
00366  */
00367 static  BOOL    MMDRV_InitPerType(LPWINE_MM_DRIVER lpDrv, UINT type, UINT wMsg)
00368 {
00369     WINE_MM_DRIVER_PART*    part = &lpDrv->parts[type];
00370     DWORD           ret;
00371     UINT            count = 0;
00372     int             i, k;
00373     TRACE("(%p, %04x, %04x)\n", lpDrv, type, wMsg);
00374 
00375     part->nIDMin = part->nIDMax = 0;
00376 
00377     /* for DRVM_INIT and DRVM_ENABLE, dwParam2 should be PnP node */
00378     /* the DRVM_ENABLE is only required when the PnP node is non zero */
00379     if (part->fnMessage32) {
00380         ret = part->fnMessage32(0, DRVM_INIT, 0L, 0L, 0L);
00381         TRACE("DRVM_INIT => %s\n", WINMM_ErrorToString(ret));
00382 #if 0
00383         ret = part->fnMessage32(0, DRVM_ENABLE, 0L, 0L, 0L);
00384         TRACE("DRVM_ENABLE => %08lx\n", ret);
00385 #endif
00386         count = part->fnMessage32(0, wMsg, 0L, 0L, 0L);
00387     }
00388     else return FALSE;
00389 
00390     TRACE("Got %u dev for (%s:%s)\n", count, lpDrv->drvname, llTypes[type].typestr);
00391     
00392     if (HIWORD(count))
00393         return FALSE;
00394 
00395     /* got some drivers */
00396     if (lpDrv->bIsMapper) {
00397     /* it seems native mappers return 0 devices :-( */
00398     if (llTypes[type].nMapper != -1)
00399         ERR("Two mappers for type %s (%d, %s)\n",
00400         llTypes[type].typestr, llTypes[type].nMapper, lpDrv->drvname);
00401     if (count > 1)
00402         ERR("Strange: mapper with %d > 1 devices\n", count);
00403     llTypes[type].nMapper = MMDrvsHi;
00404     } else {
00405     if (count == 0)
00406         return FALSE;
00407     part->nIDMin = llTypes[type].wMaxId;
00408     llTypes[type].wMaxId += count;
00409     part->nIDMax = llTypes[type].wMaxId;
00410     }
00411     TRACE("Setting min=%d max=%d (ttop=%d) for (%s:%s)\n",
00412       part->nIDMin, part->nIDMax, llTypes[type].wMaxId,
00413       lpDrv->drvname, llTypes[type].typestr);
00414     /* realloc translation table */
00415     if (llTypes[type].lpMlds)
00416         llTypes[type].lpMlds = (LPWINE_MLD)
00417     HeapReAlloc(GetProcessHeap(), 0, llTypes[type].lpMlds - 1,
00418             sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
00419     else
00420         llTypes[type].lpMlds = (LPWINE_MLD)
00421     HeapAlloc(GetProcessHeap(), 0,
00422             sizeof(WINE_MLD) * (llTypes[type].wMaxId + 1)) + 1;
00423 
00424     /* re-build the translation table */
00425     if (llTypes[type].nMapper != -1) {
00426     TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, -1, MMDrvs[llTypes[type].nMapper].drvname);
00427     llTypes[type].lpMlds[-1].uDeviceID = (UINT16)-1;
00428     llTypes[type].lpMlds[-1].type = type;
00429     llTypes[type].lpMlds[-1].mmdIndex = llTypes[type].nMapper;
00430     llTypes[type].lpMlds[-1].dwDriverInstance = 0;
00431     }
00432     for (i = k = 0; i <= MMDrvsHi; i++) {
00433     while (MMDrvs[i].parts[type].nIDMin <= k && k < MMDrvs[i].parts[type].nIDMax) {
00434         TRACE("%s:Trans[%d] -> %s\n", llTypes[type].typestr, k, MMDrvs[i].drvname);
00435         llTypes[type].lpMlds[k].uDeviceID = k;
00436         llTypes[type].lpMlds[k].type = type;
00437         llTypes[type].lpMlds[k].mmdIndex = i;
00438         llTypes[type].lpMlds[k].dwDriverInstance = 0;
00439         k++;
00440     }
00441     }
00442     return TRUE;
00443 }
00444 
00445 /**************************************************************************
00446  *              MMDRV_Install           [internal]
00447  */
00448 BOOL    MMDRV_Install(LPCSTR drvRegName, LPCSTR drvFileName, BOOL bIsMapper)
00449 {
00450     int         i, count = 0;
00451     LPWINE_MM_DRIVER    lpDrv = &MMDrvs[MMDrvsHi];
00452     LPWINE_DRIVER   d;
00453     WINEMM_msgFunc32    func;
00454 
00455     TRACE("('%s', '%s', mapper=%c);\n", drvRegName, drvFileName, bIsMapper ? 'Y' : 'N');
00456 
00457     for (i = 0; i < MMDrvsHi; i++) {
00458         if (!strcmp(drvRegName, MMDrvs[i].drvname)) return FALSE;
00459     }
00460 
00461     /* Be sure that size of MMDrvs matches the max number of loadable
00462      * drivers !!
00463      * If not just increase size of MMDrvs
00464      */
00465     assert(MMDrvsHi <= sizeof(MMDrvs)/sizeof(MMDrvs[0]));
00466 
00467     memset(lpDrv, 0, sizeof(*lpDrv));
00468 
00469     if (!(lpDrv->hDriver = OpenDriverA(drvFileName, 0, 0))) {
00470     WARN("Couldn't open driver '%s'\n", drvFileName);
00471     return FALSE;
00472     }
00473 
00474     d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
00475 
00476     if (!(d = DRIVER_FindFromHDrvr(lpDrv->hDriver))) {
00477     CloseDriver(lpDrv->hDriver, 0, 0);
00478     WARN("Couldn't get the WINE internal structure for driver '%s'\n", drvFileName);
00479     return FALSE;
00480     }
00481 
00482     /* Then look for xxxMessage functions */
00483 #define AA(_h,_w,_x,_y,_z)                  \
00484     func = (WINEMM_msgFunc##_y) _z ((_h), #_x);         \
00485     if (func != NULL)                       \
00486         { lpDrv->parts[_w].fnMessage##_y = func; count++;   \
00487           TRACE("Got %d bit func '%s'\n", _y, #_x);         }
00488 
00489     if (d->hModule) {
00490 #define A(_x,_y)    AA(d->hModule,_x,_y,32,GetProcAddress)
00491         A(MMDRV_AUX,    auxMessage);
00492         A(MMDRV_MIXER,  mxdMessage);
00493         A(MMDRV_MIDIIN, midMessage);
00494         A(MMDRV_MIDIOUT,    modMessage);
00495         A(MMDRV_WAVEIN, widMessage);
00496         A(MMDRV_WAVEOUT,    wodMessage);
00497 #undef A
00498     }
00499 #undef AA
00500 
00501     if (!count) {
00502     CloseDriver(lpDrv->hDriver, 0, 0);
00503     WARN("No message functions found\n");
00504     return FALSE;
00505     }
00506 
00507     /* FIXME: being a mapper or not should be known by another way */
00508     /* it's known for NE drvs (the description is of the form '*mapper: *'
00509      * I don't have any clue for PE drvs
00510      */
00511     lpDrv->bIsMapper = bIsMapper;
00512     lpDrv->drvname = strcpy(HeapAlloc(GetProcessHeap(), 0, strlen(drvRegName) + 1), drvRegName);
00513 
00514     /* Finish init and get the count of the devices */
00515     i = 0;
00516     if (MMDRV_InitPerType(lpDrv, MMDRV_AUX,     AUXDM_GETNUMDEVS))  i = 1;
00517     if (MMDRV_InitPerType(lpDrv, MMDRV_MIXER,   MXDM_GETNUMDEVS))   i = 1;
00518     if (MMDRV_InitPerType(lpDrv, MMDRV_MIDIIN,  MIDM_GETNUMDEVS))   i = 1;
00519     if (MMDRV_InitPerType(lpDrv, MMDRV_MIDIOUT, MODM_GETNUMDEVS))   i = 1;
00520     if (MMDRV_InitPerType(lpDrv, MMDRV_WAVEIN,  WIDM_GETNUMDEVS))   i = 1;
00521     if (MMDRV_InitPerType(lpDrv, MMDRV_WAVEOUT, WODM_GETNUMDEVS))   i = 1;
00522     /* if all those func calls return FALSE, then the driver must be unloaded */
00523     if (!i) {
00524     CloseDriver(lpDrv->hDriver, 0, 0);
00525     HeapFree(GetProcessHeap(), 0, lpDrv->drvname);
00526     WARN("Driver initialization failed\n");
00527     return FALSE;
00528     }
00529 
00530     MMDrvsHi++;
00531 
00532     return TRUE;
00533 }
00534 
00535 /**************************************************************************
00536  *              MMDRV_Init
00537  */
00538 BOOL    MMDRV_Init(void)
00539 {
00540 /* Redundant code, keeping this for reference only (for now) */
00541 #if 0
00542     HKEY    hKey;
00543     char    driver_buffer[256];
00544     char    mapper_buffer[256];
00545     char    midi_buffer[256];
00546     char*   p;
00547     DWORD   type, size;
00548     BOOL    ret = FALSE;
00549     TRACE("()\n");
00550 
00551     strcpy(driver_buffer, WINE_DEFAULT_WINMM_DRIVER);
00552     strcpy(mapper_buffer, WINE_DEFAULT_WINMM_MAPPER);
00553     strcpy(midi_buffer, WINE_DEFAULT_WINMM_MIDI);
00554 
00555     /* @@ Wine registry key: HKCU\Software\Wine\Drivers */
00556     if (!RegOpenKeyA(HKEY_CURRENT_USER, "Software\\Wine\\Drivers", &hKey))
00557     {
00558         size = sizeof(driver_buffer);
00559         if (RegQueryValueExA(hKey, "Audio", 0, &type, (LPVOID)driver_buffer, &size))
00560             strcpy(driver_buffer, WINE_DEFAULT_WINMM_DRIVER);
00561     }
00562 
00563     p = driver_buffer;
00564     while (p)
00565     {
00566         char filename[sizeof(driver_buffer)+10];
00567         char *next = strchr(p, ',');
00568         if (next) *next++ = 0;
00569         sprintf( filename, "wine%s.drv", p );
00570         if ((ret = MMDRV_Install( filename, filename, FALSE ))) break;
00571         p = next;
00572     }
00573 
00574     ret |= MMDRV_Install("beepmidi.dll", "beepmidi.dll", FALSE);
00575 
00576     ret |= MMDRV_Install("wavemapper", WINE_DEFAULT_WINMM_MAPPER, TRUE);
00577     ret |= MMDRV_Install("midimapper", WINE_DEFAULT_WINMM_MIDI, TRUE);
00578     return ret;
00579 #else
00580     INT driver_count = 0;
00581 
00582     driver_count += LoadRegistryMMEDrivers(NT_MME_DRIVERS_KEY);
00583     driver_count += LoadRegistryMMEDrivers(NT_MME_DRIVERS32_KEY);
00584 
00585     /* Explorer doesn't like us failing */
00586     return TRUE;
00587 //    return ( driver_count > 0 );
00588 #endif
00589 }
00590 
00591 /******************************************************************
00592  *      ExitPerType
00593  *
00594  *
00595  */
00596 static  BOOL    MMDRV_ExitPerType(LPWINE_MM_DRIVER lpDrv, UINT type)
00597 {
00598     WINE_MM_DRIVER_PART*    part = &lpDrv->parts[type];
00599     DWORD           ret;
00600     TRACE("(%p, %04x)\n", lpDrv, type);
00601 
00602     if (part->fnMessage32) {
00603 #if 0
00604         ret = part->fnMessage32(0, DRVM_DISABLE, 0L, 0L, 0L);
00605         TRACE("DRVM_DISABLE => %08lx\n", ret);
00606 #endif
00607         ret = part->fnMessage32(0, DRVM_EXIT, 0L, 0L, 0L);
00608         TRACE("DRVM_EXIT => %s\n", WINMM_ErrorToString(ret));
00609     }
00610 
00611     return TRUE;
00612 }
00613 
00614 /******************************************************************
00615  *      Exit
00616  *
00617  *
00618  */
00619 void    MMDRV_Exit(void)
00620 {
00621     unsigned int i;
00622     TRACE("()\n");
00623 
00624     for (i = 0; i < sizeof(MM_MLDrvs) / sizeof(MM_MLDrvs[0]); i++)
00625     {
00626         if (MM_MLDrvs[i] != NULL)
00627         {
00628             FIXME("Closing while ll-driver open\n");
00629 #if 0
00630             /* FIXME: should generate a message depending on type */
00631             MMDRV_Free((HANDLE)(i | 0x8000), MM_MLDrvs[i]);
00632 #endif
00633         }
00634     }
00635 
00636     /* unload driver, in reverse order of loading */
00637     i = MMDrvsHi;
00638     while (i-- > 0)
00639     {
00640         MMDRV_ExitPerType(&MMDrvs[i], MMDRV_AUX);
00641         MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIXER);
00642         MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIDIIN);
00643         MMDRV_ExitPerType(&MMDrvs[i], MMDRV_MIDIOUT);
00644         MMDRV_ExitPerType(&MMDrvs[i], MMDRV_WAVEIN);
00645         MMDRV_ExitPerType(&MMDrvs[i], MMDRV_WAVEOUT);
00646         CloseDriver(MMDrvs[i].hDriver, 0, 0);
00647     }
00648     if (llTypes[MMDRV_AUX].lpMlds)
00649         HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_AUX].lpMlds - 1);
00650     if (llTypes[MMDRV_MIXER].lpMlds)
00651         HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_MIXER].lpMlds - 1);
00652     if (llTypes[MMDRV_MIDIIN].lpMlds)
00653         HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_MIDIIN].lpMlds - 1);
00654     if (llTypes[MMDRV_MIDIOUT].lpMlds)
00655         HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_MIDIOUT].lpMlds - 1);
00656     if (llTypes[MMDRV_WAVEIN].lpMlds)
00657         HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_WAVEIN].lpMlds - 1);
00658     if (llTypes[MMDRV_WAVEOUT].lpMlds)
00659         HeapFree(GetProcessHeap(), 0, llTypes[MMDRV_WAVEOUT].lpMlds - 1);
00660 }

Generated on Sat May 26 2012 04:25:28 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.