~ubuntu-branches/ubuntu/hardy/openvpn/hardy-security

« back to all changes in this revision

Viewing changes to tap-win32/tapdrvr.c

  • Committer: Bazaar Package Importer
  • Author(s): Alberto Gonzalez Iniesta
  • Date: 2005-01-05 19:03:11 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050105190311-mvqzpuhmlvobg9nh
Tags: 1.99+2.rc6-1
* The 'Three Wise Men' release.
* New upstream release.
* Update README.Debian with comments on changed string remapping.
  Thanks ron@debian.org for noting this first. (Closes: #288669)

Show diffs side-by-side

added added

removed removed

Lines of Context:
46
46
#define NDIS50 1
47
47
#define NTSTRSAFE_LIB
48
48
 
 
49
// Debug info output
 
50
#define ALSO_DBGPRINT      1
 
51
#define DEBUGP_AT_DISPATCH 0
 
52
 
49
53
#include <ndis.h>
50
54
#include <ntstrsafe.h>
51
55
 
 
56
#include "lock.h"
52
57
#include "constants.h"
53
58
#include "common.h"
54
59
#include "proto.h"
62
67
#include "macinfo.c"
63
68
#include "error.c"
64
69
#include "dhcp.c"
 
70
#include "instance.c"
 
71
 
 
72
#define IS_UP(ta) \
 
73
  ((ta)->m_InterfaceIsRunning && (ta)->m_Extension.m_TapIsRunning)
 
74
 
 
75
#define INCREMENT_STAT(s) ++(s)
 
76
 
 
77
#define NAME_BUFFER_SIZE 80
65
78
 
66
79
//========================================================
67
80
//                            Globals
68
81
//========================================================
69
 
PDRIVER_DISPATCH g_DispatchHook[IRP_MJ_MAXIMUM_FUNCTION + 1];
70
 
NDIS_MINIPORT_CHARACTERISTICS g_Properties;
71
 
PDRIVER_OBJECT g_TapDriverObject = NULL;
72
 
char g_DispatchFunctionsHooked = 0;
 
82
 
73
83
NDIS_HANDLE g_NdisWrapperHandle;
74
 
MACADDR g_MAC = { 0, 0, 0, 0, 0, 0 };
75
 
 
76
 
#define IS_UP(a) \
77
 
  ((a)->m_TapIsRunning && (a)->m_InterfaceIsRunning)
78
 
 
79
 
#define INCREMENT_STAT(s) ++(s)
80
 
 
81
 
UINT g_SupportedOIDList[] = {
 
84
 
 
85
const UINT g_SupportedOIDList[] = {
82
86
  OID_GEN_HARDWARE_STATUS,
83
87
  OID_GEN_MEDIA_SUPPORTED,
84
88
  OID_GEN_MEDIA_IN_USE,
125
129
             IN PUNICODE_STRING p_RegistryPath)
126
130
{
127
131
  NDIS_STATUS l_Status = NDIS_STATUS_FAILURE;
128
 
 
129
 
  //==============================
130
 
  // Allocate debugging text space
131
 
  //==============================
132
 
#if DBG
133
 
  MyDebugInit (10000);
134
 
#endif
 
132
  NDIS_MINIPORT_CHARACTERISTICS *l_Properties = NULL;
135
133
 
136
134
  //========================================================
137
135
  // Notify NDIS that a new miniport driver is initializing.
138
136
  //========================================================
139
137
 
140
138
  NdisMInitializeWrapper (&g_NdisWrapperHandle,
141
 
                          g_TapDriverObject = p_DriverObject,
 
139
                          p_DriverObject,
142
140
                          p_RegistryPath, NULL);
143
141
 
 
142
  //======================
 
143
  // Global initialization
 
144
  //======================
 
145
 
 
146
#if DBG
 
147
  MyDebugInit (10000); // Allocate debugging text space
 
148
#endif
 
149
 
 
150
  if (!InitInstanceList ())
 
151
    {
 
152
      DEBUGP (("[TAP] Allocation failed for adapter instance list\n"));
 
153
      goto cleanup;
 
154
    }
 
155
 
144
156
  //=======================================
145
157
  // Set and register miniport entry points
146
158
  //=======================================
147
159
 
148
 
  NdisZeroMemory (&g_Properties, sizeof (g_Properties));
149
 
 
150
 
  g_Properties.MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
151
 
  g_Properties.MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
152
 
  g_Properties.InitializeHandler = AdapterCreate;
153
 
  g_Properties.HaltHandler = AdapterHalt;
154
 
  g_Properties.ResetHandler = AdapterReset;
155
 
  g_Properties.TransferDataHandler = AdapterReceive;
156
 
  g_Properties.SendHandler = AdapterTransmit;
157
 
  g_Properties.QueryInformationHandler = AdapterQuery;
158
 
  g_Properties.SetInformationHandler = AdapterModify;
159
 
  g_Properties.DisableInterruptHandler = NULL;
160
 
  g_Properties.EnableInterruptHandler = NULL;
161
 
  g_Properties.HandleInterruptHandler = NULL;
162
 
  g_Properties.ISRHandler = NULL;
163
 
  g_Properties.ReconfigureHandler = NULL;
164
 
  g_Properties.CheckForHangHandler = NULL;
165
 
  g_Properties.ReturnPacketHandler = NULL;
166
 
  g_Properties.SendPacketsHandler = NULL;
167
 
  g_Properties.AllocateCompleteHandler = NULL;
168
 
 
169
 
  g_Properties.CoCreateVcHandler = NULL;
170
 
  g_Properties.CoDeleteVcHandler = NULL;
171
 
  g_Properties.CoActivateVcHandler = NULL;
172
 
  g_Properties.CoDeactivateVcHandler = NULL;
173
 
  g_Properties.CoSendPacketsHandler = NULL;
174
 
  g_Properties.CoRequestHandler = NULL;
175
 
 
176
 
#ifndef ENABLE_RANDOM_MAC
177
 
  ConvertMacInfo (g_MAC, TAP_MAC_ROOT_ADDRESS, strlen (TAP_MAC_ROOT_ADDRESS));
178
 
#endif
 
160
  l_Properties = MemAlloc (sizeof (NDIS_MINIPORT_CHARACTERISTICS), TRUE);
 
161
 
 
162
  if (l_Properties == NULL)
 
163
    {
 
164
      DEBUGP (("[TAP] Allocation failed for miniport entry points\n"));
 
165
      goto cleanup;
 
166
    }
 
167
 
 
168
  l_Properties->MajorNdisVersion = TAP_NDIS_MAJOR_VERSION;
 
169
  l_Properties->MinorNdisVersion = TAP_NDIS_MINOR_VERSION;
 
170
  l_Properties->InitializeHandler = AdapterCreate;
 
171
  l_Properties->HaltHandler = AdapterHalt;
 
172
  l_Properties->ResetHandler = AdapterReset;               /* DISPATCH_LEVEL */
 
173
  l_Properties->TransferDataHandler = AdapterReceive;      /* DISPATCH_LEVEL */
 
174
  l_Properties->SendHandler = AdapterTransmit;             /* DISPATCH_LEVEL */
 
175
  l_Properties->QueryInformationHandler = AdapterQuery;    /* DISPATCH_LEVEL */
 
176
  l_Properties->SetInformationHandler = AdapterModify;     /* DISPATCH_LEVEL */
179
177
 
180
178
  switch (l_Status =
181
 
          NdisMRegisterMiniport (g_NdisWrapperHandle, &g_Properties,
182
 
                                 sizeof (g_Properties)))
 
179
          NdisMRegisterMiniport (g_NdisWrapperHandle, l_Properties,
 
180
                                 sizeof (NDIS_MINIPORT_CHARACTERISTICS)))
183
181
    {
184
182
    case NDIS_STATUS_SUCCESS:
185
183
      {
186
 
        DEBUGP (("[TAP] version [%d.%d] registered miniport successfully\n",
187
 
                  TAP_DRIVER_MAJOR_VERSION, TAP_DRIVER_MINOR_VERSION));
 
184
        DEBUGP (("[TAP] version [%d.%d] %s %s registered miniport successfully\n",
 
185
                 TAP_DRIVER_MAJOR_VERSION,
 
186
                 TAP_DRIVER_MINOR_VERSION,
 
187
                 __DATE__,
 
188
                 __TIME__));
 
189
        DEBUGP (("Registry Path: '%S'\n", p_RegistryPath->Buffer));
188
190
        break;
189
191
      }
190
192
 
210
212
        break;
211
213
      }
212
214
 
 
215
    default:
213
216
    case NDIS_STATUS_FAILURE:
214
217
      {
215
218
        DEBUGP (("[TAP] Unknown fatal registration error\n"));
218
221
      }
219
222
    }
220
223
 
221
 
  //==============================================================
222
 
  // Save original NDIS dispatch functions and override with ours
223
 
  //==============================================================
224
 
  HookDispatchFunctions ();
 
224
 cleanup:
 
225
  if (l_Properties)
 
226
    MemFree (l_Properties, sizeof (NDIS_MINIPORT_CHARACTERISTICS));
 
227
 
 
228
  if (l_Status == NDIS_STATUS_SUCCESS)
 
229
    NdisMRegisterUnloadHandler (g_NdisWrapperHandle, TapDriverUnload);
 
230
  else
 
231
    TapDriverUnload (p_DriverObject);
225
232
 
226
233
  return l_Status;
227
234
}
228
235
 
 
236
//============================================================
 
237
//                         Driver Unload
 
238
//============================================================
 
239
VOID 
 
240
TapDriverUnload (IN PDRIVER_OBJECT p_DriverObject)
 
241
{
 
242
  DEBUGP (("[TAP] version [%d.%d] %s %s unloaded, instances=%d, imbs=%d\n",
 
243
           TAP_DRIVER_MAJOR_VERSION,
 
244
           TAP_DRIVER_MINOR_VERSION,
 
245
           __DATE__,
 
246
           __TIME__,
 
247
           NInstances(),
 
248
           InstanceMaxBucketSize()));
 
249
 
 
250
  FreeInstanceList ();
 
251
 
 
252
  //==============================
 
253
  // Free debugging text space
 
254
  //==============================
 
255
#if DBG
 
256
  MyDebugFree ();
 
257
#endif
 
258
}
 
259
 
229
260
//==========================================================
230
261
//                            Adapter Initialization
231
262
//==========================================================
237
268
   IN NDIS_HANDLE p_AdapterHandle,
238
269
   IN NDIS_HANDLE p_ConfigurationHandle)
239
270
{
 
271
  TapAdapterPointer l_Adapter = NULL;
 
272
 
240
273
  NDIS_MEDIUM l_PreferredMedium = NdisMedium802_3; // Ethernet
241
 
  TapAdapterPointer l_Adapter = NULL;
242
 
  ANSI_STRING l_AdapterString;
243
 
#ifndef ENABLE_RANDOM_MAC
244
 
  MACADDR l_MAC;
245
 
#endif
 
274
  BOOLEAN l_MacFromRegistry = FALSE;
246
275
  UINT l_Index;
247
276
  NDIS_STATUS status;
248
277
 
267
296
  // Allocate memory for TapAdapter structure
268
297
  //=========================================
269
298
 
270
 
  status = NdisAllocateMemoryWithTag ((PVOID *) & l_Adapter,
271
 
                                      sizeof (TapAdapter), '1PAT');
 
299
  l_Adapter = MemAlloc (sizeof (TapAdapter), TRUE);
272
300
 
273
 
  if (status != NDIS_STATUS_SUCCESS || l_Adapter == NULL)
 
301
  if (l_Adapter == NULL)
274
302
    {
275
303
      DEBUGP (("[TAP] Couldn't allocate adapter memory\n"));
276
304
      return NDIS_STATUS_RESOURCES;
295
323
  // Initialize simple Adapter parameters
296
324
  //=====================================
297
325
 
298
 
  NdisZeroMemory (l_Adapter, sizeof (TapAdapter));
299
 
 
300
326
  l_Adapter->m_Lookahead = DEFAULT_PACKET_LOOKAHEAD;
301
327
  l_Adapter->m_Medium = l_PreferredMedium;
302
328
  l_Adapter->m_DeviceState = '?';
 
329
  l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;
 
330
 
 
331
  //==================================
 
332
  // Allocate spinlock for controlling
 
333
  // access to multicast address list.
 
334
  //==================================
 
335
  NdisAllocateSpinLock (&l_Adapter->m_MCLock);
 
336
  l_Adapter->m_MCLockAllocated = TRUE;
303
337
 
304
338
  //====================================================
305
339
  // Register a shutdown handler which will be called
308
342
 
309
343
  NdisMRegisterAdapterShutdownHandler (p_AdapterHandle, l_Adapter,
310
344
                                       AdapterHalt);
311
 
  l_Adapter->m_MiniportAdapterHandle = p_AdapterHandle;
312
345
  l_Adapter->m_RegisteredAdapterShutdownHandler = TRUE;
313
346
 
314
 
  //===========================================================
315
 
  // Allocate spinlocks used to control access to
316
 
  // shared data structures by concurrent threads of execution.
317
 
  // QueueLock is used to lock the packet queue used
318
 
  // for the TAP-Win32 NIC -> User Space packet flow direction.
319
 
  // This code is designed to be fully SMP-safe.
320
 
  //===========================================================
321
 
 
322
 
  NdisAllocateSpinLock (&l_Adapter->m_Lock);
323
 
  NdisAllocateSpinLock (&l_Adapter->m_QueueLock);
324
 
  l_Adapter->m_AllocatedSpinlocks = TRUE;
325
 
 
326
347
  //====================================
327
348
  // Allocate and construct adapter name
328
349
  //====================================
329
350
 
330
 
  l_AdapterString.MaximumLength =
331
 
    ((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName.Length + 5;
332
 
 
333
 
  if ((l_Adapter->m_Name = l_AdapterString.Buffer =
334
 
       ExAllocatePoolWithTag (NonPagedPool,
335
 
                              l_AdapterString.MaximumLength,
336
 
                              '2PAT')) == NULL)
 
351
  if (RtlUnicodeStringToAnsiString (
 
352
       &l_Adapter->m_NameAnsi,
 
353
       &((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName,
 
354
       TRUE) != STATUS_SUCCESS)
337
355
    {
338
356
      AdapterFreeResources (l_Adapter);
339
357
      return NDIS_STATUS_RESOURCES;
340
358
    }
341
359
 
342
 
  RtlUnicodeStringToAnsiString (
343
 
             &l_AdapterString,
344
 
             &((PNDIS_MINIPORT_BLOCK) p_AdapterHandle)->MiniportName,
345
 
             FALSE);
346
 
  l_AdapterString.Buffer[l_AdapterString.Length] = 0;
347
 
 
348
 
  //==================================
349
 
  // Store and update MAC address info
350
 
  //==================================
351
 
 
352
 
#ifdef ENABLE_RANDOM_MAC
353
 
  GenerateRandomMac (g_MAC, l_Adapter->m_Name);
354
 
  COPY_MAC (l_Adapter->m_MAC, g_MAC);
355
 
#else
356
 
  COPY_MAC (l_Adapter->m_MAC, g_MAC);
357
 
 
358
 
  l_MAC[0] = g_MAC[5];
359
 
  l_MAC[1] = g_MAC[4];
360
 
 
361
 
  ++(*((unsigned short *) l_MAC));
362
 
 
363
 
  g_MAC[5] = l_MAC[0];
364
 
  g_MAC[4] = l_MAC[1];
365
 
#endif
366
 
 
367
 
  DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
368
 
            l_Adapter->m_Name,
369
 
            l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
370
 
            l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
371
 
 
372
 
  //==================
373
 
  // Set broadcast MAC
374
 
  //==================
375
 
  {
376
 
    int i;
377
 
    for (i = 0; i < sizeof (MACADDR); ++i)
378
 
      l_Adapter->m_MAC_Broadcast[i] = 0xFF;
379
 
  }
380
 
 
381
360
  //============================================
382
361
  // Get parameters from registry which were set
383
362
  // in the adapter advanced properties dialog.
388
367
    NDIS_CONFIGURATION_PARAMETER *parm;
389
368
 
390
369
    // set defaults in case our registry query fails
391
 
    l_Adapter->m_MTU = DEFAULT_PACKET_LOOKAHEAD;
 
370
    l_Adapter->m_MTU = ETHERNET_MTU;
392
371
    l_Adapter->m_MediaStateAlwaysConnected = FALSE;
393
372
    l_Adapter->m_MediaState = FALSE;
394
373
 
432
411
            }
433
412
        }
434
413
 
 
414
        /* Read optional MAC setting from registry */
 
415
        {
 
416
          NDIS_STRING key = NDIS_STRING_CONST("MAC");
 
417
          ANSI_STRING mac_string;
 
418
          NdisReadConfiguration (&status, &parm, configHandle,
 
419
                                 &key, NdisParameterString);
 
420
          if (status == NDIS_STATUS_SUCCESS)
 
421
            {
 
422
              if (parm->ParameterType == NdisParameterString)
 
423
                {
 
424
                  if (RtlUnicodeStringToAnsiString (&mac_string, &parm->ParameterData.StringData, TRUE) == STATUS_SUCCESS)
 
425
                    {
 
426
                      l_MacFromRegistry = ParseMAC (l_Adapter->m_MAC, mac_string.Buffer);
 
427
                      RtlFreeAnsiString (&mac_string);
 
428
                    }
 
429
                }
 
430
            }
 
431
        }
 
432
 
435
433
        NdisCloseConfiguration (configHandle);
436
434
      }
437
435
 
438
 
    DEBUGP (("[%s] MTU=%d\n", l_Adapter->m_Name, l_Adapter->m_MTU));
 
436
    DEBUGP (("[%s] MTU=%d\n", NAME (l_Adapter), l_Adapter->m_MTU));
 
437
  }
 
438
 
 
439
  //==================================
 
440
  // Store and update MAC address info
 
441
  //==================================
 
442
 
 
443
  if (!l_MacFromRegistry)
 
444
    GenerateRandomMac (l_Adapter->m_MAC, NAME (l_Adapter));
 
445
 
 
446
  DEBUGP (("[%s] Using MAC %x:%x:%x:%x:%x:%x\n",
 
447
            NAME (l_Adapter),
 
448
            l_Adapter->m_MAC[0], l_Adapter->m_MAC[1], l_Adapter->m_MAC[2],
 
449
            l_Adapter->m_MAC[3], l_Adapter->m_MAC[4], l_Adapter->m_MAC[5]));
 
450
 
 
451
  //==================
 
452
  // Set broadcast MAC
 
453
  //==================
 
454
  {
 
455
    int i;
 
456
    for (i = 0; i < sizeof (MACADDR); ++i)
 
457
      l_Adapter->m_MAC_Broadcast[i] = 0xFF;
439
458
  }
440
459
 
441
460
  //====================================
443
462
  //====================================
444
463
  {
445
464
    NDIS_STATUS tap_status;
446
 
    tap_status = CreateTapDevice (l_Adapter);
 
465
    tap_status = CreateTapDevice (&l_Adapter->m_Extension, NAME (l_Adapter));
447
466
    if (tap_status != NDIS_STATUS_SUCCESS)
448
467
      {
449
468
        AdapterFreeResources (l_Adapter);
451
470
      }
452
471
  }
453
472
 
 
473
  if (!AddAdapterToInstanceList (l_Adapter))
 
474
    {
 
475
      NOTE_ERROR ();
 
476
      TapDeviceFreeResources (&l_Adapter->m_Extension);
 
477
      AdapterFreeResources (l_Adapter);
 
478
      return NDIS_STATUS_RESOURCES;
 
479
    }
 
480
 
454
481
  l_Adapter->m_InterfaceIsRunning = TRUE;
 
482
 
455
483
  return NDIS_STATUS_SUCCESS;
456
484
}
457
485
 
458
486
VOID
459
487
AdapterHalt (IN NDIS_HANDLE p_AdapterContext)
460
488
{
 
489
  BOOLEAN status;
 
490
 
461
491
  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
462
492
 
463
 
  DEBUGP (("[%s] is being halted\n", l_Adapter->m_Name));
 
493
  NOTE_ERROR ();
 
494
 
464
495
  l_Adapter->m_InterfaceIsRunning = FALSE;
465
 
  NOTE_ERROR (l_Adapter);
466
496
 
467
 
  // Close TAP device
468
 
  if (l_Adapter->m_TapDevice)
469
 
    DestroyTapDevice (l_Adapter);
 
497
  DEBUGP (("[%s] is being halted\n", NAME (l_Adapter)));
 
498
  
 
499
  DestroyTapDevice (&l_Adapter->m_Extension);
470
500
 
471
501
  // Free resources
472
 
  DEBUGP (("[%s] Freeing Resources\n", l_Adapter->m_Name));
 
502
  DEBUGP (("[%s] Freeing Resources\n", NAME (l_Adapter)));
473
503
  AdapterFreeResources (l_Adapter);
 
504
 
 
505
  status = RemoveAdapterFromInstanceList (l_Adapter);
 
506
  DEBUGP (("[TAP] RemoveAdapterFromInstanceList returned %d\n", (int) status));
 
507
 
 
508
  DEBUGP (("[TAP] version [%d.%d] %s %s AdapterHalt returning\n",
 
509
           TAP_DRIVER_MAJOR_VERSION,
 
510
           TAP_DRIVER_MINOR_VERSION,
 
511
           __DATE__,
 
512
           __TIME__));
474
513
}
475
514
 
476
515
VOID
479
518
  MYASSERT (!p_Adapter->m_CalledAdapterFreeResources);
480
519
  p_Adapter->m_CalledAdapterFreeResources = TRUE;
481
520
 
482
 
  if (p_Adapter->m_Name)
483
 
    {
484
 
      ExFreePool (p_Adapter->m_Name);
485
 
      p_Adapter->m_Name = NULL;
486
 
    }
487
 
 
488
 
  if (p_Adapter->m_AllocatedSpinlocks)
489
 
    {
490
 
      NdisFreeSpinLock (&p_Adapter->m_Lock);
491
 
      NdisFreeSpinLock (&p_Adapter->m_QueueLock);
492
 
      p_Adapter->m_AllocatedSpinlocks = FALSE;
493
 
    }
494
 
 
 
521
  if (p_Adapter->m_NameAnsi.Buffer)
 
522
    RtlFreeAnsiString (&p_Adapter->m_NameAnsi);
 
523
  
495
524
  if (p_Adapter->m_RegisteredAdapterShutdownHandler)
 
525
    NdisMDeregisterAdapterShutdownHandler (p_Adapter->m_MiniportAdapterHandle);
 
526
 
 
527
  if (p_Adapter->m_MCLockAllocated)
 
528
    NdisFreeSpinLock (&l_Adapter->m_MCLock);
 
529
}
 
530
 
 
531
VOID
 
532
DestroyTapDevice (TapExtensionPointer p_Extension)
 
533
{
 
534
  DEBUGP (("[%s] Destroying tap device\n", p_Extension->m_TapName));
 
535
 
 
536
  //======================================
 
537
  // Let clients know we are shutting down
 
538
  //======================================
 
539
  p_Extension->m_TapIsRunning = FALSE;
 
540
  p_Extension->m_TapOpens = 0;
 
541
  p_Extension->m_Halt = TRUE;
 
542
 
 
543
  //=====================================
 
544
  // If we are concurrently executing in
 
545
  // TapDeviceHook or AdapterTransmit,
 
546
  // give those calls time to finish.
 
547
  // Note that we must be running at IRQL
 
548
  // < DISPATCH_LEVEL in order to call
 
549
  // NdisMSleep.
 
550
  //=====================================
 
551
  NdisMSleep (500000);
 
552
 
 
553
  //===========================================================
 
554
  // Exhaust IRP and packet queues.  Any pending IRPs will
 
555
  // be cancelled, causing user-space to get this error
 
556
  // on overlapped reads:
 
557
  //   The I/O operation has been aborted because of either a
 
558
  //   thread exit or an application request.   (code=995)
 
559
  // It's important that user-space close the device handle
 
560
  // when this code is returned, so that when we finally
 
561
  // do a NdisMDeregisterDevice, the device reference count
 
562
  // is 0.  Otherwise the driver will not unload even if the
 
563
  // the last adapter has been halted.
 
564
  //===========================================================
 
565
  FlushQueues (p_Extension);
 
566
  NdisMSleep (500000); // give user space time to respond to IRP cancel
 
567
 
 
568
  TapDeviceFreeResources (p_Extension);
 
569
}
 
570
 
 
571
VOID
 
572
TapDeviceFreeResources (TapExtensionPointer p_Extension)
 
573
{
 
574
  MYASSERT (p_Extension);
 
575
  MYASSERT (!p_Extension->m_CalledTapDeviceFreeResources);
 
576
  p_Extension->m_CalledTapDeviceFreeResources = TRUE;
 
577
 
 
578
  if (p_Extension->m_PacketQueue)
 
579
    QueueFree (p_Extension->m_PacketQueue);
 
580
  if (p_Extension->m_IrpQueue)
 
581
    QueueFree (p_Extension->m_IrpQueue);
 
582
 
 
583
  if (p_Extension->m_CreatedUnicodeLinkName)
 
584
    RtlFreeUnicodeString (&p_Extension->m_UnicodeLinkName);
 
585
 
 
586
  //==========================================================
 
587
  // According to DDK docs, the device is not actually deleted
 
588
  // until its reference count falls to zero.  That means we
 
589
  // still need to gracefully fail TapDeviceHook requests
 
590
  // after this point, otherwise ugly things would happen if
 
591
  // the device was disabled (e.g. in the network connections
 
592
  // control panel) while a userspace app still held an open
 
593
  // file handle to it.
 
594
  //==========================================================
 
595
  
 
596
  if (p_Extension->m_TapDevice)
496
597
    {
497
 
      NdisMDeregisterAdapterShutdownHandler
498
 
        (p_Adapter->m_MiniportAdapterHandle);
499
 
      p_Adapter->m_RegisteredAdapterShutdownHandler = FALSE;
 
598
      BOOLEAN status;
 
599
      status = (NdisMDeregisterDevice (p_Extension->m_TapDeviceHandle)
 
600
                == NDIS_STATUS_SUCCESS);
 
601
      DEBUGP (("[TAP] Deregistering TAP device, status=%d\n", (int)status));
500
602
    }
501
603
 
502
 
  NdisZeroMemory ((PVOID) p_Adapter, sizeof (TapAdapter));
503
 
  NdisFreeMemory ((PVOID) p_Adapter, sizeof (TapAdapter), 0);
504
 
 
505
 
  //==============================
506
 
  // Free debugging text space
507
 
  //==============================
508
 
#if DBG
509
 
  MyDebugFree ();
510
 
#endif
 
604
  if (p_Extension->m_TapName)
 
605
    MemFree (p_Extension->m_TapName, NAME_BUFFER_SIZE);
 
606
  
 
607
  if (p_Extension->m_AllocatedSpinlocks)
 
608
    NdisFreeSpinLock (&p_Extension->m_QueueLock);
511
609
}
512
610
 
513
611
//========================================================================
514
612
//                             Tap Device Initialization
515
613
//========================================================================
 
614
 
516
615
NDIS_STATUS
517
 
CreateTapDevice (TapAdapterPointer p_Adapter)
 
616
CreateTapDevice (TapExtensionPointer p_Extension, const char *p_Name)
518
617
{
519
 
  unsigned short l_AdapterLength =
520
 
    (unsigned short) strlen (p_Adapter->m_Name);
 
618
# define SIZEOF_DISPATCH (sizeof(PDRIVER_DISPATCH) * (IRP_MJ_MAXIMUM_FUNCTION + 1))
 
619
  PDRIVER_DISPATCH *l_Dispatch = NULL;
521
620
  ANSI_STRING l_TapString, l_LinkString;
522
 
  TapExtensionPointer l_Extension;
523
621
  UNICODE_STRING l_TapUnicode;
524
622
  BOOLEAN l_FreeTapUnicode = FALSE;
525
623
  NTSTATUS l_Status, l_Return = NDIS_STATUS_SUCCESS;
 
624
  const char *l_UsableName;
 
625
 
 
626
  DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
 
627
           TAP_DRIVER_MAJOR_VERSION,
 
628
           TAP_DRIVER_MINOR_VERSION,
 
629
           p_Name));
 
630
 
 
631
  NdisZeroMemory (p_Extension, sizeof (TapExtension));
 
632
 
 
633
  INIT_MUTEX (&p_Extension->m_OpenCloseMutex);
526
634
 
527
635
  l_LinkString.Buffer = NULL;
528
 
 
529
 
  l_TapString.MaximumLength = l_LinkString.MaximumLength =
530
 
    l_AdapterLength + strlen (TAPSUFFIX);
531
 
 
532
 
  DEBUGP (("[TAP] version [%d.%d] creating tap device: %s\n",
533
 
           TAP_DRIVER_MAJOR_VERSION,
534
 
           TAP_DRIVER_MINOR_VERSION,
535
 
           p_Adapter->m_Name));
 
636
  l_TapString.Buffer = NULL;
 
637
 
 
638
  l_TapString.MaximumLength = l_LinkString.MaximumLength = NAME_BUFFER_SIZE;
 
639
 
 
640
  //=======================================
 
641
  // Set TAP device entry points
 
642
  //=======================================
 
643
 
 
644
  if ((l_Dispatch = MemAlloc (SIZEOF_DISPATCH, TRUE)) == NULL)
 
645
    {
 
646
      DEBUGP (("[%s] couldn't alloc TAP dispatch table\n", p_Name));
 
647
      l_Return = NDIS_STATUS_RESOURCES;
 
648
      goto cleanup;
 
649
    }
 
650
 
 
651
  l_Dispatch[IRP_MJ_DEVICE_CONTROL] = TapDeviceHook;
 
652
  l_Dispatch[IRP_MJ_READ] = TapDeviceHook;
 
653
  l_Dispatch[IRP_MJ_WRITE] = TapDeviceHook;
 
654
  l_Dispatch[IRP_MJ_CREATE] = TapDeviceHook;
 
655
  l_Dispatch[IRP_MJ_CLOSE] = TapDeviceHook;
 
656
 
 
657
  //==================================
 
658
  // Find the beginning of the GUID
 
659
  //==================================
 
660
  l_UsableName = p_Name;
 
661
  while (*l_UsableName != '{')
 
662
    {
 
663
      if (*l_UsableName == '\0')
 
664
        {
 
665
          DEBUGP (("[%s] couldn't find leading '{' in name\n", p_Name));
 
666
          l_Return = NDIS_STATUS_RESOURCES;
 
667
          goto cleanup;
 
668
        }
 
669
      ++l_UsableName;
 
670
    }
536
671
 
537
672
  //==================================
538
673
  // Allocate pool for TAP device name
539
674
  //==================================
540
675
 
541
 
  if ((p_Adapter->m_TapName = l_TapString.Buffer =
542
 
       ExAllocatePoolWithTag (NonPagedPool,
543
 
                              l_TapString.MaximumLength,
544
 
                              '3PAT')) == NULL)
 
676
  if ((p_Extension->m_TapName = l_TapString.Buffer =
 
677
       MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
545
678
    {
546
 
      DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Adapter->m_Name));
 
679
      DEBUGP (("[%s] couldn't alloc TAP name buffer\n", p_Name));
547
680
      l_Return = NDIS_STATUS_RESOURCES;
548
681
      goto cleanup;
549
682
    }
553
686
  //================================================
554
687
 
555
688
  if ((l_LinkString.Buffer =
556
 
       ExAllocatePoolWithTag (NonPagedPool,
557
 
                              l_LinkString.MaximumLength,
558
 
                              '4PAT')) == NULL)
 
689
       MemAlloc (NAME_BUFFER_SIZE, TRUE)) == NULL)
559
690
    {
560
691
      DEBUGP (("[%s] couldn't alloc TAP symbolic link name buffer\n",
561
 
               p_Adapter->m_Name));
562
 
      l_Return = NDIS_STATUS_RESOURCES;
563
 
      goto cleanup;
564
 
    }
565
 
 
566
 
  //=======================================================
567
 
  // Modify for tap device name ("\Device\TAPn.tap")
568
 
  //=======================================================
569
 
  NdisMoveMemory (l_TapString.Buffer, p_Adapter->m_Name, l_AdapterLength);
570
 
  NdisMoveMemory (l_TapString.Buffer + l_AdapterLength, TAPSUFFIX,
571
 
                  strlen (TAPSUFFIX) + 1);
572
 
  NdisMoveMemory (l_TapString.Buffer, "\\Device", 7);   // For Win2K problem
573
 
  l_TapString.Length = l_AdapterLength + strlen (TAPSUFFIX);
 
692
               p_Name));
 
693
      l_Return = NDIS_STATUS_RESOURCES;
 
694
      goto cleanup;
 
695
    }
 
696
 
 
697
  //=======================================================
 
698
  // Set TAP device name
 
699
  //=======================================================
 
700
 
 
701
  l_Status = RtlStringCchPrintfExA
 
702
    (l_TapString.Buffer,
 
703
     l_TapString.MaximumLength,
 
704
     NULL,
 
705
     NULL,
 
706
     STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
 
707
     "%s%s%s",
 
708
     SYSDEVICEDIR,
 
709
     l_UsableName,
 
710
     TAPSUFFIX);
 
711
 
 
712
  if (l_Status != STATUS_SUCCESS)
 
713
    {
 
714
      DEBUGP (("[%s] couldn't format TAP device name\n",
 
715
               p_Name));
 
716
      l_Return = NDIS_STATUS_RESOURCES;
 
717
      goto cleanup;
 
718
    }
 
719
  l_TapString.Length = (USHORT) strlen (l_TapString.Buffer);
574
720
 
575
721
  DEBUGP (("TAP DEV NAME: '%s'\n", l_TapString.Buffer));
576
722
 
577
723
  //=======================================================
578
 
  // And modify for tap link name ("\??\TAPn.tap")
 
724
  // Set TAP link name
579
725
  //=======================================================
580
 
  NdisMoveMemory (l_LinkString.Buffer, l_TapString.Buffer,
581
 
                  l_TapString.Length);
582
 
  NdisMoveMemory (l_LinkString.Buffer, USERDEVICEDIR, strlen (USERDEVICEDIR));
583
 
 
584
 
  NdisMoveMemory
585
 
    (l_LinkString.Buffer + strlen (USERDEVICEDIR),
586
 
     l_LinkString.Buffer + strlen (SYSDEVICEDIR),
587
 
     l_TapString.Length - strlen (SYSDEVICEDIR));
588
 
 
589
 
  l_LinkString.Buffer[l_LinkString.Length =
590
 
                      l_TapString.Length - (strlen (SYSDEVICEDIR) -
591
 
                                            strlen (USERDEVICEDIR))] = 0;
 
726
 
 
727
  l_Status = RtlStringCchPrintfExA
 
728
    (l_LinkString.Buffer,
 
729
     l_LinkString.MaximumLength,
 
730
     NULL,
 
731
     NULL,
 
732
     STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
 
733
     "%s%s%s",
 
734
     USERDEVICEDIR,
 
735
     l_UsableName,
 
736
     TAPSUFFIX);
 
737
 
 
738
  if (l_Status != STATUS_SUCCESS)
 
739
    {
 
740
      DEBUGP (("[%s] couldn't format TAP device symbolic link\n",
 
741
               p_Name));
 
742
      l_Return = NDIS_STATUS_RESOURCES;
 
743
      goto cleanup;
 
744
    }
 
745
  l_LinkString.Length = (USHORT) strlen (l_LinkString.Buffer);
592
746
 
593
747
  DEBUGP (("TAP LINK NAME: '%s'\n", l_LinkString.Buffer));
594
748
 
595
749
  //==================================================
596
 
  // Create new tap device and associate with adapter
 
750
  // Convert strings to unicode
597
751
  //==================================================
598
752
  if (RtlAnsiStringToUnicodeString (&l_TapUnicode, &l_TapString, TRUE) !=
599
753
      STATUS_SUCCESS)
600
754
    {
601
755
      DEBUGP (("[%s] couldn't alloc TAP unicode name buffer\n",
602
 
                p_Adapter->m_Name));
 
756
                p_Name));
603
757
      l_Return = NDIS_STATUS_RESOURCES;
604
758
      goto cleanup;
605
759
    }
606
760
  l_FreeTapUnicode = TRUE;
607
761
 
608
 
  l_Status = IoCreateDevice
609
 
    (g_TapDriverObject,
610
 
     sizeof (TapExtension),
611
 
     &l_TapUnicode,
612
 
     FILE_DEVICE_PHYSICAL_NETCARD | 0x8000,
613
 
     0, FALSE, &(p_Adapter->m_TapDevice));
614
 
 
615
 
  if (l_Status != STATUS_SUCCESS)
616
 
    {
617
 
      DEBUGP (("[%s] couldn't be created\n", p_Adapter->m_TapName));
618
 
      l_Return = NDIS_STATUS_RESOURCES;
619
 
      goto cleanup;
620
 
    }
621
 
 
622
762
  if (RtlAnsiStringToUnicodeString
623
 
      (&p_Adapter->m_UnicodeLinkName, &l_LinkString, TRUE)
 
763
      (&p_Extension->m_UnicodeLinkName, &l_LinkString, TRUE)
624
764
      != STATUS_SUCCESS)
625
765
    {
626
766
      DEBUGP
627
767
        (("[%s] Couldn't allocate unicode string for symbolic link name\n",
628
 
         p_Adapter->m_Name));
 
768
         p_Name));
629
769
      l_Return = NDIS_STATUS_RESOURCES;
630
770
      goto cleanup;
631
771
    }
632
 
  p_Adapter->m_CreatedUnicodeLinkName = TRUE;
633
 
 
634
 
  //==================================================
635
 
  // Associate symbolic link with new device
636
 
  //==================================================
637
 
  if (!NT_SUCCESS
638
 
      (IoCreateSymbolicLink (&p_Adapter->m_UnicodeLinkName, &l_TapUnicode)))
 
772
  p_Extension->m_CreatedUnicodeLinkName = TRUE;
 
773
 
 
774
  //==================================================
 
775
  // Create new TAP device with symbolic
 
776
  // link and associate with adapter.
 
777
  //==================================================
 
778
 
 
779
  l_Status = NdisMRegisterDevice
 
780
    (g_NdisWrapperHandle,
 
781
     &l_TapUnicode,
 
782
     &p_Extension->m_UnicodeLinkName,
 
783
     l_Dispatch,
 
784
     &p_Extension->m_TapDevice,
 
785
     &p_Extension->m_TapDeviceHandle
 
786
     );
 
787
 
 
788
  if (l_Status != STATUS_SUCCESS)
639
789
    {
640
 
      DEBUGP (("[%s] symbolic link couldn't be created\n",
641
 
                l_LinkString.Buffer));
 
790
      DEBUGP (("[%s] couldn't be created\n", p_Name));
642
791
      l_Return = NDIS_STATUS_RESOURCES;
643
792
      goto cleanup;
644
793
    }
645
 
  p_Adapter->m_CreatedSymbolLink = TRUE;
646
 
 
647
 
  //==================================================
648
 
  // Initialize device extension (basically a kind
649
 
  // of private data area containing our state info).
650
 
  //==================================================
651
 
 
652
 
  l_Extension =
653
 
    ((TapExtensionPointer) p_Adapter->m_TapDevice->DeviceExtension);
654
 
 
655
 
  NdisZeroMemory (l_Extension, sizeof (TapExtension));
656
 
 
657
 
  p_Adapter->m_DeviceExtensionIsAccessible = TRUE;
658
 
 
659
 
  l_Extension->m_Adapter = p_Adapter;
660
 
  l_Extension->m_halt = FALSE;
 
794
 
 
795
  /* Set TAP device flags */
 
796
  p_Extension->m_TapDevice->Flags |= DO_DIRECT_IO;
661
797
 
662
798
  //========================================================
663
799
  // Initialize Packet and IRP queues.
674
810
  // Basically, packets in the packet queue are used
675
811
  // to satisfy IRP requests in the IRP queue.
676
812
  //
 
813
  // QueueLock is used to lock the packet queue used
 
814
  // for the TAP-Win32 NIC -> User Space packet flow direction.
 
815
  //
677
816
  // All accesses to packet or IRP queues should be
678
817
  // bracketed by the QueueLock spinlock,
679
818
  // in order to be SMP-safe.
680
819
  //========================================================
681
820
 
682
 
  l_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE);
683
 
  l_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE);
684
 
 
685
 
  if (!l_Extension->m_PacketQueue
686
 
      || !l_Extension->m_IrpQueue)
 
821
  NdisAllocateSpinLock (&p_Extension->m_QueueLock);
 
822
  p_Extension->m_AllocatedSpinlocks = TRUE;
 
823
 
 
824
  p_Extension->m_PacketQueue = QueueInit (PACKET_QUEUE_SIZE);
 
825
  p_Extension->m_IrpQueue = QueueInit (IRP_QUEUE_SIZE);
 
826
 
 
827
  if (!p_Extension->m_PacketQueue
 
828
      || !p_Extension->m_IrpQueue)
687
829
    {
688
 
      DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Adapter->m_Name));
 
830
      DEBUGP (("[%s] couldn't alloc TAP queues\n", p_Name));
689
831
      l_Return = NDIS_STATUS_RESOURCES;
690
832
      goto cleanup;
691
833
    }
694
836
  // Finalize initialization
695
837
  //========================
696
838
 
697
 
  p_Adapter->m_TapIsRunning = TRUE;
698
 
 
699
 
  /* instead of DO_BUFFERED_IO */
700
 
  p_Adapter->m_TapDevice->Flags |= DO_DIRECT_IO;
701
 
 
702
 
  p_Adapter->m_TapDevice->Flags &= ~DO_DEVICE_INITIALIZING;
703
 
 
704
 
  DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Adapter->m_Name,
705
 
            p_Adapter->m_TapName));
 
839
  p_Extension->m_TapIsRunning = TRUE;
 
840
 
 
841
  DEBUGP (("[%s] successfully created TAP device [%s]\n", p_Name,
 
842
            p_Extension->m_TapName));
706
843
 
707
844
 cleanup:
708
845
  if (l_FreeTapUnicode)
709
846
    RtlFreeUnicodeString (&l_TapUnicode);
710
847
  if (l_LinkString.Buffer)
711
 
    ExFreePool (l_LinkString.Buffer);
 
848
    MemFree (l_LinkString.Buffer, NAME_BUFFER_SIZE);
 
849
  if (l_Dispatch)
 
850
    MemFree (l_Dispatch, SIZEOF_DISPATCH);
712
851
 
713
852
  if (l_Return != NDIS_STATUS_SUCCESS)
714
 
    TapDeviceFreeResources (p_Adapter);
 
853
    TapDeviceFreeResources (p_Extension);
715
854
 
716
855
  return l_Return;
717
856
}
718
 
 
719
 
VOID
720
 
DestroyTapDevice (TapAdapterPointer p_Adapter)
721
 
{
722
 
  TapExtensionPointer l_Extension =
723
 
    (TapExtensionPointer) p_Adapter->m_TapDevice->DeviceExtension;
724
 
 
725
 
  DEBUGP (("[%s] Destroying tap device\n", p_Adapter->m_TapName));
726
 
 
727
 
  //======================================
728
 
  // Let clients know we are shutting down
729
 
  //======================================
730
 
  p_Adapter->m_TapIsRunning = FALSE;
731
 
  p_Adapter->m_TapOpens = 0;
732
 
  l_Extension->m_halt = TRUE;
733
 
 
734
 
  //====================================
735
 
  // Give clients time to finish up.
736
 
  // Note that we must be running at IRQL
737
 
  // < DISPATCH_LEVEL in order to call
738
 
  // NdisMSleep.
739
 
  //====================================
740
 
  NdisMSleep (1000);        
741
 
 
742
 
  //================================
743
 
  // Exhaust IRP and packet queues
744
 
  //================================
745
 
  FlushQueues (p_Adapter);
746
 
 
747
 
  TapDeviceFreeResources (p_Adapter);
748
 
}
749
 
 
750
 
VOID
751
 
TapDeviceFreeResources (TapAdapterPointer p_Adapter)
752
 
{
753
 
  MYASSERT (p_Adapter);
754
 
  MYASSERT (!p_Adapter->m_CalledTapDeviceFreeResources);
755
 
  p_Adapter->m_CalledTapDeviceFreeResources = TRUE;
756
 
 
757
 
  if (p_Adapter->m_DeviceExtensionIsAccessible)
758
 
    {
759
 
      TapExtensionPointer l_Extension;
760
 
 
761
 
      MYASSERT (p_Adapter->m_TapDevice);
762
 
      l_Extension = (TapExtensionPointer)
763
 
        p_Adapter->m_TapDevice->DeviceExtension;
764
 
      MYASSERT (l_Extension);
765
 
 
766
 
      if (l_Extension->m_PacketQueue)
767
 
        QueueFree (l_Extension->m_PacketQueue);
768
 
      if (l_Extension->m_IrpQueue)
769
 
        QueueFree (l_Extension->m_IrpQueue);
770
 
 
771
 
      p_Adapter->m_DeviceExtensionIsAccessible = FALSE;
772
 
    }
773
 
 
774
 
  if (p_Adapter->m_CreatedSymbolLink)
775
 
    IoDeleteSymbolicLink (&p_Adapter->m_UnicodeLinkName);
776
 
 
777
 
  if (p_Adapter->m_CreatedUnicodeLinkName)
778
 
    RtlFreeUnicodeString (&p_Adapter->m_UnicodeLinkName);
779
 
 
780
 
  //==========================================================
781
 
  // According to DDK docs, the device is not actually deleted
782
 
  // until its reference count falls to zero.  That means we
783
 
  // still need to gracefully fail TapDeviceHook requests
784
 
  // after this point, otherwise ugly things would happen if
785
 
  // the device was disabled (e.g. in the network connections
786
 
  // control panel) while a userspace app still held an open
787
 
  // file handle to it.
788
 
  //==========================================================
789
 
  
790
 
  if (p_Adapter->m_TapDevice)
791
 
    {
792
 
      IoDeleteDevice (p_Adapter->m_TapDevice);
793
 
      p_Adapter->m_TapDevice = NULL;
794
 
    }
795
 
 
796
 
  if (p_Adapter->m_TapName)
797
 
    {
798
 
      ExFreePool (p_Adapter->m_TapName);
799
 
      p_Adapter->m_TapName = NULL;
800
 
    }
801
 
}
 
857
#undef SIZEOF_DISPATCH
802
858
 
803
859
//========================================================
804
860
//                      Adapter Control
807
863
AdapterReset (OUT PBOOLEAN p_AddressingReset, IN NDIS_HANDLE p_AdapterContext)
808
864
{
809
865
  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
810
 
  DEBUGP (("[%s] is resetting\n", l_Adapter->m_Name));
 
866
  DEBUGP (("[%s] is resetting\n", NAME (l_Adapter)));
811
867
  return NDIS_STATUS_SUCCESS;
812
868
}
813
869
 
815
871
  (OUT PNDIS_PACKET p_Packet,
816
872
   OUT PUINT p_Transferred,
817
873
   IN NDIS_HANDLE p_AdapterContext,
818
 
   IN NDIS_HANDLE p_ReceiveContext, IN UINT p_Offset, IN UINT p_ToTransfer)
 
874
   IN NDIS_HANDLE p_ReceiveContext,
 
875
   IN UINT p_Offset,
 
876
   IN UINT p_ToTransfer)
819
877
{
820
878
  return NDIS_STATUS_SUCCESS;
821
879
}
824
882
//                  Adapter Option Query/Modification
825
883
//==============================================================
826
884
NDIS_STATUS AdapterQuery
827
 
  (IN NDIS_HANDLE p_AdapterContext,
828
 
   IN NDIS_OID p_OID,
829
 
   IN PVOID p_Buffer,
830
 
   IN ULONG p_BufferLength,
831
 
   OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded)
 
885
(IN NDIS_HANDLE p_AdapterContext,
 
886
 IN NDIS_OID p_OID,
 
887
 IN PVOID p_Buffer,
 
888
 IN ULONG p_BufferLength,
 
889
 OUT PULONG p_BytesWritten, OUT PULONG p_BytesNeeded)
832
890
{
833
891
  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
834
892
  TapAdapterQuery l_Query, *l_QueryPtr = &l_Query;
835
893
  NDIS_STATUS l_Status = NDIS_STATUS_SUCCESS;
836
894
  UINT l_QueryLength = 4;
 
895
  BOOLEAN lock_succeeded;
837
896
 
838
897
  NdisZeroMemory (&l_Query, sizeof (l_Query));
839
 
  NdisAcquireSpinLock (&l_Adapter->m_Lock);
840
898
 
841
899
  switch (p_OID)
842
900
    {
948
1006
      l_QueryLength = sizeof (NDIS_MEDIUM);
949
1007
      break;
950
1008
 
 
1009
    case OID_GEN_PHYSICAL_MEDIUM:
 
1010
      l_Query.m_PhysicalMedium = NdisPhysicalMediumUnspecified;
 
1011
      l_QueryLength = sizeof (NDIS_PHYSICAL_MEDIUM);
 
1012
      break;
 
1013
      
951
1014
    case OID_GEN_LINK_SPEED:
952
1015
      l_Query.m_Long = 100000;
953
1016
      break;
954
1017
 
955
 
    case OID_802_3_MULTICAST_LIST:
956
 
      l_Query.m_Long = 0;
957
 
      break;
958
 
 
959
1018
    case OID_802_3_PERMANENT_ADDRESS:
960
1019
    case OID_802_3_CURRENT_ADDRESS:
961
1020
      COPY_MAC (l_Query.m_MacAddress, l_Adapter->m_MAC);
971
1030
      break;
972
1031
 
973
1032
    case OID_802_3_MAXIMUM_LIST_SIZE:
974
 
      l_Query.m_Long = 0;
 
1033
      l_Query.m_Long = NIC_MAX_MCAST_LIST;
975
1034
      break;
976
1035
 
977
1036
    case OID_GEN_CURRENT_LOOKAHEAD:
1021
1080
 
1022
1081
    case OID_GEN_SUPPORTED_GUIDS:
1023
1082
    case OID_GEN_MEDIA_CAPABILITIES:
1024
 
    case OID_GEN_PHYSICAL_MEDIUM:
1025
1083
    case OID_TCP_TASK_OFFLOAD:
1026
1084
    case OID_FFP_SUPPORT:
1027
1085
      l_Status = NDIS_STATUS_INVALID_OID;
1048
1106
      //                          Not Handled
1049
1107
      //===================================================================
1050
1108
    default:
1051
 
      DEBUGP (("[%s] Unhandled OID %lx\n", l_Adapter->m_Name, p_OID));
 
1109
      DEBUGP (("[%s] Unhandled OID %lx\n", NAME (l_Adapter), p_OID));
1052
1110
      l_Status = NDIS_STATUS_INVALID_OID;
1053
1111
      break;
1054
1112
    }
1064
1122
    NdisMoveMemory (p_Buffer, (PVOID) l_QueryPtr,
1065
1123
                    (*p_BytesWritten = l_QueryLength));
1066
1124
 
1067
 
  NdisReleaseSpinLock (&l_Adapter->m_Lock);
1068
 
 
1069
1125
  return l_Status;
1070
1126
}
1071
1127
 
1072
1128
NDIS_STATUS AdapterModify
1073
 
  (IN NDIS_HANDLE p_AdapterContext,
1074
 
   IN NDIS_OID p_OID,
1075
 
   IN PVOID p_Buffer,
1076
 
   IN ULONG p_BufferLength,
1077
 
   OUT PULONG p_BytesRead,
1078
 
   OUT PULONG p_BytesNeeded)
 
1129
(IN NDIS_HANDLE p_AdapterContext,
 
1130
 IN NDIS_OID p_OID,
 
1131
 IN PVOID p_Buffer,
 
1132
 IN ULONG p_BufferLength,
 
1133
 OUT PULONG p_BytesRead,
 
1134
 OUT PULONG p_BytesNeeded)
1079
1135
{
1080
1136
  TapAdapterQueryPointer l_Query = (TapAdapterQueryPointer) p_Buffer;
1081
1137
  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1082
1138
  NDIS_STATUS l_Status = NDIS_STATUS_INVALID_OID;
1083
1139
  ULONG l_Long;
1084
1140
 
1085
 
  NdisAcquireSpinLock (&l_Adapter->m_Lock);
1086
 
 
1087
1141
  switch (p_OID)
1088
1142
    {
1089
1143
      //==================================================================
1090
1144
      //                            Device Info
1091
1145
      //==================================================================
1092
1146
    case OID_802_3_MULTICAST_LIST:
1093
 
      DEBUGP (("[%s] Setting [OID_802_3_MAXIMUM_LIST_SIZE]\n",
1094
 
                l_Adapter->m_Name));
1095
 
      l_Status = NDIS_STATUS_SUCCESS;
 
1147
      DEBUGP (("[%s] Setting [OID_802_3_MULTICAST_LIST]\n",
 
1148
               NAME (l_Adapter)));
 
1149
 
 
1150
      *p_BytesNeeded = sizeof (ETH_ADDR);
 
1151
      *p_BytesRead = p_BufferLength;
 
1152
 
 
1153
      if (p_BufferLength % sizeof (ETH_ADDR))
 
1154
        l_Status = NDIS_STATUS_INVALID_LENGTH;
 
1155
      else if (p_BufferLength > sizeof (MC_LIST))
 
1156
        {
 
1157
          l_Status = NDIS_STATUS_MULTICAST_FULL;
 
1158
          *p_BytesNeeded = sizeof (MC_LIST);
 
1159
        }
 
1160
      else
 
1161
        {
 
1162
          NdisAcquireSpinLock (&l_Adapter->m_MCLock);
 
1163
 
 
1164
          NdisZeroMemory(&l_Adapter->m_MCList, sizeof (MC_LIST));
 
1165
        
 
1166
          NdisMoveMemory(&l_Adapter->m_MCList,
 
1167
                         p_Buffer,
 
1168
                         p_BufferLength);
 
1169
 
 
1170
          l_Adapter->m_MCListSize = p_BufferLength / sizeof (ETH_ADDR);
 
1171
        
 
1172
          NdisReleaseSpinLock (&l_Adapter->m_MCLock);
 
1173
 
 
1174
          l_Status = NDIS_STATUS_SUCCESS;
 
1175
        }
1096
1176
      break;
1097
1177
 
1098
1178
    case OID_GEN_CURRENT_PACKET_FILTER:
1103
1183
        {
1104
1184
          DEBUGP
1105
1185
            (("[%s] Setting [OID_GEN_CURRENT_PACKET_FILTER] to [0x%02lx]\n",
1106
 
             l_Adapter->m_Name, l_Query->m_Long));
 
1186
              NAME (l_Adapter), l_Query->m_Long));
1107
1187
          l_Status = NDIS_STATUS_SUCCESS;
1108
1188
          *p_BytesRead = sizeof (ULONG);
1109
1189
        }
1110
 
 
1111
1190
      break;
1112
1191
 
1113
1192
    case OID_GEN_CURRENT_LOOKAHEAD:
1118
1197
        }
1119
1198
      else if (l_Query->m_Long > DEFAULT_PACKET_LOOKAHEAD
1120
1199
               || l_Query->m_Long <= 0)
1121
 
        l_Status = NDIS_STATUS_INVALID_DATA;
 
1200
        {
 
1201
          l_Status = NDIS_STATUS_INVALID_DATA;
 
1202
        }
1122
1203
      else
1123
1204
        {
1124
1205
          DEBUGP (("[%s] Setting [OID_GEN_CURRENT_LOOKAHEAD] to [%d]\n",
1125
 
                    l_Adapter->m_Name, l_Query->m_Long));
 
1206
                   NAME (l_Adapter), l_Query->m_Long));
1126
1207
          l_Adapter->m_Lookahead = l_Query->m_Long;
1127
1208
          l_Status = NDIS_STATUS_SUCCESS;
1128
1209
          *p_BytesRead = sizeof (ULONG);
1129
1210
        }
1130
 
 
1131
1211
      break;
1132
1212
 
1133
1213
    case OID_GEN_NETWORK_LAYER_ADDRESSES:
1181
1261
            {
1182
1262
              l_Adapter->m_InterfaceIsRunning = FALSE;
1183
1263
              DEBUGP (("[%s] Power management device state OFF\n",
1184
 
                       l_Adapter->m_Name));
 
1264
                       NAME (l_Adapter)));
1185
1265
            }
1186
1266
          else
1187
1267
            {
1188
1268
              l_Adapter->m_InterfaceIsRunning = TRUE;
1189
1269
              DEBUGP (("[%s] Power management device state ON\n",
1190
 
                       l_Adapter->m_Name));
 
1270
                       NAME (l_Adapter)));
1191
1271
            }
1192
1272
 
1193
1273
          l_Status = NDIS_STATUS_SUCCESS;
1213
1293
      break;
1214
1294
 
1215
1295
    default:
1216
 
      DEBUGP (("[%s] Can't set value for OID %lx\n", l_Adapter->m_Name,
1217
 
                p_OID));
 
1296
      DEBUGP (("[%s] Can't set value for OID %lx\n", NAME (l_Adapter),
 
1297
               p_OID));
1218
1298
      l_Status = NDIS_STATUS_INVALID_OID;
1219
1299
      *p_BytesRead = *p_BytesNeeded = 0;
1220
1300
      break;
1221
1301
    }
1222
1302
 
1223
 
  NdisReleaseSpinLock (&l_Adapter->m_Lock);
1224
 
 
1225
1303
  return l_Status;
1226
1304
}
1227
1305
 
1229
1307
//                               Adapter Transmission
1230
1308
//====================================================================
1231
1309
NDIS_STATUS
1232
 
AdapterTransmit (IN NDIS_HANDLE p_AdapterContext, IN PNDIS_PACKET p_Packet,
 
1310
AdapterTransmit (IN NDIS_HANDLE p_AdapterContext,
 
1311
                 IN PNDIS_PACKET p_Packet,
1233
1312
                 IN UINT p_Flags)
1234
1313
{
1235
1314
  TapAdapterPointer l_Adapter = (TapAdapterPointer) p_AdapterContext;
1236
1315
  ULONG l_Index = 0, l_BufferLength = 0, l_PacketLength = 0;
1237
1316
  PIRP l_IRP;
1238
1317
  TapPacketPointer l_PacketBuffer;
1239
 
  TapExtensionPointer l_Extension;
1240
1318
  PNDIS_BUFFER l_NDIS_Buffer;
1241
1319
  PUCHAR l_Buffer;
1242
1320
  PVOID result;
1250
1328
  // silently dropped.
1251
1329
  //====================================================
1252
1330
 
1253
 
  if (l_Adapter->m_TapDevice == NULL)
1254
 
    return NDIS_STATUS_FAILURE;
1255
 
  else if ((l_Extension =
1256
 
            (TapExtensionPointer) l_Adapter->m_TapDevice->DeviceExtension) ==
1257
 
           NULL)
1258
 
    return NDIS_STATUS_FAILURE;
1259
 
  else if (l_PacketLength < ETHERNET_HEADER_SIZE)
1260
 
    return NDIS_STATUS_FAILURE;
1261
 
  else if (l_PacketLength > 65535)  // Cap packet size to TCP/IP maximum
1262
 
    return NDIS_STATUS_FAILURE;
1263
 
  else if (!l_Adapter->m_TapOpens || !l_Adapter->m_MediaState)
1264
 
    return NDIS_STATUS_SUCCESS;     // Nothing is bound to the TAP device
 
1331
  if (l_PacketLength < ETHERNET_HEADER_SIZE || l_PacketLength > 65535)
 
1332
    goto exit_fail;
 
1333
  else if (!l_Adapter->m_Extension.m_TapOpens || !l_Adapter->m_MediaState)
 
1334
    goto exit_success;              // Nothing is bound to the TAP device
1265
1335
 
1266
1336
  if (NdisAllocateMemoryWithTag (&l_PacketBuffer,
1267
1337
                                 TAP_PACKET_SIZE (l_PacketLength),
1268
1338
                                 '5PAT') != NDIS_STATUS_SUCCESS)
1269
 
    return NDIS_STATUS_RESOURCES;
 
1339
    goto exit_no_resources;
1270
1340
 
1271
1341
  if (l_PacketBuffer == NULL)
1272
 
    return NDIS_STATUS_RESOURCES;
 
1342
    goto exit_no_resources;
1273
1343
 
1274
1344
  l_PacketBuffer->m_SizeFlags = (l_PacketLength & TP_SIZE_MASK);
1275
1345
 
1398
1468
    // userspace.
1399
1469
    //===============================================
1400
1470
 
1401
 
    NdisAcquireSpinLock (&l_Adapter->m_QueueLock);
 
1471
    NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1402
1472
 
1403
1473
    result = NULL;
1404
1474
    if (IS_UP (l_Adapter))
1405
 
      result = QueuePush (l_Extension->m_PacketQueue, l_PacketBuffer);
 
1475
      result = QueuePush (l_Adapter->m_Extension.m_PacketQueue, l_PacketBuffer);
1406
1476
 
1407
 
    NdisReleaseSpinLock (&l_Adapter->m_QueueLock);
 
1477
    NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1408
1478
 
1409
1479
    if ((TapPacketPointer) result != l_PacketBuffer)
1410
1480
      {
1411
1481
        // adapter receive overrun
1412
 
#ifndef NEED_TAP_IOCTL_SET_STATISTICS
1413
1482
        INCREMENT_STAT (l_Adapter->m_TxErr);
1414
 
#endif
1415
1483
        goto no_queue;
1416
1484
      }
1417
 
#ifndef NEED_TAP_IOCTL_SET_STATISTICS
1418
1485
    else
1419
1486
      {
1420
1487
        INCREMENT_STAT (l_Adapter->m_Tx);
1421
1488
      }
1422
 
#endif
1423
1489
 
1424
1490
    //============================================================
1425
1491
    // Cycle through IRPs and packets, try to satisfy each pending
1430
1496
        l_IRP = NULL;
1431
1497
        l_PacketBuffer = NULL;
1432
1498
 
1433
 
        NdisAcquireSpinLock (&l_Adapter->m_QueueLock);
 
1499
        NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1434
1500
 
1435
1501
        if (IS_UP (l_Adapter)
1436
 
            && QueueCount (l_Extension->m_PacketQueue)
1437
 
            && QueueCount (l_Extension->m_IrpQueue))
 
1502
            && QueueCount (l_Adapter->m_Extension.m_PacketQueue)
 
1503
            && QueueCount (l_Adapter->m_Extension.m_IrpQueue))
1438
1504
          {
1439
 
            l_IRP = (PIRP) QueuePop (l_Extension->m_IrpQueue);
 
1505
            l_IRP = (PIRP) QueuePop (l_Adapter->m_Extension.m_IrpQueue);
1440
1506
            l_PacketBuffer = (TapPacketPointer)
1441
 
              QueuePop (l_Extension->m_PacketQueue);
 
1507
              QueuePop (l_Adapter->m_Extension.m_PacketQueue);
1442
1508
          }
1443
1509
 
1444
 
        NdisReleaseSpinLock (&l_Adapter->m_QueueLock);
 
1510
        NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1445
1511
 
1446
1512
        MYASSERT ((l_IRP != NULL) + (l_PacketBuffer != NULL) != 1);
1447
1513
 
1448
1514
        if (l_IRP && l_PacketBuffer)
1449
1515
          {
1450
 
            CompleteIRP (l_Adapter,
1451
 
                         l_IRP,
 
1516
            CompleteIRP (l_IRP,
1452
1517
                         l_PacketBuffer, 
1453
1518
                         IO_NETWORK_INCREMENT);
1454
1519
          }
1466
1531
  NdisFreeMemory (l_PacketBuffer,
1467
1532
                  TAP_PACKET_SIZE (l_PacketLength),
1468
1533
                  0);
 
1534
  
 
1535
 exit_success:
1469
1536
  return NDIS_STATUS_SUCCESS;
 
1537
    
 
1538
 exit_fail:
 
1539
  return NDIS_STATUS_FAILURE;
 
1540
 
 
1541
 exit_no_resources:
 
1542
  return NDIS_STATUS_RESOURCES;
1470
1543
}
1471
1544
 
1472
1545
//======================================================================
1473
 
// Hook for catching tap device IRP's.
1474
 
// Network adapter requests are forwarded on to NDIS
 
1546
// Hooks for catching TAP device IRP's.
1475
1547
//======================================================================
 
1548
 
1476
1549
NTSTATUS
1477
1550
TapDeviceHook (IN PDEVICE_OBJECT p_DeviceObject, IN PIRP p_IRP)
1478
1551
{
 
1552
  TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
1479
1553
  PIO_STACK_LOCATION l_IrpSp;
1480
 
  TapExtensionPointer l_Extension;
1481
1554
  NTSTATUS l_Status = STATUS_SUCCESS;
1482
 
  TapAdapterPointer l_Adapter;
 
1555
  BOOLEAN accessible;
1483
1556
 
1484
 
  //=======================================================================
1485
 
  //  If it's not the private data device type, call the original handler
1486
 
  //=======================================================================
1487
1557
  l_IrpSp = IoGetCurrentIrpStackLocation (p_IRP);
1488
 
  if (p_DeviceObject->DeviceType != (FILE_DEVICE_PHYSICAL_NETCARD | 0x8000))
1489
 
    {
1490
 
      return (*g_DispatchHook[l_IrpSp->MajorFunction]) (p_DeviceObject,
1491
 
                                                        p_IRP);
1492
 
    }
1493
 
 
1494
 
  //=============================================================
1495
 
  //     Only TAP device I/O requests get handled below here
1496
 
  //=============================================================
1497
 
  l_Extension = (TapExtensionPointer) p_DeviceObject->DeviceExtension;
1498
 
  l_Adapter = l_Extension->m_Adapter;
1499
1558
 
1500
1559
  p_IRP->IoStatus.Status = STATUS_SUCCESS;
1501
1560
  p_IRP->IoStatus.Information = 0;
1502
1561
 
1503
 
  if (l_Extension->m_halt)
 
1562
  if (!l_Adapter || l_Adapter->m_Extension.m_Halt)
1504
1563
    {
1505
 
      DEBUGP (("TapDeviceHook called when TAP device is halted\n"));
1506
 
      p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
1507
 
      IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1508
 
      return STATUS_NO_SUCH_DEVICE;
 
1564
      DEBUGP (("TapDeviceHook called when TAP device is halted, MajorFunction=%d\n",
 
1565
               (int)l_IrpSp->MajorFunction));
 
1566
 
 
1567
      if (l_IrpSp->MajorFunction == IRP_MJ_CLOSE)
 
1568
        {
 
1569
          IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
 
1570
          return STATUS_SUCCESS;
 
1571
        }
 
1572
      else
 
1573
        {
 
1574
          p_IRP->IoStatus.Status = STATUS_NO_SUCH_DEVICE;
 
1575
          IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
 
1576
          return STATUS_NO_SUCH_DEVICE;
 
1577
        }
1509
1578
    }
1510
1579
 
1511
1580
  switch (l_IrpSp->MajorFunction)
1528
1597
                }
1529
1598
              else
1530
1599
                {
1531
 
                  NOTE_ERROR (l_Adapter);
 
1600
                  NOTE_ERROR ();
1532
1601
                  p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1533
1602
                }
1534
1603
              break;
1547
1616
#if DBG
1548
1617
                    = 1;
1549
1618
#else
1550
 
                    = 0;
 
1619
                  = 0;
1551
1620
#endif
1552
1621
                  p_IRP->IoStatus.Information = size;
1553
1622
                }
1554
1623
              else
1555
1624
                {
1556
 
                  NOTE_ERROR (l_Adapter);
 
1625
                  NOTE_ERROR ();
1557
1626
                  p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1558
1627
                }
1559
1628
 
1571
1640
                }
1572
1641
              else
1573
1642
                {
1574
 
                  NOTE_ERROR (l_Adapter);
 
1643
                  NOTE_ERROR ();
1575
1644
                  p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1576
1645
                }
1577
1646
 
1584
1653
                state[0] = 'A';
1585
1654
              else
1586
1655
                state[0] = 'a';
1587
 
              if (l_Adapter->m_TapIsRunning)
 
1656
              if (l_Adapter->m_Extension.m_TapIsRunning)
1588
1657
                state[1] = 'T';
1589
1658
              else
1590
1659
                state[1] = 't';
1603
1672
                STRSAFE_FILL_BEHIND_NULL | STRSAFE_IGNORE_NULLS,
1604
1673
                "State=%s Err=[%s/%d] #O=%d Tx=[%d,%d] Rx=[%d,%d] IrpQ=[%d,%d,%d] PktQ=[%d,%d,%d]",
1605
1674
                state,
1606
 
                l_Adapter->m_LastErrorFilename,
1607
 
                l_Adapter->m_LastErrorLineNumber,
1608
 
                (int)l_Adapter->m_NumTapOpens,
 
1675
                g_LastErrorFilename,
 
1676
                g_LastErrorLineNumber,
 
1677
                (int)l_Adapter->m_Extension.m_NumTapOpens,
1609
1678
                (int)l_Adapter->m_Tx,
1610
1679
                (int)l_Adapter->m_TxErr,
1611
1680
                (int)l_Adapter->m_Rx,
1612
1681
                (int)l_Adapter->m_RxErr,
1613
 
                (int)l_Extension->m_IrpQueue->size,
1614
 
                (int)l_Extension->m_IrpQueue->max_size,
 
1682
                (int)l_Adapter->m_Extension.m_IrpQueue->size,
 
1683
                (int)l_Adapter->m_Extension.m_IrpQueue->max_size,
1615
1684
                (int)IRP_QUEUE_SIZE,
1616
 
                (int)l_Extension->m_PacketQueue->size,
1617
 
                (int)l_Extension->m_PacketQueue->max_size,
 
1685
                (int)l_Adapter->m_Extension.m_PacketQueue->size,
 
1686
                (int)l_Adapter->m_Extension.m_PacketQueue->max_size,
1618
1687
                (int)PACKET_QUEUE_SIZE
1619
1688
                );
1620
1689
 
1640
1709
            }
1641
1710
#endif
1642
1711
 
1643
 
#ifdef NEED_TAP_IOCTL_GET_LASTMAC
1644
 
          case TAP_IOCTL_GET_LASTMAC:
1645
 
            {
1646
 
              if (l_IrpSp->Parameters.DeviceIoControl.OutputBufferLength >=
1647
 
                  sizeof (MACADDR))
1648
 
                {
1649
 
                  COPY_MAC (p_IRP->AssociatedIrp.SystemBuffer, g_MAC);
1650
 
                  p_IRP->IoStatus.Information = sizeof (MACADDR);
1651
 
                }
1652
 
              else
1653
 
                {
1654
 
                  NOTE_ERROR (l_Adapter);
1655
 
                  p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
1656
 
                }
1657
 
 
1658
 
              break;
1659
 
            }
1660
 
#endif
1661
 
 
1662
 
#ifdef NEED_TAP_IOCTL_SET_STATISTICS
1663
 
          case TAP_IOCTL_SET_STATISTICS:
1664
 
            {
1665
 
              if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
1666
 
                  (sizeof (ULONG) * 4))
1667
 
                {
1668
 
                  l_Adapter->m_Tx =
1669
 
                    ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[0];
1670
 
                  l_Adapter->m_Rx =
1671
 
                    ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[1];
1672
 
                  l_Adapter->m_TxErr =
1673
 
                    ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[2];
1674
 
                  l_Adapter->m_RxErr =
1675
 
                    ((PULONG) (p_IRP->AssociatedIrp.SystemBuffer))[3];
1676
 
                  p_IRP->IoStatus.Information = 1; // Simple boolean value
1677
 
                }
1678
 
              else
1679
 
                {
1680
 
                  NOTE_ERROR (l_Adapter);
1681
 
                  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1682
 
                }
1683
 
              
1684
 
              break;
1685
 
            }
1686
 
#endif
1687
1712
          case TAP_IOCTL_CONFIG_POINT_TO_POINT:
1688
1713
            {
1689
1714
              if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
1691
1716
                {
1692
1717
                  MACADDR dest;
1693
1718
 
1694
 
                  NdisAcquireSpinLock (&l_Adapter->m_Lock);
 
1719
                  l_Adapter->m_PointToPoint = FALSE;
1695
1720
 
1696
1721
                  GenerateRelatedMAC (dest, l_Adapter->m_MAC, 1);
1697
1722
 
1698
 
                  l_Adapter->m_PointToPoint = TRUE;
1699
 
 
1700
1723
                  l_Adapter->m_localIP =
1701
1724
                    ((IPADDR*) (p_IRP->AssociatedIrp.SystemBuffer))[0];
1702
1725
                  l_Adapter->m_remoteIP =
1709
1732
 
1710
1733
                  l_Adapter->m_TapToUser.proto = l_Adapter->m_UserToTap.proto = htons (ETH_P_IP);
1711
1734
 
 
1735
                  l_Adapter->m_PointToPoint = TRUE;
 
1736
 
1712
1737
                  CheckIfDhcpAndPointToPointMode (l_Adapter);
1713
1738
 
1714
 
                  NdisReleaseSpinLock (&l_Adapter->m_Lock);
1715
 
 
1716
1739
                  p_IRP->IoStatus.Information = 1; // Simple boolean value
1717
1740
                }
1718
1741
              else
1719
1742
                {
1720
 
                  NOTE_ERROR (l_Adapter);
 
1743
                  NOTE_ERROR ();
1721
1744
                  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1722
1745
                }
1723
1746
              
1735
1758
                }
1736
1759
              else
1737
1760
                {
1738
 
                  NOTE_ERROR (l_Adapter);
 
1761
                  NOTE_ERROR ();
1739
1762
                  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1740
1763
                }
1741
1764
              break;
1746
1769
              if (l_IrpSp->Parameters.DeviceIoControl.InputBufferLength >=
1747
1770
                  (sizeof (IPADDR) * 4))
1748
1771
                {
1749
 
                  NdisAcquireSpinLock (&l_Adapter->m_Lock);
1750
 
 
1751
 
                  l_Adapter->m_dhcp_enabled = TRUE;
1752
 
                  l_Adapter->m_dhcp_server_arp = TRUE;
 
1772
                  l_Adapter->m_dhcp_enabled = FALSE;
 
1773
                  l_Adapter->m_dhcp_server_arp = FALSE;
1753
1774
                  l_Adapter->m_dhcp_user_supplied_options_buffer_len = 0;
1754
1775
 
1755
1776
                  // Adapter IP addr / netmask
1768
1789
 
1769
1790
                  GenerateRelatedMAC (l_Adapter->m_dhcp_server_mac, l_Adapter->m_MAC, 2);
1770
1791
 
 
1792
                  l_Adapter->m_dhcp_enabled = TRUE;
 
1793
                  l_Adapter->m_dhcp_server_arp = TRUE;
 
1794
 
1771
1795
                  CheckIfDhcpAndPointToPointMode (l_Adapter);
1772
1796
 
1773
 
                  NdisReleaseSpinLock (&l_Adapter->m_Lock);
1774
 
 
1775
1797
                  p_IRP->IoStatus.Information = 1; // Simple boolean value
1776
1798
                }
1777
1799
              else
1778
1800
                {
1779
 
                  NOTE_ERROR (l_Adapter);
 
1801
                  NOTE_ERROR ();
1780
1802
                  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1781
1803
                }
1782
1804
              
1802
1824
                }
1803
1825
              else
1804
1826
                {
1805
 
                  NOTE_ERROR (l_Adapter);
 
1827
                  NOTE_ERROR ();
1806
1828
                  p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1807
1829
                }
1808
1830
              
1811
1833
 
1812
1834
          default:
1813
1835
            {
1814
 
              NOTE_ERROR (l_Adapter);
 
1836
              NOTE_ERROR ();
1815
1837
              p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1816
1838
              break;
1817
1839
            }
1839
1861
        if (p_IRP->MdlAddress == NULL)
1840
1862
          {
1841
1863
            DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_READ\n",
1842
 
                      l_Adapter->m_Name));
1843
 
            NOTE_ERROR (l_Adapter);
 
1864
                     NAME (l_Adapter)));
 
1865
            NOTE_ERROR ();
1844
1866
            p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1845
1867
            p_IRP->IoStatus.Information = 0;
1846
1868
            IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1851
1873
                  (p_IRP->MdlAddress, NormalPagePriority)) == NULL)
1852
1874
          {
1853
1875
            DEBUGP (("[%s] Could not map address in IRP_MJ_READ\n",
1854
 
                      l_Adapter->m_Name));
1855
 
            NOTE_ERROR (l_Adapter);
 
1876
                     NAME (l_Adapter)));
 
1877
            NOTE_ERROR ();
1856
1878
            p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
1857
1879
            p_IRP->IoStatus.Information = 0;
1858
1880
            IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1861
1883
        else if (!l_Adapter->m_InterfaceIsRunning)
1862
1884
          {
1863
1885
            DEBUGP (("[%s] Interface is down in IRP_MJ_READ\n",
1864
 
                      l_Adapter->m_Name));
1865
 
            NOTE_ERROR (l_Adapter);
 
1886
                     NAME (l_Adapter)));
 
1887
            NOTE_ERROR ();
1866
1888
            p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
1867
1889
            p_IRP->IoStatus.Information = 0;
1868
1890
            IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1875
1897
 
1876
1898
        l_PacketBuffer = NULL;
1877
1899
 
1878
 
        NdisAcquireSpinLock (&l_Adapter->m_QueueLock);
 
1900
        NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1879
1901
 
1880
1902
        if (IS_UP (l_Adapter)
1881
 
            && QueueCount (l_Extension->m_PacketQueue)
1882
 
            && QueueCount (l_Extension->m_IrpQueue) == 0)
 
1903
            && QueueCount (l_Adapter->m_Extension.m_PacketQueue)
 
1904
            && QueueCount (l_Adapter->m_Extension.m_IrpQueue) == 0)
1883
1905
          {
1884
1906
            l_PacketBuffer = (TapPacketPointer)
1885
 
              QueuePop (l_Extension->m_PacketQueue);
 
1907
              QueuePop (l_Adapter->m_Extension.m_PacketQueue);
1886
1908
          }
1887
1909
 
1888
 
        NdisReleaseSpinLock (&l_Adapter->m_QueueLock);
 
1910
        NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1889
1911
 
1890
1912
        if (l_PacketBuffer)
1891
1913
          {
1892
 
            l_Status = CompleteIRP (l_Adapter,
1893
 
                                    p_IRP,
 
1914
            l_Status = CompleteIRP (p_IRP,
1894
1915
                                    l_PacketBuffer,
1895
1916
                                    IO_NO_INCREMENT);
1896
1917
            break;
1900
1921
        // Attempt to pend read request
1901
1922
        //=============================
1902
1923
 
1903
 
        NdisAcquireSpinLock (&l_Adapter->m_QueueLock);
 
1924
        NdisAcquireSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1904
1925
 
1905
1926
        if (IS_UP (l_Adapter)
1906
 
            && QueuePush (l_Extension->m_IrpQueue, p_IRP) == (PIRP) p_IRP)
 
1927
            && QueuePush (l_Adapter->m_Extension.m_IrpQueue, p_IRP) == (PIRP) p_IRP)
1907
1928
          {
1908
1929
            IoSetCancelRoutine (p_IRP, CancelIRPCallback);
1909
1930
            l_Status = STATUS_PENDING;
1911
1932
            pending = TRUE;
1912
1933
          }
1913
1934
 
1914
 
        NdisReleaseSpinLock (&l_Adapter->m_QueueLock);
 
1935
        NdisReleaseSpinLock (&l_Adapter->m_Extension.m_QueueLock);
1915
1936
 
1916
1937
        if (pending)
1917
1938
          break;
1918
1939
 
1919
1940
        // Can't queue anymore IRP's
1920
1941
        DEBUGP (("[%s] TAP [%s] read IRP overrun\n",
1921
 
                 l_Adapter->m_Name, l_Adapter->m_TapName));
1922
 
        NOTE_ERROR (l_Adapter);
 
1942
                 NAME (l_Adapter), l_Adapter->m_Extension.m_TapName));
 
1943
        NOTE_ERROR ();
1923
1944
        p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
1924
1945
        p_IRP->IoStatus.Information = 0;
1925
1946
        IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
1936
1957
        if (p_IRP->MdlAddress == NULL)
1937
1958
          {
1938
1959
            DEBUGP (("[%s] MdlAddress is NULL for IRP_MJ_WRITE\n",
1939
 
                      l_Adapter->m_Name));
1940
 
            NOTE_ERROR (l_Adapter);
 
1960
                     NAME (l_Adapter)));
 
1961
            NOTE_ERROR ();
1941
1962
            p_IRP->IoStatus.Status = l_Status = STATUS_INVALID_PARAMETER;
1942
1963
            p_IRP->IoStatus.Information = 0;
1943
1964
          }
1946
1967
                  (p_IRP->MdlAddress, NormalPagePriority)) == NULL)
1947
1968
          {
1948
1969
            DEBUGP (("[%s] Could not map address in IRP_MJ_WRITE\n",
1949
 
                      l_Adapter->m_Name));
1950
 
            NOTE_ERROR (l_Adapter);
 
1970
                     NAME (l_Adapter)));
 
1971
            NOTE_ERROR ();
1951
1972
            p_IRP->IoStatus.Status = l_Status = STATUS_INSUFFICIENT_RESOURCES;
1952
1973
            p_IRP->IoStatus.Information = 0;
1953
1974
          }
1954
1975
        else if (!l_Adapter->m_InterfaceIsRunning)
1955
1976
          {
1956
1977
            DEBUGP (("[%s] Interface is down in IRP_MJ_WRITE\n",
1957
 
                      l_Adapter->m_Name));
1958
 
            NOTE_ERROR (l_Adapter);
 
1978
                     NAME (l_Adapter)));
 
1979
            NOTE_ERROR ();
1959
1980
            p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
1960
1981
            p_IRP->IoStatus.Information = 0;
1961
1982
          }
1982
2003
 
1983
2004
                p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
1984
2005
              }
1985
 
              __except (EXCEPTION_EXECUTE_HANDLER)
 
2006
            __except (EXCEPTION_EXECUTE_HANDLER)
1986
2007
              {
1987
2008
                DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE\n",
1988
 
                         l_Adapter->m_Name));
1989
 
                NOTE_ERROR (l_Adapter);
 
2009
                         NAME (l_Adapter)));
 
2010
                NOTE_ERROR ();
1990
2011
                p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
1991
2012
                p_IRP->IoStatus.Information = 0;
1992
2013
              }
2015
2036
 
2016
2037
                p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2017
2038
              }
2018
 
              __except (EXCEPTION_EXECUTE_HANDLER)
 
2039
            __except (EXCEPTION_EXECUTE_HANDLER)
2019
2040
              {
2020
2041
                DEBUGP (("[%s] NdisMEthIndicateReceive failed in IRP_MJ_WRITE (P2P)\n",
2021
 
                         l_Adapter->m_Name));
2022
 
                NOTE_ERROR (l_Adapter);
 
2042
                         NAME (l_Adapter)));
 
2043
                NOTE_ERROR ();
2023
2044
                p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2024
2045
                p_IRP->IoStatus.Information = 0;
2025
2046
              }
2027
2048
        else
2028
2049
          {
2029
2050
            DEBUGP (("[%s] Bad buffer size in IRP_MJ_WRITE, len=%d\n",
2030
 
                          l_Adapter->m_Name,
2031
 
                          l_IrpSp->Parameters.Write.Length));
2032
 
            NOTE_ERROR (l_Adapter);
 
2051
                     NAME (l_Adapter),
 
2052
                     l_IrpSp->Parameters.Write.Length));
 
2053
            NOTE_ERROR ();
2033
2054
            p_IRP->IoStatus.Information = 0;    // ETHERNET_HEADER_SIZE;
2034
2055
            p_IRP->IoStatus.Status = l_Status = STATUS_BUFFER_TOO_SMALL;
2035
2056
          }
2036
2057
 
2037
 
#ifndef NEED_TAP_IOCTL_SET_STATISTICS
2038
2058
        if (l_Status == STATUS_SUCCESS)
2039
2059
          INCREMENT_STAT (l_Adapter->m_Rx);
2040
2060
        else
2041
2061
          INCREMENT_STAT (l_Adapter->m_RxErr);
2042
 
#endif
 
2062
 
2043
2063
        IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2044
2064
        break;
2045
2065
      }
2049
2069
      //--------------------------------------------------------------
2050
2070
    case IRP_MJ_CREATE:
2051
2071
      {
2052
 
        if (l_Adapter->m_TapIsRunning
2053
 
#ifdef DISABLE_DEVICE_SHARING
2054
 
            && l_Adapter->m_TapOpens < 1
2055
 
#endif
2056
 
            )
 
2072
        BOOLEAN succeeded = FALSE;
 
2073
        BOOLEAN mutex_succeeded;
 
2074
 
 
2075
        DEBUGP
 
2076
          (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
 
2077
            NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
 
2078
            TAP_DRIVER_MINOR_VERSION, l_Adapter->m_Extension.m_TapOpens));
 
2079
 
 
2080
        ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
 
2081
        if (mutex_succeeded)
2057
2082
          {
2058
 
            BOOLEAN first_open;
2059
 
 
2060
 
            DEBUGP
2061
 
              (("[%s] [TAP] release [%d.%d] open request (m_TapOpens=%d)\n",
2062
 
               l_Adapter->m_Name, TAP_DRIVER_MAJOR_VERSION,
2063
 
               TAP_DRIVER_MINOR_VERSION, l_Adapter->m_TapOpens));
2064
 
 
2065
 
            NdisAcquireSpinLock (&l_Adapter->m_Lock);
2066
 
            ++l_Adapter->m_TapOpens;
2067
 
            first_open = (l_Adapter->m_TapOpens == 1);
2068
 
            if (first_open)
2069
 
              ResetTapDevState (l_Adapter);
2070
 
            NdisReleaseSpinLock (&l_Adapter->m_Lock);
2071
 
 
2072
 
#ifdef SET_MEDIA_STATUS_ON_OPEN
2073
 
            if (first_open)
2074
 
              SetMediaStatus (l_Adapter, TRUE);
2075
 
#endif
2076
 
 
2077
 
            INCREMENT_STAT (l_Adapter->m_NumTapOpens);
2078
 
            p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
2079
 
            p_IRP->IoStatus.Information = 0;
 
2083
            if (l_Adapter->m_Extension.m_TapIsRunning && !l_Adapter->m_Extension.m_TapOpens)
 
2084
              {
 
2085
                ResetTapAdapterState (l_Adapter);
 
2086
                l_Adapter->m_Extension.m_TapOpens = 1;
 
2087
                succeeded = TRUE;
 
2088
              }
 
2089
 
 
2090
            if (succeeded)
 
2091
              {
 
2092
                INCREMENT_STAT (l_Adapter->m_Extension.m_NumTapOpens);
 
2093
                p_IRP->IoStatus.Status = l_Status = STATUS_SUCCESS;
 
2094
                p_IRP->IoStatus.Information = 0;
 
2095
              }
 
2096
            else
 
2097
              {
 
2098
                DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
 
2099
                         NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
 
2100
                NOTE_ERROR ();
 
2101
                p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
 
2102
                p_IRP->IoStatus.Information = 0;
 
2103
              }
 
2104
 
 
2105
            RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
2080
2106
          }
2081
2107
        else
2082
2108
          {
2083
 
            DEBUGP (("[%s] TAP is presently unavailable (m_TapOpens=%d)\n",
2084
 
                      l_Adapter->m_Name, l_Adapter->m_TapOpens));
2085
 
            NOTE_ERROR (l_Adapter);
 
2109
            DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
 
2110
                     NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
 
2111
            NOTE_ERROR ();
2086
2112
            p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2087
2113
            p_IRP->IoStatus.Information = 0;
2088
2114
          }
2096
2122
      //-----------------------------------------------------------
2097
2123
    case IRP_MJ_CLOSE:
2098
2124
      {
2099
 
        BOOLEAN fully_closed = FALSE;
2100
 
        
2101
 
        DEBUGP (("[%s] [TAP] release [%d.%d] close request\n",
2102
 
                  l_Adapter->m_Name, TAP_DRIVER_MAJOR_VERSION,
2103
 
                  TAP_DRIVER_MINOR_VERSION));
2104
 
 
2105
 
        NdisAcquireSpinLock (&l_Adapter->m_Lock);
2106
 
        if (l_Adapter->m_TapOpens)
2107
 
          {
2108
 
            --l_Adapter->m_TapOpens;
2109
 
            if (l_Adapter->m_TapOpens == 0)
2110
 
              {
2111
 
                fully_closed = TRUE;
2112
 
                ResetTapDevState (l_Adapter);
2113
 
              }
2114
 
          }
2115
 
        NdisReleaseSpinLock (&l_Adapter->m_Lock);
2116
 
 
2117
 
        if (fully_closed)
2118
 
          {
2119
 
            FlushQueues (l_Adapter);
 
2125
        BOOLEAN mutex_succeeded;
 
2126
 
 
2127
        DEBUGP (("[%s] [TAP] release [%d.%d] close/cleanup request\n",
 
2128
                 NAME (l_Adapter), TAP_DRIVER_MAJOR_VERSION,
 
2129
                 TAP_DRIVER_MINOR_VERSION));
 
2130
 
 
2131
        ACQUIRE_MUTEX_ADAPTIVE (&l_Adapter->m_Extension.m_OpenCloseMutex, mutex_succeeded);
 
2132
        if (mutex_succeeded)
 
2133
          {
 
2134
            l_Adapter->m_Extension.m_TapOpens = 0;
 
2135
            ResetTapAdapterState (l_Adapter);
 
2136
            FlushQueues (&l_Adapter->m_Extension);
2120
2137
            SetMediaStatus (l_Adapter, FALSE);
2121
 
          }
2122
 
 
 
2138
            RELEASE_MUTEX (&l_Adapter->m_Extension.m_OpenCloseMutex);
 
2139
          }
 
2140
        else
 
2141
          {
 
2142
            DEBUGP (("[%s] TAP is presently locked (m_TapOpens=%d)\n",
 
2143
                     NAME (l_Adapter), l_Adapter->m_Extension.m_TapOpens));
 
2144
            NOTE_ERROR ();
 
2145
            p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
 
2146
            p_IRP->IoStatus.Information = 0;
 
2147
          }
 
2148
        
2123
2149
        IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2124
2150
        break;
2125
2151
      }
2129
2155
      //------------------
2130
2156
    default:
2131
2157
      {
2132
 
        //NOTE_ERROR (l_Adapter);
 
2158
        //NOTE_ERROR ();
2133
2159
        p_IRP->IoStatus.Status = l_Status = STATUS_UNSUCCESSFUL;
2134
2160
        IoCompleteRequest (p_IRP, IO_NO_INCREMENT);
2135
2161
        break;
2150
2176
//=============================================================
2151
2177
 
2152
2178
NTSTATUS
2153
 
CompleteIRP (TapAdapterPointer p_Adapter,
2154
 
             IN PIRP p_IRP,
 
2179
CompleteIRP (IN PIRP p_IRP,
2155
2180
             IN TapPacketPointer p_PacketBuffer,
2156
2181
             IN CCHAR PriorityBoost)
2157
2182
{
2188
2213
    {
2189
2214
      p_IRP->IoStatus.Information = 0;
2190
2215
      p_IRP->IoStatus.Status = STATUS_BUFFER_OVERFLOW;
2191
 
      NOTE_ERROR (p_Adapter);
 
2216
      NOTE_ERROR ();
2192
2217
    }
2193
2218
  else
2194
2219
    {
2203
2228
        }
2204
2229
      __except (EXCEPTION_EXECUTE_HANDLER)
2205
2230
        {
2206
 
          NOTE_ERROR (p_Adapter);
 
2231
          NOTE_ERROR ();
2207
2232
          p_IRP->IoStatus.Status = STATUS_UNSUCCESSFUL;
2208
2233
          p_IRP->IoStatus.Information = 0;
2209
2234
        }
2243
2268
CancelIRPCallback (IN PDEVICE_OBJECT p_DeviceObject,
2244
2269
                   IN PIRP p_IRP)
2245
2270
{
2246
 
  CancelIRP (p_DeviceObject, p_IRP, TRUE);
 
2271
  TapAdapterPointer l_Adapter = LookupAdapterInInstanceList (p_DeviceObject);
 
2272
  CancelIRP (l_Adapter ? &l_Adapter->m_Extension : NULL, p_IRP, TRUE);
2247
2273
}
2248
2274
 
2249
2275
VOID
2250
 
CancelIRP (IN PDEVICE_OBJECT p_DeviceObject,
 
2276
CancelIRP (TapExtensionPointer p_Extension,
2251
2277
           IN PIRP p_IRP,
2252
2278
           BOOLEAN callback)
2253
2279
{
2254
 
  TapExtensionPointer l_Extension =
2255
 
    (TapExtensionPointer) p_DeviceObject->DeviceExtension;
2256
 
 
2257
2280
  BOOLEAN exists = FALSE;
2258
2281
 
2259
2282
  MYASSERT (p_IRP);
2260
2283
 
2261
 
  if (!l_Extension->m_halt)
 
2284
  if (p_Extension)
2262
2285
    {
2263
 
      NdisAcquireSpinLock (&l_Extension->m_Adapter->m_QueueLock);
2264
 
      exists = (QueueExtract (l_Extension->m_IrpQueue, p_IRP) == p_IRP);
2265
 
      NdisReleaseSpinLock (&l_Extension->m_Adapter->m_QueueLock);
 
2286
      NdisAcquireSpinLock (&p_Extension->m_QueueLock);
 
2287
      exists = (QueueExtract (p_Extension->m_IrpQueue, p_IRP) == p_IRP);
 
2288
      NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2266
2289
    }
2267
2290
  else
2268
2291
    exists = TRUE;
2285
2308
// Exhaust packet and IRP queues.
2286
2309
//====================================
2287
2310
VOID
2288
 
FlushQueues (TapAdapterPointer p_Adapter)
 
2311
FlushQueues (TapExtensionPointer p_Extension)
2289
2312
{
2290
2313
  PIRP l_IRP;
2291
2314
  TapPacketPointer l_PacketBuffer;
2292
2315
  int n_IRP=0, n_Packet=0;
2293
 
  TapExtensionPointer l_Extension;
2294
 
 
2295
 
  MYASSERT (p_Adapter);
2296
 
  MYASSERT (p_Adapter->m_TapDevice);
2297
 
 
2298
 
  l_Extension = (TapExtensionPointer)
2299
 
    p_Adapter->m_TapDevice->DeviceExtension;
 
2316
 
 
2317
  MYASSERT (p_Extension);
 
2318
  MYASSERT (p_Extension->m_TapDevice);
2300
2319
 
2301
2320
  while (TRUE)
2302
2321
    {
2303
 
      NdisAcquireSpinLock (&p_Adapter->m_QueueLock);
2304
 
      l_IRP = QueuePop (l_Extension->m_IrpQueue);
2305
 
      NdisReleaseSpinLock (&p_Adapter->m_QueueLock);
 
2322
      NdisAcquireSpinLock (&p_Extension->m_QueueLock);
 
2323
      l_IRP = QueuePop (p_Extension->m_IrpQueue);
 
2324
      NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2306
2325
      if (l_IRP)
2307
2326
        {
2308
2327
          ++n_IRP;
2309
 
          CancelIRP (p_Adapter->m_TapDevice, l_IRP, FALSE);
 
2328
          CancelIRP (NULL, l_IRP, FALSE);
2310
2329
        }
2311
2330
      else
2312
2331
        break;
2314
2333
 
2315
2334
  while (TRUE)
2316
2335
    {
2317
 
      NdisAcquireSpinLock (&p_Adapter->m_QueueLock);
2318
 
      l_PacketBuffer = QueuePop (l_Extension->m_PacketQueue);
2319
 
      NdisReleaseSpinLock (&p_Adapter->m_QueueLock);
 
2336
      NdisAcquireSpinLock (&p_Extension->m_QueueLock);
 
2337
      l_PacketBuffer = QueuePop (p_Extension->m_PacketQueue);
 
2338
      NdisReleaseSpinLock (&p_Extension->m_QueueLock);
2320
2339
      if (l_PacketBuffer)
2321
2340
        {
2322
2341
          ++n_Packet;
2328
2347
 
2329
2348
  DEBUGP ((
2330
2349
           "[%s] [TAP] FlushQueues n_IRP=[%d,%d,%d] n_Packet=[%d,%d,%d]\n",
2331
 
           p_Adapter->m_Name,
 
2350
           p_Extension->m_TapName,
2332
2351
           n_IRP,
2333
 
           l_Extension->m_IrpQueue->max_size,
 
2352
           p_Extension->m_IrpQueue->max_size,
2334
2353
           IRP_QUEUE_SIZE,
2335
2354
           n_Packet,
2336
 
           l_Extension->m_PacketQueue->max_size,
 
2355
           p_Extension->m_PacketQueue->max_size,
2337
2356
           PACKET_QUEUE_SIZE
2338
2357
           ));
2339
2358
}
2449
2468
//===============================================================
2450
2469
 
2451
2470
VOID
2452
 
InjectPacket (TapAdapterPointer p_Adapter, UCHAR *packet, const unsigned int len)
 
2471
InjectPacket (TapAdapterPointer p_Adapter,
 
2472
              UCHAR *packet,
 
2473
              const unsigned int len)
2453
2474
{
2454
2475
  MYASSERT (len >= ETHERNET_HEADER_SIZE);
2455
2476
 
2476
2497
  __except (EXCEPTION_EXECUTE_HANDLER)
2477
2498
    {
2478
2499
      DEBUGP (("[%s] NdisMEthIndicateReceive failed in InjectPacket\n",
2479
 
               p_Adapter->m_Name));
2480
 
      NOTE_ERROR (p_Adapter);
 
2500
               NAME (p_Adapter)));
 
2501
      NOTE_ERROR ();
2481
2502
    }
2482
2503
}
2483
2504
 
2485
2506
// Go back to default TAP mode from Point-To-Point mode.
2486
2507
// Also reset (i.e. disable) DHCP Masq mode.
2487
2508
//===================================================================
2488
 
VOID ResetTapDevState (TapAdapterPointer p_Adapter)
 
2509
VOID ResetTapAdapterState (TapAdapterPointer p_Adapter)
2489
2510
{
2490
2511
  // Point-To-Point
2491
2512
  p_Adapter->m_PointToPoint = FALSE;
2506
2527
  p_Adapter->m_dhcp_bad_requests = 0;
2507
2528
  NdisZeroMemory (p_Adapter->m_dhcp_server_mac, sizeof (MACADDR));
2508
2529
}
2509
 
 
2510
 
//===================================================================
2511
 
//                             Dispatch Table Managemement
2512
 
//===================================================================
2513
 
VOID
2514
 
HookDispatchFunctions ()
2515
 
{
2516
 
  unsigned long l_Index;
2517
 
 
2518
 
  //==============================================================
2519
 
  // Save original NDIS dispatch functions and override with ours
2520
 
  //==============================================================
2521
 
  if (!g_DispatchFunctionsHooked)
2522
 
    for (l_Index = 0, g_DispatchFunctionsHooked = 1;
2523
 
         l_Index <= IRP_MJ_MAXIMUM_FUNCTION; ++l_Index)
2524
 
      {
2525
 
        g_DispatchHook[l_Index] = g_TapDriverObject->MajorFunction[l_Index];
2526
 
        g_TapDriverObject->MajorFunction[l_Index] = TapDeviceHook;
2527
 
      }
2528
 
}
2529
 
 
2530
2530
//======================================================================
2531
2531
//                                    End of Source
2532
2532
//======================================================================