NDIS_STATUS NDIS_API PacketReset(POPEN_INSTANCE pOpen) { // reset the protocol PLIST_ENTRY ResetListEntry; NDIS_STATUS Status; // Acquire request element from list NdisAllocateSpinLock(&pOpen->RequestSpinLock); if (IsListEmpty(&pOpen->RequestList)) { NdisReleaseSpinLock(&pOpen->RequestSpinLock); return NDIS_STATUS_RESOURCES; } ResetListEntry = RemoveHeadList(&pOpen->RequestList); NdisReleaseSpinLock(&pOpen->RequestSpinLock); // Insert Reset IRP into Request Queue NdisAcquireSpinLock(&pOpen->ResetSpinLock); InsertTailList(&pOpen->ResetIrpList, ResetListEntry); NdisReleaseSpinLock(&pOpen->ResetSpinLock); // Reset the adapter NdisReset(&Status, pOpen->AdapterHandle); if (Status != NDIS_STATUS_PENDING) PacketResetComplete(pOpen, Status); return Status; }
/************************************************************ Start the reset of a instance of the driver ************************************************************/ VOID PacketReset( PNDIS_STATUS pStatus, POPEN_INSTANCE pOpen ) { PLIST_ENTRY ResetListEntry; TRACE_ENTER( "PacketReset" ); NdisAcquireSpinLock( &pOpen->RequestSpinLock ); ResetListEntry = PacketRemoveHeadList( &pOpen->RequestList ); NdisReleaseSpinLock( &pOpen->RequestSpinLock ); if ( ResetListEntry == NULL ) { *pStatus = NDIS_STATUS_RESOURCES; TRACE_LEAVE( "PacketReset" ); return; } NdisAcquireSpinLock( &pOpen->ResetSpinLock ); InsertTailList( &pOpen->ResetIrpList, ResetListEntry ); NdisReleaseSpinLock( &pOpen->ResetSpinLock ); /*Call NDIS to reset the adapter*/ NdisReset( pStatus, pOpen->AdapterHandle ); if ( *pStatus != NDIS_STATUS_PENDING ) { /*synchronous reset of the adapter*/ PacketResetComplete( pOpen, *pStatus ); } TRACE_LEAVE( "PacketReset" ); return; }
/* * Function called to reset the adapter * */ BOOL PKTReset (POPEN_INSTANCE pOI) { NDIS_STATUS Status; // Call NDIS to reset the adapter NdisReset (&Status, pOI->AdapterHandle); if (Status == NDIS_STATUS_PENDING) { SuspendExecution (pOI); } else { PacketResetComplete (pOI, Status); } if (Status != NDIS_STATUS_SUCCESS) { return FALSE; } return TRUE; }
// I/O控制派遣例程 NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp) { // 假设失败 NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST; // 取得此IRP(pIrp)的I/O堆栈指针 PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp); // 取得I/O控制代码 ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode; // 取得I/O缓冲区指针和它的长度 PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer; ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength; ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; if(uIoControlCode == IOCTL_ENUM_ADAPTERS) { ULONG nDataLen = 0; if(pDevObj != g_data.pControlDevice) status = STATUS_INVALID_DEVICE_REQUEST; else { status = GetAdapterList(pIoBuffer, uOutSize, &nDataLen); if(status != STATUS_SUCCESS) DbgPrint("GetAdapterList error "); } pIrp->IoStatus.Information = nDataLen; pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; } OPEN_INSTANCE *pOpen = (OPEN_INSTANCE *)pDevObj->DeviceExtension; if(pOpen == NULL || !pOpen->bBound) { pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return STATUS_UNSUCCESSFUL; } IoIncrement(pOpen); IoMarkIrpPending(pIrp); if(uIoControlCode == IOCTL_PROTOCOL_RESET) { // 插入此IRP到重置IRP列表 ExInterlockedInsertTailList( &pOpen->ResetIrpList, &pIrp->Tail.Overlay.ListEntry, &pOpen->ResetQueueLock); // 发出重置请求 NdisReset( &status, pOpen->hAdapter ); if(status != NDIS_STATUS_PENDING) { ProtocolResetComplete( pOpen, status); } } // 获取或者设置OID信息 else if(uIoControlCode == IOCTL_PROTOCOL_SET_OID || uIoControlCode == IOCTL_PROTOCOL_QUERY_OID) // 输入参数是一个自定义的PROTOCOL_OID_DATA结构 { PPROTOCOL_OID_DATA pOidData = (PPROTOCOL_OID_DATA)pIoBuffer; // 申请一个INTERNAL_REQUEST结构 PINTERNAL_REQUEST pInterRequest = (PINTERNAL_REQUEST)ExAllocatePool(NonPagedPool, sizeof(INTERNAL_REQUEST)); if(pInterRequest == NULL) { pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; IoCompleteRequest(pIrp, IO_NO_INCREMENT); IoDecrement(pOpen); return STATUS_PENDING; } pInterRequest->pIrp = pIrp; if(uOutSize == uInSize && uOutSize >= sizeof(PROTOCOL_OID_DATA) && uOutSize >= sizeof(PROTOCOL_OID_DATA) - 1 + pOidData->Length) // 缓冲区可用? { // 初始化NDIS_REQUEST结构 if(uIoControlCode == IOCTL_PROTOCOL_SET_OID) { pInterRequest->Request.RequestType = NdisRequestSetInformation; pInterRequest->Request.DATA.SET_INFORMATION.Oid = pOidData->Oid; pInterRequest->Request.DATA.SET_INFORMATION.InformationBuffer = pOidData->Data; pInterRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = pOidData->Length; } else { pInterRequest->Request.RequestType = NdisRequestQueryInformation; pInterRequest->Request.DATA.QUERY_INFORMATION.Oid = pOidData->Oid; pInterRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = pOidData->Data; pInterRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = pOidData->Length; } // 提交这个请求 NdisRequest(&status, pOpen->hAdapter, &pInterRequest->Request); } else { status = NDIS_STATUS_FAILURE; pInterRequest->Request.DATA.SET_INFORMATION.BytesRead = 0; pInterRequest->Request.DATA.QUERY_INFORMATION.BytesWritten = 0; } if(status != NDIS_STATUS_PENDING) { ProtocolRequestComplete(pOpen, &pInterRequest->Request, status); } } return STATUS_PENDING; }