Documentation updates.
[wine] / windows / driver.c
1 /*
2  * WINE Drivers functions
3  *
4  * Copyright 1994 Martin Ayotte
5  * Copyright 1998 Marcus Meissner
6  */
7
8 #include "windows.h"
9 #include "heap.h"
10 #include "win.h"
11 #include "callback.h"
12 #include "driver.h"
13 #include "module.h"
14 #include "debug.h"
15 #include <string.h>
16
17 LPDRIVERITEM lpDrvItemList = NULL;
18 LPDRIVERITEM32A lpDrvItemList32 = NULL;
19
20 /**************************************************************************
21  *      LoadStartupDrivers
22  */
23 static void LoadStartupDrivers(void)
24 {
25     HDRVR16 hDrv;
26     char  str[256];
27     LPSTR ptr;
28
29     if (GetPrivateProfileString32A( "drivers", NULL, "", str, sizeof(str),
30                                  "SYSTEM.INI" ) < 2)
31     {
32         ERR( driver,"Can't find drivers section in system.ini\n" );
33         return;
34     }
35
36     ptr = str;
37     while (lstrlen32A( ptr ) != 0)
38     {
39         TRACE(driver, "str='%s'\n", ptr );
40         hDrv = OpenDriver16( ptr, "drivers", 0L );
41         TRACE(driver, "hDrv=%04x\n", hDrv );
42         ptr += lstrlen32A(ptr) + 1;
43     }
44     TRACE(driver, "end of list !\n" );
45     return;
46 }
47
48 /**************************************************************************
49  *                              SendDriverMessage               [USER.251]
50  */
51 LRESULT WINAPI SendDriverMessage16(HDRVR16 hDriver, UINT16 msg, LPARAM lParam1,
52                                    LPARAM lParam2)
53 {
54     LPDRIVERITEM lpdrv;
55     LRESULT retval;
56
57     TRACE(driver, "(%04x, %04X, %08lX, %08lX)\n",
58                     hDriver, msg, lParam1, lParam2 );
59
60     lpdrv = (LPDRIVERITEM)GlobalLock16( hDriver );
61     if (lpdrv == NULL || lpdrv->dis.hDriver != hDriver)
62     {
63         GlobalUnlock16( hDriver );
64         return 0;
65     }
66
67     retval = Callbacks->CallDriverProc( lpdrv->lpDrvProc, 0L /* FIXME */,
68                                         hDriver, msg, lParam1, lParam2 );
69
70     TRACE(driver, "retval = %ld\n", retval );
71
72     GlobalUnlock16( hDriver );
73     return retval;
74 }
75
76 /**************************************************************************
77  *                              SendDriverMessage               [WINMM.19]
78  */
79 LRESULT WINAPI SendDriverMessage32(HDRVR32 hDriver, UINT32 msg, LPARAM lParam1,
80                                    LPARAM lParam2)
81 {
82     LPDRIVERITEM32A lpdrv;
83     LRESULT retval;
84
85     TRACE(driver, "(%04x, %04X, %08lX, %08lX)\n",
86                     hDriver, msg, lParam1, lParam2 );
87
88     lpdrv = (LPDRIVERITEM32A)hDriver;
89     if (!lpdrv)
90         return 0;
91
92     retval = lpdrv->driverproc(lpdrv->dis.hDriver,hDriver,msg,lParam1,lParam2);
93
94     TRACE(driver, "retval = %ld\n", retval );
95
96     return retval;
97 }
98
99 /**************************************************************************
100  *                              OpenDriver                      [USER.252]
101  */
102 HDRVR16 WINAPI OpenDriver16(
103         LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam
104 ) {
105     HDRVR16 hDrvr;
106     LPDRIVERITEM lpdrv, lpnewdrv;
107     char DrvName[128];
108
109     TRACE(driver,"('%s', '%s', %08lX);\n",
110                     lpDriverName, lpSectionName, lParam );
111
112     if (lpSectionName == NULL) {
113         lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName));
114         FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName);
115     } else {
116         GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
117                                      sizeof(DrvName), "SYSTEM.INI" );
118     }
119     TRACE(driver,"DrvName='%s'\n", DrvName );
120     if (lstrlen32A(DrvName) < 1) return 0;
121
122     lpdrv = lpDrvItemList;
123     while (lpdrv)                       /* XXX find it... like this? */
124     {
125         if (!strcasecmp( lpDriverName, lpdrv->dis.szAliasName ))
126         {
127             lpdrv->count++;
128             SendDriverMessage16( lpdrv->dis.hDriver, DRV_OPEN, 0L, lParam );
129             return lpdrv->dis.hDriver;
130         }
131         lpdrv = lpdrv->lpNextItem;
132     }
133
134     lpdrv = lpDrvItemList;      /* find end of list */
135     if (lpdrv != NULL)
136       while (lpdrv->lpNextItem != NULL)
137         lpdrv = lpdrv->lpNextItem;
138
139     hDrvr = GlobalAlloc16( GMEM_MOVEABLE, sizeof(DRIVERITEM) );
140     lpnewdrv = (LPDRIVERITEM)GlobalLock16( hDrvr );
141     if (lpnewdrv == NULL) return 0;
142     lpnewdrv->dis.length = sizeof( DRIVERINFOSTRUCT16 );
143     lpnewdrv->dis.hModule = LoadModule16( DrvName, (LPVOID)-1 );
144     if (!lpnewdrv->dis.hModule)
145     {
146         GlobalUnlock16( hDrvr );
147         GlobalFree16( hDrvr );
148         return 0;
149     }
150     lpnewdrv->dis.hDriver = hDrvr;
151     lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName );
152     lpnewdrv->count = 1;
153     if (!(lpnewdrv->lpDrvProc = (DRIVERPROC16)WIN32_GetProcAddress16(lpnewdrv->dis.hModule, "DRIVERPROC" )))
154     {
155         FreeModule16( lpnewdrv->dis.hModule );
156         GlobalUnlock16( hDrvr );
157         GlobalFree16( hDrvr );
158         return 0;
159     }
160
161     lpnewdrv->lpNextItem = NULL;
162     if (lpDrvItemList == NULL)
163     {
164         lpDrvItemList = lpnewdrv;
165         lpnewdrv->lpPrevItem = NULL;
166     }
167     else
168     {
169         lpdrv->lpNextItem = lpnewdrv;
170         lpnewdrv->lpPrevItem = lpdrv;
171     }
172
173     SendDriverMessage16( hDrvr, DRV_LOAD, 0L, lParam );
174     SendDriverMessage16( hDrvr, DRV_ENABLE, 0L, lParam );
175     SendDriverMessage16( hDrvr, DRV_OPEN, 0L, lParam );
176
177     TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr );
178     return hDrvr;
179 }
180
181 /**************************************************************************
182  *                              OpenDriver                      [WINMM.15]
183  * (0,1,DRV_LOAD  ,0       ,0)
184  * (0,1,DRV_ENABLE,0       ,0)
185  * (0,1,DRV_OPEN  ,buf[256],0)
186  */
187 HDRVR32 WINAPI OpenDriver32A(
188         LPCSTR lpDriverName, LPCSTR lpSectionName, LPARAM lParam
189 ) {
190     HDRVR32 hDrvr;
191     LPDRIVERITEM32A lpdrv, lpnewdrv;
192     char DrvName[128],*tmpbuf;
193
194     TRACE(driver,"('%s', '%s', %08lX);\n",
195                     lpDriverName,lpSectionName,lParam );
196
197     if (lpSectionName == NULL) {
198         lstrcpyn32A(DrvName,lpDriverName,sizeof(DrvName));
199         FIXME(driver,"sectionname NULL, assuming directfilename (%s)\n",lpDriverName);
200     } else  {
201         GetPrivateProfileString32A( lpSectionName, lpDriverName, "", DrvName,
202                                  sizeof(DrvName), "system.ini" );
203     }
204     TRACE(driver,"DrvName='%s'\n", DrvName );
205     if (lstrlen32A(DrvName) < 1) return 0;
206
207     lpdrv = lpDrvItemList32;
208     while (lpdrv) {
209         if (!strcasecmp( lpDriverName, lpdrv->dis.szAliasName )) {
210             lpdrv->count++;
211             lpdrv->dis.hDriver = SendDriverMessage32( lpdrv->dis.hDriver, DRV_OPEN, ""/*FIXME*/, 0L );
212             return (HDRVR32)lpdrv;
213         }
214         lpdrv = lpdrv->next;
215     }
216
217     hDrvr = (HDRVR32)HeapAlloc(SystemHeap,0, sizeof(DRIVERITEM32A) );
218     if (!hDrvr) {
219         ERR(driver,"out of memory");
220         return 0;
221     }
222     lpnewdrv = (DRIVERITEM32A*)hDrvr;
223     lpnewdrv->dis.length = sizeof( DRIVERINFOSTRUCT32A );
224     lpnewdrv->dis.hModule = LoadLibrary32A( DrvName );
225     if (!lpnewdrv->dis.hModule) {
226         FIXME(driver,"could not load library %s\n",DrvName);
227         HeapFree( SystemHeap,0,(LPVOID)hDrvr );
228         return 0;
229     }
230     lstrcpy32A( lpnewdrv->dis.szAliasName, lpDriverName );
231     lpnewdrv->count = 1;
232     if (!(lpnewdrv->driverproc = (DRIVERPROC32)GetProcAddress32(lpnewdrv->dis.hModule, "DriverProc" )))
233     {
234         FIXME(driver,"no 'DriverProc' found in %s\n",DrvName);
235         FreeModule32( lpnewdrv->dis.hModule );
236         HeapFree( SystemHeap,0, (LPVOID)hDrvr );
237         return 0;
238     }
239
240     lpnewdrv->next = lpDrvItemList32;
241     lpDrvItemList32 = lpnewdrv;
242
243     SendDriverMessage32( hDrvr, DRV_LOAD, 0L, lParam );
244     SendDriverMessage32( hDrvr, DRV_ENABLE, 0L, lParam );
245     tmpbuf = HeapAlloc(SystemHeap,0,256);
246     lpnewdrv->dis.hDriver=SendDriverMessage32(hDrvr,DRV_OPEN,tmpbuf,lParam);
247     HeapFree(SystemHeap,0,tmpbuf);
248     TRACE(driver, "hDrvr=%04x loaded !\n", hDrvr );
249     return hDrvr;
250 }
251
252 /**************************************************************************
253  *                              OpenDriver                      [WINMM.15]
254  */
255 HDRVR32 WINAPI OpenDriver32W(
256         LPCWSTR lpDriverName, LPCWSTR lpSectionName, LPARAM lParam
257 ) {
258         LPSTR dn = HEAP_strdupWtoA(GetProcessHeap(),0,lpDriverName);
259         LPSTR sn = HEAP_strdupWtoA(GetProcessHeap(),0,lpSectionName);
260         HDRVR32 ret = OpenDriver32A(dn,sn,lParam);
261
262         if (dn) HeapFree(GetProcessHeap(),0,dn);
263         if (sn) HeapFree(GetProcessHeap(),0,sn);
264         return ret;
265 }
266
267 /**************************************************************************
268  *                      CloseDriver                             [USER.253]
269  */
270 LRESULT WINAPI CloseDriver16(HDRVR16 hDrvr, LPARAM lParam1, LPARAM lParam2)
271 {
272     LPDRIVERITEM lpdrv;
273
274     TRACE(driver, "(%04x, %08lX, %08lX);\n",
275                     hDrvr, lParam1, lParam2 );
276
277     lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr );
278     if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr)
279     {
280         SendDriverMessage16( hDrvr, DRV_CLOSE, lParam1, lParam2 );
281         if (--lpdrv->count == 0)
282         {
283             SendDriverMessage16( hDrvr, DRV_DISABLE, lParam1, lParam2 );
284             SendDriverMessage16( hDrvr, DRV_FREE, lParam1, lParam2 );
285
286             if (lpdrv->lpPrevItem)
287               lpdrv->lpPrevItem->lpNextItem = lpdrv->lpNextItem;
288             else
289                 lpDrvItemList = lpdrv->lpNextItem;
290             if (lpdrv->lpNextItem)
291               lpdrv->lpNextItem->lpPrevItem = lpdrv->lpPrevItem;
292
293             FreeModule16( lpdrv->dis.hModule );
294             GlobalUnlock16( hDrvr );
295             GlobalFree16( hDrvr );
296         }
297
298         TRACE(driver, "hDrvr=%04x closed !\n",
299                         hDrvr );
300         return TRUE;
301     }
302     return FALSE;
303 }
304
305 /**************************************************************************
306  *                              GetDriverModuleHandle   [USER.254]
307  */
308 HMODULE16 WINAPI GetDriverModuleHandle16(HDRVR16 hDrvr)
309 {
310     LPDRIVERITEM lpdrv;
311     HMODULE16 hModule = 0;
312
313     TRACE(driver, "(%04x);\n", hDrvr);
314
315     lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr );
316     if (lpdrv != NULL && lpdrv->dis.hDriver == hDrvr)
317     {
318         hModule = lpdrv->dis.hModule;
319         GlobalUnlock16( hDrvr );
320     }
321     return hModule;
322 }
323
324 /**************************************************************************
325  *                              GetDriverModuleHandle   [USER.254]
326  */
327 HMODULE32 WINAPI GetDriverModuleHandle32(HDRVR32 hDrvr)
328 {
329     LPDRIVERITEM32A lpdrv = (LPDRIVERITEM32A)hDrvr;
330
331     TRACE(driver, "(%04x);\n", hDrvr);
332     if (!lpdrv)
333         return 0;
334     return lpdrv->dis.hModule;
335 }
336
337 /**************************************************************************
338  *                              DefDriverProc16                 [USER.255]
339  */
340 LRESULT WINAPI DefDriverProc16(DWORD dwDevID, HDRVR16 hDriv, UINT16 wMsg, 
341                                LPARAM lParam1, LPARAM lParam2)
342 {
343     switch(wMsg)
344     {
345       case DRV_LOAD:
346         return (LRESULT)0L;
347       case DRV_FREE:
348         return (LRESULT)0L;
349       case DRV_OPEN:
350         return (LRESULT)0L;
351       case DRV_CLOSE:
352         return (LRESULT)0L;
353       case DRV_ENABLE:
354         return (LRESULT)0L;
355       case DRV_DISABLE:
356         return (LRESULT)0L;
357       case DRV_QUERYCONFIGURE:
358         return (LRESULT)0L;
359
360       case DRV_CONFIGURE:
361         MessageBox16( 0, "Driver isn't configurable !", "Wine Driver", MB_OK );
362         return (LRESULT)0L;
363
364       case DRV_INSTALL:
365         return (LRESULT)DRVCNF_RESTART;
366
367       case DRV_REMOVE:
368         return (LRESULT)DRVCNF_RESTART;
369
370       default:
371         return (LRESULT)0L;
372     }
373 }
374
375 /**************************************************************************
376  *                              GetDriverInfo                   [USER.256]
377  */
378 BOOL16 WINAPI GetDriverInfo(HDRVR16 hDrvr, LPDRIVERINFOSTRUCT16 lpDrvInfo)
379 {
380     LPDRIVERITEM lpdrv;
381
382     TRACE(driver, "(%04x, %p);\n", hDrvr, lpDrvInfo );
383
384     if (lpDrvInfo == NULL) return FALSE;
385
386     lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr );
387     if (lpdrv == NULL) return FALSE;
388     memcpy( lpDrvInfo, &lpdrv->dis, sizeof(DRIVERINFOSTRUCT16) );
389     GlobalUnlock16( hDrvr );
390
391     return TRUE;
392 }
393
394 /**************************************************************************
395  *                              GetNextDriver                   [USER.257]
396  */
397 HDRVR16 WINAPI GetNextDriver(HDRVR16 hDrvr, DWORD dwFlags)
398 {
399     LPDRIVERITEM lpdrv;
400     HDRVR16 hRetDrv = 0;
401
402     TRACE(driver, "(%04x, %08lX);\n", hDrvr, dwFlags );
403
404     if (hDrvr == 0)
405     {
406         if (lpDrvItemList == NULL)
407         {
408             TRACE(driver, "drivers list empty !\n");
409             LoadStartupDrivers();
410             if (lpDrvItemList == NULL) return 0;
411         }
412         TRACE(driver,"return first %04x !\n",
413                         lpDrvItemList->dis.hDriver );
414         return lpDrvItemList->dis.hDriver;
415     }
416
417     lpdrv = (LPDRIVERITEM)GlobalLock16( hDrvr );
418     if (lpdrv != NULL)
419     {
420         if (dwFlags & GND_REVERSE)
421         {
422             if (lpdrv->lpPrevItem) 
423               hRetDrv = lpdrv->lpPrevItem->dis.hDriver;
424         }
425         else
426         {
427             if (lpdrv->lpNextItem) 
428               hRetDrv = lpdrv->lpNextItem->dis.hDriver;
429         }
430         GlobalUnlock16( hDrvr );
431     }
432
433     TRACE(driver, "return %04x !\n", hRetDrv );
434     return hRetDrv;
435 }