1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
4 * WINE Drivers functions
6 * Copyright 1994 Martin Ayotte
7 * Copyright 1998 Marcus Meissner
8 * Copyright 1999 Eric Pouech
12 #include "wine/winuser16.h"
21 DEFAULT_DEBUG_CHANNEL(driver
)
23 static LPWINE_DRIVER lpDrvItemList
= NULL
;
26 * - LoadModule count and clean up is not handled correctly (it's not a problem as
27 * long as FreeLibrary is not working correctly)
28 * - msacm has some FIXME related to new code here...
31 /**************************************************************************
32 * LoadStartupDrivers [internal]
34 static void WINE_UNUSED
DRIVER_LoadStartupDrivers(void)
38 if (GetPrivateProfileStringA("drivers", NULL
, "", str
, sizeof(str
), "SYSTEM.INI") < 2) {
39 ERR(driver
,"Can't find drivers section in system.ini\n");
44 for (ptr
= str
; lstrlenA(ptr
) != 0; ptr
+= lstrlenA(ptr
) + 1) {
45 TRACE(driver
, "str='%s'\n", ptr
);
46 hDrv
= OpenDriver16(ptr
, "drivers", 0L);
47 TRACE(driver
, "hDrv=%04x\n", hDrv
);
49 TRACE(driver
, "end of list !\n");
53 /**************************************************************************
54 * DRIVER_GetNumberOfModuleRefs [internal]
56 * Returns the number of open drivers which share the same module.
58 static WORD
DRIVER_GetNumberOfModuleRefs(LPWINE_DRIVER lpNewDrv
)
61 DWORD type
= lpNewDrv
->dwFlags
& WINE_DI_TYPE_MASK
;
64 for (lpDrv
= lpDrvItemList
; lpDrv
; lpDrv
= lpDrv
->lpNextItem
) {
65 if ((lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == type
) {
68 if (lpDrv
->d
.d16
.hModule
== lpNewDrv
->d
.d16
.hModule
)
72 if (lpDrv
->d
.d32
.hModule
== lpNewDrv
->d
.d32
.hModule
)
76 FIXME(driver
, "Unsupported driver type: %ld\n", type
);
84 /**************************************************************************
85 * DRIVER_FindFromHDrvr16 [internal]
87 * From a hDrvr being 16 bits, returns the WINE internal structure.
89 static LPWINE_DRIVER
DRIVER_FindFromHDrvr16(HDRVR16 hDrvr
)
93 for (lpDrv
= lpDrvItemList
; lpDrv
; lpDrv
= lpDrv
->lpNextItem
) {
94 if (lpDrv
->hDriver16
== hDrvr
) {
101 /**************************************************************************
102 * DRIVER_FindFromHDrvr [internal]
104 * From a hDrvr (being 16 or 32 bits), returns the WINE internal structure.
106 static LPWINE_DRIVER
DRIVER_FindFromHDrvr(HDRVR hDrvr
)
108 if (!IsBadWritePtr((void*)hDrvr
, sizeof(WINE_DRIVER
)) &&
109 ((LPWINE_DRIVER
)hDrvr
)->dwMagic
== WINE_DI_MAGIC
) {
110 return (LPWINE_DRIVER
)hDrvr
;
112 return DRIVER_FindFromHDrvr16(hDrvr
);
115 int DRIVER_GetType(HDRVR hDrvr
)
117 LPWINE_DRIVER lpDrv
= DRIVER_FindFromHDrvr(hDrvr
);
119 return (lpDrv
) ? (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) : 0;
122 /**************************************************************************
123 * DRIVER_MapMsg16To32 [internal]
125 * Map a 16 bit driver message to a 32 bit driver message.
126 * 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg16To32
127 * 0 : ok, no memory allocated
128 * -1 : ko, unknown message
129 * -2 : ko, memory problem
131 int DRIVER_MapMsg16To32(WORD wMsg
, DWORD
* lParam1
, DWORD
* lParam2
)
140 case DRV_QUERYCONFIGURE
:
142 case DRV_EXITSESSION
:
143 case DRV_EXITAPPLICATION
:
145 /* lParam1 and lParam2 are not used */
150 /* lParam1 is a NULL terminated string */
151 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
153 *lParam1
= (DWORD
)PTR_SEG_TO_LIN(*lParam1
);
154 if (*lParam2
&& wMsg
== DRV_OPEN
) {
155 LPMCI_OPEN_DRIVER_PARMS16 modp16
= PTR_SEG_TO_LIN(*lParam2
);
156 char* ptr
= HeapAlloc(SystemHeap
, 0, sizeof(LPMCI_OPEN_DRIVER_PARMS16
) + sizeof(MCI_OPEN_DRIVER_PARMSA
));
157 LPMCI_OPEN_DRIVER_PARMSA modp32
;
160 *(LPMCI_OPEN_DRIVER_PARMS16
*)ptr
= modp16
;
161 modp32
= (LPMCI_OPEN_DRIVER_PARMSA
)(ptr
+ sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
163 modp32
->wDeviceID
= modp16
->wDeviceID
;
164 modp32
->lpstrParams
= PTR_SEG_TO_LIN(modp16
->lpstrParams
);
168 *lParam2
= (DWORD
)modp32
;
174 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
176 LPDRVCONFIGINFO dci32
= HeapAlloc(SystemHeap
, 0, sizeof(DRVCONFIGINFO
));
177 LPDRVCONFIGINFO16 dci16
= PTR_SEG_TO_LIN(*lParam2
);
180 dci32
->dwDCISize
= sizeof(DRVCONFIGINFO
);
181 dci32
->lpszDCISectionName
= HEAP_strdupAtoW(SystemHeap
, 0, PTR_SEG_TO_LIN(dci16
->lpszDCISectionName
));
182 dci32
->lpszDCIAliasName
= HEAP_strdupAtoW(SystemHeap
, 0, PTR_SEG_TO_LIN(dci16
->lpszDCIAliasName
));
183 if (dci32
->lpszDCISectionName
== NULL
|| dci32
->lpszDCIAliasName
== NULL
)
188 *lParam2
= (DWORD
)dci32
;
195 if (wMsg
>= 0x800 && wMsg
< 0x900) {
196 /* FIXME: another hack to handle MCI messages...
197 * should find a *NICE* way to integrate DRIVER_ and
198 * MCI_ mapping/unmapping functions
202 FIXME(driver
, "Unknown message 0x%04x\n", wMsg
);
208 /**************************************************************************
209 * DRIVER_MapMsg16To32 [internal]
211 * UnMap a 16 bit driver message to a 32 bit driver message.
214 * -2 : ko, memory problem
216 int DRIVER_UnMapMsg16To32(WORD wMsg
, DWORD lParam1
, DWORD lParam2
)
225 case DRV_QUERYCONFIGURE
:
227 case DRV_EXITSESSION
:
228 case DRV_EXITAPPLICATION
:
230 /* lParam1 and lParam2 are not used */
233 /* lParam1 is a NULL terminated string */
234 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
235 if (lParam2
&& wMsg
== DRV_OPEN
) {
236 LPMCI_OPEN_DRIVER_PARMSA modp32
= (LPMCI_OPEN_DRIVER_PARMSA
)lParam2
;
237 LPMCI_OPEN_DRIVER_PARMS16 modp16
= *(LPMCI_OPEN_DRIVER_PARMS16
*)(lParam2
- sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
239 modp16
->wCustomCommandTable
= modp32
->wCustomCommandTable
;
240 modp16
->wType
= modp32
->wType
;
241 if (!HeapFree(SystemHeap
, 0, modp32
))
242 FIXME(driver
, "bad free line=%d\n", __LINE__
);
248 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
250 LPDRVCONFIGINFO dci32
= (LPDRVCONFIGINFO
)lParam2
;
251 if (!HeapFree(SystemHeap
, 0, (LPVOID
)dci32
->lpszDCISectionName
))
252 FIXME(driver
, "bad free line=%d\n", __LINE__
);
253 if (!HeapFree(SystemHeap
, 0, (LPVOID
)dci32
->lpszDCIAliasName
))
254 FIXME(driver
, "bad free line=%d\n", __LINE__
);
255 if (!HeapFree(SystemHeap
, 0, dci32
))
256 FIXME(driver
, "bad free line=%d\n", __LINE__
);
261 if (wMsg
>= 0x800 && wMsg
< 0x900) {
262 /* FIXME: another hack to handle MCI messages...
263 * should find a *NICE* way to integrate DRIVER_ and
264 * MCI_ mapping/unmapping functions
268 FIXME(driver
, "Unknown message 0x%04x\n", wMsg
);
274 /**************************************************************************
275 * DRIVER_MapMsg32To16 [internal]
277 * Map a 32 bit driver message to a 16 bit driver message.
278 * 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg32To16
279 * 0 : ok, no memory allocated
280 * -1 : ko, unknown message
281 * -2 : ko, memory problem
283 int DRIVER_MapMsg32To16(WORD wMsg
, DWORD
* lParam1
, DWORD
* lParam2
)
292 case DRV_QUERYCONFIGURE
:
294 case DRV_EXITSESSION
:
295 case DRV_EXITAPPLICATION
:
297 /* lParam1 and lParam2 are not used */
302 /* lParam1 is a NULL terminated string */
303 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
305 LPSTR str
= SEGPTR_STRDUP((LPSTR
)*lParam1
);
307 *lParam1
= (LPARAM
)SEGPTR_GET(str
);
315 if (*lParam2
&& wMsg
== DRV_OPEN
) {
316 LPMCI_OPEN_DRIVER_PARMS16 modp16
;
317 char* ptr
= SEGPTR_ALLOC(sizeof(LPMCI_OPEN_DRIVER_PARMSA
) + sizeof(MCI_OPEN_DRIVER_PARMS16
));
318 LPMCI_OPEN_DRIVER_PARMSA modp32
= (LPMCI_OPEN_DRIVER_PARMSA
)(*lParam2
);
321 *(LPMCI_OPEN_DRIVER_PARMSA
*)ptr
= modp32
;
322 modp16
= (LPMCI_OPEN_DRIVER_PARMS16
)(ptr
+ sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
324 modp16
->wDeviceID
= modp32
->wDeviceID
;
325 modp16
->lpstrParams
= PTR_SEG_TO_LIN(modp32
->lpstrParams
);
329 *lParam2
= (DWORD
)SEGPTR_GET(modp16
);
335 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
337 LPDRVCONFIGINFO16 dci16
= (LPDRVCONFIGINFO16
)SEGPTR_ALLOC(sizeof(DRVCONFIGINFO16
));
338 LPDRVCONFIGINFO dci32
= (LPDRVCONFIGINFO
)(*lParam2
);
343 dci16
->dwDCISize
= sizeof(DRVCONFIGINFO16
);
345 if ((str1
= HEAP_strdupWtoA(SystemHeap
, 0, dci32
->lpszDCISectionName
)) != NULL
&&
346 (str2
= SEGPTR_STRDUP(str1
)) != NULL
) {
347 dci16
->lpszDCISectionName
= (LPSTR
)SEGPTR_GET(str2
);
348 if (!HeapFree(SystemHeap
, 0, str1
))
349 FIXME(driver
, "bad free line=%d\n", __LINE__
);
353 if ((str1
= HEAP_strdupWtoA(SystemHeap
, 0, dci32
->lpszDCIAliasName
)) != NULL
&&
354 (str2
= SEGPTR_STRDUP(str1
)) != NULL
) {
355 dci16
->lpszDCIAliasName
= (LPSTR
)SEGPTR_GET(str2
);
356 if (!HeapFree(SystemHeap
, 0, str1
))
357 FIXME(driver
, "bad free line=%d\n", __LINE__
);
364 *lParam2
= (LPARAM
)SEGPTR_GET(dci16
);
371 if (wMsg
>= 0x800 && wMsg
< 0x900) {
372 /* FIXME: another hack to handle MCI messages...
373 * should find a *NICE* way to integrate DRIVER_ and
374 * MCI_ mapping/unmapping functions
378 FIXME(driver
, "Unknown message 0x%04x\n", wMsg
);
384 /**************************************************************************
385 * DRIVER_UnMapMsg32To16 [internal]
387 * UnMap a 32 bit driver message to a 16 bit driver message.
390 * -2 : ko, memory problem
392 int DRIVER_UnMapMsg32To16(WORD wMsg
, DWORD lParam1
, DWORD lParam2
)
401 case DRV_QUERYCONFIGURE
:
403 case DRV_EXITSESSION
:
404 case DRV_EXITAPPLICATION
:
406 /* lParam1 and lParam2 are not used */
409 /* lParam1 is a NULL terminated string, lParam2 is unknown => may lead to some problem */
410 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
411 if (lParam1
) if (!SEGPTR_FREE(PTR_SEG_TO_LIN(lParam1
)))
412 FIXME(driver
, "bad free line=%d\n", __LINE__
);
414 if (lParam2
&& wMsg
== DRV_OPEN
) {
415 LPMCI_OPEN_DRIVER_PARMS16 modp16
= (LPMCI_OPEN_DRIVER_PARMS16
)PTR_SEG_TO_LIN(lParam2
);
416 LPMCI_OPEN_DRIVER_PARMSA modp32
= *(LPMCI_OPEN_DRIVER_PARMSA
*)((char*)modp16
- sizeof(LPMCI_OPEN_DRIVER_PARMSA
));
418 modp32
->wCustomCommandTable
= modp16
->wCustomCommandTable
;
419 modp32
->wType
= modp16
->wType
;
420 if (!SEGPTR_FREE((char*)modp16
- sizeof(LPMCI_OPEN_DRIVER_PARMSA
)))
421 FIXME(driver
, "bad free line=%d\n", __LINE__
);
427 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
429 LPDRVCONFIGINFO16 dci16
= (LPDRVCONFIGINFO16
)PTR_SEG_TO_LIN(lParam2
);
431 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16
->lpszDCISectionName
)))
432 FIXME(driver
, "bad free line=%d\n", __LINE__
);
433 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16
->lpszDCIAliasName
)))
434 FIXME(driver
, "bad free line=%d\n", __LINE__
);
435 if (!SEGPTR_FREE(dci16
))
436 FIXME(driver
, "bad free line=%d\n", __LINE__
);
441 if (wMsg
>= 0x800 && wMsg
< 0x900) {
442 /* FIXME: another hack to handle MCI messages...
443 * should find a *NICE* way to integrate DRIVER_ and
444 * MCI_ mapping/unmapping functions
448 FIXME(driver
, "Unknown message 0x%04x\n", wMsg
);
454 /**************************************************************************
455 * SendDriverMessage [USER.251]
457 LRESULT WINAPI
SendDriverMessage16(HDRVR16 hDriver
, UINT16 msg
, LPARAM lParam1
,
464 TRACE(driver
, "(%04x, %04X, %08lX, %08lX)\n", hDriver
, msg
, lParam1
, lParam2
);
466 lpDrv
= DRIVER_FindFromHDrvr16(hDriver
);
467 if (lpDrv
!= NULL
&& lpDrv
->hDriver16
== hDriver
) {
468 switch (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) {
469 case WINE_DI_TYPE_16
:
470 TRACE(driver
, "Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
471 lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, hDriver
, msg
, lParam1
, lParam2
);
472 retval
= Callbacks
->CallDriverProc(lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, hDriver
,
473 msg
, lParam1
, lParam2
);
475 case WINE_DI_TYPE_32
:
476 mapRet
= DRIVER_MapMsg16To32(msg
, &lParam1
, &lParam2
);
478 TRACE(driver
, "Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
479 lpDrv
->d
.d32
.lpDrvProc
, lpDrv
->dwDriverID
, (HDRVR
)lpDrv
, msg
, lParam1
, lParam2
);
480 retval
= lpDrv
->d
.d32
.lpDrvProc(lpDrv
->dwDriverID
, (HDRVR
)lpDrv
, msg
, lParam1
, lParam2
);
482 DRIVER_UnMapMsg16To32(msg
, lParam1
, lParam2
);
489 FIXME(driver
, "Unknown driver type %08lx\n", lpDrv
->dwFlags
);
493 WARN(driver
, "Bad driver handle %u\n", hDriver
);
496 TRACE(driver
, "retval = %ld\n", retval
);
500 /**************************************************************************
501 * SendDriverMessage [WINMM.19]
503 LRESULT WINAPI
SendDriverMessage(HDRVR hDriver
, UINT msg
, LPARAM lParam1
,
510 TRACE(driver
, "(%04x, %04X, %08lX, %08lX)\n", hDriver
, msg
, lParam1
, lParam2
);
512 lpDrv
= DRIVER_FindFromHDrvr(hDriver
);
515 switch (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) {
516 case WINE_DI_TYPE_16
:
517 mapRet
= DRIVER_MapMsg32To16(msg
, &lParam1
, &lParam2
);
519 TRACE(driver
, "Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
520 lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, lpDrv
->hDriver16
, msg
, lParam1
, lParam2
);
521 retval
= Callbacks
->CallDriverProc(lpDrv
->d
.d16
.lpDrvProc
, lpDrv
->dwDriverID
, lpDrv
->hDriver16
,
522 msg
, lParam1
, lParam2
);
524 DRIVER_UnMapMsg32To16(msg
, lParam1
, lParam2
);
530 case WINE_DI_TYPE_32
:
531 TRACE(driver
, "Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
532 lpDrv
->d
.d32
.lpDrvProc
, lpDrv
->dwDriverID
, hDriver
, msg
, lParam1
, lParam2
);
533 retval
= lpDrv
->d
.d32
.lpDrvProc(lpDrv
->dwDriverID
, hDriver
, msg
, lParam1
, lParam2
);
536 FIXME(driver
, "Unknown driver type %08lx\n", lpDrv
->dwFlags
);
540 WARN(driver
, "Bad driver handle %u\n", hDriver
);
542 TRACE(driver
, "retval = %ld\n", retval
);
547 /**************************************************************************
548 * DRIVER_RemoveFromList [internal]
550 * Generates all the logic to handle driver closure / deletion
551 * Removes a driver struct to the list of open drivers.
553 static BOOL
DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv
)
555 lpDrv
->dwDriverID
= 0;
556 if (DRIVER_GetNumberOfModuleRefs(lpDrv
) == 1) {
557 SendDriverMessage((HDRVR
)lpDrv
, DRV_DISABLE
, 0L, 0L);
558 SendDriverMessage((HDRVR
)lpDrv
, DRV_FREE
, 0L, 0L);
560 if (lpDrv
->lpPrevItem
)
561 lpDrv
->lpPrevItem
->lpNextItem
= lpDrv
->lpNextItem
;
563 lpDrvItemList
= lpDrv
->lpNextItem
;
564 if (lpDrv
->lpNextItem
)
565 lpDrv
->lpNextItem
->lpPrevItem
= lpDrv
->lpPrevItem
;
570 /**************************************************************************
571 * DRIVER_AddToList [internal]
573 * Adds a driver struct to the list of open drivers.
574 * Generates all the logic to handle driver creation / open.
576 static BOOL
DRIVER_AddToList(LPWINE_DRIVER lpNewDrv
, LPARAM lParam
, BOOL bCallFrom32
)
578 lpNewDrv
->dwMagic
= WINE_DI_MAGIC
;
579 /* First driver to be loaded for this module, need to load correctly the module */
580 if (DRIVER_GetNumberOfModuleRefs(lpNewDrv
) == 0) {
581 if (SendDriverMessage((HDRVR
)lpNewDrv
, DRV_LOAD
, 0L, 0L) != DRV_SUCCESS
) {
582 TRACE(driver
, "DRV_LOAD failed on driver 0x%08lx\n", (DWORD
)lpNewDrv
);
585 if (SendDriverMessage((HDRVR
)lpNewDrv
, DRV_ENABLE
, 0L, 0L) != DRV_SUCCESS
) {
586 TRACE(driver
, "DRV_ENABLE failed on driver 0x%08lx\n", (DWORD
)lpNewDrv
);
591 lpNewDrv
->lpNextItem
= NULL
;
592 if (lpDrvItemList
== NULL
) {
593 lpDrvItemList
= lpNewDrv
;
594 lpNewDrv
->lpPrevItem
= NULL
;
596 LPWINE_DRIVER lpDrv
= lpDrvItemList
; /* find end of list */
597 while (lpDrv
->lpNextItem
!= NULL
)
598 lpDrv
= lpDrv
->lpNextItem
;
600 lpDrv
->lpNextItem
= lpNewDrv
;
601 lpNewDrv
->lpPrevItem
= lpDrv
;
604 /* Now just open a new instance of a driver on this module */
606 lpNewDrv
->dwDriverID
= SendDriverMessage((HDRVR
)lpNewDrv
, DRV_OPEN
, 0L, lParam
);
608 lpNewDrv
->dwDriverID
= SendDriverMessage16(lpNewDrv
->hDriver16
, DRV_OPEN
, 0L, lParam
);
610 if (lpNewDrv
->dwDriverID
== 0) {
611 TRACE(driver
, "DRV_OPEN failed on driver 0x%08lx\n", (DWORD
)lpNewDrv
);
612 DRIVER_RemoveFromList(lpNewDrv
);
619 /**************************************************************************
620 * DRIVER_CreateDrvr16 [internal]
622 * Creates unique ID for 16 bit drivers.
624 static HDRVR16
DRIVER_CreateDrvr16()
626 static WORD DRIVER_hDrvr16Counter
= 0;
628 while (DRIVER_FindFromHDrvr16(++DRIVER_hDrvr16Counter
));
629 return DRIVER_hDrvr16Counter
;
632 /**************************************************************************
633 * DRIVER_RegisterDriver16 [internal]
635 * Creates all the WINE internal representations for a 16 bit driver.
636 * The driver is also open by sending the correct messages.
638 LPWINE_DRIVER
DRIVER_RegisterDriver16(LPCSTR lpName
, HMODULE16 hModule
, DRIVERPROC16 lpProc
,
639 LPARAM lParam
, BOOL bCallFrom32
)
643 lpDrv
= HeapAlloc(SystemHeap
, 0, sizeof(WINE_DRIVER
));
645 lpDrv
->dwFlags
= WINE_DI_TYPE_16
;
646 lpDrv
->dwDriverID
= 0;
647 lpDrv
->hDriver16
= DRIVER_CreateDrvr16();
648 strncpy(lpDrv
->szAliasName
, lpName
, sizeof(lpDrv
->szAliasName
));
649 lpDrv
->d
.d16
.hModule
= hModule
;
650 lpDrv
->d
.d16
.lpDrvProc
= lpProc
;
652 if (!DRIVER_AddToList(lpDrv
, lParam
, bCallFrom32
)) {
653 HeapFree(SystemHeap
, 0, lpDrv
);
660 /**************************************************************************
661 * DRIVER_RegisterDriver32 [internal]
663 * Creates all the WINE internal representations for a 32 bit driver.
664 * The driver is also open by sending the correct messages.
666 LPWINE_DRIVER
DRIVER_RegisterDriver32(LPCSTR lpName
, HMODULE hModule
, DRIVERPROC lpProc
,
667 LPARAM lParam
, BOOL bCallFrom32
)
671 lpDrv
= HeapAlloc(SystemHeap
, 0, sizeof(WINE_DRIVER
));
673 lpDrv
->dwFlags
= WINE_DI_TYPE_32
;
674 lpDrv
->dwDriverID
= 0;
675 lpDrv
->hDriver16
= DRIVER_CreateDrvr16();
676 strncpy(lpDrv
->szAliasName
, lpName
, sizeof(lpDrv
->szAliasName
));
677 lpDrv
->d
.d32
.hModule
= hModule
;
678 lpDrv
->d
.d32
.lpDrvProc
= lpProc
;
680 if (!DRIVER_AddToList(lpDrv
, lParam
, bCallFrom32
)) {
681 HeapFree(SystemHeap
, 0, lpDrv
);
688 /**************************************************************************
689 * DRIVER_TryOpenDriver16 [internal]
691 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
693 static HDRVR16
DRIVER_TryOpenDriver16(LPCSTR lpFileName
, LPARAM lParam
, BOOL bCallFrom32
)
695 LPWINE_DRIVER lpDrv
= NULL
;
700 TRACE(driver
,"('%s', %08lX, %d);\n", lpFileName
, lParam
, bCallFrom32
);
702 if (lstrlenA(lpFileName
) < 1)
705 lpSFN
= strrchr(lpFileName
, '\\');
706 lpSFN
= (lpSFN
) ? (lpSFN
+ 1) : lpFileName
;
708 if ((hModule
= LoadModule16(lpFileName
, (LPVOID
)-1)) >= 32) {
709 if ((lpProc
= (DRIVERPROC16
)WIN32_GetProcAddress16(hModule
, "DRIVERPROC")) != NULL
) {
710 lpDrv
= DRIVER_RegisterDriver16(lpSFN
, hModule
, lpProc
, lParam
, bCallFrom32
);
712 FreeLibrary16(hModule
);
713 TRACE(driver
, "No DriverProc found\n");
717 TRACE(driver
, "Unable to load 16 bit module (%s): %d\n", lpFileName
, hModule
);
719 return lpDrv
? lpDrv
->hDriver16
: 0;
722 /**************************************************************************
723 * DRIVER_TryOpenDriver32 [internal]
725 * Tries to load a 32 bit driver whose DLL's (module) name is lpFileName.
727 static HDRVR
DRIVER_TryOpenDriver32(LPCSTR lpFileName
, LPARAM lParam
, BOOL bCallFrom32
)
729 LPWINE_DRIVER lpDrv
= NULL
;
734 TRACE(driver
,"('%s', %08lX, %d);\n", lpFileName
, lParam
, bCallFrom32
);
736 if (lstrlenA(lpFileName
) < 1)
739 lpSFN
= strrchr(lpFileName
, '\\');
740 lpSFN
= (lpSFN
) ? (lpSFN
+ 1) : lpFileName
;
742 if ((hModule
= LoadLibraryA(lpFileName
)) != 0) {
743 if ((lpProc
= GetProcAddress(hModule
, "DriverProc")) != NULL
) {
744 lpDrv
= DRIVER_RegisterDriver32(lpSFN
, hModule
, lpProc
, lParam
, bCallFrom32
);
746 FreeLibrary(hModule
);
748 TRACE(driver
, "No DriverProc found\n");
751 TRACE(driver
, "Unable to load 32 bit module \"%s\"\n", lpFileName
);
753 TRACE(driver
, "=> %p\n", lpDrv
);
757 /**************************************************************************
758 * OpenDriver16 [USER.252]
760 HDRVR16 WINAPI
OpenDriver16(LPCSTR lpDriverName
, LPCSTR lpSectionName
, LPARAM lParam
)
765 TRACE(driver
,"('%s', '%s', %08lX);\n", lpDriverName
, lpSectionName
, lParam
);
767 if (lpSectionName
== NULL
) {
768 hDriver
= DRIVER_TryOpenDriver16(lpDriverName
, lParam
, FALSE
);
770 hDriver
= DRIVER_TryOpenDriver32(lpDriverName
, lParam
, FALSE
);
773 /* in case hDriver is NULL, search in Drivers32 section */
774 lpSectionName
= "Drivers";
777 if (!hDriver
&& GetPrivateProfileStringA(lpSectionName
, lpDriverName
, "",
778 drvName
, sizeof(drvName
), "SYSTEM.INI") > 0) {
779 hDriver
= DRIVER_TryOpenDriver16(drvName
, lParam
, FALSE
);
784 /**************************************************************************
785 * OpenDriverA [WINMM.15]
786 * (0,1,DRV_LOAD ,0 ,0)
787 * (0,1,DRV_ENABLE,0 ,0)
788 * (0,1,DRV_OPEN ,buf[256],0)
790 HDRVR WINAPI
OpenDriverA(LPCSTR lpDriverName
, LPCSTR lpSectionName
, LPARAM lParam
)
795 TRACE(driver
,"('%s', '%s', %08lX);\n", lpDriverName
, lpSectionName
, lParam
);
797 if (lpSectionName
== NULL
) {
798 strncpy(drvName
, lpDriverName
, sizeof(drvName
));
799 hDriver
= DRIVER_TryOpenDriver32(lpDriverName
, lParam
, TRUE
);
801 hDriver
= DRIVER_TryOpenDriver16(lpDriverName
, lParam
, TRUE
);
804 if (GetPrivateProfileStringA("Drivers32", lpDriverName
, "", drvName
,
805 sizeof(drvName
), "SYSTEM.INI")) {
806 hDriver
= DRIVER_TryOpenDriver32(drvName
, lParam
, TRUE
);
811 if (GetPrivateProfileStringA("Drivers", lpDriverName
, "", drvName
,
812 sizeof(drvName
), "SYSTEM.INI")) {
813 hDriver
= DRIVER_TryOpenDriver16(drvName
, lParam
, TRUE
);
818 if (GetPrivateProfileStringA(lpSectionName
, lpDriverName
, "", drvName
,
819 sizeof(drvName
), "SYSTEM.INI")) {
820 hDriver
= DRIVER_TryOpenDriver32(drvName
, lParam
, TRUE
);
822 hDriver
= DRIVER_TryOpenDriver16(drvName
, lParam
, TRUE
);
826 TRACE(driver
, "retval='%08x'\n", hDriver
);
830 /**************************************************************************
831 * OpenDriverW [WINMM.15]
833 HDRVR WINAPI
OpenDriverW(LPCWSTR lpDriverName
, LPCWSTR lpSectionName
, LPARAM lParam
)
835 LPSTR dn
= HEAP_strdupWtoA(GetProcessHeap(), 0, lpDriverName
);
836 LPSTR sn
= HEAP_strdupWtoA(GetProcessHeap(), 0, lpSectionName
);
837 HDRVR ret
= OpenDriverA(dn
, sn
, lParam
);
839 if (dn
) HeapFree(GetProcessHeap(), 0, dn
);
840 if (sn
) HeapFree(GetProcessHeap(), 0, sn
);
844 /**************************************************************************
845 * CloseDriver16 [USER.253]
847 LRESULT WINAPI
CloseDriver16(HDRVR16 hDrvr
, LPARAM lParam1
, LPARAM lParam2
)
851 TRACE(driver
, "(%04x, %08lX, %08lX);\n", hDrvr
, lParam1
, lParam2
);
853 lpDrv
= DRIVER_FindFromHDrvr16(hDrvr
);
855 SendDriverMessage((HDRVR
)lpDrv
, DRV_CLOSE
, lParam1
, lParam2
);
857 if (DRIVER_RemoveFromList(lpDrv
)) {
858 TRACE(driver
, "hDrvr=%04x closed !\n", hDrvr
);
865 /**************************************************************************
866 * CloseDriver [WINMM.4]
868 LRESULT WINAPI
CloseDriver(HDRVR hDrvr
, LPARAM lParam1
, LPARAM lParam2
)
872 TRACE(driver
, "(%04x, %08lX, %08lX);\n", hDrvr
, lParam1
, lParam2
);
874 lpDrv
= DRIVER_FindFromHDrvr(hDrvr
);
876 SendDriverMessage((HDRVR
)lpDrv
, DRV_CLOSE
, lParam1
, lParam2
);
878 if (DRIVER_RemoveFromList(lpDrv
)) {
879 TRACE(driver
, "hDrvr=%08x closed !\n", hDrvr
);
886 /**************************************************************************
887 * GetDriverModuleHandle [USER.254]
889 HMODULE16 WINAPI
GetDriverModuleHandle16(HDRVR16 hDrvr
)
892 HMODULE16 hModule
= 0;
894 TRACE(driver
, "(%04x);\n", hDrvr
);
896 lpDrv
= DRIVER_FindFromHDrvr16(hDrvr
);
897 if (lpDrv
!= NULL
&& lpDrv
->hDriver16
== hDrvr
&&
898 (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == WINE_DI_TYPE_16
) {
899 hModule
= lpDrv
->d
.d16
.hModule
;
901 TRACE(driver
, "=> %d\n", hModule
);
905 /**************************************************************************
906 * GetDriverFlags [WINMM.13]
908 DWORD WINAPI
GetDriverFlags(HDRVR hDrvr
)
910 FIXME(driver
, "(%04x); stub!\n", hDrvr
);
914 /**************************************************************************
915 * GetDriverModuleHandle [WINMM.14]
917 HMODULE WINAPI
GetDriverModuleHandle(HDRVR hDrvr
)
922 TRACE(driver
, "(%04x);\n", hDrvr
);
924 lpDrv
= DRIVER_FindFromHDrvr(hDrvr
);
925 if (lpDrv
!= NULL
&& (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == WINE_DI_TYPE_32
) {
926 hModule
= lpDrv
->d
.d32
.hModule
;
928 TRACE(driver
, "=> %d\n", hModule
);
932 /**************************************************************************
933 * DefDriverProc16 [USER.255]
935 LRESULT WINAPI
DefDriverProc16(DWORD dwDevID
, HDRVR16 hDriv
, UINT16 wMsg
,
936 LPARAM lParam1
, LPARAM lParam2
)
938 TRACE(driver
, "devID=0x%08lx hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx\n",
939 dwDevID
, hDriv
, wMsg
, lParam1
, lParam2
);
949 case DRV_QUERYCONFIGURE
:
952 MessageBoxA(0, "Driver isn't configurable !", "Wine Driver", MB_OK
);
962 /**************************************************************************
963 * GetDriverInfo [USER.256]
965 BOOL16 WINAPI
GetDriverInfo16(HDRVR16 hDrvr
, LPDRIVERINFOSTRUCT16 lpDrvInfo
)
970 TRACE(driver
, "(%04x, %p);\n", hDrvr
, lpDrvInfo
);
972 if (lpDrvInfo
== NULL
|| lpDrvInfo
->length
!= sizeof(DRIVERINFOSTRUCT16
))
975 lpDrv
= DRIVER_FindFromHDrvr16(hDrvr
);
976 if (lpDrv
!= NULL
&& lpDrv
->hDriver16
== hDrvr
&&
977 (lpDrv
->dwFlags
& WINE_DI_TYPE_MASK
) == WINE_DI_TYPE_16
) {
978 lpDrvInfo
->hDriver
= lpDrv
->hDriver16
;
979 lpDrvInfo
->hModule
= lpDrv
->d
.d16
.hModule
;
980 strncpy(lpDrvInfo
->szAliasName
, lpDrv
->szAliasName
, sizeof(lpDrvInfo
->szAliasName
));
987 /**************************************************************************
988 * GetNextDriver [USER.257]
990 HDRVR16 WINAPI
GetNextDriver16(HDRVR16 hDrvr
, DWORD dwFlags
)
995 TRACE(driver
, "(%04x, %08lX);\n", hDrvr
, dwFlags
);
998 if (lpDrvItemList
== NULL
) {
999 FIXME(driver
, "drivers list empty !\n");
1000 /* FIXME: code was using DRIVER_LoadStartupDrivers(); before ?
1001 * I (EPP) don't quite understand this
1003 if (lpDrvItemList
== NULL
)
1006 lpDrv
= lpDrvItemList
;
1007 if (dwFlags
& GND_REVERSE
) {
1008 while (lpDrv
->lpNextItem
)
1009 lpDrv
= lpDrv
->lpNextItem
;
1012 lpDrv
= DRIVER_FindFromHDrvr16(hDrvr
);
1013 if (lpDrv
!= NULL
) {
1014 if (dwFlags
& GND_REVERSE
) {
1015 lpDrv
= (lpDrv
->lpPrevItem
) ? lpDrv
->lpPrevItem
: NULL
;
1017 lpDrv
= (lpDrv
->lpNextItem
) ? lpDrv
->lpNextItem
: NULL
;
1022 hRetDrv
= (lpDrv
) ? lpDrv
->hDriver16
: (HDRVR16
)0;
1023 TRACE(driver
, "return %04x !\n", hRetDrv
);