Exemplo n.º 1
0
// 处理IRP_MJ_CREATE、IRP_MJ_CLOSE功能代码
NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	DbgPrint(" ProtoDrv: DispatchCreate \n");
	NTSTATUS status = STATUS_SUCCESS;
	
	if(pDevObj == g_data.pControlDevice)
	{
		pIrp->IoStatus.Status = STATUS_SUCCESS;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
		return status;
	}
	
	POPEN_INSTANCE pOpen = (POPEN_INSTANCE)pDevObj->DeviceExtension;


	IoIncrement(pOpen);

	if(!pOpen->bBound)
	{
		status = STATUS_DEVICE_NOT_READY;
	}
	
	pIrp->IoStatus.Information = 0;
	pIrp->IoStatus.Status = status;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	
	IoDecrement(pOpen);
	return status;
}
Exemplo n.º 2
0
NTSTATUS
DispatchCleanup(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    )
{
    POPEN_INSTANCE      pOpen = (POPEN_INSTANCE)DeviceObject->DeviceExtension;
    NTSTATUS            status = STATUS_SUCCESS;


    if(DeviceObject == g_data.pControlDevice) 
	{
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    IoIncrement(pOpen);
 
    CancelReadIrp(DeviceObject);

    IoDecrement(pOpen);

    NdisWaitEvent(&pOpen->CleanupEvent, 0);

    Irp->IoStatus.Information = 0;    
    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    return status;

}
Exemplo n.º 3
0
NTSTATUS
PacketClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    // This is the dispatch routine for create/open and close requests.
    // These requests complete successfully.

    POPEN_INSTANCE      open;
    NTSTATUS            status = STATUS_SUCCESS;

    DebugPrint(("CloseAdapter \n"));

#ifdef XNSDRW_LOG_PACKETS
    // reset the packet sniffing log
    LogReset();
#endif

    if (DeviceObject == Globals.ControlDeviceObject)
    {
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    open = DeviceObject->DeviceExtension;

    IoIncrement(open);

    Irp->IoStatus.Information = 0;    
    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);

    IoDecrement(open);
    return status;
}
Exemplo n.º 4
0
NTSTATUS PacketRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	POPEN_INSTANCE      open;
	PNDIS_PACKET        pPacket;
	NDIS_STATUS         status;
	NTSTATUS            ntStatus;
	PIO_STACK_LOCATION  irpSp;

	// DebugPrint(("Read\n"));

	open = DeviceObject->DeviceExtension;

	IoIncrement(open);

	if(!open->Bound) {
		ntStatus = STATUS_DEVICE_NOT_READY;
		goto ERROR;
	}

	irpSp = IoGetCurrentIrpStackLocation(Irp);

	if (irpSp->Parameters.Read.Length < ETHERNET_HEADER_LENGTH) {
		ntStatus = STATUS_BUFFER_TOO_SMALL;
		goto ERROR;
	}

	NdisAllocatePacket( &status, &pPacket, open->PacketPool );
	if (status != NDIS_STATUS_SUCCESS) {
		// DebugPrint(("Packet: Read- No free packets\n"));
		ntStatus = STATUS_INSUFFICIENT_RESOURCES;
		goto ERROR;
	}

	RESERVED(pPacket)->Irp=Irp;
	RESERVED(pPacket)->pMdl=NULL;
	IoMarkIrpPending(Irp);

	IoSetCancelRoutine(Irp, PacketCancelRoutine);

	ExInterlockedInsertTailList(
			&open->RcvList,
			&RESERVED(pPacket)->ListElement,
			&open->RcvQSpinLock);

	return STATUS_PENDING;

ERROR:
	Irp->IoStatus.Status = ntStatus;
	IoCompleteRequest (Irp, IO_NO_INCREMENT);
	IoDecrement(open);
	return ntStatus;
}
Exemplo n.º 5
0
NTSTATUS DispatchWrite(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	NTSTATUS status;

	// 取得描述适配器的OPEN_INSTANCE结构的指针
	OPEN_INSTANCE *pOpen = (OPEN_INSTANCE *)pDevObj->DeviceExtension;
	// 增加IO引用计数
	IoIncrement(pOpen);
	do
	{
		if(!pOpen->bBound)
		{
			status = STATUS_DEVICE_NOT_READY;
			break;
		}

		// 从封包池中申请一个封包
		PNDIS_PACKET pPacket;
		NdisAllocatePacket((NDIS_STATUS*)&status, &pPacket, pOpen->hPacketPool);
		if(status != NDIS_STATUS_SUCCESS)	// 封包被申请完了!
		{
			status = STATUS_INSUFFICIENT_RESOURCES;
			break;
		}

		RESERVED(pPacket)->pIrp = pIrp; // 保存IRP指针,在完成例程中还要使用

		// 附加写缓冲区到封包
		NdisChainBufferAtFront(pPacket, pIrp->MdlAddress);

		// 注意,既然我们已经标识此IRP未决,我们必须返回STATUS_PENDING,即便是
		// 我们恰巧同步完成了这个IRP
		IoMarkIrpPending(pIrp);

		// 发送封包到下层NIC设备
		NdisSend((NDIS_STATUS*)&status, pOpen->hAdapter, pPacket);
		if(status != NDIS_STATUS_PENDING)
		{
			ProtocolSendComplete(pOpen, pPacket, status);
		}
		return STATUS_PENDING;		
	}while(FALSE);

	if(status != STATUS_SUCCESS)
	{
		IoDecrement(pOpen);
		pIrp->IoStatus.Information = 0;
		pIrp->IoStatus.Status = status;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	}
	return status;
}
Exemplo n.º 6
0
NTSTATUS
PacketOpen(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    // This is the dispatch routine for create/open and close requests.
    // These requests complete successfully.

    POPEN_INSTANCE      open;
    NTSTATUS            status = STATUS_SUCCESS;

    DebugPrint(("OpenAdapter\n"));

#ifdef XNSDRW_LOG_PACKETS
    // reset the packet sniffing log
    LogReset();
#endif

    if (DeviceObject == Globals.ControlDeviceObject)
    {
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }
    
    open = DeviceObject->DeviceExtension;

    DebugPrint(("AdapterName :%ws\n", open->AdapterName.Buffer));

    IoIncrement(open);

    // Check to see whether you are still bound to the adapter
    if(! open->Bound)
    {
        status = STATUS_DEVICE_NOT_READY;
    }

    Irp->IoStatus.Information = 0;    
    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    IoDecrement(open);
    return status;
}
Exemplo n.º 7
0
NTSTATUS
PacketCleanup(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
    // This is the dispatch routine for cleanup requests.
    // This routine is called whenever a handle to the device is closed.

    POPEN_INSTANCE      open;
    NTSTATUS            status = STATUS_SUCCESS;

    DebugPrint(("Packet: Cleanup\n"));

    if (DeviceObject == Globals.ControlDeviceObject)
    {
        Irp->IoStatus.Status = status;
        IoCompleteRequest(Irp, IO_NO_INCREMENT);
        return status;
    }

    open = DeviceObject->DeviceExtension;

    IoIncrement(open);
    
    // Cancel all the pending reads.
    PacketCancelReadIrps(DeviceObject);

    // Since the current implementation of NDIS doesn't
    // allow us to cancel requests pending at the 
    // miniport, we must wait here until they complete.
    IoDecrement(open);

    NdisWaitEvent(&open->CleanupEvent, 0);

    Irp->IoStatus.Information = 0;    
    Irp->IoStatus.Status = status;
    IoCompleteRequest (Irp, IO_NO_INCREMENT);
    return status;
}
Exemplo n.º 8
0
// I/O控制派遣例程
NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	// 假设失败
	NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;

	// 取得此IRP(pIrp)的I/O堆栈指针
	PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

	// 取得I/O控制代码
	ULONG uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
	// 取得I/O缓冲区指针和它的长度
	PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	ULONG uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
	ULONG uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;

	if(uIoControlCode == IOCTL_ENUM_ADAPTERS)
	{
		ULONG nDataLen = 0;
		if(pDevObj != g_data.pControlDevice)
			status = STATUS_INVALID_DEVICE_REQUEST;
		else
		{
			status = GetAdapterList(pIoBuffer, uOutSize, &nDataLen);
			if(status != STATUS_SUCCESS)
				DbgPrint("GetAdapterList error ");
		}
		pIrp->IoStatus.Information = nDataLen;
		pIrp->IoStatus.Status = status;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
		return status;
	}

	OPEN_INSTANCE *pOpen = (OPEN_INSTANCE *)pDevObj->DeviceExtension;
	if(pOpen == NULL || !pOpen->bBound)
	{
		pIrp->IoStatus.Status = STATUS_UNSUCCESSFUL;
		IoCompleteRequest(pIrp, IO_NO_INCREMENT);
		return STATUS_UNSUCCESSFUL;
	}

	IoIncrement(pOpen);

	IoMarkIrpPending(pIrp);

	if(uIoControlCode == IOCTL_PROTOCOL_RESET) 
	{
		// 插入此IRP到重置IRP列表
       ExInterlockedInsertTailList(
                &pOpen->ResetIrpList,
                &pIrp->Tail.Overlay.ListEntry,
                &pOpen->ResetQueueLock);

	   // 发出重置请求
        NdisReset(
            &status,
            pOpen->hAdapter
            );
        if(status != NDIS_STATUS_PENDING) 
		{
            ProtocolResetComplete(
                pOpen,
                status);
        }
    }

	// 获取或者设置OID信息
	else if(uIoControlCode == IOCTL_PROTOCOL_SET_OID 
				|| uIoControlCode == IOCTL_PROTOCOL_QUERY_OID) // 输入参数是一个自定义的PROTOCOL_OID_DATA结构
	{
		PPROTOCOL_OID_DATA pOidData = (PPROTOCOL_OID_DATA)pIoBuffer;
		// 申请一个INTERNAL_REQUEST结构
		PINTERNAL_REQUEST pInterRequest = 
			(PINTERNAL_REQUEST)ExAllocatePool(NonPagedPool, sizeof(INTERNAL_REQUEST));
	   if(pInterRequest == NULL)
        {
            pIrp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
            IoCompleteRequest(pIrp, IO_NO_INCREMENT);
            IoDecrement(pOpen);
            return STATUS_PENDING;
        }         
        pInterRequest->pIrp = pIrp;

		if(uOutSize == uInSize && uOutSize >= sizeof(PROTOCOL_OID_DATA) &&
					uOutSize >= sizeof(PROTOCOL_OID_DATA) - 1 + pOidData->Length)	// 缓冲区可用?
		{
			// 初始化NDIS_REQUEST结构
			if(uIoControlCode == IOCTL_PROTOCOL_SET_OID)
			{
				pInterRequest->Request.RequestType = NdisRequestSetInformation;
				pInterRequest->Request.DATA.SET_INFORMATION.Oid = pOidData->Oid;
				pInterRequest->Request.DATA.SET_INFORMATION.InformationBuffer = pOidData->Data;
				pInterRequest->Request.DATA.SET_INFORMATION.InformationBufferLength = pOidData->Length;
			}
			else
			{
				pInterRequest->Request.RequestType = NdisRequestQueryInformation;
				pInterRequest->Request.DATA.QUERY_INFORMATION.Oid = pOidData->Oid;
				pInterRequest->Request.DATA.QUERY_INFORMATION.InformationBuffer = pOidData->Data;
				pInterRequest->Request.DATA.QUERY_INFORMATION.InformationBufferLength = pOidData->Length;
			}

			// 提交这个请求
			NdisRequest(&status, pOpen->hAdapter, &pInterRequest->Request);
		}
		else
		{
			status = NDIS_STATUS_FAILURE;
            pInterRequest->Request.DATA.SET_INFORMATION.BytesRead = 0;
            pInterRequest->Request.DATA.QUERY_INFORMATION.BytesWritten = 0;
		}
		
		if(status != NDIS_STATUS_PENDING)
		{
			ProtocolRequestComplete(pOpen, &pInterRequest->Request, status);
		}
	}

	return STATUS_PENDING;
}