passthru.c
资源名称:passthru.rar [点击查看]
上传用户:sabrinaco
上传日期:2016-01-19
资源大小:3177k
文件大小:22k
源码类别:
防火墙与安全工具
开发平台:
Visual C++
- /*++
- 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)
- #define START CTL_CODE(FILE_DEVICE_UNKNOWN, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define RUN CTL_CODE(FILE_DEVICE_UNKNOWN, 0x902, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define USERNUM CTL_CODE(FILE_DEVICE_UNKNOWN, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define CUT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x904, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define CONNECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x905, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define IP CTL_CODE(FILE_DEVICE_UNKNOWN, 0x906, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define LOOKADAPT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x907, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define SETADAPT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x908, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define OPENADAPT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x909, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define QUERYOID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x90a, METHOD_BUFFERED, FILE_ANY_ACCESS )
- #define SETOID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x90b, METHOD_BUFFERED, FILE_ANY_ACCESS )
- 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 LINKNAME_STRING L"\DosDevices\Passthru"
- #define NTDEVICE_STRING L"\Device\Passthru"
- 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;
- PNDIS_CONFIGURATION_PARAMETER Param;
- NDIS_STRING Name;
- int i,j;
- usernum=0;
- for(i=0;i<60;i++)
- {
- for(j=0;j<4;j++)
- ip[i][j]=0;
- packetnum[i]=0;
- num[i]=1;
- }
- NdisAllocateMemoryWithTag(&selectpAdapt, sizeof(ADAPT), TAG);
- NdisInitializeString(&selectpAdapt->DeviceName,"a");
- Status = NDIS_STATUS_SUCCESS;
- NdisAllocateSpinLock(&GlobalLock);
- DbgPrint("hi,stating");
- 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 = MPReset;
- 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 = NULL; // MPSend;
- MChars.SendPacketsHandler = MPSendPackets;
- 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, L"Passthru"); // 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);
- }
- 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];
- UINT i;
- DBGPRINT(("==>PtRegisterDevicen"));
- 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);
- for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
- {
- DispatchTable[i] = PtDispatch;
- }
- 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: %xn", 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.
- --*/
- {
- NTSTATUS status = STATUS_SUCCESS;
- int i;
- PVOID pNext;
- ULONG id;
- ULONG tran=0;
- PADAPT pAdapt;
- POPEN_CONTEXT pOpenContext;
- PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(Irp);
- PPTUSERIO_OID_DATA pOidData = (PPTUSERIO_OID_DATA)Irp->AssociatedIrp.SystemBuffer;
- // 取得I/O控制代码
- ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
- // 取得I/O缓冲区指针和它的长度
- PVOID pIoBuffer = Irp->AssociatedIrp.SystemBuffer;
- ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
- ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
- pNext=pIoBuffer;
- DBGPRINT(("==>Pt Dispatchn"));
- switch (pIrpStack->MajorFunction)
- {
- case IRP_MJ_CREATE:
- pIrpStack->FileObject->FsContext = NULL;
- pIrpStack->FileObject->FsContext2 = NULL;
- tran=0;
- break;
- case IRP_MJ_CLOSE:
- pOpenContext = (POPEN_CONTEXT)pIrpStack->FileObject->FsContext;
- pIrpStack->FileObject->FsContext = NULL;
- pIrpStack->FileObject->FsContext2 = NULL;
- if(pOpenContext != NULL) // 关闭的是一个适配器句柄
- {
- if(pOpenContext->pAdapt != NULL)
- {
- NdisAcquireSpinLock(&(pOpenContext->pAdapt)->Lock);
- (pOpenContext->pAdapt)->pOpenContext = NULL;
- NdisReleaseSpinLock(&(pOpenContext->pAdapt)->Lock);
- }
- DevDerefOpenContext(pOpenContext);
- }
- tran=0;
- break;
- case IRP_MJ_DEVICE_CONTROL:
- switch(uIoControlCode)
- {
- case START:
- NdisMoveMemory(mac[usernum],(unsigned char*)pIoBuffer,6);
- usernum++;
- tran=0;
- break;
- case RUN:
- NdisMoveMemory((ULONG *)pIoBuffer,packetnum,240);
- tran=240;
- for(i=0;i<60;i++)
- packetnum[i]=0;
- break;
- case USERNUM:
- NdisMoveMemory(&usernum,(ULONG *)pIoBuffer,4);
- tran=0;
- break;
- case CUT:
- NdisMoveMemory(&id,(ULONG *)pIoBuffer,4);
- num[id]=0;
- tran=0;
- break;
- case CONNECT:
- NdisMoveMemory(&id,(ULONG *)pIoBuffer,4);
- num[id]=1;
- tran=0;
- break;
- case IP:
- for(i=0;i<60;i++)
- NdisMoveMemory((UCHAR *)pNext+i*4,ip[i],4);
- tran=240;
- break;
- case LOOKADAPT:
- GetBindingList(pIoBuffer,uOutSize,&tran);
- break;
- case SETADAPT:
- break;
- case OPENADAPT:
- pAdapt=LookupAdaptByName((PUCHAR)pIoBuffer,uInSize);
- if(pAdapt==NULL)
- {
- status= STATUS_OBJECT_NAME_NOT_FOUND;
- break;
- }
- // 如果正在Unbind,则失败
- NdisAcquireSpinLock(&pAdapt->Lock);
- if(pAdapt->UnbindingInProcess)
- {
- NdisReleaseSpinLock(&pAdapt->Lock);
- PtDerefAdapter(pAdapt);
- status = STATUS_INVALID_DEVICE_STATE;
- break;
- }
- NdisReleaseSpinLock(&pAdapt->Lock);
- // 如果适配器已经打开,则失败
- if(pAdapt->pOpenContext != NULL)
- {
- PtDerefAdapter(pAdapt);
- status = STATUS_DEVICE_BUSY;
- break;
- }
- pOpenContext = DevAllocateOpenContext(pAdapt);
- if(pOpenContext == NULL)
- {
- PtDerefAdapter(pAdapt);
- status = STATUS_INSUFFICIENT_RESOURCES;
- break;
- }
- if(InterlockedCompareExchangePointer(&(pAdapt->pOpenContext),
- pOpenContext, NULL) != NULL)
- {
- PtDerefAdapter(pAdapt);
- status = STATUS_DEVICE_BUSY;
- break;
- }
- selectpAdapt=pAdapt;
- // 将打开环境与句柄关联
- pIrpStack->FileObject->FsContext = pOpenContext;
- status = STATUS_SUCCESS;
- tran=0;
- break;
- case SETOID:
- case QUERYOID:
- status = STATUS_INVALID_DEVICE_REQUEST;
- do
- {
- // 取得与此句柄关联的OPEN_CONTEXT结构的指针 // 首先检查此句柄是否打开适配器
- pOpenContext = (POPEN_CONTEXT)pIrpStack->FileObject->FsContext;
- if(pOpenContext == NULL)
- {
- status = STATUS_INVALID_HANDLE;
- break;
- }
- pAdapt = pOpenContext->pAdapt;
- if(pAdapt == NULL)
- {
- status = STATUS_INVALID_HANDLE;
- break;
- }
- // 检查缓冲区
- if(uOutSize != uInSize || uOutSize < sizeof(PTUSERIO_OID_DATA) ||
- uOutSize < sizeof(PTUSERIO_OID_DATA) - 1 + pOidData->Length)
- {
- status = STATUS_INVALID_PARAMETER;
- break;
- }
- // 如果Unbind正在进行,则失败
- NdisAcquireSpinLock(&pAdapt->Lock);
- if( pAdapt->UnbindingInProcess )
- {
- NdisReleaseSpinLock(&pAdapt->Lock);
- DBGPRINT(( " Unbind In Processn" ));
- status = STATUS_INVALID_DEVICE_STATE;
- break;
- }
- // All other queries are failed, if the miniport is not at D0,
- if (pAdapt->MPDeviceState > NdisDeviceStateD0)
- {
- NdisReleaseSpinLock(&pAdapt->Lock);
- DBGPRINT(( " Invalid Miniport Device Staten" ));
- status = STATUS_INVALID_DEVICE_STATE;
- break;
- }
- // This is in the process of powering down the system, always fail the request
- if (pAdapt->StandingBy == TRUE)
- {
- NdisReleaseSpinLock(&pAdapt->Lock);
- DBGPRINT(( " Miniport Powering Downn" ));
- status = STATUS_INVALID_DEVICE_STATE;
- break;
- }
- NdisReleaseSpinLock(&pAdapt->Lock);
- // 检查完毕,最后,进行这个请求
- DevRefOpenContext(pOpenContext);
- // 初始化NDIS_REQUEST结构
- NdisZeroMemory(&pOpenContext->Request, sizeof(pOpenContext->Request));
- if(uIoControlCode == SETOID)
- {
- pOpenContext->Request.RequestType = NdisRequestSetInformation;
- pOpenContext->Request.DATA.SET_INFORMATION.Oid = pOidData->Oid;
- pOpenContext->Request.DATA.SET_INFORMATION.InformationBuffer = pOidData->Data;
- pOpenContext->Request.DATA.SET_INFORMATION.InformationBufferLength = pOidData->Length;
- }
- else
- {
- pOpenContext->Request.RequestType = NdisRequestQueryInformation;
- pOpenContext->Request.DATA.QUERY_INFORMATION.Oid = pOidData->Oid;
- pOpenContext->Request.DATA.QUERY_INFORMATION.InformationBuffer = pOidData->Data;
- pOpenContext->Request.DATA.QUERY_INFORMATION.InformationBufferLength = pOidData->Length;
- }
- NdisResetEvent( &pOpenContext->RequestEvent);
- NdisRequest(&status, pAdapt->BindingHandle, &pOpenContext->Request);
- if(status != NDIS_STATUS_PENDING)
- {
- DevRequestComplete(pAdapt, &pOpenContext->Request, status);
- }
- // 等待请求的完成,即等待Ndis调用DevRequestComplete例程
- NdisWaitEvent(&pOpenContext->RequestEvent, 0);
- if(pOpenContext->RequestStatus == NDIS_STATUS_SUCCESS)
- {
- if(uIoControlCode == SETOID)
- {
- pOidData->Length = pOpenContext->Request.DATA.SET_INFORMATION.BytesRead;
- }
- else if(uIoControlCode == QUERYOID)
- {
- pOidData->Length = pOpenContext->Request.DATA.QUERY_INFORMATION.BytesWritten;
- }
- // 设置返回给I/O管理器的信息
- tran = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
- status = STATUS_SUCCESS;
- }
- else
- {
- status = STATUS_UNSUCCESSFUL;
- }
- DevDerefOpenContext(pOpenContext);
- }while(FALSE);
- break;
- default:
- break;
- }
- }
- Irp->IoStatus.Information = tran;
- Irp->IoStatus.Status = status;
- IoCompleteRequest(Irp, IO_NO_INCREMENT);
- DBGPRINT(("<== Pt Dispatchn"));
- 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(("==>PassthruDeregisterDevicen"));
- 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: %xn", Status));
- return Status;
- }
- VOID
- PtUnloadProtocol(
- VOID
- )
- {
- NDIS_STATUS Status;
- if (ProtHandle != NULL)
- {
- NdisDeregisterProtocol(&Status, ProtHandle);
- ProtHandle = NULL;
- }
- DBGPRINT(("PtUnloadProtocol: done!n"));
- }