📄 ntdisp.c
字号:
//
// Cancel any pending reads.
//
ndisuioCancelPendingReads(pOpenContext);
}
NtStatus = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
pIrp->IoStatus.Status = NtStatus;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
DEBUGP(DL_INFO, ("Cleanup: OpenContext %p\n", pOpenContext));
return (NtStatus);
}
NTSTATUS
NdisuioIoControl(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
/*++
Routine Description:
This is the dispatch routine for handling device ioctl requests.
Arguments:
pDeviceObject - Pointer to the device object.
pIrp - Pointer to the request packet.
Return Value:
Status is returned.
--*/
{
PIO_STACK_LOCATION pIrpSp;
ULONG FunctionCode;
NTSTATUS NtStatus;
NDIS_STATUS Status;
PNDISUIO_OPEN_CONTEXT pOpenContext;
ULONG BytesReturned;
USHORT EthType;
DEBUGP(DL_LOUD, ("IoControl: DevObj %p, Irp %p\n", pDeviceObject, pIrp));
pIrpSp = IoGetCurrentIrpStackLocation(pIrp);
FunctionCode = pIrpSp->Parameters.DeviceIoControl.IoControlCode;
pOpenContext = (PNDISUIO_OPEN_CONTEXT)pIrpSp->FileObject->FsContext;
BytesReturned = 0;
switch (FunctionCode)
{
case IOCTL_NDISUIO_BIND_WAIT:
//
// Block until we have seen a NetEventBindsComplete event,
// meaning that we have finished binding to all running
// adapters that we are supposed to bind to.
//
// If we don't get this event in 5 seconds, time out.
//
if (NUIO_WAIT_EVENT(&Globals.BindsComplete, 5000))
{
NtStatus = STATUS_SUCCESS;
}
else
{
NtStatus = STATUS_TIMEOUT;
}
DEBUGP(DL_INFO, ("IoControl: BindWait returning %x\n", NtStatus));
break;
case IOCTL_NDISUIO_QUERY_BINDING:
Status = ndisuioQueryBinding(
pIrp->AssociatedIrp.SystemBuffer,
pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
&BytesReturned
);
NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
DEBUGP(DL_LOUD, ("IoControl: QueryBinding returning %x\n", NtStatus));
break;
case IOCTL_NDISUIO_OPEN_DEVICE:
if (pOpenContext != NULL)
{
NUIO_STRUCT_ASSERT(pOpenContext, oc);
DEBUGP(DL_WARN, ("IoControl: OPEN_DEVICE: FileObj %p already"
" associated with open %p\n", pIrpSp->FileObject, pOpenContext));
NtStatus = STATUS_DEVICE_BUSY;
break;
}
NtStatus = ndisuioOpenDevice(
pIrp->AssociatedIrp.SystemBuffer,
pIrpSp->Parameters.DeviceIoControl.InputBufferLength,
pIrpSp->FileObject,
&pOpenContext
);
if (NT_SUCCESS(NtStatus))
{
pIrpSp->FileObject->FsContext = (PVOID)pOpenContext;
DEBUGP(DL_VERY_LOUD, ("IoControl OPEN_DEVICE: Open %p <-> FileObject %p\n",
pOpenContext, pIrpSp->FileObject));
}
break;
case IOCTL_NDISUIO_QUERY_OID_VALUE:
if (pOpenContext != NULL)
{
Status = ndisuioQueryOidValue(
pOpenContext,
pIrp->AssociatedIrp.SystemBuffer,
pIrpSp->Parameters.DeviceIoControl.OutputBufferLength,
&BytesReturned
);
NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
}
else
{
NtStatus = STATUS_DEVICE_NOT_CONNECTED;
}
break;
case IOCTL_NDISUIO_SET_OID_VALUE:
if (pOpenContext != NULL)
{
Status = ndisuioSetOidValue(
pOpenContext,
pIrp->AssociatedIrp.SystemBuffer,
pIrpSp->Parameters.DeviceIoControl.InputBufferLength
);
BytesReturned = 0;
NDIS_STATUS_TO_NT_STATUS(Status, &NtStatus);
}
else
{
NtStatus = STATUS_DEVICE_NOT_CONNECTED;
}
break;
case IOCTL_NDISUIO_SET_ETHER_TYPE:
if (pIrpSp->Parameters.DeviceIoControl.InputBufferLength < sizeof(Globals.EthType))
{
NtStatus = STATUS_BUFFER_TOO_SMALL;
}
else
{
//
// We only allow this value to be set to certain types.
//
EthType = *(USHORT *)pIrp->AssociatedIrp.SystemBuffer;
if (EthType != NUIO_ETH_TYPE)
{
DEBUGP(DL_WARN, ("IoControl: failed setting EthType to %x\n",
EthType));
NtStatus = STATUS_INVALID_PARAMETER;
break;
}
Globals.EthType = EthType;
DEBUGP(DL_INFO, ("IoControl: new Ether Type %x\n", Globals.EthType));
NtStatus = STATUS_SUCCESS;
}
break;
default:
NtStatus = STATUS_NOT_SUPPORTED;
break;
}
if (NtStatus != STATUS_PENDING)
{
pIrp->IoStatus.Information = BytesReturned;
pIrp->IoStatus.Status = NtStatus;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
}
return NtStatus;
}
NTSTATUS
ndisuioOpenDevice(
IN PUCHAR pDeviceName,
IN ULONG DeviceNameLength,
IN PFILE_OBJECT pFileObject,
OUT PNDISUIO_OPEN_CONTEXT * ppOpenContext
)
/*++
Routine Description:
Helper routine called to process IOCTL_NDISUIO_OPEN_DEVICE. Check if
there is a binding to the specified device, and is not associated with
a file object already. If so, make an association between the binding
and this file object.
Arguments:
pDeviceName - pointer to device name string
DeviceNameLength - length of above
pFileObject - pointer to file object being associated with the device binding
Return Value:
Status is returned.
--*/
{
PNDISUIO_OPEN_CONTEXT pOpenContext;
NTSTATUS NtStatus;
ULONG PacketFilter;
NDIS_STATUS NdisStatus;
ULONG BytesProcessed;
pOpenContext = NULL;
do
{
pOpenContext = ndisuioLookupDevice(
pDeviceName,
DeviceNameLength
);
if (pOpenContext == NULL)
{
DEBUGP(DL_WARN, ("ndisuioOpenDevice: couldn't find device\n"));
NtStatus = STATUS_OBJECT_NAME_NOT_FOUND;
break;
}
//
// else ndisuioLookupDevice would have addref'ed the open.
//
NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);
if (!NUIO_TEST_FLAGS(pOpenContext->Flags, NUIOO_OPEN_FLAGS, NUIOO_OPEN_IDLE))
{
NUIO_ASSERT(pOpenContext->pFileObject != NULL);
DEBUGP(DL_WARN, ("ndisuioOpenDevice: Open %p/%x already associated"
" with another FileObject %p\n",
pOpenContext, pOpenContext->Flags, pOpenContext->pFileObject));
NUIO_RELEASE_LOCK(&pOpenContext->Lock);
NUIO_DEREF_OPEN(pOpenContext); // ndisuioOpenDevice failure
NtStatus = STATUS_DEVICE_BUSY;
break;
}
pOpenContext->pFileObject = pFileObject;
NUIO_SET_FLAGS(pOpenContext->Flags, NUIOO_OPEN_FLAGS, NUIOO_OPEN_ACTIVE);
NUIO_RELEASE_LOCK(&pOpenContext->Lock);
//
// Set the packet filter now.
//
PacketFilter = NUIOO_PACKET_FILTER;
NdisStatus = ndisuioValidateOpenAndDoRequest(
pOpenContext,
NdisRequestSetInformation,
OID_GEN_CURRENT_PACKET_FILTER,
&PacketFilter,
sizeof(PacketFilter),
&BytesProcessed,
TRUE // Do wait for power on
);
if (NdisStatus != NDIS_STATUS_SUCCESS)
{
DEBUGP(DL_WARN, ("openDevice: Open %p: set packet filter (%x) failed: %x\n",
pOpenContext, PacketFilter, NdisStatus));
//
// Undo all that we did above.
//
NUIO_ACQUIRE_LOCK(&pOpenContext->Lock);
NUIO_SET_FLAGS(pOpenContext->Flags, NUIOO_OPEN_FLAGS, NUIOO_OPEN_IDLE);
pOpenContext->pFileObject = NULL;
NUIO_RELEASE_LOCK(&pOpenContext->Lock);
NUIO_DEREF_OPEN(pOpenContext); // ndisuioOpenDevice failure
NDIS_STATUS_TO_NT_STATUS(NdisStatus, &NtStatus);
break;
}
*ppOpenContext = pOpenContext;
NtStatus = STATUS_SUCCESS;
}
while (FALSE);
return (NtStatus);
}
VOID
ndisuioRefOpen(
IN PNDISUIO_OPEN_CONTEXT pOpenContext
)
/*++
Routine Description:
Reference the given open context.
NOTE: Can be called with or without holding the opencontext lock.
Arguments:
pOpenContext - pointer to open context
Return Value:
None
--*/
{
NdisInterlockedIncrement(&pOpenContext->RefCount);
}
VOID
ndisuioDerefOpen(
IN PNDISUIO_OPEN_CONTEXT pOpenContext
)
/*++
Routine Description:
Dereference the given open context. If the ref count goes to zero,
free it.
NOTE: called without holding the opencontext lock
Arguments:
pOpenContext - pointer to open context
Return Value:
None
--*/
{
if (NdisInterlockedDecrement(&pOpenContext->RefCount) == 0)
{
DEBUGP(DL_INFO, ("DerefOpen: Open %p, Flags %x, ref count is zero!\n",
pOpenContext, pOpenContext->Flags));
NUIO_ASSERT(pOpenContext->BindingHandle == NULL);
NUIO_ASSERT(pOpenContext->RefCount == 0);
NUIO_ASSERT(pOpenContext->pFileObject == NULL);
pOpenContext->oc_sig++;
//
// Free it.
//
NUIO_FREE_MEM(pOpenContext);
}
}
#if DBG
VOID
ndisuioDbgRefOpen(
IN PNDISUIO_OPEN_CONTEXT pOpenContext,
IN ULONG FileNumber,
IN ULONG LineNumber
)
{
DEBUGP(DL_VERY_LOUD, (" RefOpen: Open %p, old ref %d, File %c%c%c%c, line %d\n",
pOpenContext,
pOpenContext->RefCount,
(CHAR)(FileNumber),
(CHAR)(FileNumber >> 8),
(CHAR)(FileNumber >> 16),
(CHAR)(FileNumber >> 24),
LineNumber));
ndisuioRefOpen(pOpenContext);
}
VOID
ndisuioDbgDerefOpen(
IN PNDISUIO_OPEN_CONTEXT pOpenContext,
IN ULONG FileNumber,
IN ULONG LineNumber
)
{
DEBUGP(DL_VERY_LOUD, ("DerefOpen: Open %p, old ref %d, File %c%c%c%c, line %d\n",
pOpenContext,
pOpenContext->RefCount,
(CHAR)(FileNumber),
(CHAR)(FileNumber >> 8),
(CHAR)(FileNumber >> 16),
(CHAR)(FileNumber >> 24),
LineNumber));
ndisuioDerefOpen(pOpenContext);
}
#endif // DBG
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -