📄 protocol.c
字号:
if (pAdapt->QueuedRequest == TRUE)
{
pAdapt->QueuedRequest = FALSE;
NdisReleaseSpinLock(&pAdapt->Lock);
PtRequestComplete(pAdapt,
&pAdapt->Request,
NDIS_STATUS_FAILURE );
}
else
{
NdisReleaseSpinLock(&pAdapt->Lock);
}
// BEGIN_PTUSERIO
//
// Make Suprise Unbind Notification
//
DevOnUnbindAdapter( pAdapt->pOpenContext );
// END_PTUSERIO
#ifndef WIN9X
//
// Check if we had called NdisIMInitializeDeviceInstanceEx and
// we are awaiting a call to MiniportInitialize.
//
if (pAdapt->MiniportInitPending == TRUE)
{
//
// Try to cancel the pending IMInit process.
//
LocalStatus = NdisIMCancelInitializeDeviceInstance(
DriverHandle,
&pAdapt->DeviceName);
if (LocalStatus == NDIS_STATUS_SUCCESS)
{
//
// Successfully cancelled IM Initialization; our
// Miniport Initialize routine will not be called
// for this device.
//
pAdapt->MiniportInitPending = FALSE;
ASSERT(pAdapt->MiniportHandle == NULL);
}
else
{
//
// Our Miniport Initialize routine will be called
// (may be running on another thread at this time).
// Wait for it to finish.
//
NdisWaitEvent(&pAdapt->MiniportInitEvent, 0);
ASSERT(pAdapt->MiniportInitPending == FALSE);
}
}
#endif // !WIN9X
//
// Call NDIS to remove our device-instance. We do most of the work
// inside the HaltHandler.
//
// The Handle will be NULL if our miniport Halt Handler has been called or
// if the IM device was never initialized
//
if (pAdapt->MiniportHandle != NULL)
{
*Status = NdisIMDeInitializeDeviceInstance(pAdapt->MiniportHandle);
if (*Status != NDIS_STATUS_SUCCESS)
{
*Status = NDIS_STATUS_FAILURE;
}
}
else
{
//
// We need to do some work here.
// Close the binding below us
// and release the memory allocated.
//
if(pAdapt->BindingHandle != NULL)
{
NdisResetEvent(&pAdapt->Event);
NdisCloseAdapter(Status, pAdapt->BindingHandle);
//
// Wait for it to complete
//
if(*Status == NDIS_STATUS_PENDING)
{
NdisWaitEvent(&pAdapt->Event, 0);
*Status = pAdapt->Status;
}
pAdapt->BindingHandle = NULL;
}
else
{
//
// Both Our MiniportHandle and Binding Handle should not be NULL.
//
*Status = NDIS_STATUS_FAILURE;
ASSERT(0);
}
// BEGIN_PTUSERIO
//
// Remove Reference To The Adapter
//
PtDerefAdapter( pAdapt );
// END_PTUSERIO
}
DBGPRINT(("<== PtUnbindAdapter: Adapt %p\n", pAdapt));
}
VOID
PtUnloadProtocol(
VOID
)
{
NDIS_STATUS Status;
if (ProtHandle != NULL)
{
NdisDeregisterProtocol(&Status, ProtHandle);
ProtHandle = NULL;
}
DBGPRINT(("PtUnloadProtocol: done!\n"));
}
VOID
PtCloseAdapterComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Completion for the CloseAdapter call.
Arguments:
ProtocolBindingContext Pointer to the adapter structure
Status Completion status
Return Value:
None.
--*/
{
PADAPT pAdapt =(PADAPT)ProtocolBindingContext;
DBGPRINT(("CloseAdapterComplete: Adapt %p, Status %x\n", pAdapt, Status));
pAdapt->Status = Status;
NdisSetEvent(&pAdapt->Event);
}
VOID
PtResetComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Completion for the reset.
Arguments:
ProtocolBindingContext Pointer to the adapter structure
Status Completion status
Return Value:
None.
--*/
{
UNREFERENCED_PARAMETER(ProtocolBindingContext);
UNREFERENCED_PARAMETER(Status);
//
// We never issue a reset, so we should not be here.
//
ASSERT(0);
}
VOID
PtRequestComplete(
IN NDIS_HANDLE ProtocolBindingContext,
IN PNDIS_REQUEST NdisRequest,
IN NDIS_STATUS Status
)
/*++
Routine Description:
Completion handler for the previously posted request. All OIDS
are completed by and sent to the same miniport that they were requested for.
If Oid == OID_PNP_QUERY_POWER then the data structure needs to returned with all entries =
NdisDeviceStateUnspecified
Arguments:
ProtocolBindingContext Pointer to the adapter structure
NdisRequest The posted request
Status Completion status
Return Value:
None
--*/
{
PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
NDIS_OID Oid = pAdapt->Request.DATA.SET_INFORMATION.Oid;
// BEGIN_PTUSERIO
//
// Handle Local NDIS Requests
// --------------------------
// Here we handle NDIS requests that do not originate from the miniport.
//
// Typically, these are requests that were initiated from user-mode but
// could also be requests initiated autonomously by the NDIS IM driver.
//
if( NdisRequest != &(pAdapt->Request) )
{
PNDIS_REQUEST_EX pLocalRequest = (PNDIS_REQUEST_EX )NdisRequest;
(*pLocalRequest->RequestCompleteHandler )( pAdapt, pLocalRequest, Status );
return;
}
// END_PTUSERIO
//
// Since our request is not outstanding anymore
//
ASSERT(pAdapt->OutstandingRequests == TRUE);
pAdapt->OutstandingRequests = FALSE;
//
// Complete the Set or Query, and fill in the buffer for OID_PNP_CAPABILITIES, if need be.
//
switch (NdisRequest->RequestType)
{
case NdisRequestQueryInformation:
//
// We never pass OID_PNP_QUERY_POWER down.
//
ASSERT(Oid != OID_PNP_QUERY_POWER);
if ((Oid == OID_PNP_CAPABILITIES) && (Status == NDIS_STATUS_SUCCESS))
{
MPQueryPNPCapabilities(pAdapt, &Status);
}
*pAdapt->BytesReadOrWritten = NdisRequest->DATA.QUERY_INFORMATION.BytesWritten;
*pAdapt->BytesNeeded = NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded;
if ((Oid == OID_GEN_MAC_OPTIONS) && (Status == NDIS_STATUS_SUCCESS))
{
//
// Remove the no-loopback bit from mac-options. In essence we are
// telling NDIS that we can handle loopback. We don't, but the
// interface below us does. If we do not do this, then loopback
// processing happens both below us and above us. This is wasteful
// at best and if Netmon is running, it will see multiple copies
// of loopback packets when sniffing above us.
//
// Only the lowest miniport is a stack of layered miniports should
// ever report this bit set to NDIS.
//
*(PULONG)NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer &= ~NDIS_MAC_OPTION_NO_LOOPBACK;
}
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;
}
}
VOID
PtStatus(
IN NDIS_HANDLE ProtocolBindingContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize
)
/*++
Routine Description:
Status handler for the lower-edge(protocol).
Arguments:
ProtocolBindingContext Pointer to the adapter structure
GeneralStatus Status code
StatusBuffer Status buffer
StatusBufferSize Size of the status buffer
Return Value:
None
--*/
{
PADAPT pAdapt = (PADAPT)ProtocolBindingContext;
//
// Pass up this indication only if the upper edge miniport is initialized
// and powered on. Also ignore indications that might be sent by the lower
// miniport when it isn't at D0.
//
if ((pAdapt->MiniportHandle != NULL) &&
(pAdapt->MPDeviceState == NdisDeviceStateD0) &&
(pAdapt->PTDeviceState == NdisDeviceStateD0))
{
if ((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) ||
(GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT))
{
pAdapt->LastIndicatedStatus = GeneralStatus;
}
NdisMIndicateStatus(pAdapt->MiniportHandle,
GeneralStatus,
StatusBuffer,
StatusBufferSize);
}
//
// Save the last indicated media status
//
else
{
if ((pAdapt->MiniportHandle != NULL) &&
((GeneralStatus == NDIS_STATUS_MEDIA_CONNECT) ||
(GeneralStatus == NDIS_STATUS_MEDIA_DISCONNECT)))
{
pAdapt->LatestUnIndicateStatus = GeneralStatus;
}
}
}
VOID
PtStatusComplete(
IN NDIS_HANDLE ProtocolBindingContext
)
/*++
Routine Description:
Arguments:
Return Value:
--*/
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -