Split driver functions into USER (16 bit part) and WINMM (32 bit part).

Fixed some bugs in 16 bit part as well.
Now correctly parsing the system.ini extra parameters.
This commit is contained in:
Eric Pouech 2000-12-13 02:07:40 +00:00 committed by Alexandre Julliard
parent af5ff94f4e
commit 66b4468bd4
8 changed files with 860 additions and 930 deletions

View File

@ -8,6 +8,7 @@ ALTNAMES = mmsystem sound
IMPORTS = user32 kernel32 ntdll IMPORTS = user32 kernel32 ntdll
C_SRCS = \ C_SRCS = \
driver.c \
joystick.c \ joystick.c \
lolvldrv.c \ lolvldrv.c \
mci.c \ mci.c \

610
dlls/winmm/driver.c Normal file
View File

@ -0,0 +1,610 @@
/* -*- tab-width: 8; c-basic-offset: 4 -*- */
/*
* WINE Drivers functions
*
* Copyright 1994 Martin Ayotte
* Copyright 1998 Marcus Meissner
* Copyright 1999 Eric Pouech
*/
#include <string.h>
#include "heap.h"
#include "windef.h"
#include "wingdi.h"
#include "winuser.h"
#include "mmddk.h"
#include "winemm.h"
#include "ldt.h"
#include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(driver);
static LPWINE_DRIVER lpDrvItemList = NULL;
/* TODO list :
* - LoadModule count and clean up is not handled correctly (it's not a
* problem as long as FreeLibrary is not working correctly)
*/
/* ### start build ### */
extern LONG CALLBACK DRIVER_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
/* ### stop build ### */
/**************************************************************************
* LoadStartupDrivers [internal]
*/
static void WINE_UNUSED DRIVER_LoadStartupDrivers(void)
{
char str[256];
if (GetPrivateProfileStringA("drivers", NULL, "", str, sizeof(str), "SYSTEM.INI") < 2) {
ERR("Can't find drivers section in system.ini\n");
} else {
HDRVR16 hDrv;
LPSTR ptr;
for (ptr = str; *ptr; ptr += strlen(ptr) + 1) {
TRACE("str='%s'\n", ptr);
hDrv = OpenDriver16(ptr, "drivers", 0L);
TRACE("hDrv=%04x\n", hDrv);
}
TRACE("end of list !\n");
}
}
/**************************************************************************
* DRIVER_GetNumberOfModuleRefs [internal]
*
* Returns the number of open drivers which share the same module.
*/
static WORD DRIVER_GetNumberOfModuleRefs(LPWINE_DRIVER lpNewDrv)
{
LPWINE_DRIVER lpDrv;
WORD count = 0;
if (lpNewDrv->dwFlags & WINE_GDF_16BIT) ERR("OOOch");
for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
if (!(lpDrv->dwFlags & WINE_GDF_16BIT) &&
lpDrv->d.d32.hModule == lpNewDrv->d.d32.hModule) {
count++;
}
}
return count;
}
/**************************************************************************
* DRIVER_FindFromHDrvr [internal]
*
* From a hDrvr being 32 bits, returns the WINE internal structure.
*/
LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr)
{
LPWINE_DRIVER d = (LPWINE_DRIVER)hDrvr;
if (hDrvr && HeapValidate(GetProcessHeap(), 0, d) && d->dwMagic == WINE_DI_MAGIC) {
return d;
}
return NULL;
}
/**************************************************************************
* DRIVER_MapMsg32To16 [internal]
*
* Map a 32 bit driver message to a 16 bit driver message.
* 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg32To16
* 0 : ok, no memory allocated
* -1 : ko, unknown message
* -2 : ko, memory problem
*/
static int DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
{
int ret = -1;
switch (wMsg) {
case DRV_LOAD:
case DRV_ENABLE:
case DRV_DISABLE:
case DRV_FREE:
case DRV_QUERYCONFIGURE:
case DRV_REMOVE:
case DRV_EXITSESSION:
case DRV_EXITAPPLICATION:
case DRV_POWER:
case DRV_CLOSE: /* should be 0/0 */
case DRV_OPEN: /* pass thru */
/* lParam1 and lParam2 are not used */
ret = 0;
break;
break;
case DRV_CONFIGURE:
case DRV_INSTALL:
/* lParam1 is a handle to a window (conf) or to a driver (inst) or not used,
* lParam2 is a pointer to DRVCONFIGINFO
*/
if (*lParam2) {
LPDRVCONFIGINFO16 dci16 = (LPDRVCONFIGINFO16)SEGPTR_ALLOC(sizeof(DRVCONFIGINFO16));
LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
if (dci16) {
LPSTR str1, str2;
dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCISectionName)) != NULL &&
(str2 = SEGPTR_STRDUP(str1)) != NULL) {
dci16->lpszDCISectionName = (LPSTR)SEGPTR_GET(str2);
if (!HeapFree(GetProcessHeap(), 0, str1))
FIXME("bad free line=%d\n", __LINE__);
} else {
return -2;
}
if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCIAliasName)) != NULL &&
(str2 = SEGPTR_STRDUP(str1)) != NULL) {
dci16->lpszDCIAliasName = (LPSTR)SEGPTR_GET(str2);
if (!HeapFree(GetProcessHeap(), 0, str1))
FIXME("bad free line=%d\n", __LINE__);
} else {
return -2;
}
} else {
return -2;
}
*lParam2 = (LPARAM)SEGPTR_GET(dci16);
ret = 1;
} else {
ret = 0;
}
break;
default:
if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
FIXME("Unknown message 0x%04x\n", wMsg);
}
ret = 0;
}
return ret;
}
/**************************************************************************
* DRIVER_UnMapMsg32To16 [internal]
*
* UnMap a 32 bit driver message to a 16 bit driver message.
* 0 : ok
* -1 : ko
* -2 : ko, memory problem
*/
static int DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
{
int ret = -1;
switch (wMsg) {
case DRV_LOAD:
case DRV_ENABLE:
case DRV_DISABLE:
case DRV_FREE:
case DRV_QUERYCONFIGURE:
case DRV_REMOVE:
case DRV_EXITSESSION:
case DRV_EXITAPPLICATION:
case DRV_POWER:
case DRV_OPEN:
case DRV_CLOSE:
/* lParam1 and lParam2 are not used */
break;
case DRV_CONFIGURE:
case DRV_INSTALL:
/* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
if (lParam2) {
LPDRVCONFIGINFO16 dci16 = (LPDRVCONFIGINFO16)PTR_SEG_TO_LIN(lParam2);
if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCISectionName)))
FIXME("bad free line=%d\n", __LINE__);
if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCIAliasName)))
FIXME("bad free line=%d\n", __LINE__);
if (!SEGPTR_FREE(dci16))
FIXME("bad free line=%d\n", __LINE__);
}
ret = 0;
break;
default:
if (!((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100))) {
FIXME("Unknown message 0x%04x\n", wMsg);
}
ret = 0;
}
return ret;
}
/**************************************************************************
* DRIVER_SendMessage [internal]
*/
static LRESULT inline DRIVER_SendMessage(LPWINE_DRIVER lpDrv, UINT msg,
LPARAM lParam1, LPARAM lParam2)
{
if (lpDrv->dwFlags & WINE_GDF_16BIT) {
LRESULT ret;
int map = 0;
TRACE("Before sdm16 call hDrv=%04x wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->d.d16.hDriver16, msg, lParam1, lParam2);
if ((map = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2)) >= 0) {
ret = SendDriverMessage16(lpDrv->d.d16.hDriver16, msg, lParam1, lParam2);
if (map == 1)
DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
} else {
ret = 0;
}
return ret;
}
TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%08x wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->d.d32.lpDrvProc, lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
return lpDrv->d.d32.lpDrvProc(lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
}
/**************************************************************************
* SendDriverMessage [WINMM.19]
*/
LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1,
LPARAM lParam2)
{
LPWINE_DRIVER lpDrv;
LRESULT retval = 0;
TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2);
if ((lpDrv = DRIVER_FindFromHDrvr(hDriver)) != NULL) {
retval = DRIVER_SendMessage(lpDrv, msg, lParam1, lParam2);
} else {
WARN("Bad driver handle %u\n", hDriver);
}
TRACE("retval = %ld\n", retval);
return retval;
}
/**************************************************************************
* DRIVER_RemoveFromList [internal]
*
* Generates all the logic to handle driver closure / deletion
* Removes a driver struct to the list of open drivers.
*/
static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
{
if (!(lpDrv->dwFlags & WINE_GDF_16BIT)) {
if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) {
DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L);
}
}
if (lpDrv->lpPrevItem)
lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
else
lpDrvItemList = lpDrv->lpNextItem;
if (lpDrv->lpNextItem)
lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
return TRUE;
}
/**************************************************************************
* DRIVER_AddToList [internal]
*
* Adds a driver struct to the list of open drivers.
* Generates all the logic to handle driver creation / open.
*/
static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lParam2)
{
lpNewDrv->dwMagic = WINE_DI_MAGIC;
/* First driver to be loaded for this module, need to load correctly the module */
if (!(lpNewDrv->dwFlags & WINE_GDF_16BIT)) {
if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) {
if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
return FALSE;
}
/* returned value is not checked */
DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
}
}
lpNewDrv->lpNextItem = NULL;
if (lpDrvItemList == NULL) {
lpDrvItemList = lpNewDrv;
lpNewDrv->lpPrevItem = NULL;
} else {
LPWINE_DRIVER lpDrv = lpDrvItemList; /* find end of list */
while (lpDrv->lpNextItem != NULL)
lpDrv = lpDrv->lpNextItem;
lpDrv->lpNextItem = lpNewDrv;
lpNewDrv->lpPrevItem = lpDrv;
}
if (!(lpNewDrv->dwFlags & WINE_GDF_16BIT)) {
/* Now just open a new instance of a driver on this module */
lpNewDrv->d.d32.dwDriverID = DRIVER_SendMessage(lpNewDrv, DRV_OPEN, lParam1, lParam2);
if (lpNewDrv->d.d32.dwDriverID == 0) {
TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
DRIVER_RemoveFromList(lpNewDrv);
return FALSE;
}
}
return TRUE;
}
/**************************************************************************
* DRIVER_GetLibName [internal]
*
*/
BOOL DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz)
{
/* should also do some registry diving */
return GetPrivateProfileStringA(sectName, keyName, "", buf, sz, "SYSTEM.INI");
}
/**************************************************************************
* DRIVER_TryOpenDriver32 [internal]
*
* Tries to load a 32 bit driver whose DLL's (module) name is fn
*/
LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCSTR fn, LPARAM lParam2)
{
LPWINE_DRIVER lpDrv = NULL;
HMODULE hModule = 0;
LPSTR ptr;
LPCSTR cause = 0;
TRACE("('%s', %08lX);\n", fn, lParam2);
if ((ptr = strchr(fn, ' ')) != NULL) {
*ptr++ = '\0';
while (*ptr == ' ') ptr++;
if (*ptr == '\0') ptr = NULL;
}
lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
if (lpDrv == NULL) {cause = "OOM"; goto exit;}
if ((hModule = LoadLibraryA(fn)) == 0) {cause = "Not a 32 bit lib"; goto exit;}
lpDrv->d.d32.lpDrvProc = GetProcAddress(hModule, "DriverProc");
if (lpDrv->d.d32.lpDrvProc == NULL) {cause = "no DriverProc"; goto exit;}
lpDrv->dwFlags = 0;
lpDrv->d.d32.hModule = hModule;
lpDrv->d.d32.dwDriverID = 0;
if (!DRIVER_AddToList(lpDrv, (LPARAM)ptr, lParam2)) {cause = "load faile"; goto exit;}
TRACE("=> %p\n", lpDrv);
return lpDrv;
exit:
FreeLibrary(hModule);
HeapFree(GetProcessHeap(), 0, lpDrv);
TRACE("Unable to load 32 bit module \"%s\": %s\n", fn, cause);
return NULL;
}
/**************************************************************************
* DRIVER_TryOpenDriver16 [internal]
*
* Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
*/
static LPWINE_DRIVER DRIVER_TryOpenDriver16(LPCSTR fn, LPCSTR sn, LPARAM lParam2)
{
LPWINE_DRIVER lpDrv = NULL;
LPCSTR cause = 0;
TRACE("('%s', %08lX);\n", sn, lParam2);
lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
if (lpDrv == NULL) {cause = "OOM"; goto exit;}
/* FIXME: shall we do some black magic here on sn ?
* drivers32 => drivers
* mci32 => mci
* ...
*/
lpDrv->d.d16.hDriver16 = OpenDriver16(fn, sn, lParam2);
if (lpDrv->d.d16.hDriver16 == 0) {cause = "Not a 16 bit driver"; goto exit;}
lpDrv->dwFlags = WINE_GDF_16BIT;
if (!DRIVER_AddToList(lpDrv, 0, lParam2)) {cause = "load faile"; goto exit;}
TRACE("=> %p\n", lpDrv);
return lpDrv;
exit:
HeapFree(GetProcessHeap(), 0, lpDrv);
TRACE("Unable to load 32 bit module \"%s\": %s\n", fn, cause);
return NULL;
}
/**************************************************************************
* OpenDriverA [WINMM.15]
* (0,1,DRV_LOAD ,0 ,0)
* (0,1,DRV_ENABLE,0 ,0)
* (0,1,DRV_OPEN ,buf[256],0)
*/
HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
{
LPWINE_DRIVER lpDrv = NULL;
char libName[128];
LPCSTR lsn = lpSectionName;
TRACE("(%s, %s, 0x%08lx);\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam2);
if (lsn == NULL) {
lstrcpynA(libName, lpDriverName, sizeof(libName));
if ((lpDrv = DRIVER_TryOpenDriver32(libName, lParam2)))
goto the_end;
lsn = "Drivers32";
}
if (DRIVER_GetLibName(lpDriverName, lsn, libName, sizeof(libName)) &&
(lpDrv = DRIVER_TryOpenDriver32(libName, lParam2)))
goto the_end;
if (!(lpDrv = DRIVER_TryOpenDriver16(lpDriverName, lpSectionName, lParam2)))
ERR("Failed to open driver %s from section %s\n", lpDriverName, lpSectionName);
the_end:
if (lpDrv) TRACE("=> %08lx\n", (DWORD)lpDrv);
return (DWORD)lpDrv;
}
/**************************************************************************
* OpenDriverW [WINMM.15]
*/
HDRVR WINAPI OpenDriverW(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
{
LPSTR dn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDriverName);
LPSTR sn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpSectionName);
HDRVR ret = OpenDriverA(dn, sn, lParam);
if (dn) HeapFree(GetProcessHeap(), 0, dn);
if (sn) HeapFree(GetProcessHeap(), 0, sn);
return ret;
}
/**************************************************************************
* CloseDriver [WINMM.4]
*/
LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
{
LPWINE_DRIVER lpDrv;
TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
if (lpDrv->dwFlags & WINE_GDF_16BIT)
CloseDriver16(lpDrv->d.d16.hDriver16, lParam1, lParam2);
else
DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
if (DRIVER_RemoveFromList(lpDrv)) {
HeapFree(GetProcessHeap(), 0, lpDrv);
return TRUE;
}
}
WARN("Failed to close driver\n");
return FALSE;
}
/**************************************************************************
* GetDriverFlags [WINMM.13]
* [in] hDrvr handle to the driver
*
* Returns:
* 0x00000000 if hDrvr is an invalid handle
* 0x80000000 if hDrvr is a valid 32 bit driver
* 0x90000000 if hDrvr is a valid 16 bit driver
*
* native WINMM doesn't return those flags
* 0x80000000 for a valid 32 bit driver and that's it
* (I may have mixed up the two flags :-(
*/
DWORD WINAPI GetDriverFlags(HDRVR hDrvr)
{
LPWINE_DRIVER lpDrv;
DWORD ret = 0;
TRACE("(%04x)\n", hDrvr);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
ret = WINE_GDF_EXIST | lpDrv->dwFlags;
}
return ret;
}
/**************************************************************************
* GetDriverModuleHandle [WINMM.14]
*/
HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
{
LPWINE_DRIVER lpDrv;
HMODULE hModule = 0;
TRACE("(%04x);\n", hDrvr);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
hModule = lpDrv->d.d32.hModule;
}
TRACE("=> %04x\n", hModule);
return hModule;
}
/**************************************************************************
* DrvOpen [MMSYSTEM.1100]
*/
HDRVR16 WINAPI DrvOpen16(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
{
return OpenDriver16(lpDriverName, lpSectionName, lParam);
}
/**************************************************************************
* DrvClose [MMSYSTEM.1101]
*/
LRESULT WINAPI DrvClose16(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
{
return CloseDriver16(hDrv, lParam1, lParam2);
}
/**************************************************************************
* DrvSendMessage [MMSYSTEM.1102]
*/
LRESULT WINAPI DrvSendMessage16(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
LPARAM lParam2)
{
return SendDriverMessage16(hDrv, msg, lParam1, lParam2);
}
/**************************************************************************
* DrvGetModuleHandle [MMSYSTEM.1103]
*/
HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
{
return GetDriverModuleHandle16(hDrv);
}
/**************************************************************************
* DrvDefDriverProc [MMSYSTEM.1104]
*/
LRESULT WINAPI DrvDefDriverProc16(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
}
/**************************************************************************
* DefDriverProc [WINMM.5]
*/
LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hDrv,
UINT Msg, LPARAM lParam1, LPARAM lParam2)
{
switch (Msg) {
case DRV_LOAD:
case DRV_FREE:
case DRV_ENABLE:
case DRV_DISABLE:
return 1;
case DRV_INSTALL:
case DRV_REMOVE:
return DRV_SUCCESS;
default:
return 0;
}
}
/**************************************************************************
* DriverProc [MMSYSTEM.6]
*/
LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
TRACE("dwDevID=%08lx hDrv=%04x wMsg=%04x dwParam1=%08lx dwParam2=%08lx\n",
dwDevID, hDrv, wMsg, dwParam1, dwParam2);
return DrvDefDriverProc16(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
}

View File

@ -35,7 +35,7 @@ typedef struct tagWINE_MM_DRIVER_PART {
/* each low-level .drv will be associated with an instance of this structure */ /* each low-level .drv will be associated with an instance of this structure */
typedef struct tagWINE_MM_DRIVER { typedef struct tagWINE_MM_DRIVER {
HDRVR hDrvr; /* handle of loader driver */ HDRVR hDriver;
LPSTR name; /* name of the driver */ LPSTR name; /* name of the driver */
BOOL bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */ BOOL bIs32 : 1, /* TRUE if 32 bit driver, FALSE for 16 */
bIsMapper : 1; /* TRUE if mapper */ bIsMapper : 1; /* TRUE if mapper */
@ -2244,32 +2244,33 @@ static BOOL MMDRV_Install(LPCSTR name, int num, BOOL bIsMapper)
{ {
int count = 0; int count = 0;
char buffer[128]; char buffer[128];
HMODULE hModule;
LPWINE_MM_DRIVER lpDrv = &MMDrvs[num]; LPWINE_MM_DRIVER lpDrv = &MMDrvs[num];
LPWINE_DRIVER d;
TRACE("('%s');\n", name); TRACE("('%s');\n", name);
memset(lpDrv, 0, sizeof(*lpDrv)); memset(lpDrv, 0, sizeof(*lpDrv));
/* First load driver */ if (!(lpDrv->hDriver = OpenDriverA(name, 0, 0))) {
if ((lpDrv->hDrvr = OpenDriverA(name, 0, 0)) == 0) {
WARN("Couldn't open driver '%s'\n", name); WARN("Couldn't open driver '%s'\n", name);
return FALSE; return FALSE;
} }
d = DRIVER_FindFromHDrvr(lpDrv->hDriver);
lpDrv->bIs32 = (d->dwFlags & WINE_GDF_16BIT) ? FALSE : TRUE;
/* Then look for xxxMessage functions */ /* Then look for xxxMessage functions */
#define AA(_w,_x,_y,_z) \ #define AA(_h,_w,_x,_y,_z) \
func = (WINEMM_msgFunc##_y) _z (hModule, #_x); \ func = (WINEMM_msgFunc##_y) _z ((_h), #_x); \
if (func != NULL) \ if (func != NULL) \
{ lpDrv->parts[_w].u.fnMessage##_y = func; count++; \ { lpDrv->parts[_w].u.fnMessage##_y = func; count++; \
TRACE("Got %d bit func '%s'\n", _y, #_x); } TRACE("Got %d bit func '%s'\n", _y, #_x); }
if ((GetDriverFlags(lpDrv->hDrvr) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) == WINE_GDF_EXIST) { if (lpDrv->bIs32) {
WINEMM_msgFunc32 func; WINEMM_msgFunc32 func;
lpDrv->bIs32 = TRUE; if (d->d.d32.hModule) {
if ((hModule = GetDriverModuleHandle(lpDrv->hDrvr))) { #define A(_x,_y) AA(d->d.d32.hModule,_x,_y,32,GetProcAddress)
#define A(_x,_y) AA(_x,_y,32,GetProcAddress)
A(MMDRV_AUX, auxMessage); A(MMDRV_AUX, auxMessage);
A(MMDRV_MIXER, mixMessage); A(MMDRV_MIXER, mixMessage);
A(MMDRV_MIDIIN, midMessage); A(MMDRV_MIDIIN, midMessage);
@ -2297,9 +2298,8 @@ static BOOL MMDRV_Install(LPCSTR name, int num, BOOL bIsMapper)
* mixer for mixer devices * mixer for mixer devices
*/ */
lpDrv->bIs32 = FALSE; if (d->d.d16.hDriver16) {
if ((hModule = GetDriverModuleHandle16(lpDrv->hDrvr))) { #define A(_x,_y) AA(d->d.d16.hDriver16,_x,_y,16,GetProcAddress16)
#define A(_x,_y) AA(_x,_y,16,GetProcAddress16)
A(MMDRV_AUX, auxMessage); A(MMDRV_AUX, auxMessage);
A(MMDRV_MIXER, mixMessage); A(MMDRV_MIXER, mixMessage);
A(MMDRV_MIDIIN, midMessage); A(MMDRV_MIDIIN, midMessage);
@ -2320,7 +2320,7 @@ static BOOL MMDRV_Install(LPCSTR name, int num, BOOL bIsMapper)
} }
if (!count) { if (!count) {
CloseDriver(lpDrv->hDrvr, 0, 0); CloseDriver(lpDrv->hDriver, 0, 0);
WARN("No message functions found\n"); WARN("No message functions found\n");
return FALSE; return FALSE;
} }

View File

@ -26,6 +26,18 @@ DEFAULT_DEBUG_CHANNEL(mci);
static int MCI_InstalledCount; static int MCI_InstalledCount;
static LPSTR MCI_lpInstallNames = NULL; static LPSTR MCI_lpInstallNames = NULL;
typedef enum {
MCI_MAP_NOMEM, /* ko, memory problem */
MCI_MAP_MSGERROR, /* ko, unknown message */
MCI_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
MCI_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
} MCI_MapType;
static MCI_MapType MCI_MapMsg16To32A (WORD uDevType, WORD wMsg, DWORD* lParam);
static MCI_MapType MCI_UnMapMsg16To32A(WORD uDevType, WORD wMsg, DWORD lParam);
static MCI_MapType MCI_MapMsg32ATo16 (WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD* lParam);
static MCI_MapType MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DWORD lParam);
/* First MCI valid device ID (0 means error) */ /* First MCI valid device ID (0 means error) */
#define MCI_MAGIC 0x0001 #define MCI_MAGIC 0x0001
@ -387,8 +399,7 @@ static BOOL MCI_UnLoadMciDriver(LPWINE_MM_IDATA iData, LPWINE_MCIDRIVER wmd)
if (!wmd) if (!wmd)
return TRUE; return TRUE;
if (wmd->hDrv) CloseDriver(wmd->hDriver, 0, 0);
CloseDriver(wmd->hDrv, 0, 0);
if (wmd->dwPrivate != 0) if (wmd->dwPrivate != 0)
WARN("Unloading mci driver with non nul dwPrivate field\n"); WARN("Unloading mci driver with non nul dwPrivate field\n");
@ -410,6 +421,42 @@ static BOOL MCI_UnLoadMciDriver(LPWINE_MM_IDATA iData, LPWINE_MCIDRIVER wmd)
return TRUE; return TRUE;
} }
/**************************************************************************
* MCI_OpenMciDriver [internal]
*/
static BOOL MCI_OpenMciDriver(LPWINE_MCIDRIVER wmd, LPCSTR drvTyp, LPARAM lp)
{
char libName[128];
if (!DRIVER_GetLibName(drvTyp, "mci", libName, sizeof(libName)))
return FALSE;
wmd->bIs32 = 0xFFFF;
/* First load driver */
if ((wmd->hDriver = (HDRVR)DRIVER_TryOpenDriver32(libName, lp))) {
wmd->bIs32 = TRUE;
} else {
MCI_MapType res;
switch (res = MCI_MapMsg32ATo16(0, MCI_OPEN_DRIVER, 0, &lp)) {
case MCI_MAP_MSGERROR:
TRACE("Not handled yet (MCI_OPEN_DRIVER)\n");
break;
case MCI_MAP_NOMEM:
TRACE("Problem mapping msg=MCI_OPEN_DRIVER from 32a to 16\n");
break;
case MCI_MAP_OK:
case MCI_MAP_OKMEM:
if ((wmd->hDriver = OpenDriverA(drvTyp, "mci", lp)))
wmd->bIs32 = FALSE;
if (res == MCI_MAP_OKMEM)
MCI_UnMapMsg32ATo16(0, MCI_OPEN_DRIVER, 0, lp);
break;
}
}
return (wmd->bIs32 == 0xFFFF) ? FALSE : TRUE;
}
/************************************************************************** /**************************************************************************
* MCI_LoadMciDriver [internal] * MCI_LoadMciDriver [internal]
*/ */
@ -420,7 +467,6 @@ static DWORD MCI_LoadMciDriver(LPWINE_MM_IDATA iData, LPCSTR _strDevTyp,
LPWINE_MCIDRIVER wmd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wmd)); LPWINE_MCIDRIVER wmd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*wmd));
MCI_OPEN_DRIVER_PARMSA modp; MCI_OPEN_DRIVER_PARMSA modp;
DWORD dwRet = 0; DWORD dwRet = 0;
HDRVR hDrv = 0;
if (!wmd || !strDevTyp) { if (!wmd || !strDevTyp) {
dwRet = MCIERR_OUT_OF_MEMORY; dwRet = MCIERR_OUT_OF_MEMORY;
@ -450,9 +496,7 @@ static DWORD MCI_LoadMciDriver(LPWINE_MM_IDATA iData, LPCSTR _strDevTyp,
modp.lpstrParams = NULL; modp.lpstrParams = NULL;
hDrv = OpenDriverA(strDevTyp, "mci", (LPARAM)&modp); if (!MCI_OpenMciDriver(wmd, strDevTyp, (LPARAM)&modp)) {
if (!hDrv) {
FIXME("Couldn't load driver for type %s.\n" FIXME("Couldn't load driver for type %s.\n"
"If you don't have a windows installation accessible from Wine,\n" "If you don't have a windows installation accessible from Wine,\n"
"you perhaps forgot to create a [mci] section in system.ini\n", "you perhaps forgot to create a [mci] section in system.ini\n",
@ -465,13 +509,12 @@ static DWORD MCI_LoadMciDriver(LPWINE_MM_IDATA iData, LPCSTR _strDevTyp,
* MODULENAME:[MCI] comment * MODULENAME:[MCI] comment
*/ */
wmd->hDrv = hDrv;
/* some drivers will return 0x0000FFFF, some others 0xFFFFFFFF */ /* some drivers will return 0x0000FFFF, some others 0xFFFFFFFF */
wmd->uSpecificCmdTable = LOWORD(modp.wCustomCommandTable); wmd->uSpecificCmdTable = LOWORD(modp.wCustomCommandTable);
wmd->uTypeCmdTable = MCI_COMMAND_TABLE_NOT_LOADED; wmd->uTypeCmdTable = MCI_COMMAND_TABLE_NOT_LOADED;
TRACE("Loaded driver %x (%s), type is %d, cmdTable=%08x\n", TRACE("Loaded driver %x (%s), type is %d, cmdTable=%08x\n",
hDrv, strDevTyp, modp.wType, modp.wCustomCommandTable); wmd->hDriver, strDevTyp, modp.wType, modp.wCustomCommandTable);
wmd->lpstrDeviceType = strDevTyp; wmd->lpstrDeviceType = strDevTyp;
wmd->wType = modp.wType; wmd->wType = modp.wType;
@ -746,7 +789,9 @@ static DWORD MCI_HandleReturnValues(LPWINE_MM_IDATA iData, DWORD dwRet,
case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER: case MCI_RESOURCE_RETURNED|MCI_RESOURCE_DRIVER:
/* return string which ID is HIWORD(data[1]), /* return string which ID is HIWORD(data[1]),
* string is loaded from driver */ * string is loaded from driver */
LoadStringA(wmd->hDrv, HIWORD(data[1]), lpstrRet, uRetLen); /* FIXME: this is wrong for a 16 bit handle */
LoadStringA(GetDriverModuleHandle(wmd->hDriver),
HIWORD(data[1]), lpstrRet, uRetLen);
break; break;
case MCI_COLONIZED3_RETURN: case MCI_COLONIZED3_RETURN:
snprintf(lpstrRet, uRetLen, "%d:%d:%d", snprintf(lpstrRet, uRetLen, "%d:%d:%d",
@ -1078,14 +1123,6 @@ BOOL WINAPI mciFreeCommandResource(UINT uTable)
return mciFreeCommandResource16(uTable); return mciFreeCommandResource16(uTable);
} }
typedef enum {
MCI_MAP_NOMEM, /* ko, memory problem */
MCI_MAP_MSGERROR, /* ko, unknown message */
MCI_MAP_OK, /* ok, no memory allocated. to be sent to the proc. */
MCI_MAP_OKMEM, /* ok, some memory allocated, need to call UnMapMsg. to be sent to the proc. */
MCI_MAP_PASS /* not handled (no memory allocated) to be sent to the driver */
} MCI_MapType;
/************************************************************************** /**************************************************************************
* MCI_MapMsg16To32A [internal] * MCI_MapMsg16To32A [internal]
*/ */
@ -1739,7 +1776,7 @@ static MCI_MapType MCI_MapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags, DW
case DRV_EXITSESSION: case DRV_EXITSESSION:
case DRV_EXITAPPLICATION: case DRV_EXITAPPLICATION:
case DRV_POWER: case DRV_POWER:
return MCI_MAP_PASS; return MCI_MAP_OK;
default: default:
WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg)); WARN("Don't know how to map msg=%s\n", MCI_MessageToString(wMsg));
@ -1924,7 +1961,7 @@ static MCI_MapType MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags,
case DRV_EXITAPPLICATION: case DRV_EXITAPPLICATION:
case DRV_POWER: case DRV_POWER:
FIXME("This is a hack\n"); FIXME("This is a hack\n");
return MCI_MAP_PASS; return MCI_MAP_OK;
default: default:
FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg)); FIXME("Map/Unmap internal error on msg=%s\n", MCI_MessageToString(wMsg));
return MCI_MAP_MSGERROR; return MCI_MAP_MSGERROR;
@ -1937,15 +1974,13 @@ static MCI_MapType MCI_UnMapMsg32ATo16(WORD uDevType, WORD wMsg, DWORD dwFlags,
*/ */
DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2) DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
{ {
DWORD dwRet = MCIERR_DEVICE_NOT_INSTALLED; DWORD dwRet = MCIERR_INVALID_DEVICE_ID;
LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID); LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID);
if (!wmd) { if (wmd) {
dwRet = MCIERR_INVALID_DEVICE_ID; if (wmd->bIs32) {
dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
} else { } else {
switch (GetDriverFlags(wmd->hDrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) {
case WINE_GDF_EXIST|WINE_GDF_16BIT:
{
MCI_MapType res; MCI_MapType res;
switch (res = MCI_MapMsg32ATo16(wmd->wType, wMsg, dwParam1, &dwParam2)) { switch (res = MCI_MapMsg32ATo16(wmd->wType, wMsg, dwParam1, &dwParam2)) {
@ -1959,23 +1994,12 @@ DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwPa
break; break;
case MCI_MAP_OK: case MCI_MAP_OK:
case MCI_MAP_OKMEM: case MCI_MAP_OKMEM:
dwRet = SendDriverMessage16(wmd->hDrv, wMsg, dwParam1, dwParam2); dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
if (res == MCI_MAP_OKMEM) if (res == MCI_MAP_OKMEM)
MCI_UnMapMsg32ATo16(wmd->wType, wMsg, dwParam1, dwParam2); MCI_UnMapMsg32ATo16(wmd->wType, wMsg, dwParam1, dwParam2);
break; break;
case MCI_MAP_PASS:
dwRet = SendDriverMessage(wmd->hDrv, wMsg, dwParam1, dwParam2);
break;
} }
} }
break;
case WINE_GDF_EXIST:
dwRet = SendDriverMessage(wmd->hDrv, wMsg, dwParam1, dwParam2);
break;
default:
WARN("Unknown driver %u\n", wmd->hDrv);
dwRet = MCIERR_DRIVER_INTERNAL;
}
} }
return dwRet; return dwRet;
} }
@ -1985,19 +2009,15 @@ DWORD MCI_SendCommandFrom32(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwPa
*/ */
DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2) DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwParam2)
{ {
DWORD dwRet = MCIERR_DEVICE_NOT_INSTALLED; DWORD dwRet = MCIERR_INVALID_DEVICE_ID;
LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID); LPWINE_MCIDRIVER wmd = MCI_GetDriver(wDevID);
if (!wmd) { if (wmd) {
dwRet = MCIERR_INVALID_DEVICE_ID; dwRet = MCIERR_INVALID_DEVICE_ID;
} else {
if (wmd->bIs32) {
MCI_MapType res; MCI_MapType res;
switch (GetDriverFlags(wmd->hDrv) & (WINE_GDF_EXIST|WINE_GDF_16BIT)) {
case WINE_GDF_EXIST|WINE_GDF_16BIT:
dwRet = SendDriverMessage16(wmd->hDrv, wMsg, dwParam1, dwParam2);
break;
case WINE_GDF_EXIST:
switch (res = MCI_MapMsg16To32A(wmd->wType, wMsg, &dwParam2)) { switch (res = MCI_MapMsg16To32A(wmd->wType, wMsg, &dwParam2)) {
case MCI_MAP_MSGERROR: case MCI_MAP_MSGERROR:
TRACE("Not handled yet (%s)\n", MCI_MessageToString(wMsg)); TRACE("Not handled yet (%s)\n", MCI_MessageToString(wMsg));
@ -2009,18 +2029,13 @@ DWORD MCI_SendCommandFrom16(UINT wDevID, UINT16 wMsg, DWORD dwParam1, DWORD dwPa
break; break;
case MCI_MAP_OK: case MCI_MAP_OK:
case MCI_MAP_OKMEM: case MCI_MAP_OKMEM:
dwRet = SendDriverMessage(wmd->hDrv, wMsg, dwParam1, dwParam2); dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
if (res == MCI_MAP_OKMEM) if (res == MCI_MAP_OKMEM)
MCI_UnMapMsg16To32A(wmd->wType, wMsg, dwParam2); MCI_UnMapMsg16To32A(wmd->wType, wMsg, dwParam2);
break; break;
case MCI_MAP_PASS:
dwRet = SendDriverMessage16(wmd->hDrv, wMsg, dwParam1, dwParam2);
break;
} }
break; } else {
default: dwRet = SendDriverMessage(wmd->hDriver, wMsg, dwParam1, dwParam2);
WARN("Unknown driver %u\n", wmd->hDrv);
dwRet = MCIERR_DRIVER_INTERNAL;
} }
} }
return dwRet; return dwRet;

View File

@ -32,9 +32,6 @@
DEFAULT_DEBUG_CHANNEL(mmsys); DEFAULT_DEBUG_CHANNEL(mmsys);
LONG WINAPI DrvDefDriverProc(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2);
static LPWINE_MM_IDATA lpFirstIData = NULL; static LPWINE_MM_IDATA lpFirstIData = NULL;
static LPWINE_MM_IDATA MULTIMEDIA_GetIDataNoCheck(void) static LPWINE_MM_IDATA MULTIMEDIA_GetIDataNoCheck(void)
@ -636,18 +633,6 @@ UINT16 WINAPI mmsystemGetVersion16(void)
return 0x030a; return 0x030a;
} }
/**************************************************************************
* DriverProc [MMSYSTEM.6]
*/
LRESULT WINAPI DriverProc16(DWORD dwDevID, HDRVR16 hDrv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
TRACE("dwDevID=%08lx hDrv=%04x wMsg=%04x dwParam1=%08lx dwParam2=%08lx\n",
dwDevID, hDrv, wMsg, dwParam1, dwParam2);
return DrvDefDriverProc(dwDevID, hDrv, wMsg, dwParam1, dwParam2);
}
/************************************************************************** /**************************************************************************
* DriverCallback [MMSYSTEM.31] * DriverCallback [MMSYSTEM.31]
*/ */
@ -4857,73 +4842,6 @@ DWORD WINAPI waveInMessage16(HWAVEIN16 hWaveIn, UINT16 uMessage,
return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE); return MMDRV_Message(wmld, uMessage, dwParam1, dwParam2, TRUE);
} }
/**************************************************************************
* DrvOpen [MMSYSTEM.1100]
*/
HDRVR16 WINAPI DrvOpen(LPSTR lpDriverName, LPSTR lpSectionName, LPARAM lParam)
{
TRACE("('%s','%s', %08lX);\n", lpDriverName, lpSectionName, lParam);
return OpenDriver16(lpDriverName, lpSectionName, lParam);
}
/**************************************************************************
* DrvClose [MMSYSTEM.1101]
*/
LRESULT WINAPI DrvClose(HDRVR16 hDrv, LPARAM lParam1, LPARAM lParam2)
{
TRACE("(%04X, %08lX, %08lX);\n", hDrv, lParam1, lParam2);
return CloseDriver16(hDrv, lParam1, lParam2);
}
/**************************************************************************
* DrvSendMessage [MMSYSTEM.1102]
*/
LRESULT WINAPI DrvSendMessage(HDRVR16 hDrv, WORD msg, LPARAM lParam1,
LPARAM lParam2)
{
return SendDriverMessage(hDrv, msg, lParam1, lParam2);
}
/**************************************************************************
* DrvGetModuleHandle [MMSYSTEM.1103]
*/
HANDLE16 WINAPI DrvGetModuleHandle16(HDRVR16 hDrv)
{
return GetDriverModuleHandle16(hDrv);
}
/**************************************************************************
* DrvDefDriverProc [MMSYSTEM.1104]
*/
LRESULT WINAPI DrvDefDriverProc(DWORD dwDriverID, HDRVR16 hDrv, WORD wMsg,
DWORD dwParam1, DWORD dwParam2)
{
/* FIXME : any mapping from 32 to 16 bit structure ? */
return DefDriverProc16(dwDriverID, hDrv, wMsg, dwParam1, dwParam2);
}
/**************************************************************************
* DefDriverProc [WINMM.5]
*/
LRESULT WINAPI DefDriverProc(DWORD dwDriverIdentifier, HDRVR hDrv,
UINT Msg, LPARAM lParam1, LPARAM lParam2)
{
switch (Msg) {
case DRV_LOAD:
case DRV_FREE:
case DRV_ENABLE:
case DRV_DISABLE:
return 1;
case DRV_INSTALL:
case DRV_REMOVE:
return DRV_SUCCESS;
default:
return 0;
}
}
/*#define USE_MM_TSK_WINE*/ /*#define USE_MM_TSK_WINE*/
/************************************************************************** /**************************************************************************

View File

@ -137,11 +137,11 @@ owner winmm
903 pascal mmTaskSignal(word) mmTaskSignal16 903 pascal mmTaskSignal(word) mmTaskSignal16
904 pascal mmGetCurrentTask() WIN16_GetCurrentTask #just the same 904 pascal mmGetCurrentTask() WIN16_GetCurrentTask #just the same
905 pascal mmTaskYield() mmTaskYield16 905 pascal mmTaskYield() mmTaskYield16
1100 pascal DrvOpen(str str long) DrvOpen 1100 pascal DrvOpen(str str long) DrvOpen16
1101 pascal DrvClose(word long long) DrvClose 1101 pascal DrvClose(word long long) DrvClose16
1102 pascal DrvSendMessage(word word long long) DrvSendMessage 1102 pascal DrvSendMessage(word word long long) DrvSendMessage16
1103 pascal DrvGetModuleHandle(word) DrvGetModuleHandle16 1103 pascal DrvGetModuleHandle(word) DrvGetModuleHandle16
1104 pascal DrvDefDriverProc(long word word long long) DrvDefDriverProc 1104 pascal DrvDefDriverProc(long word word long long) DrvDefDriverProc16
1120 pascal mmThreadCreate(segptr ptr long long) mmThreadCreate16 1120 pascal mmThreadCreate(segptr ptr long long) mmThreadCreate16
1121 pascal mmThreadSignal(word) mmThreadSignal16 1121 pascal mmThreadSignal(word) mmThreadSignal16
1122 pascal mmThreadBlock(word) mmThreadBlock16 1122 pascal mmThreadBlock(word) mmThreadBlock16
@ -176,5 +176,5 @@ owner winmm
#2006 stub WINMMSL_THUNKDATA16 #2006 stub WINMMSL_THUNKDATA16
2046 pascal DllEntryPoint(long word word word long word) MMSYSTEM_LibMain 2046 pascal DllEntryPoint(long word word word long word) MMSYSTEM_LibMain
# this is a wine only exported function. Is there another way to do it ? # these are Wine only exported functions. Is there another way to do it ?
2047 pascal WINE_mmThreadEntryPoint(long) WINE_mmThreadEntryPoint 2047 pascal __wine_mmThreadEntryPoint(long) WINE_mmThreadEntryPoint

View File

@ -15,6 +15,28 @@
typedef DWORD WINAPI (*MessageProc16)(UINT16 wDevID, UINT16 wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2); typedef DWORD WINAPI (*MessageProc16)(UINT16 wDevID, UINT16 wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
typedef DWORD WINAPI (*MessageProc32)(UINT wDevID, UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2); typedef DWORD WINAPI (*MessageProc32)(UINT wDevID, UINT wMsg, DWORD dwUser, DWORD dwParam1, DWORD dwParam2);
/* Who said goofy boy ? */
#define WINE_DI_MAGIC 0x900F1B01
typedef struct tagWINE_DRIVER
{
DWORD dwMagic;
/* as usual LPWINE_DRIVER == hDriver32 */
DWORD dwFlags;
union {
struct {
HMODULE hModule;
DRIVERPROC lpDrvProc;
DWORD dwDriverID;
} d32;
struct {
HDRVR16 hDriver16;
} d16;
} d;
struct tagWINE_DRIVER* lpPrevItem;
struct tagWINE_DRIVER* lpNextItem;
} WINE_DRIVER, *LPWINE_DRIVER;
typedef struct tagWINE_MLD { typedef struct tagWINE_MLD {
/* EPP struct tagWINE_MLD* lpNext; */ /* not used so far */ /* EPP struct tagWINE_MLD* lpNext; */ /* not used so far */
UINT uDeviceID; UINT uDeviceID;
@ -85,7 +107,7 @@ typedef struct tagWINE_MCIDRIVER {
LPSTR lpstrElementName; LPSTR lpstrElementName;
LPSTR lpstrDeviceType; LPSTR lpstrDeviceType;
LPSTR lpstrAlias; LPSTR lpstrAlias;
HDRVR hDrv; HDRVR hDriver;
DRIVERPROC16 driverProc; DRIVERPROC16 driverProc;
DWORD dwPrivate; DWORD dwPrivate;
YIELDPROC lpfnYieldProc; YIELDPROC lpfnYieldProc;
@ -150,6 +172,10 @@ typedef struct tagWINE_MM_IDATA {
typedef LONG (*MCIPROC16)(DWORD, HDRVR16, WORD, DWORD, DWORD); typedef LONG (*MCIPROC16)(DWORD, HDRVR16, WORD, DWORD, DWORD);
typedef LONG (*MCIPROC)(DWORD, HDRVR, DWORD, DWORD, DWORD); typedef LONG (*MCIPROC)(DWORD, HDRVR, DWORD, DWORD, DWORD);
extern LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr);
extern BOOL DRIVER_GetLibName(LPCSTR keyName, LPCSTR sectName, LPSTR buf, int sz);
extern LPWINE_DRIVER DRIVER_TryOpenDriver32(LPCSTR fn, LPARAM lParam2);
extern LPWINE_MCIDRIVER MCI_GetDriver(UINT16 uDevID); extern LPWINE_MCIDRIVER MCI_GetDriver(UINT16 uDevID);
extern UINT MCI_GetDriverFromString(LPCSTR str); extern UINT MCI_GetDriverFromString(LPCSTR str);
extern DWORD MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr); extern DWORD MCI_WriteString(LPSTR lpDstStr, DWORD dstSize, LPCSTR lpSrcStr);

View File

@ -5,7 +5,7 @@
* *
* Copyright 1994 Martin Ayotte * Copyright 1994 Martin Ayotte
* Copyright 1998 Marcus Meissner * Copyright 1998 Marcus Meissner
* Copyright 1999 Eric Pouech * Copyright 1999,2000 Eric Pouech
*/ */
#include <string.h> #include <string.h>
@ -14,54 +14,28 @@
#include "wine/winbase16.h" #include "wine/winbase16.h"
#include "wingdi.h" #include "wingdi.h"
#include "winuser.h" #include "winuser.h"
#include "ldt.h"
#include "mmddk.h" #include "mmddk.h"
#include "debugtools.h" #include "debugtools.h"
DEFAULT_DEBUG_CHANNEL(driver); DEFAULT_DEBUG_CHANNEL(driver);
/* The following definitions are WINE internals */
/* FIXME: This is a WINE internal struct and should be moved in include/wine directory
* Please note that WINE shares 16 and 32 bit drivers on a single list...
* Basically, we maintain an external double view on drivers, so that a 16 bit drivers
* can be loaded/used... by 32 functions transparently
*/
/* Who said goofy boy ? */
#define WINE_DI_MAGIC 0x900F1B01
typedef struct tagWINE_DRIVER typedef struct tagWINE_DRIVER
{ {
DWORD dwMagic;
char szAliasName[128]; char szAliasName[128];
/* as usual LPWINE_DRIVER == hDriver32 */ /* as usual LPWINE_DRIVER == hDriver32 */
HDRVR16 hDriver16; HDRVR16 hDriver16;
union { HMODULE16 hModule16;
struct {
HMODULE16 hModule;
DRIVERPROC16 lpDrvProc; DRIVERPROC16 lpDrvProc;
} d16;
struct {
HMODULE hModule;
DRIVERPROC lpDrvProc;
} d32;
} d;
DWORD dwDriverID; DWORD dwDriverID;
DWORD dwFlags;
struct tagWINE_DRIVER* lpPrevItem; struct tagWINE_DRIVER* lpPrevItem;
struct tagWINE_DRIVER* lpNextItem; struct tagWINE_DRIVER* lpNextItem;
} WINE_DRIVER, *LPWINE_DRIVER; } WINE_DRIVER, *LPWINE_DRIVER;
LPWINE_DRIVER DRIVER_RegisterDriver16(LPCSTR, HMODULE16, DRIVERPROC16, LPARAM, BOOL);
LPWINE_DRIVER DRIVER_RegisterDriver32(LPCSTR, HMODULE, DRIVERPROC, LPARAM, BOOL);
static LPWINE_DRIVER lpDrvItemList = NULL; static LPWINE_DRIVER lpDrvItemList = NULL;
/* TODO list : /* TODO list :
* - LoadModule count and clean up is not handled correctly (it's not a * - LoadModule count and clean up is not handled correctly (it's not a
* problem as long as FreeLibrary is not working correctly) * problem as long as FreeLibrary is not working correctly)
* - shoudln't the allocations be done on a per process basis ?
* - split 16/32 bit functions between DLLs as windows do (16 bit in USER, 32 bit in WINMM)
*/ */
/* ### start build ### */ /* ### start build ### */
@ -101,15 +75,9 @@ static WORD DRIVER_GetNumberOfModuleRefs(LPWINE_DRIVER lpNewDrv)
WORD count = 0; WORD count = 0;
for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) { for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
if (lpDrv->dwFlags & WINE_GDF_16BIT) { if (lpDrv->hModule16 == lpNewDrv->hModule16) {
if (lpDrv->d.d16.hModule == lpNewDrv->d.d16.hModule) {
count++; count++;
} }
} else {
if (lpDrv->d.d32.hModule == lpNewDrv->d.d32.hModule) {
count++;
}
}
} }
return count; return count;
} }
@ -132,349 +100,15 @@ static LPWINE_DRIVER DRIVER_FindFromHDrvr16(HDRVR16 hDrvr)
} }
/************************************************************************** /**************************************************************************
* DRIVER_FindFromHDrvr [internal] * DRIVER_SendMessage [internal]
*
* From a hDrvr (being 16 or 32 bits), returns the WINE internal structure.
*/ */
static LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr) static LRESULT inline DRIVER_SendMessage(LPWINE_DRIVER lpDrv, UINT16 msg,
LPARAM lParam1, LPARAM lParam2)
{ {
if (!IsBadWritePtr((void*)hDrvr, sizeof(WINE_DRIVER)) && TRACE("Before CallDriverProc proc=%p driverID=%08lx wMsg=%04x p1=%08lx p2=%08lx\n",
((LPWINE_DRIVER)hDrvr)->dwMagic == WINE_DI_MAGIC) { lpDrv->lpDrvProc, lpDrv->dwDriverID, msg, lParam1, lParam2);
return (LPWINE_DRIVER)hDrvr; return DRIVER_CallTo16_long_lwwll((FARPROC16)lpDrv->lpDrvProc, lpDrv->dwDriverID,
} lpDrv->hDriver16, msg, lParam1, lParam2);
return DRIVER_FindFromHDrvr16(hDrvr);
}
/**************************************************************************
* DRIVER_MapMsg16To32 [internal]
*
* Map a 16 bit driver message to a 32 bit driver message.
* 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg16To32
* 0 : ok, no memory allocated
* -1 : ko, unknown message
* -2 : ko, memory problem
*/
static int DRIVER_MapMsg16To32(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
{
int ret = -1;
switch (wMsg) {
case DRV_LOAD:
case DRV_ENABLE:
case DRV_DISABLE:
case DRV_FREE:
case DRV_QUERYCONFIGURE:
case DRV_REMOVE:
case DRV_EXITSESSION:
case DRV_EXITAPPLICATION:
case DRV_POWER:
/* lParam1 and lParam2 are not used */
ret = 0;
break;
case DRV_OPEN:
case DRV_CLOSE:
/* lParam1 is a NULL terminated string */
/* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
if (*lParam1)
*lParam1 = (DWORD)PTR_SEG_TO_LIN(*lParam1);
if (*lParam2 && wMsg == DRV_OPEN) {
LPMCI_OPEN_DRIVER_PARMS16 modp16 = PTR_SEG_TO_LIN(*lParam2);
char* ptr = HeapAlloc(GetProcessHeap(), 0, sizeof(LPMCI_OPEN_DRIVER_PARMS16) + sizeof(MCI_OPEN_DRIVER_PARMSA));
LPMCI_OPEN_DRIVER_PARMSA modp32;
if (ptr) {
*(LPMCI_OPEN_DRIVER_PARMS16*)ptr = modp16;
modp32 = (LPMCI_OPEN_DRIVER_PARMSA)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA));
modp32->wDeviceID = modp16->wDeviceID;
modp32->lpstrParams = PTR_SEG_TO_LIN(modp16->lpstrParams);
} else {
return -2;
}
*lParam2 = (DWORD)modp32;
}
ret = 1;
break;
case DRV_CONFIGURE:
case DRV_INSTALL:
/* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
if (*lParam2) {
LPDRVCONFIGINFO dci32 = HeapAlloc(GetProcessHeap(), 0, sizeof(DRVCONFIGINFO));
LPDRVCONFIGINFO16 dci16 = PTR_SEG_TO_LIN(*lParam2);
if (dci32) {
dci32->dwDCISize = sizeof(DRVCONFIGINFO);
dci32->lpszDCISectionName = HEAP_strdupAtoW(GetProcessHeap(), 0, PTR_SEG_TO_LIN(dci16->lpszDCISectionName));
dci32->lpszDCIAliasName = HEAP_strdupAtoW(GetProcessHeap(), 0, PTR_SEG_TO_LIN(dci16->lpszDCIAliasName));
if (dci32->lpszDCISectionName == NULL || dci32->lpszDCIAliasName == NULL)
return -2;
} else {
return -2;
}
*lParam2 = (DWORD)dci32;
ret = 1;
} else {
ret = 0;
}
break;
default:
if ((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100 )) {
/* FIXME: another hack to handle MCI and ICM messages...
* should find a *NICE* way to integrate DRIVER_ and
* MCI_ mapping/unmapping functions
*/
ret = 0;
} else {
FIXME("Unknown message 0x%04x\n", wMsg);
}
}
return ret;
}
/**************************************************************************
* DRIVER_MapMsg16To32 [internal]
*
* UnMap a 16 bit driver message to a 32 bit driver message.
* 0 : ok
* -1 : ko
* -2 : ko, memory problem
*/
static int DRIVER_UnMapMsg16To32(WORD wMsg, DWORD lParam1, DWORD lParam2)
{
int ret = -1;
switch (wMsg) {
case DRV_LOAD:
case DRV_ENABLE:
case DRV_DISABLE:
case DRV_FREE:
case DRV_QUERYCONFIGURE:
case DRV_REMOVE:
case DRV_EXITSESSION:
case DRV_EXITAPPLICATION:
case DRV_POWER:
/* lParam1 and lParam2 are not used */
case DRV_OPEN:
case DRV_CLOSE:
/* lParam1 is a NULL terminated string */
/* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
if (lParam2 && wMsg == DRV_OPEN) {
LPMCI_OPEN_DRIVER_PARMSA modp32 = (LPMCI_OPEN_DRIVER_PARMSA)lParam2;
LPMCI_OPEN_DRIVER_PARMS16 modp16 = *(LPMCI_OPEN_DRIVER_PARMS16*)(lParam2 - sizeof(LPMCI_OPEN_DRIVER_PARMSA));
modp16->wCustomCommandTable = modp32->wCustomCommandTable;
modp16->wType = modp32->wType;
if (!HeapFree(GetProcessHeap(), 0, modp32))
FIXME("bad free line=%d\n", __LINE__);
}
ret = 0;
break;
case DRV_CONFIGURE:
case DRV_INSTALL:
/* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
if (lParam2) {
LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)lParam2;
if (!HeapFree(GetProcessHeap(), 0, (LPVOID)dci32->lpszDCISectionName))
FIXME("bad free line=%d\n", __LINE__);
if (!HeapFree(GetProcessHeap(), 0, (LPVOID)dci32->lpszDCIAliasName))
FIXME("bad free line=%d\n", __LINE__);
if (!HeapFree(GetProcessHeap(), 0, dci32))
FIXME("bad free line=%d\n", __LINE__);
}
ret = 0;
break;
default:
if ((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100 )) {
/* FIXME: another hack to handle MCI and ICM messages...
* should find a *NICE* way to integrate DRIVER_ and
* MCI_ mapping/unmapping functions
*/
ret = 0;
} else {
FIXME("Unknown message 0x%04x\n", wMsg);
}
}
return ret;
}
/**************************************************************************
* DRIVER_MapMsg32To16 [internal]
*
* Map a 32 bit driver message to a 16 bit driver message.
* 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg32To16
* 0 : ok, no memory allocated
* -1 : ko, unknown message
* -2 : ko, memory problem
*/
static int DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
{
int ret = -1;
switch (wMsg) {
case DRV_LOAD:
case DRV_ENABLE:
case DRV_DISABLE:
case DRV_FREE:
case DRV_QUERYCONFIGURE:
case DRV_REMOVE:
case DRV_EXITSESSION:
case DRV_EXITAPPLICATION:
case DRV_POWER:
/* lParam1 and lParam2 are not used */
ret = 0;
break;
case DRV_OPEN:
case DRV_CLOSE:
/* lParam1 is a NULL terminated string */
/* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
if (*lParam1) {
LPSTR str = SEGPTR_STRDUP((LPSTR)*lParam1);
if (str) {
*lParam1 = (LPARAM)SEGPTR_GET(str);
ret = 0;
} else {
ret = -2;
}
} else {
ret = 0;
}
if (*lParam2 && wMsg == DRV_OPEN) {
LPMCI_OPEN_DRIVER_PARMS16 modp16;
char* ptr = SEGPTR_ALLOC(sizeof(LPMCI_OPEN_DRIVER_PARMSA) + sizeof(MCI_OPEN_DRIVER_PARMS16));
LPMCI_OPEN_DRIVER_PARMSA modp32 = (LPMCI_OPEN_DRIVER_PARMSA)(*lParam2);
if (ptr) {
*(LPMCI_OPEN_DRIVER_PARMSA*)ptr = modp32;
modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA));
modp16->wDeviceID = modp32->wDeviceID;
modp16->lpstrParams = PTR_SEG_TO_LIN(modp32->lpstrParams);
} else {
return -2;
}
*lParam2 = (DWORD)SEGPTR_GET(modp16);
ret = 1;
}
break;
case DRV_CONFIGURE:
case DRV_INSTALL:
/* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
if (*lParam2) {
LPDRVCONFIGINFO16 dci16 = (LPDRVCONFIGINFO16)SEGPTR_ALLOC(sizeof(DRVCONFIGINFO16));
LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
if (dci16) {
LPSTR str1, str2;
dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCISectionName)) != NULL &&
(str2 = SEGPTR_STRDUP(str1)) != NULL) {
dci16->lpszDCISectionName = (LPSTR)SEGPTR_GET(str2);
if (!HeapFree(GetProcessHeap(), 0, str1))
FIXME("bad free line=%d\n", __LINE__);
} else {
return -2;
}
if ((str1 = HEAP_strdupWtoA(GetProcessHeap(), 0, dci32->lpszDCIAliasName)) != NULL &&
(str2 = SEGPTR_STRDUP(str1)) != NULL) {
dci16->lpszDCIAliasName = (LPSTR)SEGPTR_GET(str2);
if (!HeapFree(GetProcessHeap(), 0, str1))
FIXME("bad free line=%d\n", __LINE__);
} else {
return -2;
}
} else {
return -2;
}
*lParam2 = (LPARAM)SEGPTR_GET(dci16);
ret = 1;
} else {
ret = 0;
}
break;
default:
if ((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100 )) {
/* FIXME: another hack to handle MCI and ICM messages...
* should find a *NICE* way to integrate DRIVER_ and
* MCI_ mapping/unmapping functions
*/
ret = 0;
} else {
FIXME("Unknown message 0x%04x\n", wMsg);
}
}
return ret;
}
/**************************************************************************
* DRIVER_UnMapMsg32To16 [internal]
*
* UnMap a 32 bit driver message to a 16 bit driver message.
* 0 : ok
* -1 : ko
* -2 : ko, memory problem
*/
static int DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
{
int ret = -1;
switch (wMsg) {
case DRV_LOAD:
case DRV_ENABLE:
case DRV_DISABLE:
case DRV_FREE:
case DRV_QUERYCONFIGURE:
case DRV_REMOVE:
case DRV_EXITSESSION:
case DRV_EXITAPPLICATION:
case DRV_POWER:
/* lParam1 and lParam2 are not used */
case DRV_OPEN:
case DRV_CLOSE:
/* lParam1 is a NULL terminated string, lParam2 is unknown => may lead to some problem */
/* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
if (lParam1) if (!SEGPTR_FREE(PTR_SEG_TO_LIN(lParam1)))
FIXME("bad free line=%d\n", __LINE__);
if (lParam2 && wMsg == DRV_OPEN) {
LPMCI_OPEN_DRIVER_PARMS16 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)PTR_SEG_TO_LIN(lParam2);
LPMCI_OPEN_DRIVER_PARMSA modp32 = *(LPMCI_OPEN_DRIVER_PARMSA*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA));
modp32->wCustomCommandTable = modp16->wCustomCommandTable;
modp32->wType = modp16->wType;
if (!SEGPTR_FREE((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA)))
FIXME("bad free line=%d\n", __LINE__);
}
ret = 0;
break;
case DRV_CONFIGURE:
case DRV_INSTALL:
/* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
if (lParam2) {
LPDRVCONFIGINFO16 dci16 = (LPDRVCONFIGINFO16)PTR_SEG_TO_LIN(lParam2);
if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCISectionName)))
FIXME("bad free line=%d\n", __LINE__);
if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCIAliasName)))
FIXME("bad free line=%d\n", __LINE__);
if (!SEGPTR_FREE(dci16))
FIXME("bad free line=%d\n", __LINE__);
}
ret = 0;
break;
default:
if ((wMsg >= 0x800 && wMsg < 0x900) || (wMsg >= 0x4000 && wMsg < 0x4100 )) {
/* FIXME: another hack to handle MCI and ICM messages...
* should find a *NICE* way to integrate DRIVER_ and
* MCI_ mapping/unmapping functions
*/
ret = 0;
} else {
FIXME("Unknown message 0x%04x\n", wMsg);
}
}
return ret;
} }
/************************************************************************** /**************************************************************************
@ -485,30 +119,11 @@ LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
{ {
LPWINE_DRIVER lpDrv; LPWINE_DRIVER lpDrv;
LRESULT retval = 0; LRESULT retval = 0;
int mapRet;
TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2); TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2);
lpDrv = DRIVER_FindFromHDrvr16(hDriver); if ((lpDrv = DRIVER_FindFromHDrvr16(hDriver)) != NULL) {
if (lpDrv != NULL && lpDrv->hDriver16 == hDriver) { retval = DRIVER_SendMessage(lpDrv, msg, lParam1, lParam2);
if (lpDrv->dwFlags & WINE_GDF_16BIT) {
TRACE("Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID, hDriver, msg, lParam1, lParam2);
retval = DRIVER_CallTo16_long_lwwll((FARPROC16)lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID,
hDriver, msg, lParam1, lParam2);
} else {
mapRet = DRIVER_MapMsg16To32(msg, &lParam1, &lParam2);
if (mapRet >= 0) {
TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->d.d32.lpDrvProc, lpDrv->dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
retval = lpDrv->d.d32.lpDrvProc(lpDrv->dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
if (mapRet >= 1) {
DRIVER_UnMapMsg16To32(msg, lParam1, lParam2);
}
} else {
retval = 0;
}
}
} else { } else {
WARN("Bad driver handle %u\n", hDriver); WARN("Bad driver handle %u\n", hDriver);
} }
@ -517,47 +132,6 @@ LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
return retval; return retval;
} }
/**************************************************************************
* SendDriverMessage [WINMM.19]
*/
LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1,
LPARAM lParam2)
{
LPWINE_DRIVER lpDrv;
LRESULT retval = 0;
int mapRet;
TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2);
lpDrv = DRIVER_FindFromHDrvr(hDriver);
if (lpDrv != NULL) {
if (lpDrv->dwFlags & WINE_GDF_16BIT) {
mapRet = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2);
if (mapRet >= 0) {
TRACE("Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID, lpDrv->hDriver16, msg, lParam1, lParam2);
retval = DRIVER_CallTo16_long_lwwll((FARPROC16)lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID,
lpDrv->hDriver16, msg, lParam1, lParam2);
if (mapRet >= 1) {
DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
}
} else {
retval = 0;
}
} else {
TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
lpDrv->d.d32.lpDrvProc, lpDrv->dwDriverID, hDriver, msg, lParam1, lParam2);
retval = lpDrv->d.d32.lpDrvProc(lpDrv->dwDriverID, hDriver, msg, lParam1, lParam2);
}
} else {
WARN("Bad driver handle %u\n", hDriver);
}
TRACE("retval = %ld\n", retval);
return retval;
}
/************************************************************************** /**************************************************************************
* DRIVER_RemoveFromList [internal] * DRIVER_RemoveFromList [internal]
* *
@ -568,8 +142,8 @@ static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
{ {
lpDrv->dwDriverID = 0; lpDrv->dwDriverID = 0;
if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) { if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) {
SendDriverMessage((HDRVR)lpDrv, DRV_DISABLE, 0L, 0L); DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
SendDriverMessage((HDRVR)lpDrv, DRV_FREE, 0L, 0L); DRIVER_SendMessage(lpDrv, DRV_FREE, 0L, 0L);
} }
if (lpDrv->lpPrevItem) if (lpDrv->lpPrevItem)
@ -588,19 +162,16 @@ static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
* Adds a driver struct to the list of open drivers. * Adds a driver struct to the list of open drivers.
* Generates all the logic to handle driver creation / open. * Generates all the logic to handle driver creation / open.
*/ */
static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam, BOOL bCallFrom32) static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam1, LPARAM lParam2)
{ {
lpNewDrv->dwMagic = WINE_DI_MAGIC;
/* First driver to be loaded for this module, need to load correctly the module */ /* First driver to be loaded for this module, need to load correctly the module */
if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) { if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) {
if (SendDriverMessage((HDRVR)lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) { if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv); TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
return FALSE; return FALSE;
} }
if (SendDriverMessage((HDRVR)lpNewDrv, DRV_ENABLE, 0L, 0L) != DRV_SUCCESS) { /* returned value is not checked */
TRACE("DRV_ENABLE failed on driver 0x%08lx\n", (DWORD)lpNewDrv); DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
return FALSE;
}
} }
lpNewDrv->lpNextItem = NULL; lpNewDrv->lpNextItem = NULL;
@ -616,11 +187,8 @@ static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam, BOOL bCallFr
lpNewDrv->lpPrevItem = lpDrv; lpNewDrv->lpPrevItem = lpDrv;
} }
/* Now just open a new instance of a driver on this module */ /* Now just open a new instance of a driver on this module */
if (bCallFrom32) { lpNewDrv->dwDriverID = DRIVER_SendMessage(lpNewDrv, DRV_OPEN, lParam1, lParam2);
lpNewDrv->dwDriverID = SendDriverMessage((HDRVR)lpNewDrv, DRV_OPEN, 0L, lParam);
} else {
lpNewDrv->dwDriverID = SendDriverMessage16(lpNewDrv->hDriver16, DRV_OPEN, 0L, lParam);
}
if (lpNewDrv->dwDriverID == 0) { if (lpNewDrv->dwDriverID == 0) {
TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv); TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
DRIVER_RemoveFromList(lpNewDrv); DRIVER_RemoveFromList(lpNewDrv);
@ -631,26 +199,101 @@ static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam, BOOL bCallFr
} }
/************************************************************************** /**************************************************************************
* DRIVER_CreateDrvr16 [internal] * DRIVER_TryOpenDriver16 [internal]
* *
* Creates unique ID for 16 bit drivers. * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
*/ */
static HDRVR16 DRIVER_CreateDrvr16(void) static LPWINE_DRIVER DRIVER_TryOpenDriver16(LPCSTR lpFileName, LPARAM lParam2)
{ {
static WORD DRIVER_hDrvr16Counter = 0; static WORD DRIVER_hDrvr16Counter /* = 0 */;
LPWINE_DRIVER lpDrv = NULL;
HMODULE16 hModule;
DRIVERPROC16 lpProc;
LPCSTR lpSFN;
LPSTR ptr;
TRACE("('%s', %08lX);\n", lpFileName, lParam2);
if (strlen(lpFileName) < 1) return lpDrv;
if ((lpSFN = strrchr(lpFileName, '\\')) == NULL)
lpSFN = lpFileName;
else
lpSFN++;
if ((ptr = strchr(lpFileName, ' ')) != NULL) {
*ptr++ = '\0';
while (*ptr == ' ') ptr++;
if (*ptr == '\0') ptr = NULL;
}
if ((hModule = LoadModule16(lpFileName, (LPVOID)-1)) < 32) goto exit;
if ((lpProc = (DRIVERPROC16)GetProcAddress16(hModule, "DRIVERPROC")) == NULL)
goto exit;
if ((lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER))) == NULL)
goto exit;
lpDrv->dwDriverID = 0;
while (DRIVER_FindFromHDrvr16(++DRIVER_hDrvr16Counter)); while (DRIVER_FindFromHDrvr16(++DRIVER_hDrvr16Counter));
return DRIVER_hDrvr16Counter; lpDrv->hDriver16 = DRIVER_hDrvr16Counter;
lstrcpynA(lpDrv->szAliasName, lpSFN, sizeof(lpDrv->szAliasName));
lpDrv->hModule16 = hModule;
lpDrv->lpDrvProc = lpProc;
if (!DRIVER_AddToList(lpDrv, (LPARAM)ptr, lParam2)) goto exit;
return lpDrv;
exit:
TRACE("Unable to load 16 bit module (%s): %04x\n", lpFileName, hModule);
if (hModule >= 32) FreeLibrary16(hModule);
HeapFree(GetProcessHeap(), 0, lpDrv);
return NULL;
} }
/************************************************************************** /**************************************************************************
* DRIVER_CloseDriver [internal] * OpenDriver16 [USER.252]
*
*/ */
BOOL DRIVER_CloseDriver(LPWINE_DRIVER lpDrv, DWORD lParam1, DWORD lParam2) HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam2)
{ {
if (lpDrv != NULL) { LPWINE_DRIVER lpDrv = NULL;
SendDriverMessage((HDRVR)lpDrv, DRV_CLOSE, lParam1, lParam2); char drvName[128];
TRACE("('%s', '%s', %08lX);\n", lpDriverName, lpSectionName, lParam2);
if (!lpDriverName || !*lpDriverName) return 0;
if (lpSectionName == NULL) {
strcpy(drvName, lpDriverName);
if ((lpDrv = DRIVER_TryOpenDriver16(drvName, lParam2)))
goto the_end;
/* in case hDriver is NULL, search in Drivers section */
lpSectionName = "Drivers";
}
if (GetPrivateProfileStringA(lpSectionName, lpDriverName, "",
drvName, sizeof(drvName), "SYSTEM.INI") > 0) {
lpDrv = DRIVER_TryOpenDriver16(drvName, lParam2);
}
if (!lpDrv) {
ERR("Failed to open driver %s from system.ini file, section %s\n", lpDriverName, lpSectionName);
return 0;
}
the_end:
TRACE("=> %04x / %08lx\n", lpDrv->hDriver16, (DWORD)lpDrv);
return lpDrv->hDriver16;
}
/**************************************************************************
* CloseDriver16 [USER.253]
*/
LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
{
LPWINE_DRIVER lpDrv;
TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
if ((lpDrv = DRIVER_FindFromHDrvr16(hDrvr)) != NULL) {
DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
if (DRIVER_RemoveFromList(lpDrv)) { if (DRIVER_RemoveFromList(lpDrv)) {
HeapFree(GetProcessHeap(), 0, lpDrv); HeapFree(GetProcessHeap(), 0, lpDrv);
@ -661,245 +304,6 @@ BOOL DRIVER_CloseDriver(LPWINE_DRIVER lpDrv, DWORD lParam1, DWORD lParam2)
return FALSE; return FALSE;
} }
/**************************************************************************
* DRIVER_RegisterDriver16 [internal]
*
* Creates all the WINE internal representations for a 16 bit driver.
* The driver is also open by sending the correct messages.
*/
LPWINE_DRIVER DRIVER_RegisterDriver16(LPCSTR lpName, HMODULE16 hModule, DRIVERPROC16 lpProc,
LPARAM lParam, BOOL bCallFrom32)
{
LPWINE_DRIVER lpDrv;
lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
if (lpDrv != NULL) {
lpDrv->dwFlags = WINE_GDF_EXIST|WINE_GDF_16BIT;
lpDrv->dwDriverID = 0;
lpDrv->hDriver16 = DRIVER_CreateDrvr16();
lstrcpynA(lpDrv->szAliasName, lpName, sizeof(lpDrv->szAliasName));
lpDrv->d.d16.hModule = hModule;
lpDrv->d.d16.lpDrvProc = lpProc;
if (!DRIVER_AddToList(lpDrv, lParam, bCallFrom32)) {
HeapFree(GetProcessHeap(), 0, lpDrv);
lpDrv = NULL;
}
}
return lpDrv;
}
/**************************************************************************
* DRIVER_RegisterDriver32 [internal]
*
* Creates all the WINE internal representations for a 32 bit driver.
* The driver is also open by sending the correct messages.
*/
LPWINE_DRIVER DRIVER_RegisterDriver32(LPCSTR lpName, HMODULE hModule, DRIVERPROC lpProc,
LPARAM lParam, BOOL bCallFrom32)
{
LPWINE_DRIVER lpDrv;
lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
if (lpDrv != NULL) {
lpDrv->dwFlags = WINE_GDF_EXIST;
lpDrv->dwDriverID = 0;
lpDrv->hDriver16 = DRIVER_CreateDrvr16();
lstrcpynA(lpDrv->szAliasName, lpName, sizeof(lpDrv->szAliasName));
lpDrv->d.d32.hModule = hModule;
lpDrv->d.d32.lpDrvProc = lpProc;
if (!DRIVER_AddToList(lpDrv, lParam, bCallFrom32)) {
HeapFree(GetProcessHeap(), 0, lpDrv);
lpDrv = NULL;
}
}
return lpDrv;
}
/**************************************************************************
* DRIVER_TryOpenDriver16 [internal]
*
* Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
*/
static HDRVR16 DRIVER_TryOpenDriver16(LPCSTR lpFileName, LPARAM lParam, BOOL bCallFrom32)
{
LPWINE_DRIVER lpDrv = NULL;
LPCSTR lpSFN;
HMODULE16 hModule;
DRIVERPROC16 lpProc;
TRACE("('%s', %08lX, %d);\n", lpFileName, lParam, bCallFrom32);
if (strlen(lpFileName) < 1)
return 0;
lpSFN = strrchr(lpFileName, '\\');
lpSFN = (lpSFN) ? (lpSFN + 1) : lpFileName;
if ((hModule = LoadModule16(lpFileName, (LPVOID)-1)) >= 32) {
if ((lpProc = (DRIVERPROC16)GetProcAddress16(hModule, "DRIVERPROC")) != NULL) {
lpDrv = DRIVER_RegisterDriver16(lpSFN, hModule, lpProc, lParam, bCallFrom32);
} else {
FreeLibrary16(hModule);
TRACE("No DriverProc found\n");
lpDrv = 0;
}
} else {
TRACE("Unable to load 16 bit module (%s): %d\n", lpFileName, hModule);
}
return lpDrv ? lpDrv->hDriver16 : 0;
}
/**************************************************************************
* DRIVER_TryOpenDriver32 [internal]
*
* Tries to load a 32 bit driver whose DLL's (module) name is lpFileName.
*/
static HDRVR DRIVER_TryOpenDriver32(LPCSTR lpFileName, LPARAM lParam, BOOL bCallFrom32)
{
LPWINE_DRIVER lpDrv = NULL;
LPCSTR lpSFN;
HMODULE hModule;
DRIVERPROC lpProc;
TRACE("('%s', %08lX, %d);\n", lpFileName, lParam, bCallFrom32);
if (strlen(lpFileName) < 1)
return 0;
lpSFN = strrchr(lpFileName, '\\');
lpSFN = (lpSFN) ? (lpSFN + 1) : lpFileName;
if ((hModule = LoadLibraryA(lpFileName)) != 0) {
if ((lpProc = GetProcAddress(hModule, "DriverProc")) != NULL) {
lpDrv = DRIVER_RegisterDriver32(lpSFN, hModule, lpProc, lParam, bCallFrom32);
} else {
FreeLibrary(hModule);
lpDrv = 0;
TRACE("No DriverProc found\n");
}
} else {
TRACE("Unable to load 32 bit module \"%s\"\n", lpFileName);
}
TRACE("=> %p\n", lpDrv);
return (HDRVR)lpDrv;
}
/**************************************************************************
* OpenDriver16 [USER.252]
*/
HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
{
HDRVR16 hDriver = 0;
char drvName[128];
TRACE("('%s', '%s', %08lX);\n", lpDriverName, lpSectionName, lParam);
if (lpSectionName == NULL) {
hDriver = DRIVER_TryOpenDriver16(lpDriverName, lParam, FALSE);
if (!hDriver) {
hDriver = DRIVER_TryOpenDriver32(lpDriverName, lParam, FALSE);
}
if (!hDriver) {
/* in case hDriver is NULL, search in Drivers32 section */
lpSectionName = "Drivers";
}
}
if (!hDriver && GetPrivateProfileStringA(lpSectionName, lpDriverName, "",
drvName, sizeof(drvName), "SYSTEM.INI") > 0) {
hDriver = DRIVER_TryOpenDriver16(drvName, lParam, FALSE);
}
if (!hDriver)
ERR("Failed to open driver %s from system.ini file, section %s\n", lpDriverName, lpSectionName);
else
TRACE("=> %08x\n", hDriver);
return hDriver;
}
/**************************************************************************
* OpenDriverA [WINMM.15]
* (0,1,DRV_LOAD ,0 ,0)
* (0,1,DRV_ENABLE,0 ,0)
* (0,1,DRV_OPEN ,buf[256],0)
*/
HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
{
HDRVR hDriver = 0;
char drvName[128];
TRACE("(%s, %s, 0x%08lx);\n", debugstr_a(lpDriverName), debugstr_a(lpSectionName), lParam);
if (lpSectionName == NULL) {
lstrcpynA(drvName, lpDriverName, sizeof(drvName));
hDriver = DRIVER_TryOpenDriver32(lpDriverName, lParam, TRUE);
if (!hDriver) {
hDriver = DRIVER_TryOpenDriver16(lpDriverName, lParam, TRUE);
}
if (!hDriver) {
if (GetPrivateProfileStringA("Drivers32", lpDriverName, "", drvName,
sizeof(drvName), "SYSTEM.INI")) {
hDriver = DRIVER_TryOpenDriver32(drvName, lParam, TRUE);
}
}
if (!hDriver) {
if (GetPrivateProfileStringA("Drivers", lpDriverName, "", drvName,
sizeof(drvName), "SYSTEM.INI")) {
hDriver = DRIVER_TryOpenDriver16(drvName, lParam, TRUE);
}
}
} else {
if (GetPrivateProfileStringA(lpSectionName, lpDriverName, "", drvName,
sizeof(drvName), "SYSTEM.INI")) {
hDriver = DRIVER_TryOpenDriver32(drvName, lParam, TRUE);
if (!hDriver) {
hDriver = DRIVER_TryOpenDriver16(drvName, lParam, TRUE);
}
}
}
if (!hDriver)
ERR("Failed to open driver %s from system.ini file, section %s\n", lpDriverName, lpSectionName);
else
TRACE("=> %08x\n", hDriver);
return hDriver;
}
/**************************************************************************
* OpenDriverW [WINMM.15]
*/
HDRVR WINAPI OpenDriverW(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
{
LPSTR dn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDriverName);
LPSTR sn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpSectionName);
HDRVR ret = OpenDriverA(dn, sn, lParam);
if (dn) HeapFree(GetProcessHeap(), 0, dn);
if (sn) HeapFree(GetProcessHeap(), 0, sn);
return ret;
}
/**************************************************************************
* CloseDriver16 [USER.253]
*/
LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
{
TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
return DRIVER_CloseDriver(DRIVER_FindFromHDrvr16(hDrvr), lParam1, lParam2);
}
/**************************************************************************
* CloseDriver [WINMM.4]
*/
LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
{
TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
return DRIVER_CloseDriver(DRIVER_FindFromHDrvr(hDrvr), lParam1, lParam2);
}
/************************************************************************** /**************************************************************************
* GetDriverModuleHandle [USER.254] * GetDriverModuleHandle [USER.254]
*/ */
@ -910,51 +314,10 @@ HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
TRACE("(%04x);\n", hDrvr); TRACE("(%04x);\n", hDrvr);
lpDrv = DRIVER_FindFromHDrvr16(hDrvr); if ((lpDrv = DRIVER_FindFromHDrvr16(hDrvr)) != NULL) {
if (lpDrv != NULL && lpDrv->hDriver16 == hDrvr && (lpDrv->dwFlags & WINE_GDF_16BIT)) { hModule = lpDrv->hModule16;
hModule = lpDrv->d.d16.hModule;
} }
TRACE("=> %d\n", hModule); TRACE("=> %04x\n", hModule);
return hModule;
}
/**************************************************************************
* GetDriverFlags [WINMM.13]
* [in] hDrvr handle to the driver
*
* Returns:
* 0x00000000 if hDrvr is an invalid handle
* 0x80000000 if hDrvr is a valid 32 bit driver
* 0x90000000 if hDrvr is a valid 16 bit driver
*/
DWORD WINAPI GetDriverFlags(HDRVR hDrvr)
{
LPWINE_DRIVER lpDrv;
DWORD ret = 0;
TRACE("(%04x)\n", hDrvr);
if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
ret = lpDrv->dwFlags;
}
return ret;
}
/**************************************************************************
* GetDriverModuleHandle [WINMM.14]
*/
HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
{
LPWINE_DRIVER lpDrv;
HMODULE hModule = 0;
TRACE("(%04x);\n", hDrvr);
lpDrv = DRIVER_FindFromHDrvr(hDrvr);
if (lpDrv != NULL && !(lpDrv->dwFlags & WINE_GDF_16BIT)) {
hModule = lpDrv->d.d32.hModule;
}
TRACE("=> %d\n", hModule);
return hModule; return hModule;
} }
@ -1001,11 +364,9 @@ BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, LPDRIVERINFOSTRUCT16 lpDrvInfo)
if (lpDrvInfo == NULL || lpDrvInfo->length != sizeof(DRIVERINFOSTRUCT16)) if (lpDrvInfo == NULL || lpDrvInfo->length != sizeof(DRIVERINFOSTRUCT16))
return FALSE; return FALSE;
lpDrv = DRIVER_FindFromHDrvr16(hDrvr); if ((lpDrv = DRIVER_FindFromHDrvr16(hDrvr)) != NULL) {
if (lpDrv != NULL && lpDrv->hDriver16 == hDrvr &&
(lpDrv->dwFlags & WINE_GDF_16BIT)) {
lpDrvInfo->hDriver = lpDrv->hDriver16; lpDrvInfo->hDriver = lpDrv->hDriver16;
lpDrvInfo->hModule = lpDrv->d.d16.hModule; lpDrvInfo->hModule = lpDrv->hModule16;
lstrcpynA(lpDrvInfo->szAliasName, lpDrv->szAliasName, sizeof(lpDrvInfo->szAliasName)); lstrcpynA(lpDrvInfo->szAliasName, lpDrv->szAliasName, sizeof(lpDrvInfo->szAliasName));
ret = TRUE; ret = TRUE;
} }
@ -1038,8 +399,7 @@ HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
lpDrv = lpDrv->lpNextItem; lpDrv = lpDrv->lpNextItem;
} }
} else { } else {
lpDrv = DRIVER_FindFromHDrvr16(hDrvr); if ((lpDrv = DRIVER_FindFromHDrvr16(hDrvr)) != NULL) {
if (lpDrv != NULL) {
if (dwFlags & GND_REVERSE) { if (dwFlags & GND_REVERSE) {
lpDrv = (lpDrv->lpPrevItem) ? lpDrv->lpPrevItem : NULL; lpDrv = (lpDrv->lpPrevItem) ? lpDrv->lpPrevItem : NULL;
} else { } else {