📄 ndisbind.c
字号:
}
NPROT_RELEASE_LOCK(&Globals.GlobalLock);
return (pOpenContext);
}
NDIS_STATUS
ndisprotQueryOidValue(
IN PNDISPROT_OPEN_CONTEXT pOpenContext,
OUT PVOID pDataBuffer,
IN ULONG BufferLength,
OUT PULONG pBytesWritten
)
/*++
Routine Description:
Query an arbitrary OID value from the miniport.
Arguments:
pOpenContext - pointer to open context representing our binding to the miniport
pDataBuffer - place to store the returned value
BufferLength - length of the above
pBytesWritten - place to return length returned
Return Value:
NDIS_STATUS_SUCCESS if we successfully queried the OID.
NDIS_STATUS_XXX error code otherwise.
--*/
{
NDIS_STATUS Status;
PNDISPROT_QUERY_OID pQuery;
NDIS_OID Oid;
Oid = 0;
do
{
if (BufferLength < sizeof(NDISPROT_QUERY_OID))
{
Status = NDIS_STATUS_BUFFER_TOO_SHORT;
break;
}
pQuery = (PNDISPROT_QUERY_OID)pDataBuffer;
Oid = pQuery->Oid;
NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);
if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NUIOO_BIND_FLAGS, NUIOO_BIND_ACTIVE))
{
DEBUGP(DL_WARN,
("QueryOid: Open %p/%x is in invalid state\n",
pOpenContext, pOpenContext->Flags));
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
Status = NDIS_STATUS_FAILURE;
break;
}
//
// Make sure the binding doesn't go away.
//
NdisInterlockedIncrement((PLONG)&pOpenContext->PendedSendCount);
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
Status = ndisprotDoRequest(
pOpenContext,
NdisRequestQueryInformation,
Oid,
&pQuery->Data[0],
BufferLength - FIELD_OFFSET(NDISPROT_QUERY_OID, Data),
pBytesWritten);
NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);
NdisInterlockedDecrement((PLONG)&pOpenContext->PendedSendCount);
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
if (Status == NDIS_STATUS_SUCCESS)
{
*pBytesWritten += FIELD_OFFSET(NDISPROT_QUERY_OID, Data);
}
}
while (FALSE);
DEBUGP(DL_LOUD, ("QueryOid: Open %p/%x, OID %x, Status %x\n",
pOpenContext, pOpenContext->Flags, Oid, Status));
return (Status);
}
NDIS_STATUS
ndisprotSetOidValue(
IN PNDISPROT_OPEN_CONTEXT pOpenContext,
OUT PVOID pDataBuffer,
IN ULONG BufferLength
)
/*++
Routine Description:
Set an arbitrary OID value to the miniport.
Arguments:
pOpenContext - pointer to open context representing our binding to the miniport
pDataBuffer - buffer that contains the value to be set
BufferLength - length of the above
Return Value:
NDIS_STATUS_SUCCESS if we successfully set the OID
NDIS_STATUS_XXX error code otherwise.
--*/
{
NDIS_STATUS Status;
PNDISPROT_SET_OID pSet;
NDIS_OID Oid;
ULONG BytesWritten;
Oid = 0;
do
{
if (BufferLength < sizeof(NDISPROT_SET_OID))
{
Status = NDIS_STATUS_BUFFER_TOO_SHORT;
break;
}
pSet = (PNDISPROT_SET_OID)pDataBuffer;
Oid = pSet->Oid;
NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);
if (!NPROT_TEST_FLAGS(pOpenContext->Flags, NUIOO_BIND_FLAGS, NUIOO_BIND_ACTIVE))
{
DEBUGP(DL_WARN,
("SetOid: Open %p/%x is in invalid state\n",
pOpenContext, pOpenContext->Flags));
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
Status = NDIS_STATUS_FAILURE;
break;
}
//
// Make sure the binding doesn't go away.
//
NdisInterlockedIncrement((PLONG)&pOpenContext->PendedSendCount);
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
Status = ndisprotDoRequest(
pOpenContext,
NdisRequestSetInformation,
Oid,
&pSet->Data[0],
BufferLength - FIELD_OFFSET(NDISPROT_SET_OID, Data),
&BytesWritten);
NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);
NdisInterlockedDecrement((PLONG)&pOpenContext->PendedSendCount);
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
}
while (FALSE);
DEBUGP(DL_LOUD, ("SetOid: Open %p/%x, OID %x, Status %x\n",
pOpenContext, pOpenContext->Flags, Oid, Status));
return (Status);
}
NTSTATUS
ndisprotQueueStatusIndicationIrp(
IN PNDISPROT_OPEN_CONTEXT pOpenContext,
IN PIRP pIrp,
OUT PULONG pBytesReturned
)
/*++
Routine Description:
Queue the IRP in the context structure. This IRP will be completed
one of the following occurs: 1) Status indication is received by
the bound miniport, 2) IRP is cancelled by the sender, 3) We have
been asked to unbind from the miniport either because the device is removed
or user unchecked our binding in the network connection applet.
Arguments:
pOpenContext - pointer to open context representing our binding to the miniport
Return Value:
NTSTATUS code
--*/
{
NTSTATUS NtStatus;
DEBUGP(DL_LOUD, ("-->ndisprotQueueStatusIndicationIrp\n"));
NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);
if(pOpenContext->StatusIndicationIrp){
DEBUGP(DL_WARN, ("Control IRP to indicate status is already pending: %p\n", pIrp));
NtStatus = STATUS_DEVICE_BUSY;
}else {
//
// Since we are queueing the IRP, we should set the cancel routine.
//
IoSetCancelRoutine(pIrp, ndisCancelIndicateStatusIrp);
//
// Let us check to see if the IRP is cancelled at this point.
//
if(pIrp->Cancel && IoSetCancelRoutine(pIrp, NULL)){
//
// The IRP has been already cancelled but the I/O manager
// hasn't called the cancel routine yet. So complete the
// IRP after releasing the lock.
//
NtStatus = STATUS_CANCELLED;
}else {
//
// Queue the IRP and return status pending.
//
IoMarkIrpPending(pIrp);
pOpenContext->StatusIndicationIrp = pIrp;
NtStatus = STATUS_PENDING;
//
// The IRP shouldn't be accessed after the lock is released
// It could be grabbed by another thread or the cancel routine
// is running.
//
}
}
*pBytesReturned = 0;
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
DEBUGP(DL_LOUD, ("<--ndisprotQueueStatusIndicationIrp\n"));
return NtStatus;
}
VOID
ndisServiceIndicateStatusIrp(
IN PNDISPROT_OPEN_CONTEXT OpenContext,
IN NDIS_STATUS GeneralStatus,
IN PVOID StatusBuffer,
IN UINT StatusBufferSize,
IN BOOLEAN Cancel
)
/*++
Routine Description:
We process the IRP based on the input arguments and complete
the IRP. If the IRP was cancelled for some reason we will let
the cancel routine do the IRP completion.
Arguments:
ProtocolBindingContext - pointer to open context
GeneralStatus - status code
StatusBuffer - status-specific additional information
StatusBufferSize - size of the above
Cancel - Should the IRP be cancelled right away.
Return Value:
None
--*/
{
PIRP pIrp = NULL;
PIO_STACK_LOCATION pIrpSp = NULL;
PNDISPROT_INDICATE_STATUS pIndicateStatus = NULL;
NTSTATUS ntStatus;
ULONG bytes = 0;
ULONG inBufLength, outBufLength;
DEBUGP(DL_LOUD, ("-->ndisServiceIndicateStatusIrp\n"));
NPROT_ACQUIRE_LOCK(&OpenContext->Lock);
pIrp = OpenContext->StatusIndicationIrp;
do {
if(pIrp){
pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
pIndicateStatus = pIrp->AssociatedIrp.SystemBuffer;
inBufLength = pIrpSp->Parameters.DeviceIoControl.InputBufferLength;
outBufLength = pIrpSp->Parameters.DeviceIoControl.OutputBufferLength;
//
// Clear the cancel routine.
//
if(IoSetCancelRoutine(pIrp, NULL)){
//
// Cancel routine cannot run now and cannot have already
// started to run.
//
ntStatus = STATUS_CANCELLED;
if(!Cancel){
//
// Check to see whether the buffer is large enough.
//
if(outBufLength >= sizeof(NDISPROT_INDICATE_STATUS) &&
(outBufLength - sizeof(NDISPROT_INDICATE_STATUS)) >= StatusBufferSize){
pIndicateStatus->IndicatedStatus = GeneralStatus;
pIndicateStatus->StatusBufferLength = StatusBufferSize;
pIndicateStatus->StatusBufferOffset = sizeof(NDISPROT_INDICATE_STATUS);
NPROT_COPY_MEM((PUCHAR)pIndicateStatus +
pIndicateStatus->StatusBufferOffset,
StatusBuffer,
StatusBufferSize);
ntStatus = STATUS_SUCCESS;
} else {
ntStatus = STATUS_BUFFER_OVERFLOW;
}
}
//
// Since we are completing the IRP below, clear this field.
//
OpenContext->StatusIndicationIrp = NULL;
//
// Number of bytes copied or number of bytes required.
//
bytes = sizeof(NDISPROT_INDICATE_STATUS) + StatusBufferSize;
break;
}else {
//
// Cancel rotuine is running. Leave the irp alone.
//
pIrp = NULL;
}
}
}while(FALSE);
NPROT_RELEASE_LOCK(&OpenContext->Lock);
if(pIrp){
pIrp->IoStatus.Information = bytes;
pIrp->IoStatus.Status = ntStatus;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
}
DEBUGP(DL_LOUD, ("<--ndisServiceIndicateStatusIrp\n"));
return;
}
VOID
ndisCancelIndicateStatusIrp(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
/*++
Routine Description:
Cancel the pending status indication IRP registered by the app or
another driver.
Arguments:
pDeviceObject - pointer to our device object
pIrp - IRP to be cancelled
Return Value:
None
--*/
{
PNDISPROT_OPEN_CONTEXT pOpenContext;
PIO_STACK_LOCATION pIrpSp = NULL;
UNREFERENCED_PARAMETER(pDeviceObject);
DEBUGP(DL_LOUD, ("-->ndisCancelIndicateStatusIrp\n"));
IoReleaseCancelSpinLock(pIrp->CancelIrql);
pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
pOpenContext = (PNDISPROT_OPEN_CONTEXT)pIrpSp->FileObject->FsContext;
NPROT_STRUCT_ASSERT(pOpenContext, oc);
NPROT_ACQUIRE_LOCK(&pOpenContext->Lock);
pOpenContext->StatusIndicationIrp = NULL;
NPROT_RELEASE_LOCK(&pOpenContext->Lock);
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = STATUS_CANCELLED;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
DEBUGP(DL_LOUD, ("<--ndisCancelIndicateStatusIrp\n"));
return;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -