ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/BasiliskII/src/Windows/b2ether/packet32.cpp
Revision: 1.3
Committed: 2008-01-01T09:40:34Z (16 years, 11 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# User Rev Content
1 gbeauche 1.1 /*
2     * packet32.cpp
3     *
4 gbeauche 1.3 * Basilisk II (C) 1997-2008 Christian Bauer
5 gbeauche 1.1 *
6     * Windows platform specific code copyright (C) Lauri Pesonen
7     *
8     * This program is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License as published by
10     * the Free Software Foundation; either version 2 of the License, or
11     * (at your option) any later version.
12     *
13     * This program is distributed in the hope that it will be useful,
14     * but WITHOUT ANY WARRANTY; without even the implied warranty of
15     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16     * GNU General Public License for more details.
17     *
18     * You should have received a copy of the GNU General Public License
19     * along with this program; if not, write to the Free Software
20     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21     */
22    
23     #include "sysdeps.h"
24     #include <windows.h>
25     #include <windowsx.h>
26     #include <winioctl.h>
27     #include "cpu_emulation.h"
28     typedef unsigned long ULONG_PTR, *PULONG_PTR;
29    
30     // VC6 does not have this, Platform SDK has.
31     // In case of errors, try to comment out, the needed
32     // definitions are below (#ifndef _NTDDNDIS_)
33    
34     // Most people don't have the Platform SDK, so I take this one out.
35     // #include <ntddndis.h>
36    
37 gbeauche 1.2 #include "inc/ntddpack.h"
38 gbeauche 1.1
39     #include "ether.h"
40     #include "ether_defs.h"
41 gbeauche 1.2 #include "b2ether/multiopt.h"
42     #include "b2ether/inc/b2ether_hl.h"
43 gbeauche 1.1
44    
45    
46     #ifndef _NTDDNDIS_
47     #define NDIS_PACKET_TYPE_DIRECTED 0x00000001
48     #define NDIS_PACKET_TYPE_MULTICAST 0x00000002
49     #define NDIS_PACKET_TYPE_ALL_MULTICAST 0x00000004
50     #define NDIS_PACKET_TYPE_BROADCAST 0x00000008
51     #define NDIS_PACKET_TYPE_SOURCE_ROUTING 0x00000010
52     #define NDIS_PACKET_TYPE_PROMISCUOUS 0x00000020
53    
54     #define OID_802_3_PERMANENT_ADDRESS 0x01010101
55     #define OID_802_3_CURRENT_ADDRESS 0x01010102
56     #define OID_802_3_MULTICAST_LIST 0x01010103
57    
58     #define OID_GEN_CURRENT_PACKET_FILTER 0x0001010E
59     #endif
60    
61     #define DEBUG_PACKETS 0
62     #define DEBUG 0
63     #include "debug.h"
64    
65     #ifdef __cplusplus
66     extern "C" {
67     #endif
68    
69     #if DEBUG
70     #pragma optimize("",off)
71     #endif
72    
73     #define MAX_MULTICAST 100
74     #define MAX_MULTICAST_SZ (20*ETH_802_3_ADDRESS_LENGTH)
75    
76     static int os = VER_PLATFORM_WIN32_WINDOWS;
77    
78     static ULONG packet_filter = 0;
79    
80    
81     LPADAPTER PacketOpenAdapter( LPCSTR AdapterName, int16 mode )
82     {
83     LPADAPTER lpAdapter;
84     BOOLEAN Result = TRUE;
85     OSVERSIONINFO osv;
86    
87     D(bug("Packet32: PacketOpenAdapter\n"));
88    
89     osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
90     if(GetVersionEx( &osv )) os = osv.dwPlatformId;
91    
92     if(os == VER_PLATFORM_WIN32_NT) {
93     // May fail if user is not an Administrator.
94     StartPacketDriver( "B2ether" );
95     }
96    
97     lpAdapter = (LPADAPTER)GlobalAllocPtr( GMEM_MOVEABLE|GMEM_ZEROINIT, sizeof(ADAPTER) );
98     if (lpAdapter==NULL) {
99     D(bug("Packet32: PacketOpenAdapter GlobalAlloc Failed\n"));
100     return NULL;
101     }
102    
103     if(os == VER_PLATFORM_WIN32_NT) {
104     char device_name[256];
105     wsprintf( lpAdapter->SymbolicLink, "\\\\.\\B2ether_%s", AdapterName );
106     wsprintf( device_name, "\\Device\\B2ether_%s", AdapterName );
107    
108     // Work around one subtle NT4 bug.
109     DefineDosDevice(
110     DDD_REMOVE_DEFINITION,
111     &lpAdapter->SymbolicLink[4],
112     NULL
113     );
114     DefineDosDevice(
115     DDD_RAW_TARGET_PATH,
116     &lpAdapter->SymbolicLink[4],
117     device_name
118     );
119     } else {
120     wsprintf( lpAdapter->SymbolicLink, "\\\\.\\B2ether" );
121     }
122    
123     packet_filter = NDIS_PACKET_TYPE_DIRECTED |
124     NDIS_PACKET_TYPE_MULTICAST |
125     NDIS_PACKET_TYPE_BROADCAST;
126    
127     if(mode == ETHER_MULTICAST_ALL) packet_filter |= NDIS_PACKET_TYPE_ALL_MULTICAST;
128     if(mode == ETHER_MULTICAST_PROMISCUOUS) packet_filter |= NDIS_PACKET_TYPE_PROMISCUOUS;
129    
130     if (Result) {
131     lpAdapter->hFile = CreateFile(lpAdapter->SymbolicLink,
132     GENERIC_WRITE | GENERIC_READ,
133     0,
134     NULL,
135     // (os == VER_PLATFORM_WIN32_NT) ? CREATE_ALWAYS : OPEN_EXISTING,
136     OPEN_EXISTING,
137     FILE_FLAG_OVERLAPPED,
138     0
139     );
140     if (lpAdapter->hFile != INVALID_HANDLE_VALUE) {
141     if(*AdapterName && strcmp(AdapterName,"<None>") != 0) {
142     if(os == VER_PLATFORM_WIN32_WINDOWS) {
143     PacketSelectAdapterByName( lpAdapter, AdapterName );
144     }
145     PacketSetFilter( lpAdapter, packet_filter );
146     }
147     return lpAdapter;
148     }
149     }
150     D(bug("Packet32: PacketOpenAdapter Could not open adapter\n"));
151     GlobalFreePtr( lpAdapter );
152     return NULL;
153     }
154    
155     VOID PacketCloseAdapter( LPADAPTER lpAdapter )
156     {
157     D(bug("Packet32: PacketCloseAdapter\n"));
158    
159     if(lpAdapter) {
160     if(lpAdapter->hFile) {
161     CloseHandle(lpAdapter->hFile);
162     }
163     GlobalFreePtr(lpAdapter);
164     }
165     }
166    
167     LPPACKET PacketAllocatePacket( LPADAPTER AdapterObject, UINT Length )
168     {
169     LPPACKET lpPacket;
170    
171     lpPacket = (LPPACKET)GlobalAllocPtr( GMEM_MOVEABLE|GMEM_ZEROINIT, sizeof(PACKET) );
172     if(lpPacket==NULL) {
173     D(bug("Packet32: PacketAllocatePacket: GlobalAlloc Failed\n"));
174     return NULL;
175     }
176    
177     lpPacket->OverLapped.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
178     if(!lpPacket->OverLapped.hEvent) {
179     D(bug("Packet32: PacketAllocatePacket: CreateEvent Failed\n"));
180     GlobalFreePtr(lpPacket);
181     return NULL;
182     }
183    
184     lpPacket->Buffer = GlobalAllocPtr(GMEM_MOVEABLE,2048); // 1514
185     if(!lpPacket->Buffer) {
186     D(bug("Packet32: PacketAllocatePacket: GlobalAllocPtr Failed\n"));
187     if(lpPacket->OverLapped.hEvent) CloseHandle(lpPacket->OverLapped.hEvent);
188     GlobalFreePtr(lpPacket);
189     return NULL;
190     }
191    
192     lpPacket->OverLapped.Offset = 0;
193     lpPacket->OverLapped.OffsetHigh = 0;
194     lpPacket->Length = Length;
195     lpPacket->BytesReceived = 0;
196     lpPacket->bIoComplete = FALSE;
197     lpPacket->free = TRUE;
198    
199     return lpPacket;
200     }
201    
202     VOID PacketFreePacket( LPPACKET lpPacket )
203     {
204     if(lpPacket) {
205     if(lpPacket->Buffer) GlobalFreePtr(lpPacket->Buffer);
206     if(lpPacket->OverLapped.hEvent) CloseHandle(lpPacket->OverLapped.hEvent);
207     GlobalFreePtr(lpPacket);
208     }
209     }
210    
211     BOOLEAN PacketDeviceIoControl(
212     LPADAPTER lpAdapterObject,
213     LPPACKET lpPacket,
214     ULONG ulIoctl,
215     BOOLEAN bSync
216     )
217     {
218     BOOLEAN Result;
219    
220     lpPacket->OverLapped.Offset = 0;
221     lpPacket->OverLapped.OffsetHigh = 0;
222     lpPacket->BytesReceived = 0;
223    
224     if ( !ResetEvent( lpPacket->OverLapped.hEvent ) ) {
225     lpPacket->bIoComplete = FALSE;
226     D(bug( "Packet32: PacketDeviceIoControl failed to reset event\r\n", GetLastError() ));
227     return FALSE;
228     }
229    
230     Result = DeviceIoControl(
231     lpAdapterObject->hFile,
232     ulIoctl,
233     lpPacket->Buffer,
234     lpPacket->Length,
235     lpPacket->Buffer,
236     lpPacket->Length,
237     &(lpPacket->BytesReceived),
238     &(lpPacket->OverLapped) );
239    
240     if( !Result && bSync ) {
241     if (GetLastError() == ERROR_IO_PENDING) {
242     Result = GetOverlappedResult( lpAdapterObject->hFile,
243     &(lpPacket->OverLapped),
244     &(lpPacket->BytesReceived),
245     TRUE );
246     } else {
247     D(bug( "Packet32: unsupported API call returned error 0x%x\r\n", GetLastError() ));
248     }
249     }
250     lpPacket->bIoComplete = Result;
251     return Result;
252     }
253    
254     VOID CALLBACK PacketSendCompletionRoutine(
255     DWORD dwErrorCode,
256     DWORD dwNumberOfBytesTransfered,
257     LPOVERLAPPED lpOverlapped
258     )
259     {
260     LPPACKET lpPacket = CONTAINING_RECORD(lpOverlapped,PACKET,OverLapped);
261    
262     #if DEBUG_PACKETS
263     D(bug("PacketSendCompletionRoutine %d\n",dwNumberOfBytesTransfered));
264     #endif
265    
266     lpPacket->bIoComplete = TRUE;
267     // lpPacket->free = TRUE;
268     // PacketFreePacket(lpPacket);
269     recycle_write_packet(lpPacket);
270     }
271    
272     BOOLEAN PacketSendPacket(
273     LPADAPTER AdapterObject,
274     LPPACKET lpPacket,
275     BOOLEAN Sync,
276     BOOLEAN RecyclingAllowed
277     )
278     {
279     BOOLEAN Result;
280    
281     #if DEBUG_PACKETS
282     D(bug("Packet32: PacketSendPacket bytes=%d, sync=%d\n",lpPacket->Length,Sync));
283     #endif
284    
285     if(os == VER_PLATFORM_WIN32_NT) {
286     lpPacket->OverLapped.Offset = 0;
287     lpPacket->OverLapped.OffsetHigh = 0;
288     lpPacket->bIoComplete = FALSE;
289    
290     if(Sync) {
291     Result = WriteFile(
292     AdapterObject->hFile,
293     lpPacket->Buffer,
294     lpPacket->Length,
295     &lpPacket->BytesReceived,
296     &lpPacket->OverLapped
297     );
298     if(Result) {
299     Result = GetOverlappedResult(
300     AdapterObject->hFile,
301     &lpPacket->OverLapped,
302     &lpPacket->BytesReceived,
303     TRUE
304     );
305     } else {
306     D(bug("Packet32: PacketSendPacket WriteFile failed, err=%d\n",(int)GetLastError()));
307     }
308     lpPacket->bIoComplete = TRUE;
309     if(RecyclingAllowed) PacketFreePacket(lpPacket);
310     #if DEBUG_PACKETS
311     D(bug("Packet32: PacketSendPacket result=%d, bytes=%d\n",(int)Result,(int)lpPacket->BytesReceived));
312     #endif
313     } else {
314     // don't care about the result
315     Result = WriteFileEx(
316     AdapterObject->hFile,
317     lpPacket->Buffer,
318     lpPacket->Length,
319     &lpPacket->OverLapped,
320     PacketSendCompletionRoutine
321     );
322     #if DEBUG_PACKETS
323     D(bug("Packet32: PacketSendPacket result=%d\n",(int)Result));
324     #endif
325     if(!Result && RecyclingAllowed) {
326     recycle_write_packet(lpPacket);
327     }
328     }
329     } else {
330     // Now: make writes always synchronous under Win9x
331     Sync = TRUE;
332     Result = PacketDeviceIoControl( AdapterObject,
333     lpPacket,
334     IOCTL_PROTOCOL_WRITE,
335     Sync );
336     if(RecyclingAllowed) recycle_write_packet(lpPacket);
337     }
338    
339     return Result;
340     }
341    
342     BOOLEAN PacketReceivePacket(
343     LPADAPTER AdapterObject,
344     LPPACKET lpPacket,
345     BOOLEAN Sync
346     )
347     {
348     BOOLEAN Result;
349    
350     if(os == VER_PLATFORM_WIN32_NT) {
351     lpPacket->OverLapped.Offset=0;
352     lpPacket->OverLapped.OffsetHigh=0;
353     lpPacket->bIoComplete = FALSE;
354    
355     #if DEBUG_PACKETS
356     D(bug("Packet32: PacketReceivePacket\n"));
357     #endif
358    
359     if (Sync) {
360     Result = ReadFile(
361     AdapterObject->hFile,
362     lpPacket->Buffer,
363     lpPacket->Length,
364     &lpPacket->BytesReceived,
365     &lpPacket->OverLapped
366     );
367     if(Result) {
368     Result = GetOverlappedResult(
369     AdapterObject->hFile,
370     &lpPacket->OverLapped,
371     &lpPacket->BytesReceived,
372     TRUE
373     );
374     if(Result)
375     lpPacket->bIoComplete = TRUE;
376     else
377     lpPacket->free = TRUE;
378     }
379     } else {
380     Result = ReadFileEx(
381     AdapterObject->hFile,
382     lpPacket->Buffer,
383     lpPacket->Length,
384     &lpPacket->OverLapped,
385     packet_read_completion
386     );
387     }
388    
389     if(!Result) lpPacket->BytesReceived = 0;
390     } else {
391     Result = PacketDeviceIoControl( AdapterObject,
392     lpPacket,
393     IOCTL_PROTOCOL_READ,
394     Sync );
395     if( !Result && !Sync ) {
396     if (GetLastError() == ERROR_IO_PENDING) {
397     Result = TRUE;
398     }
399     }
400     }
401    
402     #if DEBUG_PACKETS
403     D(bug("Packet32: PacketReceivePacket got %d bytes, result=%d\n",lpPacket->BytesReceived,(int)Result));
404     #endif
405    
406     return Result;
407     }
408    
409     BOOLEAN PacketRequest(
410     LPADAPTER lpAdapterObject,
411     LPPACKET lpPacket,
412     BOOLEAN bSet
413     )
414     {
415     BOOLEAN Result = FALSE;
416    
417     Result = PacketDeviceIoControl(
418     lpAdapterObject,
419     lpPacket,
420     (ULONG) ((bSet) ? IOCTL_PROTOCOL_SET_OID : IOCTL_PROTOCOL_QUERY_OID),
421     TRUE );
422    
423     if ( lpPacket->BytesReceived == 0 ) {
424     D(bug( "Packet32: Ndis returned error to OID\r\n"));
425     Result = FALSE;
426     }
427     return Result;
428     }
429    
430     LPPACKET PacketQueryOid(
431     LPADAPTER lpAdapter,
432     ULONG ulOid,
433     ULONG ulLength
434     )
435     {
436     ULONG ioctl;
437     LPPACKET lpPacket;
438    
439     #define pOidData ((PPACKET_OID_DATA)(lpPacket->Buffer))
440    
441     lpPacket = PacketAllocatePacket( lpAdapter, sizeof(PACKET_OID_DATA)-1+ulLength );
442    
443     if( lpPacket ) {
444     ioctl = IOCTL_PROTOCOL_QUERY_OID;
445     pOidData->Oid = ulOid;
446     pOidData->Length = ulLength;
447    
448     if (PacketRequest( lpAdapter, lpPacket, FALSE )) {
449     return lpPacket;
450     }
451     PacketFreePacket( lpPacket );
452     }
453    
454     #undef pOidData
455    
456     return 0;
457     }
458    
459     BOOLEAN PacketGetMAC( LPADAPTER AdapterObject, LPBYTE address, BOOL permanent )
460     {
461     BOOLEAN Status;
462     LPPACKET lpPacket;
463    
464     lpPacket = PacketQueryOid(
465     AdapterObject,
466     permanent ? OID_802_3_PERMANENT_ADDRESS : OID_802_3_CURRENT_ADDRESS,
467     ETH_802_3_ADDRESS_LENGTH
468     );
469     if(lpPacket) {
470     memcpy( address,
471     ((BYTE *)(lpPacket->Buffer)) + sizeof(PACKET_OID_DATA) - 1,
472     ETH_802_3_ADDRESS_LENGTH );
473     PacketFreePacket( lpPacket );
474     Status = TRUE;
475     } else {
476     Status = FALSE;
477     }
478    
479     return Status;
480     }
481    
482     // There are other ways to do this.
483    
484     BOOLEAN PacketAddMulticast( LPADAPTER AdapterObject, LPBYTE address )
485     {
486     BOOLEAN Status = FALSE;
487     LPBYTE p;
488     int i, count;
489     LPPACKET lpPacket;
490    
491     D(bug("PacketAddMulticast\n"));
492    
493     /*
494     if(packet_filter & (NDIS_PACKET_TYPE_ALL_MULTICAST|NDIS_PACKET_TYPE_PROMISCUOUS)) {
495     D(bug("PacketAddMulticast: already listening for all multicast\n"));
496     return TRUE;
497     }
498     */
499    
500     lpPacket = PacketQueryOid( AdapterObject, OID_802_3_MULTICAST_LIST, MAX_MULTICAST_SZ );
501     #define OidData ((PPACKET_OID_DATA)(lpPacket->Buffer))
502    
503     if(lpPacket) {
504     count = OidData->Length / ETH_802_3_ADDRESS_LENGTH;
505    
506     D(bug("PacketAddMulticast: %d old addresses\n",count));
507    
508     p = (LPBYTE)OidData->Data;
509    
510     for( i=0; i<count; i++ ) {
511     if(memcmp(p,address,ETH_802_3_ADDRESS_LENGTH) == 0) {
512     // This multicast is already defined -- error or not?
513     Status = TRUE;
514     D(bug("PacketAddMulticast: address already defined\n"));
515     break;
516     }
517     p += ETH_802_3_ADDRESS_LENGTH;
518     }
519     if(i == count) {
520     if(i >= MAX_MULTICAST) {
521     D(bug("PacketAddMulticast: too many addresses\n"));
522     Status = FALSE;
523     } else {
524     D(bug("PacketAddMulticast: adding a new address\n"));
525    
526     // ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA)+ETH_802_3_ADDRESS_LENGTH*1-1);
527     ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA)+ETH_802_3_ADDRESS_LENGTH*(count+1)-1);
528    
529     LPPACKET lpPacket2 = PacketAllocatePacket( AdapterObject, IoCtlBufferLength );
530     #define OidData2 ((PPACKET_OID_DATA)(lpPacket2->Buffer))
531     if ( lpPacket2 ) {
532     OidData2->Oid = OID_802_3_MULTICAST_LIST;
533    
534     // OidData2->Length = ETH_802_3_ADDRESS_LENGTH*1;
535     // memcpy( OidData2->Data, address, ETH_802_3_ADDRESS_LENGTH );
536    
537     memcpy( OidData2->Data, OidData->Data, ETH_802_3_ADDRESS_LENGTH*count );
538     memcpy( OidData2->Data+ETH_802_3_ADDRESS_LENGTH*count, address, ETH_802_3_ADDRESS_LENGTH );
539     OidData2->Length = ETH_802_3_ADDRESS_LENGTH*(count+1);
540    
541     Status = PacketRequest( AdapterObject, lpPacket2, TRUE );
542     PacketFreePacket( lpPacket2 );
543     }
544     #undef OidData2
545     }
546     }
547     PacketFreePacket( lpPacket );
548     }
549    
550     #undef OidData
551    
552     // return Status;
553     return TRUE;
554     }
555    
556     // It seems that the last multicast address is never deleted. Why?
557     // Don't know the reason, but luckily this is not fatal.
558     // Hard to examine return codes. See NE2000 sources, always returns ok.
559    
560     BOOLEAN PacketDelMulticast( LPADAPTER AdapterObject, LPBYTE address )
561     {
562     BOOLEAN Status = FALSE;
563     LPBYTE p;
564     int i, count;
565     LPPACKET lpPacket, lpPacket2;
566    
567     D(bug("PacketDelMulticast\n"));
568    
569     if(packet_filter & (NDIS_PACKET_TYPE_ALL_MULTICAST|NDIS_PACKET_TYPE_PROMISCUOUS)) {
570     D(bug("PacketDelMulticast: already listening for all multicast\n"));
571     return TRUE;
572     }
573    
574     lpPacket = PacketQueryOid( AdapterObject, OID_802_3_MULTICAST_LIST, MAX_MULTICAST_SZ );
575     #define OidData ((PPACKET_OID_DATA)(lpPacket->Buffer))
576    
577     if(lpPacket) {
578     count = OidData->Length / ETH_802_3_ADDRESS_LENGTH;
579    
580     D(bug("PacketDelMulticast: %d old addresses\n",count));
581    
582     Status = FALSE;
583    
584     p = (LPBYTE)OidData->Data;
585    
586     for( i=0; i<count; i++ ) {
587     int tail_len;
588     if(memcmp(p,address,ETH_802_3_ADDRESS_LENGTH) == 0) {
589     D(bug("PacketDelMulticast: address found, deleting\n"));
590     ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA)+ETH_802_3_ADDRESS_LENGTH*(count-1)-1);
591     lpPacket2 = PacketAllocatePacket( AdapterObject, IoCtlBufferLength );
592     #define OidData2 ((PPACKET_OID_DATA)(lpPacket2->Buffer))
593     if ( lpPacket2 ) {
594     OidData2->Oid = OID_802_3_MULTICAST_LIST;
595     OidData2->Length = ETH_802_3_ADDRESS_LENGTH*(count-1);
596     tail_len = ETH_802_3_ADDRESS_LENGTH * (count-i-1);
597     if(tail_len) memmove( p, p+ETH_802_3_ADDRESS_LENGTH, tail_len );
598     if(OidData2->Length) memcpy( OidData2->Data, OidData->Data, OidData2->Length );
599     if(count == 1) memset( OidData2->Data, 0, ETH_802_3_ADDRESS_LENGTH ); // eh...
600     Status = PacketRequest( AdapterObject, lpPacket2, TRUE );
601     PacketFreePacket( lpPacket2 );
602     D(bug("PacketDelMulticast: PacketRequest returned status 0x%X, last error = 0x%X\n",Status,GetLastError()));
603     }
604     break;
605     #undef OidData2
606     }
607     p += ETH_802_3_ADDRESS_LENGTH;
608     }
609     if( i == count ) {
610     D(bug("PacketDelMulticast: cannot delete, was not defined\n"));
611     }
612     PacketFreePacket( lpPacket );
613     #undef OidData
614     }
615    
616     // return Status;
617     return TRUE;
618     }
619    
620     BOOLEAN PacketSetFilter( LPADAPTER AdapterObject, ULONG Filter )
621     {
622     BOOLEAN Status;
623     ULONG IoCtlBufferLength = (sizeof(PACKET_OID_DATA)+sizeof(ULONG)-1);
624     LPPACKET lpPacket;
625    
626     lpPacket = PacketAllocatePacket( AdapterObject, IoCtlBufferLength );
627     #define lpOidData ((PPACKET_OID_DATA)(lpPacket->Buffer))
628    
629     if ( lpPacket ) {
630     lpOidData->Oid = OID_GEN_CURRENT_PACKET_FILTER;
631     lpOidData->Length = sizeof(ULONG);
632     *((PULONG)lpOidData->Data) = Filter;
633     Status = PacketRequest( AdapterObject, lpPacket, TRUE );
634     PacketFreePacket( lpPacket );
635     } else {
636     Status = FALSE;
637     }
638    
639     #undef lpOidData
640    
641     return Status;
642     }
643    
644     BOOLEAN StartPacketDriver( LPTSTR ServiceName )
645     {
646     BOOLEAN Status = FALSE;
647    
648     SC_HANDLE SCManagerHandle;
649     SC_HANDLE SCServiceHandle;
650    
651     SCManagerHandle = OpenSCManager(
652     NULL,
653     NULL,
654     SC_MANAGER_ALL_ACCESS);
655    
656     if(SCManagerHandle == NULL) {
657     D(bug("Could not open Service Control Manager\r\n"));
658     } else {
659     SCServiceHandle = OpenService(SCManagerHandle,ServiceName,SERVICE_START);
660     if (SCServiceHandle == NULL) {
661     D(bug("Could not open service %s\r\n",ServiceName));
662     } else {
663     Status = StartService( SCServiceHandle, 0, NULL );
664     if(!Status) {
665     if (GetLastError()==ERROR_SERVICE_ALREADY_RUNNING) {
666     Status = TRUE;
667     }
668     }
669     BOOL waiting = TRUE;
670     // loop until the service is fully started.
671     while (waiting) {
672     SERVICE_STATUS ServiceStatus;
673     if (QueryServiceStatus(SCServiceHandle, &ServiceStatus)) {
674     switch(ServiceStatus.dwCurrentState) {
675     case SERVICE_RUNNING:
676     waiting = FALSE;
677     Status = TRUE;
678     break;
679     case SERVICE_START_PENDING:
680     Sleep(500);
681     break;
682     default:
683     waiting = FALSE;
684     break;
685     }
686     } else {
687     waiting = FALSE;
688     }
689     }
690     CloseServiceHandle(SCServiceHandle);
691     }
692     CloseServiceHandle(SCManagerHandle);
693     }
694     return Status;
695     }
696    
697     ULONG PacketGetAdapterNames( LPADAPTER lpAdapter, PTSTR pStr, PULONG BufferSize )
698     {
699     LONG Status;
700    
701     if(os == VER_PLATFORM_WIN32_NT) {
702     HKEY hKey;
703     DWORD RegType;
704    
705     Status = RegOpenKey(
706     HKEY_LOCAL_MACHINE,
707     "SYSTEM\\CurrentControlSet\\Services\\B2Ether\\Linkage",
708     &hKey
709     );
710     if( Status == ERROR_SUCCESS ) {
711     Status = RegQueryValueEx(
712     hKey,
713     "Export",
714     NULL,
715     &RegType,
716     (LPBYTE)pStr,
717     BufferSize
718     );
719     RegCloseKey(hKey);
720     }
721     } else {
722     if (lpAdapter && lpAdapter->hFile != INVALID_HANDLE_VALUE) {
723     LPPACKET Packet = PacketAllocatePacket( lpAdapter, *BufferSize );
724     if(Packet) {
725     memset( pStr, 0, *BufferSize );
726     Packet->Buffer = (PVOID)pStr;
727     Packet->Length = *BufferSize;
728     Status = PacketDeviceIoControl(
729     lpAdapter,
730     Packet,
731     (ULONG)IOCTL_PROTOCOL_MACNAME,
732     TRUE
733     );
734     if(Status) {
735     while(*pStr) {
736     if(*pStr == '|' || *pStr == ' ') *pStr = 0;
737     pStr++;
738     }
739     *(++pStr) = 0;
740     Status = ERROR_SUCCESS;
741     } else {
742     Status = ERROR_ACCESS_DENIED;
743     }
744     *BufferSize = Packet->BytesReceived;
745     PacketFreePacket(Packet);
746     }
747     }
748     }
749    
750     return Status;
751     }
752    
753    
754     ULONG PacketSelectAdapterByName( LPADAPTER lpAdapter, LPCSTR name )
755     {
756     ULONG Status = 0;
757    
758     if(os == VER_PLATFORM_WIN32_WINDOWS) {
759     int len = strlen(name) + 1;
760     LPPACKET Packet = PacketAllocatePacket( lpAdapter, len );
761     if(Packet) {
762     Packet->Buffer = (PVOID)name;
763     Packet->Length = len;
764     Status = PacketDeviceIoControl(
765     lpAdapter,
766     Packet,
767     (ULONG)IOCTL_PROTOCOL_SELECT_BY_NAME,
768     TRUE
769     );
770     if(Status) {
771     Status = ERROR_SUCCESS;
772     } else {
773     Status = ERROR_ACCESS_DENIED;
774     }
775     PacketFreePacket(Packet);
776     }
777     }
778     return Status;
779     }
780    
781    
782     #ifdef __cplusplus
783     }
784     #endif
785    
786     #if DEBUG
787     #pragma optimize("",on)
788     #endif