Moved the 16 bit driver functions callout into the dir.
[wine/multimedia.git] / windows / driver.c
blob9522fe7cb0b7bd77643a3e97e4451c8943ecf81f
1 /* -*- tab-width: 8; c-basic-offset: 4 -*- */
3 /*
4 * WINE Drivers functions
6 * Copyright 1994 Martin Ayotte
7 * Copyright 1998 Marcus Meissner
8 * Copyright 1999 Eric Pouech
9 */
11 #include <string.h>
12 #include "heap.h"
13 #include "winuser.h"
14 #include "driver.h"
15 #include "ldt.h"
16 #include "module.h"
17 #include "mmddk.h"
18 #include "debugtools.h"
20 DEFAULT_DEBUG_CHANNEL(driver)
22 static LPWINE_DRIVER lpDrvItemList = NULL;
24 /* TODO list :
25 * - LoadModule count and clean up is not handled correctly (it's not a
26 * problem as long as FreeLibrary is not working correctly)
27 * - shoudln't the allocations be done on a per process basis ?
28 * - get rid of external function "int DRIVER_GetType(HDRVR hDrvr)"
29 * - split 16/32 bit functions between DLLs as windows do (16 bit in USER, 32 bit in WINMM)
32 /* ### start build ### */
33 extern LONG CALLBACK DRIVER_CallTo16_long_lwwll(FARPROC16,LONG,WORD,WORD,LONG,LONG);
34 /* ### stop build ### */
36 /**************************************************************************
37 * LoadStartupDrivers [internal]
39 static void WINE_UNUSED DRIVER_LoadStartupDrivers(void)
41 char str[256];
43 if (GetPrivateProfileStringA("drivers", NULL, "", str, sizeof(str), "SYSTEM.INI") < 2) {
44 ERR("Can't find drivers section in system.ini\n");
45 } else {
46 HDRVR16 hDrv;
47 LPSTR ptr;
49 for (ptr = str; lstrlenA(ptr) != 0; ptr += lstrlenA(ptr) + 1) {
50 TRACE("str='%s'\n", ptr);
51 hDrv = OpenDriver16(ptr, "drivers", 0L);
52 TRACE("hDrv=%04x\n", hDrv);
54 TRACE("end of list !\n");
58 /**************************************************************************
59 * DRIVER_GetNumberOfModuleRefs [internal]
61 * Returns the number of open drivers which share the same module.
63 static WORD DRIVER_GetNumberOfModuleRefs(LPWINE_DRIVER lpNewDrv)
65 LPWINE_DRIVER lpDrv;
66 DWORD type = lpNewDrv->dwFlags & WINE_DI_TYPE_MASK;
67 WORD count = 0;
69 for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
70 if ((lpDrv->dwFlags & WINE_DI_TYPE_MASK) == type) {
71 switch (type) {
72 case WINE_DI_TYPE_16:
73 if (lpDrv->d.d16.hModule == lpNewDrv->d.d16.hModule)
74 count++;
75 break;
76 case WINE_DI_TYPE_32:
77 if (lpDrv->d.d32.hModule == lpNewDrv->d.d32.hModule)
78 count++;
79 break;
80 default:
81 FIXME("Unsupported driver type: %ld\n", type);
82 break;
86 return count;
89 /**************************************************************************
90 * DRIVER_FindFromHDrvr16 [internal]
92 * From a hDrvr being 16 bits, returns the WINE internal structure.
94 static LPWINE_DRIVER DRIVER_FindFromHDrvr16(HDRVR16 hDrvr)
96 LPWINE_DRIVER lpDrv;
98 for (lpDrv = lpDrvItemList; lpDrv; lpDrv = lpDrv->lpNextItem) {
99 if (lpDrv->hDriver16 == hDrvr) {
100 break;
103 return lpDrv;
106 /**************************************************************************
107 * DRIVER_FindFromHDrvr [internal]
109 * From a hDrvr (being 16 or 32 bits), returns the WINE internal structure.
111 static LPWINE_DRIVER DRIVER_FindFromHDrvr(HDRVR hDrvr)
113 if (!IsBadWritePtr((void*)hDrvr, sizeof(WINE_DRIVER)) &&
114 ((LPWINE_DRIVER)hDrvr)->dwMagic == WINE_DI_MAGIC) {
115 return (LPWINE_DRIVER)hDrvr;
117 return DRIVER_FindFromHDrvr16(hDrvr);
120 /**************************************************************************
121 * DRIVER_GetType [internal]
123 * From a hDrvr (being 16 or 32 bits), returns TRUE the flags for the driver.
125 int DRIVER_GetType(HDRVR hDrvr)
127 LPWINE_DRIVER lpDrv = DRIVER_FindFromHDrvr(hDrvr);
129 return (lpDrv) ? (lpDrv->dwFlags & WINE_DI_TYPE_MASK) : 0;
132 /**************************************************************************
133 * DRIVER_MapMsg16To32 [internal]
135 * Map a 16 bit driver message to a 32 bit driver message.
136 * 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg16To32
137 * 0 : ok, no memory allocated
138 * -1 : ko, unknown message
139 * -2 : ko, memory problem
141 static int DRIVER_MapMsg16To32(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
143 int ret = -1;
145 switch (wMsg) {
146 case DRV_LOAD:
147 case DRV_ENABLE:
148 case DRV_DISABLE:
149 case DRV_FREE:
150 case DRV_QUERYCONFIGURE:
151 case DRV_REMOVE:
152 case DRV_EXITSESSION:
153 case DRV_EXITAPPLICATION:
154 case DRV_POWER:
155 /* lParam1 and lParam2 are not used */
156 ret = 0;
157 break;
158 case DRV_OPEN:
159 case DRV_CLOSE:
160 /* lParam1 is a NULL terminated string */
161 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
162 if (*lParam1)
163 *lParam1 = (DWORD)PTR_SEG_TO_LIN(*lParam1);
164 if (*lParam2 && wMsg == DRV_OPEN) {
165 LPMCI_OPEN_DRIVER_PARMS16 modp16 = PTR_SEG_TO_LIN(*lParam2);
166 char* ptr = HeapAlloc(SystemHeap, 0, sizeof(LPMCI_OPEN_DRIVER_PARMS16) + sizeof(MCI_OPEN_DRIVER_PARMSA));
167 LPMCI_OPEN_DRIVER_PARMSA modp32;
169 if (ptr) {
170 *(LPMCI_OPEN_DRIVER_PARMS16*)ptr = modp16;
171 modp32 = (LPMCI_OPEN_DRIVER_PARMSA)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA));
173 modp32->wDeviceID = modp16->wDeviceID;
174 modp32->lpstrParams = PTR_SEG_TO_LIN(modp16->lpstrParams);
175 } else {
176 return -2;
178 *lParam2 = (DWORD)modp32;
180 ret = 1;
181 break;
182 case DRV_CONFIGURE:
183 case DRV_INSTALL:
184 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
185 if (*lParam2) {
186 LPDRVCONFIGINFO dci32 = HeapAlloc(SystemHeap, 0, sizeof(DRVCONFIGINFO));
187 LPDRVCONFIGINFO16 dci16 = PTR_SEG_TO_LIN(*lParam2);
189 if (dci32) {
190 dci32->dwDCISize = sizeof(DRVCONFIGINFO);
191 dci32->lpszDCISectionName = HEAP_strdupAtoW(SystemHeap, 0, PTR_SEG_TO_LIN(dci16->lpszDCISectionName));
192 dci32->lpszDCIAliasName = HEAP_strdupAtoW(SystemHeap, 0, PTR_SEG_TO_LIN(dci16->lpszDCIAliasName));
193 if (dci32->lpszDCISectionName == NULL || dci32->lpszDCIAliasName == NULL)
194 return -2;
195 } else {
196 return -2;
198 *lParam2 = (DWORD)dci32;
199 ret = 1;
200 } else {
201 ret = 0;
203 break;
204 default:
205 if (wMsg >= 0x800 && wMsg < 0x900) {
206 /* FIXME: another hack to handle MCI messages...
207 * should find a *NICE* way to integrate DRIVER_ and
208 * MCI_ mapping/unmapping functions
210 ret = 0;
211 } else {
212 FIXME("Unknown message 0x%04x\n", wMsg);
215 return ret;
218 /**************************************************************************
219 * DRIVER_MapMsg16To32 [internal]
221 * UnMap a 16 bit driver message to a 32 bit driver message.
222 * 0 : ok
223 * -1 : ko
224 * -2 : ko, memory problem
226 static int DRIVER_UnMapMsg16To32(WORD wMsg, DWORD lParam1, DWORD lParam2)
228 int ret = -1;
230 switch (wMsg) {
231 case DRV_LOAD:
232 case DRV_ENABLE:
233 case DRV_DISABLE:
234 case DRV_FREE:
235 case DRV_QUERYCONFIGURE:
236 case DRV_REMOVE:
237 case DRV_EXITSESSION:
238 case DRV_EXITAPPLICATION:
239 case DRV_POWER:
240 /* lParam1 and lParam2 are not used */
241 case DRV_OPEN:
242 case DRV_CLOSE:
243 /* lParam1 is a NULL terminated string */
244 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
245 if (lParam2 && wMsg == DRV_OPEN) {
246 LPMCI_OPEN_DRIVER_PARMSA modp32 = (LPMCI_OPEN_DRIVER_PARMSA)lParam2;
247 LPMCI_OPEN_DRIVER_PARMS16 modp16 = *(LPMCI_OPEN_DRIVER_PARMS16*)(lParam2 - sizeof(LPMCI_OPEN_DRIVER_PARMSA));
249 modp16->wCustomCommandTable = modp32->wCustomCommandTable;
250 modp16->wType = modp32->wType;
251 if (!HeapFree(SystemHeap, 0, modp32))
252 FIXME("bad free line=%d\n", __LINE__);
254 ret = 0;
255 break;
256 case DRV_CONFIGURE:
257 case DRV_INSTALL:
258 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
259 if (lParam2) {
260 LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)lParam2;
261 if (!HeapFree(SystemHeap, 0, (LPVOID)dci32->lpszDCISectionName))
262 FIXME("bad free line=%d\n", __LINE__);
263 if (!HeapFree(SystemHeap, 0, (LPVOID)dci32->lpszDCIAliasName))
264 FIXME("bad free line=%d\n", __LINE__);
265 if (!HeapFree(SystemHeap, 0, dci32))
266 FIXME("bad free line=%d\n", __LINE__);
268 ret = 0;
269 break;
270 default:
271 if (wMsg >= 0x800 && wMsg < 0x900) {
272 /* FIXME: another hack to handle MCI messages...
273 * should find a *NICE* way to integrate DRIVER_ and
274 * MCI_ mapping/unmapping functions
276 ret = 0;
277 } else {
278 FIXME("Unknown message 0x%04x\n", wMsg);
281 return ret;
284 /**************************************************************************
285 * DRIVER_MapMsg32To16 [internal]
287 * Map a 32 bit driver message to a 16 bit driver message.
288 * 1 : ok, some memory allocated, need to call DRIVER_UnMapMsg32To16
289 * 0 : ok, no memory allocated
290 * -1 : ko, unknown message
291 * -2 : ko, memory problem
293 static int DRIVER_MapMsg32To16(WORD wMsg, DWORD* lParam1, DWORD* lParam2)
295 int ret = -1;
297 switch (wMsg) {
298 case DRV_LOAD:
299 case DRV_ENABLE:
300 case DRV_DISABLE:
301 case DRV_FREE:
302 case DRV_QUERYCONFIGURE:
303 case DRV_REMOVE:
304 case DRV_EXITSESSION:
305 case DRV_EXITAPPLICATION:
306 case DRV_POWER:
307 /* lParam1 and lParam2 are not used */
308 ret = 0;
309 break;
310 case DRV_OPEN:
311 case DRV_CLOSE:
312 /* lParam1 is a NULL terminated string */
313 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
314 if (*lParam1) {
315 LPSTR str = SEGPTR_STRDUP((LPSTR)*lParam1);
316 if (str) {
317 *lParam1 = (LPARAM)SEGPTR_GET(str);
318 ret = 0;
319 } else {
320 ret = -2;
322 } else {
323 ret = 0;
325 if (*lParam2 && wMsg == DRV_OPEN) {
326 LPMCI_OPEN_DRIVER_PARMS16 modp16;
327 char* ptr = SEGPTR_ALLOC(sizeof(LPMCI_OPEN_DRIVER_PARMSA) + sizeof(MCI_OPEN_DRIVER_PARMS16));
328 LPMCI_OPEN_DRIVER_PARMSA modp32 = (LPMCI_OPEN_DRIVER_PARMSA)(*lParam2);
330 if (ptr) {
331 *(LPMCI_OPEN_DRIVER_PARMSA*)ptr = modp32;
332 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)(ptr + sizeof(LPMCI_OPEN_DRIVER_PARMSA));
334 modp16->wDeviceID = modp32->wDeviceID;
335 modp16->lpstrParams = PTR_SEG_TO_LIN(modp32->lpstrParams);
336 } else {
337 return -2;
339 *lParam2 = (DWORD)SEGPTR_GET(modp16);
340 ret = 1;
342 break;
343 case DRV_CONFIGURE:
344 case DRV_INSTALL:
345 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO */
346 if (*lParam2) {
347 LPDRVCONFIGINFO16 dci16 = (LPDRVCONFIGINFO16)SEGPTR_ALLOC(sizeof(DRVCONFIGINFO16));
348 LPDRVCONFIGINFO dci32 = (LPDRVCONFIGINFO)(*lParam2);
350 if (dci16) {
351 LPSTR str1, str2;
353 dci16->dwDCISize = sizeof(DRVCONFIGINFO16);
355 if ((str1 = HEAP_strdupWtoA(SystemHeap, 0, dci32->lpszDCISectionName)) != NULL &&
356 (str2 = SEGPTR_STRDUP(str1)) != NULL) {
357 dci16->lpszDCISectionName = (LPSTR)SEGPTR_GET(str2);
358 if (!HeapFree(SystemHeap, 0, str1))
359 FIXME("bad free line=%d\n", __LINE__);
360 } else {
361 return -2;
363 if ((str1 = HEAP_strdupWtoA(SystemHeap, 0, dci32->lpszDCIAliasName)) != NULL &&
364 (str2 = SEGPTR_STRDUP(str1)) != NULL) {
365 dci16->lpszDCIAliasName = (LPSTR)SEGPTR_GET(str2);
366 if (!HeapFree(SystemHeap, 0, str1))
367 FIXME("bad free line=%d\n", __LINE__);
368 } else {
369 return -2;
371 } else {
372 return -2;
374 *lParam2 = (LPARAM)SEGPTR_GET(dci16);
375 ret = 1;
376 } else {
377 ret = 0;
379 break;
380 default:
381 if (wMsg >= 0x800 && wMsg < 0x900) {
382 /* FIXME: another hack to handle MCI messages...
383 * should find a *NICE* way to integrate DRIVER_ and
384 * MCI_ mapping/unmapping functions
386 ret = 0;
387 } else {
388 FIXME("Unknown message 0x%04x\n", wMsg);
391 return ret;
394 /**************************************************************************
395 * DRIVER_UnMapMsg32To16 [internal]
397 * UnMap a 32 bit driver message to a 16 bit driver message.
398 * 0 : ok
399 * -1 : ko
400 * -2 : ko, memory problem
402 static int DRIVER_UnMapMsg32To16(WORD wMsg, DWORD lParam1, DWORD lParam2)
404 int ret = -1;
406 switch (wMsg) {
407 case DRV_LOAD:
408 case DRV_ENABLE:
409 case DRV_DISABLE:
410 case DRV_FREE:
411 case DRV_QUERYCONFIGURE:
412 case DRV_REMOVE:
413 case DRV_EXITSESSION:
414 case DRV_EXITAPPLICATION:
415 case DRV_POWER:
416 /* lParam1 and lParam2 are not used */
417 case DRV_OPEN:
418 case DRV_CLOSE:
419 /* lParam1 is a NULL terminated string, lParam2 is unknown => may lead to some problem */
420 /* lParam2 is a pointer to an MCI_OPEN_DRIVER_PARMS for an MCI device */
421 if (lParam1) if (!SEGPTR_FREE(PTR_SEG_TO_LIN(lParam1)))
422 FIXME("bad free line=%d\n", __LINE__);
424 if (lParam2 && wMsg == DRV_OPEN) {
425 LPMCI_OPEN_DRIVER_PARMS16 modp16 = (LPMCI_OPEN_DRIVER_PARMS16)PTR_SEG_TO_LIN(lParam2);
426 LPMCI_OPEN_DRIVER_PARMSA modp32 = *(LPMCI_OPEN_DRIVER_PARMSA*)((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA));
428 modp32->wCustomCommandTable = modp16->wCustomCommandTable;
429 modp32->wType = modp16->wType;
430 if (!SEGPTR_FREE((char*)modp16 - sizeof(LPMCI_OPEN_DRIVER_PARMSA)))
431 FIXME("bad free line=%d\n", __LINE__);
433 ret = 0;
434 break;
435 case DRV_CONFIGURE:
436 case DRV_INSTALL:
437 /* lParam1 is a handle to a window (or not used), lParam2 is a pointer to DRVCONFIGINFO, lParam2 */
438 if (lParam2) {
439 LPDRVCONFIGINFO16 dci16 = (LPDRVCONFIGINFO16)PTR_SEG_TO_LIN(lParam2);
441 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCISectionName)))
442 FIXME("bad free line=%d\n", __LINE__);
443 if (!SEGPTR_FREE(PTR_SEG_TO_LIN(dci16->lpszDCIAliasName)))
444 FIXME("bad free line=%d\n", __LINE__);
445 if (!SEGPTR_FREE(dci16))
446 FIXME("bad free line=%d\n", __LINE__);
448 ret = 0;
449 break;
450 default:
451 if (wMsg >= 0x800 && wMsg < 0x900) {
452 /* FIXME: another hack to handle MCI messages...
453 * should find a *NICE* way to integrate DRIVER_ and
454 * MCI_ mapping/unmapping functions
456 ret = 0;
457 } else {
458 FIXME("Unknown message 0x%04x\n", wMsg);
461 return ret;
464 /**************************************************************************
465 * SendDriverMessage [USER.251]
467 LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
468 LPARAM lParam2)
470 LPWINE_DRIVER lpDrv;
471 LRESULT retval = 0;
472 int mapRet;
474 TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2);
476 lpDrv = DRIVER_FindFromHDrvr16(hDriver);
477 if (lpDrv != NULL && lpDrv->hDriver16 == hDriver) {
478 switch (lpDrv->dwFlags & WINE_DI_TYPE_MASK) {
479 case WINE_DI_TYPE_16:
480 TRACE("Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
481 lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID, hDriver, msg, lParam1, lParam2);
482 retval = DRIVER_CallTo16_long_lwwll((FARPROC16)lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID,
483 hDriver, msg, lParam1, lParam2);
484 break;
485 case WINE_DI_TYPE_32:
486 mapRet = DRIVER_MapMsg16To32(msg, &lParam1, &lParam2);
487 if (mapRet >= 0) {
488 TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
489 lpDrv->d.d32.lpDrvProc, lpDrv->dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
490 retval = lpDrv->d.d32.lpDrvProc(lpDrv->dwDriverID, (HDRVR)lpDrv, msg, lParam1, lParam2);
491 if (mapRet >= 1) {
492 DRIVER_UnMapMsg16To32(msg, lParam1, lParam2);
494 } else {
495 retval = 0;
497 break;
498 default:
499 FIXME("Unknown driver type %08lx\n", lpDrv->dwFlags);
500 break;
502 } else {
503 WARN("Bad driver handle %u\n", hDriver);
506 TRACE("retval = %ld\n", retval);
507 return retval;
510 /**************************************************************************
511 * SendDriverMessage [WINMM.19]
513 LRESULT WINAPI SendDriverMessage(HDRVR hDriver, UINT msg, LPARAM lParam1,
514 LPARAM lParam2)
516 LPWINE_DRIVER lpDrv;
517 LRESULT retval = 0;
518 int mapRet;
520 TRACE("(%04x, %04X, %08lX, %08lX)\n", hDriver, msg, lParam1, lParam2);
522 lpDrv = DRIVER_FindFromHDrvr(hDriver);
524 if (lpDrv != NULL) {
525 switch (lpDrv->dwFlags & WINE_DI_TYPE_MASK) {
526 case WINE_DI_TYPE_16:
527 mapRet = DRIVER_MapMsg32To16(msg, &lParam1, &lParam2);
528 if (mapRet >= 0) {
529 TRACE("Before CallDriverProc proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
530 lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID, lpDrv->hDriver16, msg, lParam1, lParam2);
531 retval = DRIVER_CallTo16_long_lwwll((FARPROC16)lpDrv->d.d16.lpDrvProc, lpDrv->dwDriverID,
532 lpDrv->hDriver16, msg, lParam1, lParam2);
533 if (mapRet >= 1) {
534 DRIVER_UnMapMsg32To16(msg, lParam1, lParam2);
536 } else {
537 retval = 0;
539 break;
540 case WINE_DI_TYPE_32:
541 TRACE("Before func32 call proc=%p driverID=%08lx hDrv=%u wMsg=%04x p1=%08lx p2=%08lx\n",
542 lpDrv->d.d32.lpDrvProc, lpDrv->dwDriverID, hDriver, msg, lParam1, lParam2);
543 retval = lpDrv->d.d32.lpDrvProc(lpDrv->dwDriverID, hDriver, msg, lParam1, lParam2);
544 break;
545 default:
546 FIXME("Unknown driver type %08lx\n", lpDrv->dwFlags);
547 break;
549 } else {
550 WARN("Bad driver handle %u\n", hDriver);
552 TRACE("retval = %ld\n", retval);
554 return retval;
557 /**************************************************************************
558 * DRIVER_RemoveFromList [internal]
560 * Generates all the logic to handle driver closure / deletion
561 * Removes a driver struct to the list of open drivers.
563 static BOOL DRIVER_RemoveFromList(LPWINE_DRIVER lpDrv)
565 lpDrv->dwDriverID = 0;
566 if (DRIVER_GetNumberOfModuleRefs(lpDrv) == 1) {
567 SendDriverMessage((HDRVR)lpDrv, DRV_DISABLE, 0L, 0L);
568 SendDriverMessage((HDRVR)lpDrv, DRV_FREE, 0L, 0L);
571 if (lpDrv->lpPrevItem)
572 lpDrv->lpPrevItem->lpNextItem = lpDrv->lpNextItem;
573 else
574 lpDrvItemList = lpDrv->lpNextItem;
575 if (lpDrv->lpNextItem)
576 lpDrv->lpNextItem->lpPrevItem = lpDrv->lpPrevItem;
578 return TRUE;
581 /**************************************************************************
582 * DRIVER_AddToList [internal]
584 * Adds a driver struct to the list of open drivers.
585 * Generates all the logic to handle driver creation / open.
587 static BOOL DRIVER_AddToList(LPWINE_DRIVER lpNewDrv, LPARAM lParam, BOOL bCallFrom32)
589 lpNewDrv->dwMagic = WINE_DI_MAGIC;
590 /* First driver to be loaded for this module, need to load correctly the module */
591 if (DRIVER_GetNumberOfModuleRefs(lpNewDrv) == 0) {
592 if (SendDriverMessage((HDRVR)lpNewDrv, DRV_LOAD, 0L, 0L) != DRV_SUCCESS) {
593 TRACE("DRV_LOAD failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
594 return FALSE;
596 if (SendDriverMessage((HDRVR)lpNewDrv, DRV_ENABLE, 0L, 0L) != DRV_SUCCESS) {
597 TRACE("DRV_ENABLE failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
598 return FALSE;
602 lpNewDrv->lpNextItem = NULL;
603 if (lpDrvItemList == NULL) {
604 lpDrvItemList = lpNewDrv;
605 lpNewDrv->lpPrevItem = NULL;
606 } else {
607 LPWINE_DRIVER lpDrv = lpDrvItemList; /* find end of list */
608 while (lpDrv->lpNextItem != NULL)
609 lpDrv = lpDrv->lpNextItem;
611 lpDrv->lpNextItem = lpNewDrv;
612 lpNewDrv->lpPrevItem = lpDrv;
615 /* Now just open a new instance of a driver on this module */
616 if (bCallFrom32) {
617 lpNewDrv->dwDriverID = SendDriverMessage((HDRVR)lpNewDrv, DRV_OPEN, 0L, lParam);
618 } else {
619 lpNewDrv->dwDriverID = SendDriverMessage16(lpNewDrv->hDriver16, DRV_OPEN, 0L, lParam);
621 if (lpNewDrv->dwDriverID == 0) {
622 TRACE("DRV_OPEN failed on driver 0x%08lx\n", (DWORD)lpNewDrv);
623 DRIVER_RemoveFromList(lpNewDrv);
624 return FALSE;
627 return TRUE;
630 /**************************************************************************
631 * DRIVER_CreateDrvr16 [internal]
633 * Creates unique ID for 16 bit drivers.
635 static HDRVR16 DRIVER_CreateDrvr16()
637 static WORD DRIVER_hDrvr16Counter = 0;
639 while (DRIVER_FindFromHDrvr16(++DRIVER_hDrvr16Counter));
640 return DRIVER_hDrvr16Counter;
643 /**************************************************************************
644 * DRIVER_CloseDriver [internal]
647 BOOL DRIVER_CloseDriver(LPWINE_DRIVER lpDrv, DWORD lParam1, DWORD lParam2)
649 if (lpDrv != NULL) {
650 SendDriverMessage((HDRVR)lpDrv, DRV_CLOSE, lParam1, lParam2);
652 if (DRIVER_RemoveFromList(lpDrv)) {
653 HeapFree(SystemHeap, 0, lpDrv);
654 return TRUE;
657 WARN("Failed to close driver\n");
658 return FALSE;
661 /**************************************************************************
662 * DRIVER_RegisterDriver16 [internal]
664 * Creates all the WINE internal representations for a 16 bit driver.
665 * The driver is also open by sending the correct messages.
667 LPWINE_DRIVER DRIVER_RegisterDriver16(LPCSTR lpName, HMODULE16 hModule, DRIVERPROC16 lpProc,
668 LPARAM lParam, BOOL bCallFrom32)
670 LPWINE_DRIVER lpDrv;
672 lpDrv = HeapAlloc(SystemHeap, 0, sizeof(WINE_DRIVER));
673 if (lpDrv != NULL) {
674 lpDrv->dwFlags = WINE_DI_TYPE_16;
675 lpDrv->dwDriverID = 0;
676 lpDrv->hDriver16 = DRIVER_CreateDrvr16();
677 lstrcpynA(lpDrv->szAliasName, lpName, sizeof(lpDrv->szAliasName));
678 lpDrv->d.d16.hModule = hModule;
679 lpDrv->d.d16.lpDrvProc = lpProc;
681 if (!DRIVER_AddToList(lpDrv, lParam, bCallFrom32)) {
682 HeapFree(SystemHeap, 0, lpDrv);
683 lpDrv = NULL;
686 return lpDrv;
689 /**************************************************************************
690 * DRIVER_RegisterDriver32 [internal]
692 * Creates all the WINE internal representations for a 32 bit driver.
693 * The driver is also open by sending the correct messages.
695 LPWINE_DRIVER DRIVER_RegisterDriver32(LPCSTR lpName, HMODULE hModule, DRIVERPROC lpProc,
696 LPARAM lParam, BOOL bCallFrom32)
698 LPWINE_DRIVER lpDrv;
700 lpDrv = HeapAlloc(SystemHeap, 0, sizeof(WINE_DRIVER));
701 if (lpDrv != NULL) {
702 lpDrv->dwFlags = WINE_DI_TYPE_32;
703 lpDrv->dwDriverID = 0;
704 lpDrv->hDriver16 = DRIVER_CreateDrvr16();
705 lstrcpynA(lpDrv->szAliasName, lpName, sizeof(lpDrv->szAliasName));
706 lpDrv->d.d32.hModule = hModule;
707 lpDrv->d.d32.lpDrvProc = lpProc;
709 if (!DRIVER_AddToList(lpDrv, lParam, bCallFrom32)) {
710 HeapFree(SystemHeap, 0, lpDrv);
711 lpDrv = NULL;
714 return lpDrv;
717 /**************************************************************************
718 * DRIVER_TryOpenDriver16 [internal]
720 * Tries to load a 16 bit driver whose DLL's (module) name is lpFileName.
722 static HDRVR16 DRIVER_TryOpenDriver16(LPCSTR lpFileName, LPARAM lParam, BOOL bCallFrom32)
724 LPWINE_DRIVER lpDrv = NULL;
725 LPCSTR lpSFN;
726 HMODULE16 hModule;
727 DRIVERPROC16 lpProc;
729 TRACE("('%s', %08lX, %d);\n", lpFileName, lParam, bCallFrom32);
731 if (lstrlenA(lpFileName) < 1)
732 return 0;
734 lpSFN = strrchr(lpFileName, '\\');
735 lpSFN = (lpSFN) ? (lpSFN + 1) : lpFileName;
737 if ((hModule = LoadModule16(lpFileName, (LPVOID)-1)) >= 32) {
738 if ((lpProc = (DRIVERPROC16)WIN32_GetProcAddress16(hModule, "DRIVERPROC")) != NULL) {
739 lpDrv = DRIVER_RegisterDriver16(lpSFN, hModule, lpProc, lParam, bCallFrom32);
740 } else {
741 FreeLibrary16(hModule);
742 TRACE("No DriverProc found\n");
743 lpDrv = 0;
745 } else {
746 TRACE("Unable to load 16 bit module (%s): %d\n", lpFileName, hModule);
748 return lpDrv ? lpDrv->hDriver16 : 0;
751 /**************************************************************************
752 * DRIVER_TryOpenDriver32 [internal]
754 * Tries to load a 32 bit driver whose DLL's (module) name is lpFileName.
756 static HDRVR DRIVER_TryOpenDriver32(LPCSTR lpFileName, LPARAM lParam, BOOL bCallFrom32)
758 LPWINE_DRIVER lpDrv = NULL;
759 LPCSTR lpSFN;
760 HMODULE hModule;
761 DRIVERPROC lpProc;
763 TRACE("('%s', %08lX, %d);\n", lpFileName, lParam, bCallFrom32);
765 if (lstrlenA(lpFileName) < 1)
766 return 0;
768 lpSFN = strrchr(lpFileName, '\\');
769 lpSFN = (lpSFN) ? (lpSFN + 1) : lpFileName;
771 if ((hModule = LoadLibraryA(lpFileName)) != 0) {
772 if ((lpProc = GetProcAddress(hModule, "DriverProc")) != NULL) {
773 lpDrv = DRIVER_RegisterDriver32(lpSFN, hModule, lpProc, lParam, bCallFrom32);
774 } else {
775 FreeLibrary(hModule);
776 lpDrv = 0;
777 TRACE("No DriverProc found\n");
779 } else {
780 TRACE("Unable to load 32 bit module \"%s\"\n", lpFileName);
782 TRACE("=> %p\n", lpDrv);
783 return (HDRVR)lpDrv;
786 /**************************************************************************
787 * OpenDriver16 [USER.252]
789 HDRVR16 WINAPI OpenDriver16(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
791 HDRVR16 hDriver = 0;
792 char drvName[128];
794 TRACE("('%s', '%s', %08lX);\n", lpDriverName, lpSectionName, lParam);
796 if (lpSectionName == NULL) {
797 hDriver = DRIVER_TryOpenDriver16(lpDriverName, lParam, FALSE);
798 if (!hDriver) {
799 hDriver = DRIVER_TryOpenDriver32(lpDriverName, lParam, FALSE);
801 if (!hDriver) {
802 /* in case hDriver is NULL, search in Drivers32 section */
803 lpSectionName = "Drivers";
806 if (!hDriver && GetPrivateProfileStringA(lpSectionName, lpDriverName, "",
807 drvName, sizeof(drvName), "SYSTEM.INI") > 0) {
808 hDriver = DRIVER_TryOpenDriver16(drvName, lParam, FALSE);
810 if (!hDriver)
811 ERR("Failed to open driver %s from section %s\n", lpDriverName, lpSectionName);
812 else
813 TRACE("=> %08x\n", hDriver);
814 return hDriver;
817 /**************************************************************************
818 * OpenDriverA [WINMM.15]
819 * (0,1,DRV_LOAD ,0 ,0)
820 * (0,1,DRV_ENABLE,0 ,0)
821 * (0,1,DRV_OPEN ,buf[256],0)
823 HDRVR WINAPI OpenDriverA(LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam)
825 HDRVR hDriver = 0;
826 char drvName[128];
828 TRACE("('%s', '%s', %08lX);\n", lpDriverName, lpSectionName, lParam);
830 if (lpSectionName == NULL) {
831 lstrcpynA(drvName, lpDriverName, sizeof(drvName));
832 hDriver = DRIVER_TryOpenDriver32(lpDriverName, lParam, TRUE);
833 if (!hDriver) {
834 hDriver = DRIVER_TryOpenDriver16(lpDriverName, lParam, TRUE);
836 if (!hDriver) {
837 if (GetPrivateProfileStringA("Drivers32", lpDriverName, "", drvName,
838 sizeof(drvName), "SYSTEM.INI")) {
839 hDriver = DRIVER_TryOpenDriver32(drvName, lParam, TRUE);
843 if (!hDriver) {
844 if (GetPrivateProfileStringA("Drivers", lpDriverName, "", drvName,
845 sizeof(drvName), "SYSTEM.INI")) {
846 hDriver = DRIVER_TryOpenDriver16(drvName, lParam, TRUE);
850 } else {
851 if (GetPrivateProfileStringA(lpSectionName, lpDriverName, "", drvName,
852 sizeof(drvName), "SYSTEM.INI")) {
853 hDriver = DRIVER_TryOpenDriver32(drvName, lParam, TRUE);
854 if (!hDriver) {
855 hDriver = DRIVER_TryOpenDriver16(drvName, lParam, TRUE);
859 if (!hDriver)
860 ERR("Failed to open driver %s from section %s\n", lpDriverName, lpSectionName);
861 else
862 TRACE("=> %08x\n", hDriver);
863 return hDriver;
866 /**************************************************************************
867 * OpenDriverW [WINMM.15]
869 HDRVR WINAPI OpenDriverW(LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam)
871 LPSTR dn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpDriverName);
872 LPSTR sn = HEAP_strdupWtoA(GetProcessHeap(), 0, lpSectionName);
873 HDRVR ret = OpenDriverA(dn, sn, lParam);
875 if (dn) HeapFree(GetProcessHeap(), 0, dn);
876 if (sn) HeapFree(GetProcessHeap(), 0, sn);
877 return ret;
880 /**************************************************************************
881 * CloseDriver16 [USER.253]
883 LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
885 TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
887 return DRIVER_CloseDriver(DRIVER_FindFromHDrvr16(hDrvr), lParam1, lParam2);
890 /**************************************************************************
891 * CloseDriver [WINMM.4]
893 LRESULT WINAPI CloseDriver(HDRVR hDrvr, LPARAM lParam1, LPARAM lParam2)
895 TRACE("(%04x, %08lX, %08lX);\n", hDrvr, lParam1, lParam2);
897 return DRIVER_CloseDriver(DRIVER_FindFromHDrvr(hDrvr), lParam1, lParam2);
900 /**************************************************************************
901 * GetDriverModuleHandle [USER.254]
903 HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
905 LPWINE_DRIVER lpDrv;
906 HMODULE16 hModule = 0;
908 TRACE("(%04x);\n", hDrvr);
910 lpDrv = DRIVER_FindFromHDrvr16(hDrvr);
911 if (lpDrv != NULL && lpDrv->hDriver16 == hDrvr &&
912 (lpDrv->dwFlags & WINE_DI_TYPE_MASK) == WINE_DI_TYPE_16) {
913 hModule = lpDrv->d.d16.hModule;
915 TRACE("=> %d\n", hModule);
916 return hModule;
919 /**************************************************************************
920 * GetDriverFlags [WINMM.13]
922 DWORD WINAPI GetDriverFlags(HDRVR hDrvr)
924 FIXME("(%04x); stub!\n", hDrvr);
925 /* should I merge it with DRIVER_GetType() ? */
926 return 0;
929 /**************************************************************************
930 * GetDriverModuleHandle [WINMM.14]
932 HMODULE WINAPI GetDriverModuleHandle(HDRVR hDrvr)
934 LPWINE_DRIVER lpDrv;
935 HMODULE hModule = 0;
937 TRACE("(%04x);\n", hDrvr);
939 lpDrv = DRIVER_FindFromHDrvr(hDrvr);
940 if (lpDrv != NULL && (lpDrv->dwFlags & WINE_DI_TYPE_MASK) == WINE_DI_TYPE_32) {
941 hModule = lpDrv->d.d32.hModule;
943 TRACE("=> %d\n", hModule);
944 return hModule;
947 /**************************************************************************
948 * DefDriverProc16 [USER.255]
950 LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg,
951 LPARAM lParam1, LPARAM lParam2)
953 TRACE("devID=0x%08lx hDrv=0x%04x wMsg=%04x lP1=0x%08lx lP2=0x%08lx\n",
954 dwDevID, hDriv, wMsg, lParam1, lParam2);
956 switch(wMsg) {
957 case DRV_LOAD:
958 case DRV_FREE:
959 case DRV_ENABLE:
960 case DRV_DISABLE:
961 return (LRESULT)1L;
962 case DRV_OPEN:
963 case DRV_CLOSE:
964 case DRV_QUERYCONFIGURE:
965 return (LRESULT)0L;
966 case DRV_CONFIGURE:
967 MessageBoxA(0, "Driver isn't configurable !", "Wine Driver", MB_OK);
968 return (LRESULT)0L;
969 case DRV_INSTALL:
970 case DRV_REMOVE:
971 return DRV_SUCCESS;
972 default:
973 return (LRESULT)0L;
977 /**************************************************************************
978 * GetDriverInfo [USER.256]
980 BOOL16 WINAPI GetDriverInfo16(HDRVR16 hDrvr, LPDRIVERINFOSTRUCT16 lpDrvInfo)
982 LPWINE_DRIVER lpDrv;
983 BOOL16 ret = FALSE;
985 TRACE("(%04x, %p);\n", hDrvr, lpDrvInfo);
987 if (lpDrvInfo == NULL || lpDrvInfo->length != sizeof(DRIVERINFOSTRUCT16))
988 return FALSE;
990 lpDrv = DRIVER_FindFromHDrvr16(hDrvr);
991 if (lpDrv != NULL && lpDrv->hDriver16 == hDrvr &&
992 (lpDrv->dwFlags & WINE_DI_TYPE_MASK) == WINE_DI_TYPE_16) {
993 lpDrvInfo->hDriver = lpDrv->hDriver16;
994 lpDrvInfo->hModule = lpDrv->d.d16.hModule;
995 lstrcpynA(lpDrvInfo->szAliasName, lpDrv->szAliasName, sizeof(lpDrvInfo->szAliasName));
996 ret = TRUE;
999 return ret;
1002 /**************************************************************************
1003 * GetNextDriver [USER.257]
1005 HDRVR16 WINAPI GetNextDriver16(HDRVR16 hDrvr, DWORD dwFlags)
1007 HDRVR16 hRetDrv = 0;
1008 LPWINE_DRIVER lpDrv;
1010 TRACE("(%04x, %08lX);\n", hDrvr, dwFlags);
1012 if (hDrvr == 0) {
1013 if (lpDrvItemList == NULL) {
1014 FIXME("drivers list empty !\n");
1015 /* FIXME: code was using DRIVER_LoadStartupDrivers(); before ?
1016 * I (EPP) don't quite understand this
1018 if (lpDrvItemList == NULL)
1019 return 0;
1021 lpDrv = lpDrvItemList;
1022 if (dwFlags & GND_REVERSE) {
1023 while (lpDrv->lpNextItem)
1024 lpDrv = lpDrv->lpNextItem;
1026 } else {
1027 lpDrv = DRIVER_FindFromHDrvr16(hDrvr);
1028 if (lpDrv != NULL) {
1029 if (dwFlags & GND_REVERSE) {
1030 lpDrv = (lpDrv->lpPrevItem) ? lpDrv->lpPrevItem : NULL;
1031 } else {
1032 lpDrv = (lpDrv->lpNextItem) ? lpDrv->lpNextItem : NULL;
1037 hRetDrv = (lpDrv) ? lpDrv->hDriver16 : (HDRVR16)0;
1038 TRACE("return %04x !\n", hRetDrv);
1039 return hRetDrv;