passthru.c
上传用户:zhuzhu0204
上传日期:2020-07-13
资源大小:13165k
文件大小:11k
开发平台:

Visual C++

  1. /*++
  2. Copyright (c) 1992-2000  Microsoft Corporation
  3.  
  4. Module Name:
  5.  
  6.     passthru.c
  7. Abstract:
  8.     Ndis Intermediate Miniport driver sample. This is a passthru driver.
  9. Author:
  10. Environment:
  11. Revision History:
  12. --*/
  13. #include "precomp.h"
  14. #pragma hdrstop
  15. #pragma NDIS_INIT_FUNCTION(DriverEntry)
  16. NDIS_HANDLE         ProtHandle = NULL;
  17. NDIS_HANDLE         DriverHandle = NULL;
  18. NDIS_MEDIUM         MediumArray[4] =
  19.                     {
  20.                         NdisMedium802_3,    // Ethernet
  21.                         NdisMedium802_5,    // Token-ring
  22.                         NdisMediumFddi,     // Fddi
  23.                         NdisMediumWan       // NDISWAN
  24.                     };
  25. NDIS_SPIN_LOCK     GlobalLock;
  26. PADAPT             pAdaptList = NULL;
  27. LONG               MiniportCount = 0;
  28. NDIS_HANDLE        NdisWrapperHandle;
  29. //
  30. // To support ioctls from user-mode:
  31. //
  32. #define LINKNAME_STRING     L"\DosDevices\Passthru"
  33. #define NTDEVICE_STRING     L"\Device\Passthru"
  34. NDIS_HANDLE     NdisDeviceHandle = NULL;
  35. PDEVICE_OBJECT  ControlDeviceObject = NULL;
  36. int nWorkMode = 0;
  37. BOOLEAN bPingIn  = FALSE;
  38. BOOLEAN bPingOut = TRUE;
  39. enum _DEVICE_STATE
  40. {
  41.     PS_DEVICE_STATE_READY = 0,    // ready for create/delete
  42.     PS_DEVICE_STATE_CREATING,    // create operation in progress
  43.     PS_DEVICE_STATE_DELETING    // delete operation in progress
  44. } ControlDeviceState = PS_DEVICE_STATE_READY;
  45. NTSTATUS
  46. DriverEntry(
  47.     IN PDRIVER_OBJECT        DriverObject,
  48.     IN PUNICODE_STRING       RegistryPath
  49.     )
  50. /*++
  51. Routine Description:
  52.     First entry point to be called, when this driver is loaded.
  53.     Register with NDIS as an intermediate driver.
  54. Arguments:
  55.     DriverObject - pointer to the system's driver object structure
  56.         for this driver
  57.     
  58.     RegistryPath - system's registry path for this driver
  59.     
  60. Return Value:
  61.     STATUS_SUCCESS if all initialization is successful, STATUS_XXX
  62.     error code if not.
  63. --*/
  64. {
  65.     NDIS_STATUS                        Status;
  66.     NDIS_PROTOCOL_CHARACTERISTICS      PChars;
  67.     NDIS_MINIPORT_CHARACTERISTICS      MChars;
  68.     NDIS_STRING                        Name;
  69.     Status = NDIS_STATUS_SUCCESS;
  70.     NdisAllocateSpinLock(&GlobalLock);
  71.     NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);
  72.     do
  73.     {
  74.         //
  75.         // Register the miniport with NDIS. Note that it is the miniport
  76.         // which was started as a driver and not the protocol. Also the miniport
  77.         // must be registered prior to the protocol since the protocol's BindAdapter
  78.         // handler can be initiated anytime and when it is, it must be ready to
  79.         // start driver instances.
  80.         //
  81.         NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
  82.         MChars.MajorNdisVersion = PASSTHRU_MAJOR_NDIS_VERSION;
  83.         MChars.MinorNdisVersion = PASSTHRU_MINOR_NDIS_VERSION;
  84.         MChars.InitializeHandler = MPInitialize;
  85.         MChars.QueryInformationHandler = MPQueryInformation;
  86.         MChars.SetInformationHandler = MPSetInformation;
  87.         MChars.ResetHandler = NULL;
  88.         MChars.TransferDataHandler = MPTransferData;
  89.         MChars.HaltHandler = MPHalt;
  90. #ifdef NDIS51_MINIPORT
  91.         MChars.CancelSendPacketsHandler = MPCancelSendPackets;
  92.         MChars.PnPEventNotifyHandler = MPDevicePnPEvent;
  93.         MChars.AdapterShutdownHandler = MPAdapterShutdown;
  94. #endif // NDIS51_MINIPORT
  95.         //
  96.         // We will disable the check for hang timeout so we do not
  97.         // need a check for hang handler!
  98.         //
  99.         MChars.CheckForHangHandler = NULL;
  100.         MChars.ReturnPacketHandler = MPReturnPacket;
  101.         //
  102.         // Either the Send or the SendPackets handler should be specified.
  103.         // If SendPackets handler is specified, SendHandler is ignored
  104.         //
  105.         MChars.SendHandler = NULL;    // MPSend;
  106.         MChars.SendPacketsHandler = MPSendPackets;
  107.         Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle,
  108.                                                   &MChars,
  109.                                                   sizeof(MChars),
  110.                                                   &DriverHandle);
  111.         if (Status != NDIS_STATUS_SUCCESS)
  112.         {
  113.             break;
  114.         }
  115. #ifndef WIN9X
  116.         NdisMRegisterUnloadHandler(NdisWrapperHandle, PtUnload);
  117. #endif
  118.         //
  119.         // Now register the protocol.
  120.         //
  121.         NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  122.         PChars.MajorNdisVersion = PASSTHRU_PROT_MAJOR_NDIS_VERSION;
  123.         PChars.MinorNdisVersion = PASSTHRU_PROT_MINOR_NDIS_VERSION;
  124.         //
  125.         // Make sure the protocol-name matches the service-name
  126.         // (from the INF) under which this protocol is installed.
  127.         // This is needed to ensure that NDIS can correctly determine
  128.         // the binding and call us to bind to miniports below.
  129.         //
  130.         NdisInitUnicodeString(&Name, L"Passthru");    // Protocol name
  131.         PChars.Name = Name;
  132.         PChars.OpenAdapterCompleteHandler = PtOpenAdapterComplete;
  133.         PChars.CloseAdapterCompleteHandler = PtCloseAdapterComplete;
  134.         PChars.SendCompleteHandler = PtSendComplete;
  135.         PChars.TransferDataCompleteHandler = PtTransferDataComplete;
  136.     
  137.         PChars.ResetCompleteHandler = PtResetComplete;
  138.         PChars.RequestCompleteHandler = PtRequestComplete;
  139.         PChars.ReceiveHandler = PtReceive;
  140.         PChars.ReceiveCompleteHandler = PtReceiveComplete;
  141.         PChars.StatusHandler = PtStatus;
  142.         PChars.StatusCompleteHandler = PtStatusComplete;
  143.         PChars.BindAdapterHandler = PtBindAdapter;
  144.         PChars.UnbindAdapterHandler = PtUnbindAdapter;
  145.         PChars.UnloadHandler = PtUnloadProtocol;
  146.         PChars.ReceivePacketHandler = PtReceivePacket;
  147.         PChars.PnPEventHandler= PtPNPHandler;
  148.         NdisRegisterProtocol(&Status,
  149.                              &ProtHandle,
  150.                              &PChars,
  151.                              sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
  152.         if (Status != NDIS_STATUS_SUCCESS)
  153.         {
  154.             NdisIMDeregisterLayeredMiniport(DriverHandle);
  155.             break;
  156.         }
  157.         NdisIMAssociateMiniport(DriverHandle, ProtHandle);
  158.     }
  159.     while (FALSE);
  160.     if (Status != NDIS_STATUS_SUCCESS)
  161.     {
  162.         NdisTerminateWrapper(NdisWrapperHandle, NULL);
  163.     }
  164.     return(Status);
  165. }
  166. NDIS_STATUS
  167. PtRegisterDevice(
  168.     VOID
  169.     )
  170. /*++
  171. Routine Description:
  172.     Register an ioctl interface - a device object to be used for this
  173.     purpose is created by NDIS when we call NdisMRegisterDevice.
  174.     This routine is called whenever a new miniport instance is
  175.     initialized. However, we only create one global device object,
  176.     when the first miniport instance is initialized. This routine
  177.     handles potential race conditions with PtDeregisterDevice via
  178.     the ControlDeviceState and MiniportCount variables.
  179.     NOTE: do not call this from DriverEntry; it will prevent the driver
  180.     from being unloaded (e.g. on uninstall).
  181. Arguments:
  182.     None
  183. Return Value:
  184.     NDIS_STATUS_SUCCESS if we successfully register a device object.
  185. --*/
  186. {
  187.     NDIS_STATUS            Status = NDIS_STATUS_SUCCESS;
  188.     UNICODE_STRING         DeviceName;
  189.     UNICODE_STRING         DeviceLinkUnicodeString;
  190.     PDRIVER_DISPATCH       DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
  191.     DBGPRINT(("==>PtRegisterDevice  Register our ioctl interface n"));
  192.     NdisAcquireSpinLock(&GlobalLock);
  193.     ++MiniportCount;
  194.     
  195.     if (1 == MiniportCount)
  196.     {
  197.         ASSERT(ControlDeviceState != PS_DEVICE_STATE_CREATING);
  198.         //
  199.         // Another thread could be running PtDeregisterDevice on
  200.         // behalf of another miniport instance. If so, wait for
  201.         // it to exit.
  202.         //
  203.         while (ControlDeviceState != PS_DEVICE_STATE_READY)
  204.         {
  205.             NdisReleaseSpinLock(&GlobalLock);
  206.             NdisMSleep(1);
  207.             NdisAcquireSpinLock(&GlobalLock);
  208.         }
  209.         ControlDeviceState = PS_DEVICE_STATE_CREATING;
  210.         NdisReleaseSpinLock(&GlobalLock);
  211.     
  212.         NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));
  213. // BEGIN_PTUSERIO 我们自己的派遣例程
  214.         DispatchTable[IRP_MJ_CREATE] = DevOpen;
  215. DispatchTable[IRP_MJ_CLEANUP] = DevCleanup;
  216.         DispatchTable[IRP_MJ_CLOSE] = DevClose;
  217.         DispatchTable[IRP_MJ_DEVICE_CONTROL] = DevIoControl;
  218. // END_PTUSERIO
  219.         
  220.         NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
  221.         NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);
  222.         //
  223.         // Create a device object and register our dispatch handlers
  224.         //
  225.         
  226.         Status = NdisMRegisterDevice(
  227.                     NdisWrapperHandle, 
  228.                     &DeviceName,
  229.                     &DeviceLinkUnicodeString,
  230.                     &DispatchTable[0],
  231.                     &ControlDeviceObject,
  232.                     &NdisDeviceHandle
  233.                     );
  234.         NdisAcquireSpinLock(&GlobalLock);
  235.         ControlDeviceState = PS_DEVICE_STATE_READY;
  236.     }
  237.     NdisReleaseSpinLock(&GlobalLock);
  238.     DBGPRINT(("<==PtRegisterDevice: %xn", Status));
  239.     return (Status);
  240. }
  241. // BEGIN_PTUSERIO
  242.       // 在这里删除了PtDispatch的实现
  243. // END_PTUSERIO
  244. NDIS_STATUS
  245. PtDeregisterDevice(
  246.     VOID
  247.     )
  248. /*++
  249. Routine Description:
  250.     Deregister the ioctl interface. This is called whenever a miniport
  251.     instance is halted. When the last miniport instance is halted, we
  252.     request NDIS to delete the device object
  253. Arguments:
  254.     NdisDeviceHandle - Handle returned by NdisMRegisterDevice
  255. Return Value:
  256.     NDIS_STATUS_SUCCESS if everything worked ok
  257. --*/
  258. {
  259.     NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  260.     DBGPRINT(("==>PassthruDeregisterDevicen"));
  261.     NdisAcquireSpinLock(&GlobalLock);
  262.     ASSERT(MiniportCount > 0);
  263.     --MiniportCount;
  264.     
  265.     if (0 == MiniportCount)
  266.     {
  267.         //
  268.         // All miniport instances have been halted. Deregister
  269.         // the control device.
  270.         //
  271.         ASSERT(ControlDeviceState == PS_DEVICE_STATE_READY);
  272.         //
  273.         // Block PtRegisterDevice() while we release the control
  274.         // device lock and deregister the device.
  275.         // 
  276.         ControlDeviceState = PS_DEVICE_STATE_DELETING;
  277.         NdisReleaseSpinLock(&GlobalLock);
  278.         if (NdisDeviceHandle != NULL)
  279.         {
  280.             Status = NdisMDeregisterDevice(NdisDeviceHandle);
  281.             NdisDeviceHandle = NULL;
  282.         }
  283.         NdisAcquireSpinLock(&GlobalLock);
  284.         ControlDeviceState = PS_DEVICE_STATE_READY;
  285.     }
  286.     NdisReleaseSpinLock(&GlobalLock);
  287.     DBGPRINT(("<== PassthruDeregisterDevice: %xn", Status));
  288.     return Status;
  289.     
  290. }
  291. VOID
  292. PtUnload(
  293.     IN PDRIVER_OBJECT        DriverObject
  294.     )
  295. //
  296. // PassThru driver unload function
  297. //
  298. {
  299.     UNREFERENCED_PARAMETER(DriverObject);
  300.     
  301.     DBGPRINT(("PtUnload: enteredn"));
  302.     PtUnloadProtocol();
  303.     NdisIMDeregisterLayeredMiniport(DriverHandle);
  304.     NdisFreeSpinLock(&GlobalLock);
  305.     DBGPRINT(("PtUnload: done!n"));
  306. }