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, 6 months ago) by gbeauche
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +1 -1 lines
Log Message:
Happy New Year!

File Contents

# Content
1 /*
2 * packet32.cpp
3 *
4 * Basilisk II (C) 1997-2008 Christian Bauer
5 *
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 #include "inc/ntddpack.h"
38
39 #include "ether.h"
40 #include "ether_defs.h"
41 #include "b2ether/multiopt.h"
42 #include "b2ether/inc/b2ether_hl.h"
43
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