/* -*- 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 "wine/winbase16.h"
#include "wingdi.h"
#include "winuser.h"
#include "ldt.h"
#include "module.h"
#include "mmddk.h"
#include "debugtools.h"

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
{
    DWORD			dwMagic;
    char			szAliasName[128];
    /* as usual LPWINE_DRIVER == hDriver32 */
    HDRVR16			hDriver16;
    union {
       struct {
	  HMODULE16		hModule;
	  DRIVERPROC16          lpDrvProc;
       } d16;
       struct {
	  HMODULE		hModule;
	  DRIVERPROC		lpDrvProc;
       } d32;
    } d;
    DWORD		  	dwDriverID;
    DWORD			dwFlags;
    struct tagWINE_DRIVER*	lpPrevItem;
    struct tagWINE_DRIVER*	lpNextItem;
} 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;

/* TODO list :
 *	- LoadModule count and clean up is not handled correctly (it's not a 
 *	  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 ### */
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;
    
    for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
	if (lpDrv->dwFlags & WINE_GDF_16BIT) {
	    if (lpDrv->d.d16.hModule == lpNewDrv->d.d16.hModule) {
		count++;
	    }
	} else {
	    if (lpDrv->d.d32.hModule == lpNewDrv->d.d32.hModule) {
		count++;
	    }
	}
    }
    return count;
}

/**************************************************************************
 *				DRIVER_FindFromHDrvr16		[internal]
 *
 * From a hDrvr being 16 bits, returns the WINE internal structure.
 */
static	LPWINE_DRIVER	DRIVER_FindFromHDrvr16(HDRVR16 hDrvr)
{    
    LPWINE_DRIVER	lpDrv;
    
    for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
	if (lpDrv->hDriver16 == hDrvr) {
	    break;
	}
    }
    return lpDrv;
}

/**************************************************************************
 *				DRIVER_FindFromHDrvr		[internal]
 * 
 * From a hDrvr (being 16 or 32 bits), returns the WINE internal structure.
 */
static	LPWINE_DRIVER	DRIVER_FindFromHDrvr(HDRVR hDrvr)
{    
    if (!IsBadWritePtr((void*)hDrvr, sizeof(WINE_DRIVER)) && 
	((LPWINE_DRIVER)hDrvr)->dwMagic == WINE_DI_MAGIC) {
	return (LPWINE_DRIVER)hDrvr;
    }
    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;
}

/**************************************************************************
 *				SendDriverMessage		[USER.251]
 */
LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 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_FindFromHDrvr16(hDriver);
    if (lpDrv != NULL && lpDrv->hDriver16 == hDriver) {
	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 {
	WARN("Bad driver handle %u\n", hDriver);
    }
    
    TRACE("retval = %ld\n", 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]
 *
 * 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)
{
    lpDrv->dwDriverID = 0;
    if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) {
	SendDriverMessage((HDRVR)lpDrv, DRV_DISABLE, 0L, 0L);
	SendDriverMessage((HDRVR)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 lParam, BOOL bCallFrom32)
{
    lpNewDrv->dwMagic = WINE_DI_MAGIC;
    /* First driver to be loaded for this module, need to load correctly the module */
    if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) {
	if (SendDriverMessage((HDRVR)lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
	    TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
	    return FALSE;
	}
	if (SendDriverMessage((HDRVR)lpNewDrv, DRV_ENABLE, 0L, 0L) != DRV_SUCCESS) {
	    TRACE("DRV_ENABLE failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
	    return FALSE;
	}
    }

    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;
    }
    /* Now just open a new instance of a driver on this module */
    if (bCallFrom32) {
	lpNewDrv->dwDriverID = SendDriverMessage((HDRVR)lpNewDrv, DRV_OPEN, 0L, lParam);
    } else {
	lpNewDrv->dwDriverID = SendDriverMessage16(lpNewDrv->hDriver16, DRV_OPEN, 0L, lParam);
    }
    if (lpNewDrv->dwDriverID == 0) {
	TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
	DRIVER_RemoveFromList(lpNewDrv);
	return FALSE;
    }
    
    return TRUE;
}

/**************************************************************************
 *				DRIVER_CreateDrvr16		[internal]
 *
 * Creates unique ID for 16 bit drivers.
 */
static	HDRVR16	DRIVER_CreateDrvr16(void)
{
    static	WORD	DRIVER_hDrvr16Counter = 0;
    
    while (DRIVER_FindFromHDrvr16(++DRIVER_hDrvr16Counter));
    return DRIVER_hDrvr16Counter;
}

/**************************************************************************
 *				DRIVER_CloseDriver		[internal]
 *
 */
BOOL DRIVER_CloseDriver(LPWINE_DRIVER lpDrv, DWORD lParam1, DWORD lParam2)
{
    if (lpDrv != NULL) {
	SendDriverMessage((HDRVR)lpDrv, DRV_CLOSE, lParam1, lParam2);
    
	if (DRIVER_RemoveFromList(lpDrv)) {
	    HeapFree(GetProcessHeap(), 0, lpDrv);
	    return TRUE;
	}
    }
    WARN("Failed to close driver\n");
    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)WIN32_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 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]
 */
HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
{
    LPWINE_DRIVER 	lpDrv;
    HMODULE16 		hModule = 0;
    
    TRACE("(%04x);\n", hDrvr);
    
    lpDrv = DRIVER_FindFromHDrvr16(hDrvr);
    if (lpDrv != NULL && lpDrv->hDriver16 == hDrvr && (lpDrv->dwFlags & WINE_GDF_16BIT)) {
	hModule = lpDrv->d.d16.hModule;
    }
    TRACE("=> %d\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;
}

/**************************************************************************
 *				DefDriverProc16			[USER.255]
 */
LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, 
                               LPARAM lParam1, LPARAM lParam2)
{
    TRACE("devID=0x%08lx hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx\n",
	  dwDevID, hDriv, wMsg, lParam1, lParam2);

    switch(wMsg) {
    case DRV_LOAD:		
    case DRV_FREE:		
    case DRV_ENABLE:
    case DRV_DISABLE:
	return (LRESULT)1L;
    case DRV_OPEN:		
    case DRV_CLOSE:		
    case DRV_QUERYCONFIGURE:
	return (LRESULT)0L;
    case DRV_CONFIGURE:		
	MessageBoxA(0, "Driver isn't configurable !", "Wine Driver", MB_OK); 
	return (LRESULT)0L;
    case DRV_INSTALL:		
    case DRV_REMOVE:		
	return DRV_SUCCESS;
    default:			
	return (LRESULT)0L;
    }
}

/**************************************************************************
 *				GetDriverInfo			[USER.256]
 */
BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, LPDRIVERINFOSTRUCT16 lpDrvInfo)
{
    LPWINE_DRIVER 	lpDrv;
    BOOL16		ret = FALSE;
    
    TRACE("(%04x, %p);\n", hDrvr, lpDrvInfo);
    
    if (lpDrvInfo == NULL || lpDrvInfo->length != sizeof(DRIVERINFOSTRUCT16)) 
	return FALSE;
    
    lpDrv = DRIVER_FindFromHDrvr16(hDrvr);
    if (lpDrv != NULL && lpDrv->hDriver16 == hDrvr && 
	(lpDrv->dwFlags & WINE_GDF_16BIT)) {
	lpDrvInfo->hDriver = lpDrv->hDriver16;
	lpDrvInfo->hModule = lpDrv->d.d16.hModule;
	lstrcpynA(lpDrvInfo->szAliasName, lpDrv->szAliasName, sizeof(lpDrvInfo->szAliasName));
	ret = TRUE;
    }
    
    return ret;
}

/**************************************************************************
 *				GetNextDriver			[USER.257]
 */
HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
{
    HDRVR16 		hRetDrv = 0;
    LPWINE_DRIVER 	lpDrv;
    
    TRACE("(%04x, %08lX);\n", hDrvr, dwFlags);
    
    if (hDrvr == 0) {
	if (lpDrvItemList == NULL) {
	    FIXME("drivers list empty !\n");
	    /* FIXME: code was using DRIVER_LoadStartupDrivers(); before ? 
	     * I (EPP) don't quite understand this 
	     */
	    if (lpDrvItemList == NULL) 
		return 0;
	}
	lpDrv = lpDrvItemList;
	if (dwFlags & GND_REVERSE) {
	    while (lpDrv->lpNextItem)
		lpDrv = lpDrv->lpNextItem;
	}
    } else {
	lpDrv = DRIVER_FindFromHDrvr16(hDrvr);
	if (lpDrv != NULL) {
	    if (dwFlags & GND_REVERSE) {
		lpDrv = (lpDrv->lpPrevItem) ? lpDrv->lpPrevItem : NULL;
	    } else {
		lpDrv = (lpDrv->lpNextItem) ? lpDrv->lpNextItem : NULL;
	    }
	}
    }
    
    hRetDrv = (lpDrv) ? lpDrv->hDriver16 : (HDRVR16)0;
    TRACE("return %04x !\n", hRetDrv);
    return hRetDrv;
}

