driver.c 19.8 KB
Newer Older
1 2 3 4 5 6
/*
 * WINE Drivers functions
 *
 * Copyright 1994 Martin Ayotte
 * Copyright 1998 Marcus Meissner
 * Copyright 1999 Eric Pouech
7 8 9 10 11 12 13 14 15 16 17 18 19
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
20
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 22
 */

23 24 25
#include "config.h"
#include "wine/port.h"

26
#include <string.h>
27
#include <stdarg.h>
28
#include "windef.h"
29
#include "winbase.h"
30 31
#include "wingdi.h"
#include "winuser.h"
32
#include "winnls.h"
33
#include "winreg.h"
34 35
#include "mmddk.h"
#include "winemm.h"
36
#include "wine/debug.h"
37
#include "wine/unicode.h"
38 39
#include "excpt.h"
#include "wine/exception.h"
40

41
WINE_DEFAULT_DEBUG_CHANNEL(driver);
42

43 44 45 46 47 48 49 50 51
static CRITICAL_SECTION mmdriver_lock;
static CRITICAL_SECTION_DEBUG mmdriver_lock_debug =
{
    0, 0, &mmdriver_lock,
    { &mmdriver_lock_debug.ProcessLocksList, &mmdriver_lock_debug.ProcessLocksList },
      0, 0, { (DWORD_PTR)(__FILE__ ": mmdriver_lock") }
};
static CRITICAL_SECTION mmdriver_lock = { &mmdriver_lock_debug, -1, 0, 0, 0, 0 };

52
static LPWINE_DRIVER   lpDrvItemList  /* = NULL */;
53 54
static const WCHAR HKLM_BASE[] = {'S','o','f','t','w','a','r','e','\\','M','i','c','r','o','s','o','f','t','\\',
                                  'W','i','n','d','o','w','s',' ','N','T','\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
55

56
WINE_MMTHREAD*  (*pFnGetMMThread16)(UINT16 h) /* = NULL */;
57
LPWINE_DRIVER   (*pFnOpenDriver16)(LPCWSTR,LPCWSTR,LPARAM) /* = NULL */;
58 59
LRESULT         (*pFnCloseDriver16)(UINT16,LPARAM,LPARAM) /* = NULL */;
LRESULT         (*pFnSendMessage16)(UINT16,UINT,LPARAM,LPARAM) /* = NULL */;
60

61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
static void DRIVER_Dump(const char *comment)
{
#if 0
    LPWINE_DRIVER 	lpDrv;

    TRACE("%s\n", comment);

    EnterCriticalSection( &mmdriver_lock );

    for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpDrv->lpNextItem)
    {
        TRACE("%p, magic %04lx, id %p, next %p\n", lpDrv, lpDrv->dwMagic, (void *)lpDrv->d.d32.dwDriverID, lpDrv->lpNextItem);
    }

    LeaveCriticalSection( &mmdriver_lock );
#endif
}

79 80 81 82 83
/**************************************************************************
 *			DRIVER_GetNumberOfModuleRefs		[internal]
 *
 * Returns the number of open drivers which share the same module.
 */
84
static	unsigned DRIVER_GetNumberOfModuleRefs(HMODULE hModule, WINE_DRIVER** found)
85 86
{
    LPWINE_DRIVER	lpDrv;
87 88
    unsigned		count = 0;

89 90
    EnterCriticalSection( &mmdriver_lock );

91
    if (found) *found = NULL;
92
    for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem)
93
    {
94
	if (!(lpDrv->dwFlags & WINE_GDF_16BIT) && lpDrv->d.d32.hModule == hModule)
95 96
        {
            if (found && !*found) *found = lpDrv;
97 98 99
	    count++;
	}
    }
100 101

    LeaveCriticalSection( &mmdriver_lock );
102 103 104 105 106
    return count;
}

/**************************************************************************
 *				DRIVER_FindFromHDrvr		[internal]
107
 *
108 109 110
 * From a hDrvr being 32 bits, returns the WINE internal structure.
 */
LPWINE_DRIVER	DRIVER_FindFromHDrvr(HDRVR hDrvr)
111
{
112
    LPWINE_DRIVER d;
113

114 115
    __TRY
    {
116
        d = (LPWINE_DRIVER)hDrvr;
117 118
        if (d && d->dwMagic != WINE_DI_MAGIC) d = NULL;
    }
119
    __EXCEPT_PAGE_FAULT
120 121
    {
        return NULL;
122
    }
123 124
    __ENDTRY;

125 126 127
    if (d) TRACE("%p -> %p, %p\n", hDrvr, d->d.d32.lpDrvProc, (void *)d->d.d32.dwDriverID);
    else TRACE("%p -> NULL\n", hDrvr);

128
    return d;
129 130 131 132 133
}

/**************************************************************************
 *				DRIVER_SendMessage		[internal]
 */
134
static inline LRESULT DRIVER_SendMessage(LPWINE_DRIVER lpDrv, UINT msg,
135
                                         LPARAM lParam1, LPARAM lParam2)
136
{
137 138
    LRESULT		ret = 0;

139
    if (lpDrv->dwFlags & WINE_GDF_16BIT) {
140 141 142 143 144
        /* no need to check mmsystem presence: the driver must have been opened as a 16 bit one,
         */
        if (pFnSendMessage16)
            ret = pFnSendMessage16(lpDrv->d.d16.hDriver16, msg, lParam1, lParam2);
    } else {
145
        TRACE("Before call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx\n", 
146 147
              lpDrv->d.d32.lpDrvProc, lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
        ret = lpDrv->d.d32.lpDrvProc(lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
148
        TRACE("After  call32 proc=%p drvrID=%08lx hDrv=%p wMsg=%04x p1=%08lx p2=%08lx => %08lx\n", 
149
              lpDrv->d.d32.lpDrvProc, lpDrv->d.d32.dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2, ret);
150
    }
151
    return ret;
152 153 154
}

/**************************************************************************
155
 *				SendDriverMessage		[WINMM.@]
Patrik Stridvall's avatar
Patrik Stridvall committed
156
 *				DrvSendMessage			[WINMM.@]
157 158 159 160 161 162
 */
LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1,
				 LPARAM lParam2)
{
    LPWINE_DRIVER	lpDrv;
    LRESULT 		retval = 0;
163

164
    TRACE("(%p, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2);
165

166 167 168
    if ((lpDrv = DRIVER_FindFromHDrvr(hDriver)) != NULL) {
	retval = DRIVER_SendMessage(lpDrv, msg, lParam1, lParam2);
    } else {
169
	WARN("Bad driver handle %p\n", hDriver);
170 171
    }
    TRACE("retval = %ld\n", retval);
172

173 174 175 176 177 178 179 180 181 182 183 184
    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)) {
185 186
        /* last of this driver in list ? */
	if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, NULL) == 1) {
187 188 189 190
	    DRIVER_SendMessage(lpDrv, DRV_DISABLE, 0L, 0L);
	    DRIVER_SendMessage(lpDrv, DRV_FREE,    0L, 0L);
	}
    }
191

192 193
    EnterCriticalSection( &mmdriver_lock );

194 195 196 197 198 199
    if (lpDrv->lpPrevItem)
	lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
    else
	lpDrvItemList = lpDrv->lpNextItem;
    if (lpDrv->lpNextItem)
	lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
200 201
    /* trash magic number */
    lpDrv->dwMagic ^= 0xa5a5a5a5;
202 203 204 205 206
    lpDrv->d.d32.lpDrvProc = NULL;
    lpDrv->d.d32.dwDriverID = 0;
    lpDrv->d.d16.hDriver16 = 0;

    LeaveCriticalSection( &mmdriver_lock );
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221

    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)) {
222 223
        /* first of this driver in list ? */
	if (DRIVER_GetNumberOfModuleRefs(lpNewDrv->d.d32.hModule, NULL) == 0) {
224
	    if (DRIVER_SendMessage(lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
225
		TRACE("DRV_LOAD failed on driver %p\n", lpNewDrv);
226 227 228 229 230
		return FALSE;
	    }
	    /* returned value is not checked */
	    DRIVER_SendMessage(lpNewDrv, DRV_ENABLE, 0L, 0L);
	}
231 232 233 234 235 236 237 238 239

	/* 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 %p\n", lpNewDrv);
	    return FALSE;
	}
240 241
    }

242 243
    EnterCriticalSection( &mmdriver_lock );

244 245 246 247 248 249 250 251
    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;
252

253 254 255 256
	lpDrv->lpNextItem = lpNewDrv;
	lpNewDrv->lpPrevItem = lpDrv;
    }

257
    LeaveCriticalSection( &mmdriver_lock );
258 259 260 261 262 263 264
    return TRUE;
}

/**************************************************************************
 *				DRIVER_GetLibName		[internal]
 *
 */
265
BOOL	DRIVER_GetLibName(LPCWSTR keyName, LPCWSTR sectName, LPWSTR buf, int sz)
266
{
267 268
    HKEY	hKey, hSecKey;
    DWORD	bufLen, lRet;
269 270
    static const WCHAR wszSystemIni[] = {'S','Y','S','T','E','M','.','I','N','I',0};
    WCHAR       wsznull = '\0';
271

272 273
    TRACE("registry: %s, %s, %p, %d\n", debugstr_w(keyName), debugstr_w(sectName), buf, sz);

274
    lRet = RegOpenKeyExW(HKEY_LOCAL_MACHINE, HKLM_BASE, 0, KEY_QUERY_VALUE, &hKey);
275
    if (lRet == ERROR_SUCCESS) {
276
	lRet = RegOpenKeyExW(hKey, sectName, 0, KEY_QUERY_VALUE, &hSecKey);
277
	if (lRet == ERROR_SUCCESS) {
278 279
            bufLen = sz;
	    lRet = RegQueryValueExW(hSecKey, keyName, 0, 0, (void*)buf, &bufLen);
280 281 282 283 284
	    RegCloseKey( hSecKey );
	}
        RegCloseKey( hKey );
    }
    if (lRet == ERROR_SUCCESS) return TRUE;
285

286 287
    /* default to system.ini if we can't find it in the registry,
     * to support native installations where system.ini is still used */
288
    TRACE("system.ini: %s, %s, %p, %d\n", debugstr_w(keyName), debugstr_w(sectName), buf, sz);
289
    return GetPrivateProfileStringW(sectName, keyName, &wsznull, buf, sz / sizeof(WCHAR), wszSystemIni);
290 291 292 293 294 295 296
}

/**************************************************************************
 *				DRIVER_TryOpenDriver32		[internal]
 *
 * Tries to load a 32 bit driver whose DLL's (module) name is fn
 */
297
LPWINE_DRIVER	DRIVER_TryOpenDriver32(LPCWSTR fn, LPARAM lParam2)
298 299 300
{
    LPWINE_DRIVER 	lpDrv = NULL;
    HMODULE		hModule = 0;
301
    LPWSTR		ptr;
302 303
    LPCSTR		cause = 0;

304
    TRACE("(%s, %08lX);\n", debugstr_w(fn), lParam2);
305

306
    if ((ptr = strchrW(fn, ' ')) != NULL) {
307 308 309 310 311 312 313 314
	*ptr++ = '\0';
	while (*ptr == ' ') ptr++;
	if (*ptr == '\0') ptr = NULL;
    }

    lpDrv = HeapAlloc(GetProcessHeap(), 0, sizeof(WINE_DRIVER));
    if (lpDrv == NULL) {cause = "OOM"; goto exit;}

315
    if ((hModule = LoadLibraryW(fn)) == 0) {cause = "Not a 32 bit lib"; goto exit;}
316

317
    lpDrv->d.d32.lpDrvProc = (DRIVERPROC)GetProcAddress(hModule, "DriverProc");
318 319 320 321 322 323
    if (lpDrv->d.d32.lpDrvProc == NULL) {cause = "no DriverProc"; goto exit;}

    lpDrv->dwFlags          = 0;
    lpDrv->d.d32.hModule    = hModule;
    lpDrv->d.d32.dwDriverID = 0;

324
    /* Win32 installable drivers must support a two phase opening scheme:
325
     * + first open with NULL as lParam2 (session instance),
326 327 328 329 330 331 332 333
     * + then do a second open with the real non null lParam2)
     */
    if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, NULL) == 0 && lParam2)
    {
        LPWINE_DRIVER   ret;

        if (!DRIVER_AddToList(lpDrv, (LPARAM)ptr, 0L))
        {
334
            cause = "load0 failed";
335 336 337
            goto exit;
        }
        ret = DRIVER_TryOpenDriver32(fn, lParam2);
338
        if (!ret)
339 340
        {
            CloseDriver((HDRVR)lpDrv, 0L, 0L);
341
            cause = "load1 failed";
342 343
            goto exit;
        }
Eric Pouech's avatar
Eric Pouech committed
344
        lpDrv->dwFlags |= WINE_GDF_SESSION;
345 346 347
        return ret;
    }

348
    if (!DRIVER_AddToList(lpDrv, (LPARAM)ptr, lParam2))
349
    {cause = "load failed"; goto exit;}
350 351 352 353 354 355

    TRACE("=> %p\n", lpDrv);
    return lpDrv;
 exit:
    FreeLibrary(hModule);
    HeapFree(GetProcessHeap(), 0, lpDrv);
356
    TRACE("Unable to load 32 bit module %s: %s\n", debugstr_w(fn), cause);
357 358 359 360
    return NULL;
}

/**************************************************************************
361
 *				OpenDriverA		        [WINMM.@]
Patrik Stridvall's avatar
Patrik Stridvall committed
362
 *				DrvOpenA			[WINMM.@]
363 364 365 366
 * (0,1,DRV_LOAD  ,0       ,0)
 * (0,1,DRV_ENABLE,0       ,0)
 * (0,1,DRV_OPEN  ,buf[256],0)
 */
367 368 369 370 371
HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
{
    INT                 len;
    LPWSTR 		dn = NULL;
    LPWSTR 		sn = NULL;
372
    HDRVR		ret = 0;
373 374 375 376 377

    if (lpDriverName)
    {
        len = MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, NULL, 0 );
        dn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
378
        if (!dn) goto done;
379 380 381 382 383 384 385
        MultiByteToWideChar( CP_ACP, 0, lpDriverName, -1, dn, len );
    }

    if (lpSectionName)
    {
        len = MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, NULL, 0 );
        sn = HeapAlloc( GetProcessHeap(), 0, len * sizeof(WCHAR) );
386
        if (!sn) goto done;
387 388 389 390 391
        MultiByteToWideChar( CP_ACP, 0, lpSectionName, -1, sn, len );
    }

    ret = OpenDriver(dn, sn, lParam);

392 393 394
done:
    HeapFree(GetProcessHeap(), 0, dn);
    HeapFree(GetProcessHeap(), 0, sn);
395 396 397 398 399 400 401 402
    return ret;
}

/**************************************************************************
 *				OpenDriver 		        [WINMM.@]
 *				DrvOpen				[WINMM.@]
 */
HDRVR WINAPI OpenDriver(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
403 404
{
    LPWINE_DRIVER	lpDrv = NULL;
405
    WCHAR 		libName[MAX_PATH + 1];
406
    LPCWSTR		lsn = lpSectionName;
407

408 409
    TRACE("(%s, %s, 0x%08lx);\n", 
          debugstr_w(lpDriverName), debugstr_w(lpSectionName), lParam);
410

411 412
    DRIVER_Dump("BEFORE:");

413
    if (lsn == NULL) {
414 415
        static const WCHAR wszDrivers32[] = {'D','r','i','v','e','r','s','3','2',0};
	lstrcpynW(libName, lpDriverName, sizeof(libName) / sizeof(WCHAR));
416

417
	if ((lpDrv = DRIVER_TryOpenDriver32(libName, lParam)))
418
	    goto the_end;
419
	lsn = wszDrivers32;
420 421
    }
    if (DRIVER_GetLibName(lpDriverName, lsn, libName, sizeof(libName)) &&
422
	(lpDrv = DRIVER_TryOpenDriver32(libName, lParam)))
423 424
	goto the_end;

425 426 427 428 429 430
    /* now we will try a 16 bit driver (and add all the glue to make it work... which
     * is located in our mmsystem implementation)
     * so ensure, we can load our mmsystem, otherwise just fail
     */
    WINMM_CheckForMMSystem();
    if (pFnOpenDriver16 &&
431
        (lpDrv = pFnOpenDriver16(lpDriverName, lpSectionName, lParam)))
432
    {
433
        if (DRIVER_AddToList(lpDrv, 0, lParam)) goto the_end;
434 435
        HeapFree(GetProcessHeap(), 0, lpDrv);
    }
436 437
    TRACE("Failed to open driver %s from system.ini file, section %s\n", 
          debugstr_w(lpDriverName), debugstr_w(lpSectionName));
438

439 440 441 442 443
the_end:
    TRACE("=> %p\n", lpDrv);

    DRIVER_Dump("AFTER:");

444
    return (HDRVR)lpDrv;
445 446 447
}

/**************************************************************************
448
 *			CloseDriver				[WINMM.@]
Patrik Stridvall's avatar
Patrik Stridvall committed
449
 *			DrvClose				[WINMM.@]
450 451 452
 */
LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
{
453
    BOOL ret;
454 455
    LPWINE_DRIVER	lpDrv;

456
    TRACE("(%p, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
457

458 459
    DRIVER_Dump("BEFORE:");

460
    if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL)
461
    {
462
	if (lpDrv->dwFlags & WINE_GDF_16BIT)
463 464 465 466
        {
            if (pFnCloseDriver16)
                pFnCloseDriver16(lpDrv->d.d16.hDriver16, lParam1, lParam2);
        }
467 468
	else
	    DRIVER_SendMessage(lpDrv, DRV_CLOSE, lParam1, lParam2);
469 470 471 472 473 474 475 476 477 478 479 480

        DRIVER_RemoveFromList(lpDrv);

        if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
        {
            LPWINE_DRIVER lpDrv0;

            if (lpDrv->dwFlags & WINE_GDF_SESSION)
                FIXME("WINE_GDF_SESSION: Shouldn't happen (%p)\n", lpDrv);
            /* if driver has an opened session instance, we have to close it too */
            if (DRIVER_GetNumberOfModuleRefs(lpDrv->d.d32.hModule, &lpDrv0) == 1 &&
                (lpDrv0->dwFlags & WINE_GDF_SESSION))
481
            {
482 483 484 485
                DRIVER_SendMessage(lpDrv0, DRV_CLOSE, 0, 0);
                DRIVER_RemoveFromList(lpDrv0);
                FreeLibrary(lpDrv0->d.d32.hModule);
                HeapFree(GetProcessHeap(), 0, lpDrv0);
486
            }
487
            FreeLibrary(lpDrv->d.d32.hModule);
488
        }
489 490 491 492 493 494 495
        HeapFree(GetProcessHeap(), 0, lpDrv);
        ret = TRUE;
    }
    else
    {
        WARN("Failed to close driver\n");
        ret = FALSE;
496
    }
497 498 499 500

    DRIVER_Dump("AFTER:");

    return ret;
501 502 503
}

/**************************************************************************
504
 *				GetDriverFlags		[WINMM.@]
505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520
 * [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;

521
    TRACE("(%p)\n", hDrvr);
522 523

    if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
Eric Pouech's avatar
Eric Pouech committed
524
	ret = WINE_GDF_EXIST | (lpDrv->dwFlags & WINE_GDF_EXTERNAL_MASK);
525 526 527 528 529
    }
    return ret;
}

/**************************************************************************
530
 *				GetDriverModuleHandle	[WINMM.@]
Patrik Stridvall's avatar
Patrik Stridvall committed
531
 *				DrvGetModuleHandle	[WINMM.@]
532 533 534 535 536
 */
HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
{
    LPWINE_DRIVER 	lpDrv;
    HMODULE		hModule = 0;
537

538
    TRACE("(%p);\n", hDrvr);
539

540 541 542 543
    if ((lpDrv = DRIVER_FindFromHDrvr(hDrvr)) != NULL) {
	if (!(lpDrv->dwFlags & WINE_GDF_16BIT))
	    hModule = lpDrv->d.d32.hModule;
    }
544
    TRACE("=> %p\n", hModule);
545 546 547 548
    return hModule;
}

/**************************************************************************
549
 * 				DefDriverProc			  [WINMM.@]
Patrik Stridvall's avatar
Patrik Stridvall committed
550
 * 				DrvDefDriverProc		  [WINMM.@]
551
 */
552
LRESULT WINAPI DefDriverProc(DWORD_PTR dwDriverIdentifier, HDRVR hDrv,
553 554 555 556 557 558 559 560 561 562 563 564 565 566 567
			     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;
    }
}
568 569 570 571

/**************************************************************************
 * 				DriverCallback			[WINMM.@]
 */
572 573 574
BOOL WINAPI DriverCallback(DWORD_PTR dwCallBack, DWORD uFlags, HDRVR hDev,
			   DWORD wMsg, DWORD_PTR dwUser, DWORD_PTR dwParam1,
			   DWORD_PTR dwParam2)
575
{
576
    TRACE("(%08lX, %04X, %p, %04X, %08lX, %08lX, %08lX)\n",
577 578 579 580 581 582
	  dwCallBack, uFlags, hDev, wMsg, dwUser, dwParam1, dwParam2);

    switch (uFlags & DCB_TYPEMASK) {
    case DCB_NULL:
	TRACE("Null !\n");
	if (dwCallBack)
583
	    WARN("uFlags=%04X has null DCB value, but dwCallBack=%08lX is not null !\n", uFlags, dwCallBack);
584 585
	break;
    case DCB_WINDOW:
586
	TRACE("Window(%04lX) handle=%p!\n", dwCallBack, hDev);
587 588 589
	PostMessageA((HWND)dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
	break;
    case DCB_TASK: /* aka DCB_THREAD */
590
	TRACE("Task(%04lx) !\n", dwCallBack);
591 592 593 594 595 596 597
	PostThreadMessageA(dwCallBack, wMsg, (WPARAM)hDev, dwParam1);
	break;
    case DCB_FUNCTION:
	TRACE("Function (32 bit) !\n");
	((LPDRVCALLBACK)dwCallBack)(hDev, wMsg, dwUser, dwParam1, dwParam2);
	break;
    case DCB_EVENT:
598
	TRACE("Event(%08lx) !\n", dwCallBack);
599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628
	SetEvent((HANDLE)dwCallBack);
	break;
    case 6: /* I would dub it DCB_MMTHREADSIGNAL */
	/* this is an undocumented DCB_ value used for mmThreads
	 * loword of dwCallBack contains the handle of the lpMMThd block
	 * which dwSignalCount has to be incremented
	 */     
        if (pFnGetMMThread16)
	{
	    WINE_MMTHREAD*	lpMMThd = pFnGetMMThread16(LOWORD(dwCallBack));

	    TRACE("mmThread (%04x, %p) !\n", LOWORD(dwCallBack), lpMMThd);
	    /* same as mmThreadSignal16 */
	    InterlockedIncrement(&lpMMThd->dwSignalCount);
	    SetEvent(lpMMThd->hEvent);
	    /* some other stuff on lpMMThd->hVxD */
	}
	break;
#if 0
    case 4:
	/* this is an undocumented DCB_ value for... I don't know */
	break;
#endif
    default:
	WARN("Unknown callback type %d\n", uFlags & DCB_TYPEMASK);
	return FALSE;
    }
    TRACE("Done\n");
    return TRUE;
}
629 630 631 632 633 634 635 636 637 638 639 640

/******************************************************************
 *		DRIVER_UnloadAll
 *
 *
 */
void    DRIVER_UnloadAll(void)
{
    LPWINE_DRIVER 	lpDrv;
    LPWINE_DRIVER 	lpNextDrv = NULL;
    unsigned            count = 0;

641 642 643
restart:
    EnterCriticalSection( &mmdriver_lock );

644 645 646
    for (lpDrv = lpDrvItemList; lpDrv != NULL; lpDrv = lpNextDrv)
    {
        lpNextDrv = lpDrv->lpNextItem;
647 648 649 650 651 652 653 654 655 656

        /* session instances will be unloaded automatically */
        if (!(lpDrv->dwFlags & WINE_GDF_SESSION))
        {
            LeaveCriticalSection( &mmdriver_lock );
            CloseDriver((HDRVR)lpDrv, 0, 0);
            count++;
            /* restart from the beginning of the list */
            goto restart;
        }
657
    }
658 659 660

    LeaveCriticalSection( &mmdriver_lock );

661 662
    TRACE("Unloaded %u drivers\n", count);
}