📄 minihook.c
字号:
/*——————————————————————————————————————
设置pAdapt的StandingBy数值,来决定阻断或者允许引入的请求。
*/
VOID
MPProcessSetPowerOid(
IN OUT PNDIS_STATUS pNdisStatus,
IN PADAPT pAdapt,
IN PVOID InformationBuffer,
IN ULONG InformationBufferLength,
OUT PULONG BytesRead,
OUT PULONG BytesNeeded
)
{
NDIS_DEVICE_POWER_STATE NewDeviceState;
DBGPRINT ("==>MPProcessSetPowerOid");
ASSERT (InformationBuffer != NULL);
NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);
*pNdisStatus = NDIS_STATUS_FAILURE;
do
{
//——————————————————————————————————
// 检查是否是无效的长度
//
if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))
{
*pNdisStatus = NDIS_STATUS_INVALID_LENGTH;
break;
}
//——————————————————————————————————
// 检查是否是无效的设备状态
//
if ((pAdapt->MPDeviceState > NdisDeviceStateD0)
&& (NewDeviceState != NdisDeviceStateD0))
{
ASSERT (!(pAdapt->MPDeviceState > NdisDeviceStateD0)
&& (NewDeviceState != NdisDeviceStateD0));
*pNdisStatus = NDIS_STATUS_FAILURE;
break;
}
//——————————————————————————————————
// 如果miniport从On(D0)状态转换成Low Power状态(>D0),设置StandingBy
// 为TRUE,阻挡所有引入的请求。
//
if (pAdapt->MPDeviceState == NdisDeviceStateD0
&& NewDeviceState > NdisDeviceStateD0)
pAdapt->StandingBy = TRUE;
//——————————————————————————————————
// 如果miniport从Low Power状态(>D0)转换成On(D0)状态,设置StandingBy
// 为FALSE,所有引入的请求将挂起,直到物理Miniport打开(turns ON)。
//
if (pAdapt->MPDeviceState > NdisDeviceStateD0
&& NewDeviceState == NdisDeviceStateD0)
pAdapt->StandingBy = FALSE;
//——————————————————————————————————
// 更新pAdapt结构中的状态成员变量值
//
pAdapt->MPDeviceState = NewDeviceState;
*pNdisStatus = NDIS_STATUS_SUCCESS;
} while (FALSE);
if (*pNdisStatus == NDIS_STATUS_SUCCESS)
{
*BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);
*BytesNeeded = 0;
}
else
{
*BytesRead = 0;
*BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);
}
DBGPRINT ("<==MPProcessSetPowerOid");
}
/*——————————————————————————————————————
Miniport必需的函数,当设备停止时释放相应的资源。详情请参阅DDK文档关于
MiniportHalt函数的解释。
*/
VOID
MPHalt(
IN NDIS_HANDLE MiniportAdapterContext
)
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
NDIS_STATUS Status;
PADAPT pCursor, *ppCursor;
PADAPT pPromoteAdapt = NULL;
KIRQL OldIrql;
DBGPRINT("==>Passthru Miniport MPHalt\n");
//————————————————————————————————————
// 从全局列表中移除pAdapt。
//
// 在操作全局列表时必须保持多进程间同步
//
KeAcquireSpinLock (&pAdapt->SpinLock, &OldIrql);
//————————————————————————————————————
// 从列表中移除pAdapt。
//
for (ppCursor = &pAdaptList; *ppCursor != NULL; ppCursor = &(*ppCursor)->Next)
{
if (*ppCursor == pAdapt)
{
*ppCursor = pAdapt->Next;
break;
}
}
//————————————————————————————————————
// 从列表里移除所有指向pAdapt的指针。
//
for (pCursor = pAdaptList; pCursor != NULL; pCursor = pCursor->Next)
{
//——————————————————————————————————
// 在全局列表里的指针或许无效,首先对Primary进行检查
//
if (pCursor->pPrimaryAdapt == pAdapt)
{
ASSERT (pCursor->isSecondary == TRUE);
pPromoteAdapt = pCursor;
}
//——————————————————————————————————
// 检查下一个
//
if (pCursor->pSecondaryAdapt == pAdapt)
{
ASSERT(pCursor->isSecondary == FALSE);
pCursor->pSecondaryAdapt = pCursor;
}
}
KeReleaseSpinLock (&pAdapt->SpinLock, OldIrql);
//————————————————————————————————————
// 如果miniport需要保留pPromoteAdapt调用自定义函数MPPromoteSecondary
// 保留实例。
//
if (pPromoteAdapt != NULL)
MPPromoteSecondary(pPromoteAdapt);
//————————————————————————————————————
// 如果有一个无效的绑定,关闭miniport下面的protocol。
//
if (pAdapt->BindingHandle != NULL)
{
//——————————————————————————————————
// 关闭miniport下面的protocol并等待结束。
//
NdisResetEvent(&pAdapt->Event);
NdisCloseAdapter(&Status, pAdapt->BindingHandle);
if (Status == NDIS_STATUS_PENDING)
{
NdisWaitEvent(&pAdapt->Event, 0);
Status = pAdapt->Status;
}
ASSERT (Status == NDIS_STATUS_SUCCESS);
pAdapt->BindingHandle = NULL;
}
//————————————————————————————————————
// 释放资源
//
NdisFreePacketPool(pAdapt->SendPacketPoolHandle);
NdisFreePacketPool(pAdapt->RecvPacketPoolHandle);
NdisFreeMemory(pAdapt->BundleUniString.Buffer, MAX_BUNDLEID_LENGTH,0);
NdisFreeMemory(pAdapt, sizeof(ADAPT), 0);
DBGPRINT("<==Passthru Minport Halt\n");
}
/*——————————————————————————————————————
Miniport必需的函数,复位操作,这里我们什么都不需要做。详情请参阅DDK
文档关于MiniportReset的说明。
*/
NDIS_STATUS
MPReset(
OUT PBOOLEAN AddressingReset,
IN NDIS_HANDLE MiniportAdapterContext
)
{
PADAPT pAdapt = (PADAPT)MiniportAdapterContext;
DBGPRINT("==>Passthru Miniport MPReset\n");
*AddressingReset = FALSE;
return(NDIS_STATUS_SUCCESS);
}
/*——————————————————————————————————————
遍历全局列表查找并设置第二个设备的绑定
*/
NDIS_STATUS
MPBundleSearchAndSetSecondary(
IN PADAPT pAdapt
)
{
NDIS_STATUS Status = NDIS_STATUS_FAILURE;
NDIS_STRING NoBundle = NDIS_STRING_CONST ("<no-bundle>");
PADAPT pCursor = NULL;
PADAPT pPrimary = NULL;
KIRQL OldIrql;
DBGPRINT("==>Passthru Miniport MPBundleSearchAndSetSecondary\n");
do
{
//——————————————————————————————————
// 如果bundle == '<bundle id>'那么这个miniport将不是任何绑定的一部分
//
if (NdisEqualUnicodeString(&NoBundle, &pAdapt->BundleUniString, TRUE))
{
Status = NDIS_STATUS_SUCCESS;
break;
}
//——————————————————————————————————
// 如果绑定标识为空字符串,这个miniport不是任何绑定的一部分。
//
if (pAdapt->BundleUniString.Length == 0)
{
Status = NDIS_STATUS_SUCCESS;
break;
}
//——————————————————————————————————
// 加同步锁。
//
KeAcquireSpinLock (&pAdapt->SpinLock, &OldIrql);
//——————————————————————————————————
// 查找全局链表中具有相同绑定ID的设备。
//
for (pCursor = pAdaptList; pCursor != NULL; pCursor = pCursor->Next)
{
if (pCursor == pAdapt)
{
//——————————————————————————————
// 如果指向自己跳过。
//
continue;
}
//————————————————————————————————
// 如果匹配将第二个设置为当前的pAdapt。
//
if (NdisEqualUnicodeString(
&pCursor->BundleUniString, &pAdapt->BundleUniString, TRUE))
{
//——————————————————————————————
// 确认这是一个绑定的主设备。
//
ASSERT (pCursor->pSecondaryAdapt
== pCursor && pCursor->isSecondary == FALSE);
pPrimary = pCursor;
break;
}
}
//——————————————————————————————————
// 解同步锁。
//
KeReleaseSpinLock (&pAdapt->SpinLock, OldIrql);
//——————————————————————————————————
// 调用自定义函数MPSetMiniportSecondary进行设置。
//
if (pPrimary != NULL)
{
Status = MPSetMiniportSecondary (pAdapt, pPrimary);
ASSERT (Status == NDIS_STATUS_SUCCESS);
}
//——————————————————————————————————
// 成功的搜索了列表尽管没有找到绑定仍然返回成功。
//
Status = NDIS_STATUS_SUCCESS;
} while (FALSE) ;
return Status;
}
/*——————————————————————————————————————
调用NdisMSetMiniportSecondary设置绑定并且改变成员变量的状态值
*/
NDIS_STATUS
MPSetMiniportSecondary (
IN PADAPT Secondary,
IN PADAPT Primary
)
{
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DBGPRINT("==>Passthru Miniport MPSetMiniportSecondary\n");
//————————————————————————————————————
// 保证主设备不是其它绑定的一部分
//
ASSERT (Primary != Secondary);
ASSERT (Primary->isSecondary == 0);
ASSERT (Primary->pSecondaryAdapt == Primary);
DBGPRINT ("Calling NdisMSetSecondary API on the two handles\n");
Status = NdisMSetMiniportSecondary(Secondary->MiniportHandle,
Primary->MiniportHandle);
ASSERT (Status == NDIS_STATUS_SUCCESS);
if (Status == NDIS_STATUS_SUCCESS)
{
//——————————————————————————————————
// 初始化LBFO变量来记录当前状态
//
Secondary->isSecondary = TRUE;
Secondary->pPrimaryAdapt = Primary;
Primary->pSecondaryAdapt = Secondary;
//——————————————————————————————————
// 保证其它一些状态变量也由正确的状态值
//
Secondary->pSecondaryAdapt = Secondary;
Primary->pPrimaryAdapt = Primary;
Primary->isSecondary = FALSE;
}
return Status;
}
/*——————————————————————————————————————
从第二个设备升迁为主设备,保留升迁设备的实例
*/
NDIS_STATUS
MPPromoteSecondary(
IN PADAPT pAdapt
)
{
NDIS_STATUS Status = NdisMPromoteMiniport(pAdapt->MiniportHandle);
ASSERT (Status == NDIS_STATUS_SUCCESS);
if (Status == NDIS_STATUS_SUCCESS)
{
pAdapt->isSecondary = FALSE;
pAdapt->pPrimaryAdapt = pAdapt;
pAdapt->pSecondaryAdapt = pAdapt;
}
DBGPRINT ("<== MPPromoteMiniport\n");
return Status;
}
/*——————————————————————————————————————
根据OID判断是发送还是接收
*/
BOOLEAN
MPIsSendOID (
IN NDIS_OID Oid
)
{
BOOLEAN fIsSend = FALSE; // 默认是一个接收OID
DBGPRINT("==>Passthru Miniport MPIsSendOID\n");
switch (Oid)
{
//——————————————————————————————————
// 如果需要发送OID,设置fIsSend为TRUE;
//
case OID_GEN_TRANSMIT_BUFFER_SPACE :
case OID_GEN_TRANSMIT_BLOCK_SIZE :
case OID_GEN_MAXIMUM_TOTAL_SIZE :
case OID_GEN_XMIT_OK :
case OID_GEN_XMIT_ERROR :
case OID_GEN_DIRECTED_BYTES_XMIT :
case OID_GEN_DIRECTED_FRAMES_XMIT :
case OID_GEN_MULTICAST_BYTES_XMIT :
case OID_GEN_MULTICAST_FRAMES_XMIT :
case OID_GEN_BROADCAST_BYTES_XMIT :
case OID_GEN_BROADCAST_FRAMES_XMIT :
case OID_GEN_TRANSMIT_QUEUE_LENGTH :
fIsSend = TRUE;
break;
default:
fIsSend = FALSE;
break;
}
return fIsSend;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -