+++ /dev/null
-/*++
-
-Copyright (c) 1992-2000 Microsoft Corporation
-
-Module Name:
-
- passthru.c
-
-Abstract:
-
- Ndis Intermediate Miniport driver sample. This is a passthru driver.
-
-Author:
-
-Environment:
-
-
-Revision History:
-
-
---*/
-
-
-#include "precomp.h"
-#pragma hdrstop
-
-#pragma NDIS_INIT_FUNCTION(DriverEntry)
-
-NDIS_HANDLE ProtHandle = NULL;
-NDIS_HANDLE DriverHandle = NULL;
-NDIS_MEDIUM MediumArray[4] =
- {
- NdisMedium802_3, // Ethernet
- NdisMedium802_5, // Token-ring
- NdisMediumFddi, // Fddi
- NdisMediumWan // NDISWAN
- };
-
-NDIS_SPIN_LOCK GlobalLock;
-
-PADAPT pAdaptList = NULL;
-LONG MiniportCount = 0;
-
-NDIS_HANDLE NdisWrapperHandle;
-
-//
-// To support ioctls from user-mode:
-//
-
-#define STR2(x) #x
-#define STR(x) STR2(x)
-#define DOSPREFIX "\\DosDevices\\"
-#define NTPREFIX "\\Device\\"
-#define WIDEN2(x) L ## x
-#define WIDEN(x) WIDEN2(x)
-#define LINKNAME_STRING WIDEN(DOSPREFIX) WIDEN(STR(MODULENAME))
-#define NTDEVICE_STRING WIDEN(NTPREFIX) WIDEN(STR(MODULENAME))
-#define PROTOCOLNAME_STRING WIDEN(STR(MODULENAME))
-
-NDIS_HANDLE NdisDeviceHandle = NULL;
-PDEVICE_OBJECT ControlDeviceObject = NULL;
-
-enum _DEVICE_STATE
-{
- PS_DEVICE_STATE_READY = 0, // ready for create/delete
- PS_DEVICE_STATE_CREATING, // create operation in progress
- PS_DEVICE_STATE_DELETING // delete operation in progress
-} ControlDeviceState = PS_DEVICE_STATE_READY;
-
-
-
-NTSTATUS
-DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
-/*++
-
-Routine Description:
-
- First entry point to be called, when this driver is loaded.
- Register with NDIS as an intermediate driver.
-
-Arguments:
-
- DriverObject - pointer to the system's driver object structure
- for this driver
-
- RegistryPath - system's registry path for this driver
-
-Return Value:
-
- STATUS_SUCCESS if all initialization is successful, STATUS_XXX
- error code if not.
-
---*/
-{
- NDIS_STATUS Status;
- NDIS_PROTOCOL_CHARACTERISTICS PChars;
- NDIS_MINIPORT_CHARACTERISTICS MChars;
- NDIS_STRING Name;
-
- Status = NDIS_STATUS_SUCCESS;
- NdisAllocateSpinLock(&GlobalLock);
-
- NdisMInitializeWrapper(&NdisWrapperHandle, DriverObject, RegistryPath, NULL);
-
- do
- {
- //
- // Register the miniport with NDIS. Note that it is the miniport
- // which was started as a driver and not the protocol. Also the miniport
- // must be registered prior to the protocol since the protocol's BindAdapter
- // handler can be initiated anytime and when it is, it must be ready to
- // start driver instances.
- //
-
- NdisZeroMemory(&MChars, sizeof(NDIS_MINIPORT_CHARACTERISTICS));
-
- MChars.MajorNdisVersion = PASSTHRU_MAJOR_NDIS_VERSION;
- MChars.MinorNdisVersion = PASSTHRU_MINOR_NDIS_VERSION;
-
- MChars.InitializeHandler = MPInitialize;
- MChars.QueryInformationHandler = MPQueryInformation;
- MChars.SetInformationHandler = MPSetInformation;
- MChars.ResetHandler = NULL;
- MChars.TransferDataHandler = MPTransferData;
- MChars.HaltHandler = MPHalt;
-#ifdef NDIS51_MINIPORT
- MChars.CancelSendPacketsHandler = MPCancelSendPackets;
- MChars.PnPEventNotifyHandler = MPDevicePnPEvent;
- MChars.AdapterShutdownHandler = MPAdapterShutdown;
-#endif // NDIS51_MINIPORT
-
- //
- // We will disable the check for hang timeout so we do not
- // need a check for hang handler!
- //
- MChars.CheckForHangHandler = NULL;
- MChars.ReturnPacketHandler = MPReturnPacket;
-
- //
- // Either the Send or the SendPackets handler should be specified.
- // If SendPackets handler is specified, SendHandler is ignored
- //
- MChars.SendHandler = MPSend; // IPFW: use MPSend, not SendPackets
- MChars.SendPacketsHandler = NULL;
-
- Status = NdisIMRegisterLayeredMiniport(NdisWrapperHandle,
- &MChars,
- sizeof(MChars),
- &DriverHandle);
- if (Status != NDIS_STATUS_SUCCESS)
- {
- break;
- }
-
-#ifndef WIN9X
- NdisMRegisterUnloadHandler(NdisWrapperHandle, PtUnload);
-#endif
-
- //
- // Now register the protocol.
- //
- NdisZeroMemory(&PChars, sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
- PChars.MajorNdisVersion = PASSTHRU_PROT_MAJOR_NDIS_VERSION;
- PChars.MinorNdisVersion = PASSTHRU_PROT_MINOR_NDIS_VERSION;
-
- //
- // Make sure the protocol-name matches the service-name
- // (from the INF) under which this protocol is installed.
- // This is needed to ensure that NDIS can correctly determine
- // the binding and call us to bind to miniports below.
- //
- NdisInitUnicodeString(&Name, PROTOCOLNAME_STRING); // Protocol name
- PChars.Name = Name;
- PChars.OpenAdapterCompleteHandler = PtOpenAdapterComplete;
- PChars.CloseAdapterCompleteHandler = PtCloseAdapterComplete;
- PChars.SendCompleteHandler = PtSendComplete;
- PChars.TransferDataCompleteHandler = PtTransferDataComplete;
-
- PChars.ResetCompleteHandler = PtResetComplete;
- PChars.RequestCompleteHandler = PtRequestComplete;
- PChars.ReceiveHandler = PtReceive;
- PChars.ReceiveCompleteHandler = PtReceiveComplete;
- PChars.StatusHandler = PtStatus;
- PChars.StatusCompleteHandler = PtStatusComplete;
- PChars.BindAdapterHandler = PtBindAdapter;
- PChars.UnbindAdapterHandler = PtUnbindAdapter;
- PChars.UnloadHandler = PtUnloadProtocol;
-
- PChars.ReceivePacketHandler = PtReceivePacket;
- PChars.PnPEventHandler= PtPNPHandler;
-
- NdisRegisterProtocol(&Status,
- &ProtHandle,
- &PChars,
- sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
-
- if (Status != NDIS_STATUS_SUCCESS)
- {
- NdisIMDeregisterLayeredMiniport(DriverHandle);
- break;
- }
-
- NdisIMAssociateMiniport(DriverHandle, ProtHandle);
- }
- while (FALSE);
-
- if (Status != NDIS_STATUS_SUCCESS)
- {
- NdisTerminateWrapper(NdisWrapperHandle, NULL);
- }
-
- ipfw_module_init(); // IPFW - start the system
-
- return(Status);
-}
-
-
-NDIS_STATUS
-PtRegisterDevice(
- VOID
- )
-/*++
-
-Routine Description:
-
- Register an ioctl interface - a device object to be used for this
- purpose is created by NDIS when we call NdisMRegisterDevice.
-
- This routine is called whenever a new miniport instance is
- initialized. However, we only create one global device object,
- when the first miniport instance is initialized. This routine
- handles potential race conditions with PtDeregisterDevice via
- the ControlDeviceState and MiniportCount variables.
-
- NOTE: do not call this from DriverEntry; it will prevent the driver
- from being unloaded (e.g. on uninstall).
-
-Arguments:
-
- None
-
-Return Value:
-
- NDIS_STATUS_SUCCESS if we successfully register a device object.
-
---*/
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
- UNICODE_STRING DeviceName;
- UNICODE_STRING DeviceLinkUnicodeString;
- PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
-
- DBGPRINT(("==>PtRegisterDevice\n"));
-
- NdisAcquireSpinLock(&GlobalLock);
-
- ++MiniportCount;
-
- if (1 == MiniportCount)
- {
- ASSERT(ControlDeviceState != PS_DEVICE_STATE_CREATING);
-
- //
- // Another thread could be running PtDeregisterDevice on
- // behalf of another miniport instance. If so, wait for
- // it to exit.
- //
- while (ControlDeviceState != PS_DEVICE_STATE_READY)
- {
- NdisReleaseSpinLock(&GlobalLock);
- NdisMSleep(1);
- NdisAcquireSpinLock(&GlobalLock);
- }
-
- ControlDeviceState = PS_DEVICE_STATE_CREATING;
-
- NdisReleaseSpinLock(&GlobalLock);
-
-
- NdisZeroMemory(DispatchTable, (IRP_MJ_MAXIMUM_FUNCTION+1) * sizeof(PDRIVER_DISPATCH));
-
- DispatchTable[IRP_MJ_CREATE] = PtDispatch;
- DispatchTable[IRP_MJ_CLEANUP] = PtDispatch;
- DispatchTable[IRP_MJ_CLOSE] = PtDispatch;
- // IPFW we use DevIoControl ?
- DispatchTable[IRP_MJ_DEVICE_CONTROL] = DevIoControl;
-
-
- NdisInitUnicodeString(&DeviceName, NTDEVICE_STRING);
- NdisInitUnicodeString(&DeviceLinkUnicodeString, LINKNAME_STRING);
-
- //
- // Create a device object and register our dispatch handlers
- //
-
- Status = NdisMRegisterDevice(
- NdisWrapperHandle,
- &DeviceName,
- &DeviceLinkUnicodeString,
- &DispatchTable[0],
- &ControlDeviceObject,
- &NdisDeviceHandle
- );
-
- NdisAcquireSpinLock(&GlobalLock);
-
- ControlDeviceState = PS_DEVICE_STATE_READY;
- }
-
- NdisReleaseSpinLock(&GlobalLock);
-
- DBGPRINT(("<==PtRegisterDevice: %x\n", Status));
-
- return (Status);
-}
-
-
-NTSTATUS
-PtDispatch(
- IN PDEVICE_OBJECT DeviceObject,
- IN PIRP Irp
- )
-/*++
-Routine Description:
-
- Process IRPs sent to this device.
-
-Arguments:
-
- DeviceObject - pointer to a device object
- Irp - pointer to an I/O Request Packet
-
-Return Value:
-
- NTSTATUS - STATUS_SUCCESS always - change this when adding
- real code to handle ioctls.
-
---*/
-{
- PIO_STACK_LOCATION irpStack;
- NTSTATUS status = STATUS_SUCCESS;
-
- UNREFERENCED_PARAMETER(DeviceObject);
-
- DBGPRINT(("==>Pt Dispatch\n"));
- irpStack = IoGetCurrentIrpStackLocation(Irp);
-
-
- switch (irpStack->MajorFunction)
- {
- case IRP_MJ_CREATE:
- break;
-
- case IRP_MJ_CLEANUP:
- break;
-
- case IRP_MJ_CLOSE:
- break;
-
- case IRP_MJ_DEVICE_CONTROL:
- //
- // Add code here to handle ioctl commands sent to passthru.
- //
- break;
- default:
- break;
- }
-
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
-
- DBGPRINT(("<== Pt Dispatch\n"));
-
- return status;
-
-}
-
-
-NDIS_STATUS
-PtDeregisterDevice(
- VOID
- )
-/*++
-
-Routine Description:
-
- Deregister the ioctl interface. This is called whenever a miniport
- instance is halted. When the last miniport instance is halted, we
- request NDIS to delete the device object
-
-Arguments:
-
- NdisDeviceHandle - Handle returned by NdisMRegisterDevice
-
-Return Value:
-
- NDIS_STATUS_SUCCESS if everything worked ok
-
---*/
-{
- NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
-
- DBGPRINT(("==>PassthruDeregisterDevice\n"));
-
- NdisAcquireSpinLock(&GlobalLock);
-
- ASSERT(MiniportCount > 0);
-
- --MiniportCount;
-
- if (0 == MiniportCount)
- {
- //
- // All miniport instances have been halted. Deregister
- // the control device.
- //
-
- ASSERT(ControlDeviceState == PS_DEVICE_STATE_READY);
-
- //
- // Block PtRegisterDevice() while we release the control
- // device lock and deregister the device.
- //
- ControlDeviceState = PS_DEVICE_STATE_DELETING;
-
- NdisReleaseSpinLock(&GlobalLock);
-
- if (NdisDeviceHandle != NULL)
- {
- Status = NdisMDeregisterDevice(NdisDeviceHandle);
- NdisDeviceHandle = NULL;
- }
-
- NdisAcquireSpinLock(&GlobalLock);
- ControlDeviceState = PS_DEVICE_STATE_READY;
- }
-
- NdisReleaseSpinLock(&GlobalLock);
-
- DBGPRINT(("<== PassthruDeregisterDevice: %x\n", Status));
- return Status;
-
-}
-
-VOID
-PtUnload(
- IN PDRIVER_OBJECT DriverObject
- )
-//
-// PassThru driver unload function
-//
-{
- UNREFERENCED_PARAMETER(DriverObject);
-
- DBGPRINT(("PtUnload: entered\n"));
-
- PtUnloadProtocol();
-
- NdisIMDeregisterLayeredMiniport(DriverHandle);
-
- NdisFreeSpinLock(&GlobalLock);
-
- ipfw_module_exit(); // IPFW unloading dummynet
-
- DBGPRINT(("PtUnload: done!\n"));
-}