Implement ResetDC and PHYSICALOFFSET[X|Y] devcaps.
[wine] / dlls / netapi32 / netapi32.c
1 /*              
2  * Copyright 2001 Mike McCormack
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19 #include "config.h"
20
21 #include <string.h>
22 #include <stdio.h>
23 #include <fcntl.h>
24 #include <unistd.h>
25
26 #include "winbase.h"
27 #include "winreg.h"
28 #include "wingdi.h"
29 #include "winuser.h"
30 #include "wine/debug.h"
31 #include "winerror.h"
32 #include "nb30.h"
33
34 #ifdef HAVE_SYS_FILE_H
35 # include <sys/file.h>
36 #endif
37 #include <sys/ioctl.h>
38 #ifdef HAVE_SYS_SOCKET_H
39 # include <sys/socket.h>
40 #endif
41 #ifdef HAVE_SYS_SOCKIO_H
42 # include <sys/sockio.h>
43 #endif
44 #ifdef HAVE_NET_IF_H
45 # include <net/if.h>
46 #endif
47 #ifdef HAVE_NETINET_IN_H
48 # include <netinet/in.h>
49 #endif
50
51 #ifdef HAVE_SOCKADDR_SA_LEN
52 #  ifndef max
53 #   define max(a,b) ((a) > (b) ? (a) : (b))
54 #  endif
55 #  define ifreq_size(i) max(sizeof(struct ifreq),\
56 sizeof((i).ifr_name)+(i).ifr_addr.sa_len)
57 # else
58 #  define ifreq_size(i) sizeof(struct ifreq)
59 # endif /* defined(HAVE_SOCKADDR_SA_LEN) */
60
61 WINE_DEFAULT_DEBUG_CHANNEL(netbios);
62
63 HMODULE NETAPI32_hModule = 0;
64
65 struct NetBiosAdapter
66 {
67     int valid;
68     unsigned char address[6];
69 };
70
71 static struct NetBiosAdapter NETBIOS_Adapter[MAX_LANA];
72
73 # ifdef SIOCGIFHWADDR
74 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
75 {
76     if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0)
77         return -1;
78     memcpy(address, (unsigned char *)&ifr->ifr_hwaddr.sa_data, 6);
79     return 0;
80 }
81 # else
82 #  ifdef SIOCGENADDR
83 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
84 {
85     if (ioctl(sd, SIOCGENADDR, ifr) < 0)
86         return -1;
87     memcpy(address, (unsigned char *) ifr->ifr_enaddr, 6);
88     return 0;
89 }
90 #   else
91 int get_hw_address(int sd, struct ifreq *ifr, unsigned char *address)
92 {
93     return -1;
94 }
95 #  endif /* SIOCGENADDR */
96 # endif /* SIOCGIFHWADDR */
97
98 static UCHAR NETBIOS_Enum(PNCB ncb)
99 {
100 #ifdef HAVE_NET_IF_H
101     int             sd;
102     struct ifreq    ifr, *ifrp;
103     struct ifconf   ifc;
104     unsigned char   buf[1024];
105     int             i, ofs;
106 #endif
107     LANA_ENUM *lanas = (PLANA_ENUM) ncb->ncb_buffer;
108
109     TRACE("NCBENUM\n");
110
111     lanas->length = 0;
112
113 #ifdef HAVE_NET_IF_H
114     /* BSD 4.4 defines the size of an ifreq to be
115      * max(sizeof(ifreq), sizeof(ifreq.ifr_name)+ifreq.ifr_addr.sa_len
116      * However, under earlier systems, sa_len isn't present, so
117      *  the size is just sizeof(struct ifreq)
118      */
119
120     sd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
121     if (sd < 0)
122         return NRC_OPENERROR;
123
124     memset(buf, 0, sizeof(buf));
125     ifc.ifc_len = sizeof(buf);
126     ifc.ifc_buf = buf;
127     /* get the ifconf interface */
128     if (ioctl (sd, SIOCGIFCONF, (char *)&ifc) < 0)
129     {
130         close(sd);
131         return NRC_OPENERROR;
132     }
133
134     /* loop through the interfaces, looking for a valid one */
135     /* n = ifc.ifc_len; */
136     ofs = 0;
137     for (i = 0; i < ifc.ifc_len; i++)
138     {
139         unsigned char *a = NETBIOS_Adapter[i].address;
140
141         ifrp = (struct ifreq *)((char *)ifc.ifc_buf+ofs);
142         strncpy(ifr.ifr_name, ifrp->ifr_name, IFNAMSIZ);
143
144         /* try to get the address for this interface */
145         if(get_hw_address(sd, &ifr, a)==0)
146         {
147             /* make sure it's not blank */
148             /* if (!a[0] && !a[1] && !a[2] && !a[3] && !a[4] && !a[5])
149                 continue; */
150
151             TRACE("Found valid adapter %d at %02x:%02x:%02x:%02x:%02x:%02x\n", i,
152                         a[0],a[1],a[2],a[3],a[4],a[5]);
153
154             NETBIOS_Adapter[i].valid = TRUE;
155             lanas->lana[lanas->length] = i;
156             lanas->length++;
157         }
158         ofs += ifreq_size(ifr);
159     }
160     close(sd);
161 #endif /* HAVE_NET_IF_H */
162     return NRC_GOODRET;
163 }
164
165
166 static UCHAR NETBIOS_Astat(PNCB ncb)
167 {
168     struct NetBiosAdapter *nad = &NETBIOS_Adapter[ncb->ncb_lana_num];
169     PADAPTER_STATUS astat = (PADAPTER_STATUS) ncb->ncb_buffer;
170
171     TRACE("NCBASTAT (Adapter %d)\n", ncb->ncb_lana_num);
172
173     if(!nad->valid)
174         return NRC_INVADDRESS;
175
176     memset(astat, 0, sizeof astat);
177     memcpy(astat->adapter_address, nad->address, sizeof astat->adapter_address);
178
179     return NRC_GOODRET;
180 }
181
182 BOOL WINAPI
183 NETAPI32_LibMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
184 {
185     TRACE("%x,%lx,%p\n", hinstDLL, fdwReason, lpvReserved);
186
187     switch (fdwReason) {
188         case DLL_PROCESS_ATTACH:
189             NETAPI32_hModule = hinstDLL;
190             break;
191         case DLL_PROCESS_DETACH:
192             break;
193     }
194
195     return TRUE;
196 }
197
198 BOOL WINAPI Netbios(PNCB pncb)
199 {
200     UCHAR ret = NRC_ILLCMD; 
201
202     TRACE("ncb = %p\n",pncb);
203
204     if(!pncb)
205         return NRC_INVADDRESS;
206
207     switch(pncb->ncb_command&0x7f)
208     {
209     case NCBRESET:
210         FIXME("NCBRESET adapter %d\n",pncb->ncb_lana_num);
211         if( (pncb->ncb_lana_num < MAX_LANA ) && 
212              NETBIOS_Adapter[pncb->ncb_lana_num].valid)
213             ret = NRC_GOODRET;
214         else
215             ret = NRC_ILLCMD; /* NetBIOS emulator not found */
216         break;
217
218     case NCBADDNAME:
219         FIXME("NCBADDNAME\n");
220         break;
221
222     case NCBADDGRNAME:
223         FIXME("NCBADDGRNAME\n");
224         break;
225
226     case NCBDELNAME:
227         FIXME("NCBDELNAME\n");
228         break;
229
230     case NCBSEND:
231         FIXME("NCBSEND\n");
232         break;
233
234     case NCBRECV:
235         FIXME("NCBRECV\n");
236         break;
237
238     case NCBHANGUP:
239         FIXME("NCBHANGUP\n");
240         break;
241
242     case NCBCANCEL:
243         FIXME("NCBCANCEL\n");
244         break;
245
246     case NCBLISTEN:
247         FIXME("NCBLISTEN\n");
248         break;
249
250     case NCBASTAT:
251         ret = NETBIOS_Astat(pncb);
252         break;
253
254     case NCBENUM:
255         ret = NETBIOS_Enum(pncb);
256         break;
257
258     default:
259         FIXME("(%p): command code %02x\n", pncb, pncb->ncb_command);
260
261         ret = NRC_ILLCMD; /* NetBIOS emulator not found */
262     }
263     pncb->ncb_retcode = ret;
264     return ret;
265 }
266