~ubuntu-branches/ubuntu/vivid/basilisk2/vivid

« back to all changes in this revision

Viewing changes to src/Windows/b2ether/packet32.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-03-06 19:33:01 UTC
  • mfrom: (2.1.4 gutsy)
  • Revision ID: james.westby@ubuntu.com-20080306193301-cc2ofn705nfsq3y0
Tags: 0.9.20070407-4
* Update copyright-check cdbs snippet to parse licensecheck using perl:
  + No longer randomly drops newlines
  + More compact hint file (and ordered more like wiki-proposed new copyright
    syntax).
  + No longer ignore files without copyright.
* Update copyright_hints.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *  packet32.cpp
 
3
 *
 
4
 *  Basilisk II (C) 1997-1999 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