📄 prothook.c
字号:
pAdapt->Status = Status;
NdisSetEvent(&pAdapt->Event);
DBGPRINT("<== Passthru Protocol PtCloseAdapterComplete\n");
}
/*——————————————————————————————————————
复位操作完成后的处理函数,由于Passthru不需要复位,所以这里什么都没有做。
*/
VOID
PtResetComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
ASSERT(0);
DBGPRINT("<== Passthru Protocol PtResetComplete\n");
}
/*——————————————————————————————————————
完成请求的操作函数,所有的OID被完整的发送到同一个请求的miniport设备
如果Oid == OID_PNP_QUERY_POWER那么数据结构都需要以 entries =
NdisDeviceStateUnspecified的形式返回
*/
VOID
PtRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status
)
{
PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
NDIS_OID Oid = pAdapt->Request.DATA.SET_INFORMATION.Oid ;
//————————————————————————————————————
// 根据请求来源改变pAdapt
//
if(MPIsSendOID(Oid))
pAdapt = pAdapt->pPrimaryAdapt;
//————————————————————————————————————
// 设置我们的请求不再紧急
//
pAdapt->OutstandingRequests = FALSE;
//————————————————————————————————————
// 如果需要,完成设置或者查询,并且为OID_PNP_CAPABILITIES缓冲区填充
//
switch(NdisRequest->RequestType)
{
case NdisRequestQueryInformation:
ASSERT(Oid != OID_PNP_QUERY_POWER);
//————————————————————————————————
// 如果oid == OID_PNP_CAPABILITIES并且查询成功便填充必须的数值
//
if(Oid == OID_PNP_CAPABILITIES && Status == NDIS_STATUS_SUCCESS)
MPQueryPNPCapbilities(pAdapt,&Status);
*pAdapt->BytesReadOrWritten
= NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
*pAdapt->BytesNeeded
= NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
NdisMQueryInformationComplete(pAdapt->MiniportHandle, Status);
break;
case NdisRequestSetInformation:
ASSERT( Oid != OID_PNP_SET_POWER);
*pAdapt->BytesReadOrWritten
= NdisRequest->DATA.SET_INFORMATION.BytesRead;
*pAdapt->BytesNeeded
= NdisRequest->DATA.SET_INFORMATION.BytesNeeded;
NdisMSetInformationComplete(pAdapt->MiniportHandle, Status);
break;
default:
ASSERT(0);
break;
}
DBGPRINT("<== Passthru Protocol PtRequestComplete\n");
}
/*——————————————————————————————————————
调用NdisMIndicateStatus完成状态标识的传递
*/
VOID
PtStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
//————————————————————————————————————
// 在miniport初始化前得到的状态指示需要跳过,如果passthru没有设置为ON,
// 我们不传递状态标识
//
if(pAdapt->MiniportHandle != NULL &&
pAdapt->MPDeviceState == NdisDeviceStateD0 &&
pAdapt->PTDeviceState == NdisDeviceStateD0 )
{
NdisMIndicateStatus(pAdapt->MiniportHandle
, GeneralStatus, StatusBuffer, StatusBufferSize);
}
DBGPRINT("<== Passthru Protocol PtStatus\n");
}
/*——————————————————————————————————————
状态标识传递完成后的处理函数
*/
VOID
PtStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
//————————————————————————————————————
// 在miniport初始化前得到的状态指示需要跳过
//
if(pAdapt->MiniportHandle != NULL &&
pAdapt->MPDeviceState == NdisDeviceStateD0 &&
pAdapt->PTDeviceState == NdisDeviceStateD0 )
{
NdisMIndicateStatusComplete(pAdapt->MiniportHandle);
}
DBGPRINT("<== Passthru Protocol PtStatusComplete\n");
}
/*——————————————————————————————————————
这是一个Protocol PNP操作函数。所有PNP相关的OID请求被送到这个函数进行处理
*/
NDIS_STATUS
PtPNPHandler(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNET_PNP_EVENT pNetPnPEvent
)
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
DBGPRINT("==> Passthru Protocol PtPNPHandler\n");
//————————————————————————————————————
// 用当在系统中所有的实体需要改变时这里将执行
//
switch(pNetPnPEvent->NetEvent)
{
case NetEventSetPower :
Status = PtPnPNetEventSetPower(pAdapt, pNetPnPEvent);
break;
case NetEventReconfigure :
Status = PtPnPNetEventReconfigure(pAdapt, (PCWSTR)pNetPnPEvent->Buffer);
break;
default :
Status = NDIS_STATUS_SUCCESS;
break;
}
return Status;
}
/*——————————————————————————————————————
只要PNPNetEventReconfigure被触发,这个函数将被调用。这里protocol将从注
册表读取绑定信息。
*/
NDIS_STATUS
PtPnPNetEventReconfigure(
IN PADAPT pAdapt,
IN PCWSTR pBundleString
)
{
NDIS_STATUS BundleStatus = NDIS_STATUS_SUCCESS;
NDIS_STRING NewBundleUniString;
DBGPRINT("==> Passthru Protocol PtPnPNetEventReconfigure\n");
if(pAdapt == NULL)
{
NdisReEnumerateProtocolBindings (ProtHandle);
return BundleStatus;
}
if (pBundleString == NULL)
return BundleStatus;
NdisInitUnicodeString( &NewBundleUniString, pBundleString);
do
{
//——————————————————————————————————
// 如果绑定标识没有改变,不需要做任何处理。
//
if(NdisEqualUnicodeString(
&NewBundleUniString, &pAdapt->BundleUniString, TRUE))
break;
//——————————————————————————————————
// 有一个新的绑定ID,复制它并作一些需要的绑定工作。
//
RtlCopyUnicodeString(&pAdapt->BundleUniString , &NewBundleUniString);
if(pAdapt->isSecondary)
{
PADAPT pPrimaryAdapt = pAdapt->pPrimaryAdapt;
BundleStatus = MPPromoteSecondary(pAdapt);
if(BundleStatus != NDIS_STATUS_SUCCESS)
{
ASSERT(0);
break;
}
//————————————————————————————————
// 重新设置主设备所有的成员变量。
//
pPrimaryAdapt->pPrimaryAdapt = pPrimaryAdapt;
pPrimaryAdapt->pSecondaryAdapt = pPrimaryAdapt;
pPrimaryAdapt->isSecondary = FALSE;
}
else
{
//————————————————————————————————
// 绑定ID已经改变,如果我们绑定主设备,那吗我们需要设置第二个
// 设备为主设备。
//
if(pAdapt->pSecondaryAdapt != pAdapt)
{
BundleStatus = MPPromoteSecondary(pAdapt->pSecondaryAdapt);
if(BundleStatus != NDIS_STATUS_SUCCESS)
{
ASSERT(0);
break;
}
pAdapt->pSecondaryAdapt = pAdapt;
pAdapt->pPrimaryAdapt = pAdapt;
pAdapt->isSecondary = FALSE ;
}
}
//——————————————————————————————————
// 如果做了一个新的绑定,需要设置当前设备为第二个设备
//
BundleStatus = MPBundleSearchAndSetSecondary(pAdapt);
} while(FALSE) ;
DBGPRINT("<==PtPNPNetEventReconfigure\n");
return BundleStatus;
}
/*——————————————————————————————————————
设置电源状态到需要的级别,等待所有的发送和请求完成。
*/
NDIS_STATUS
PtPnPNetEventSetPower(
IN PADAPT pAdapt,
IN PNET_PNP_EVENT pNetPnPEvent
)
{
PNDIS_DEVICE_POWER_STATE pDeviceState;
NDIS_DEVICE_POWER_STATE PrevDeviceState = pAdapt->PTDeviceState;
NDIS_STATUS Status ;
pDeviceState = (PNDIS_DEVICE_POWER_STATE)(pNetPnPEvent->Buffer);
DBGPRINT("==> Passthru Protocol PtPnPNetEventSetPower\n");
//————————————————————————————————————
// 设置设备状态,这将阻断所有新的发送和接收请求
//
pAdapt->PTDeviceState = *pDeviceState;
if(*pDeviceState > NdisDeviceStateD0)
{
//——————————————————————————————————
// 如果物理miniport变成待命,所有进入的请求失败。
//
if (PrevDeviceState == NdisDeviceStateD0)
pAdapt->StandingBy = TRUE;
//——————————————————————————————————
// 等待直到发送完成。
//
while(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) != 0)
NdisMSleep(10);
//——————————————————————————————————
// 等待直到请求完成。
//
while(pAdapt->OutstandingRequests == TRUE)
NdisMSleep(10);
ASSERT(NdisPacketPoolUsage(pAdapt->SendPacketPoolHandle) == 0);
ASSERT(pAdapt->OutstandingRequests == FALSE);
}
else
{
//——————————————————————————————————
// protocol设备已经打开,一个挂起的请求必须完成。
//
if (pAdapt->QueuedRequest == TRUE)
{
pAdapt->QueuedRequest = FALSE;
NdisRequest(&Status, pAdapt->BindingHandle, &pAdapt->Request);
//————————————————————————————————
// 下层的miniport同步的完成请求,passthru需要完成挂起的请求。
//
if (Status != NDIS_STATUS_PENDING)
PtRequestComplete(pAdapt, &pAdapt->Request, Status);
}
//——————————————————————————————————
// 如果物理miniport的状态为D0,清除标记
//
if (PrevDeviceState > NdisDeviceStateD0)
pAdapt->StandingBy = FALSE;
}
Status = NDIS_STATUS_SUCCESS;
return Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -