⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dispatch.cpp

📁 USBconvert232 USB转232驱动源程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
NTSTATUS Vcp4usbClose(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
    PVCP4USB_DEVICE_EXTENSION dx=(PVCP4USB_DEVICE_EXTENSION)fdo->DeviceExtension;
    NTSTATUS status = STATUS_SUCCESS;
    
    DPrint(DBG_CLOSE, ("Vcp4usbClose() @ %d\n", KeGetCurrentIrql()));
    
    Irp->IoStatus.Information = 0;
    
    CancelTimer(&dx->readIntervalTimer);
    CancelTimer(&dx->readTotalTimer);
    CancelTimer(&dx->writeTotalTimer);
    
    KeSetEvent(&dx->eventThreadExiting, 0, TRUE);
    KeWaitForSingleObject(&dx->eventThreadExit, Executive, KernelMode, TRUE, NULL);
    if (dx->pThreadObj)
    {
        KeWaitForSingleObject(dx->pThreadObj, Executive, KernelMode, FALSE, NULL);
        ObDereferenceObject(dx->pThreadObj);
        dx->pThreadObj = NULL;
    }
    KeResetEvent(&dx->eventThreadExit);
    
    DPrint(DBG_CLOSE, ("Vcp4usbClose() exit\n"));
    
    // Complete successfully
    return Vcp4usbCompleteIrp(Irp, status, Irp->IoStatus.Information);
}

//
NTSTATUS Vcp4usbCompleteIrp(PIRP Irp, NTSTATUS status, ULONG info)
{
    Irp->IoStatus.Status = status;
    Irp->IoStatus.Information = info;
    IoCompleteRequest(Irp,IO_NO_INCREMENT);
    return status;
}

//
NTSTATUS GetUsbDeviceName(OUT PUNICODE_STRING devName, IN CONST GUID *pGuid, IN CONST PWSTR pPrefix, IN ULONG prefixLength, IN ULONG instance)
{
    NTSTATUS status;
    UNICODE_STRING usbSymName;
    PWSTR pSymLink, pCur, p;
    ULONG instanceCur;
    USHORT size;
    
    status = IoGetDeviceInterfaces(pGuid, NULL, 0, &pSymLink);
    DPrint(DBG_OTHER, ("IoGetDeviceInterface return %d\n", status));
    
    if ((status == STATUS_INVALID_DEVICE_REQUEST) || (*pSymLink == NULL))
        return STATUS_UNSUCCESSFUL;
    
    pCur = pSymLink;
    instanceCur = 0;
    status = STATUS_INVALID_INFO_CLASS;
    while (*pCur != NULL)
    {
        p = pCur;
        for (size = 0; *p != NULL; size ++)
            p ++;
        DPrint(DBG_OTHER, ("No.%d: size=%d\n", instanceCur, size));
        DPrint(DBG_OTHER, ("name:%ws\n", pCur));
        if (instance == instanceCur)
        {
            if (RtlCompareMemory(pCur, pPrefix, prefixLength) == prefixLength)
            {
                DPrint(DBG_OTHER, ("Find OK\n"));
                devName->MaximumLength = size * sizeof(WCHAR);
                devName->Buffer = (PWSTR)ExAllocatePool(NonPagedPool, (size + 1) * sizeof(WCHAR));
                if (devName->Buffer == NULL)
                {
                    DPrint(DBG_OTHER, ("Allocate devName error.\n"));
                    status = STATUS_INSUFFICIENT_RESOURCES;
                    break;
                }
                RtlCopyMemory(devName->Buffer, pCur, (size+1) * sizeof(WCHAR));
                RtlInitUnicodeString(devName, devName->Buffer);
                status = STATUS_SUCCESS;
                break; // find ok and break
            }
        }
        pCur += size + 1; // skip last NULL
        instanceCur ++;
        if (instanceCur >= 2) // for debug
            break;
    }
    
    ExFreePool(pSymLink);
    return status;
}

NTSTATUS createFile(OUT PHANDLE pHandle, IN PUNICODE_STRING pDevName, IN PWSTR suffix, IN USHORT suffixLength, IN ACCESS_MASK mode)
{
    NTSTATUS status = STATUS_SUCCESS;
    OBJECT_ATTRIBUTES objAttribute;
    IO_STATUS_BLOCK ioStatus;
    UNICODE_STRING deviceName;
    
    // pDevName + suffix => deviceName
    RtlZeroMemory(&deviceName, sizeof(UNICODE_STRING));
    deviceName.MaximumLength = pDevName->MaximumLength + suffixLength * sizeof(WCHAR);
    deviceName.Buffer = (PWSTR)ExAllocatePool(NonPagedPool, deviceName.MaximumLength + sizeof(WCHAR));
    if (deviceName.Buffer == NULL)
    {
        DPrint(DBG_OTHER, ("Allocate deviceName.Buffer error.\n"));
        return STATUS_INSUFFICIENT_RESOURCES;
    }
    RtlAppendUnicodeToString(&deviceName, pDevName->Buffer);
    RtlAppendUnicodeToString(&deviceName, suffix);
    DPrint(DBG_OTHER, ("deviceName=%ws\n", deviceName.Buffer));
    
    InitializeObjectAttributes(&objAttribute,
        &deviceName,
        OBJ_CASE_INSENSITIVE,
        NULL,
        NULL);
    
    status = ZwCreateFile(pHandle,
        mode,
        &objAttribute,
        &ioStatus, // IoStatusBlock 
        0, // AllocationSize 
        FILE_ATTRIBUTE_DEVICE, // FileAttributes [FILE_ATTRIBUTE_DEVICE(0xC000000D)]
        0, // exclusive
        FILE_OPEN, // open exist
        0,//FILE_SYNCHRONOUS_IO_NONALERT,
        NULL,
        0);
    DPrint(DBG_OTHER, ("ZwCreateFile return:0x%x, ioStatus=%d\n", status, ioStatus.Status));
    
    ExFreePool(deviceName.Buffer);
    return status;
}

BOOLEAN CalculateWriteTimeout(IN PVCP4USB_DEVICE_EXTENSION pDevExt, IN ULONG dataSize,
                              OUT PLARGE_INTEGER pTotalTimeout)
{
    KIRQL           oldIrql;
    SERIAL_TIMEOUTS timeouts;
    SERIAL_HANDFLOW handflow;
    
    DPrint(DBG_OTHER, ("CalculateWriteTimeout\n"));
    
    RtlMoveMemory(&timeouts, &pDevExt->curTimeouts, sizeof(SERIAL_TIMEOUTS));
    RtlMoveMemory(&handflow, &pDevExt->curHandflow, sizeof(SERIAL_HANDFLOW));
    
    pTotalTimeout->QuadPart =
        ((LONGLONG)UInt32x32To64(timeouts.WriteTotalTimeoutMultiplier, dataSize) +
        timeouts.WriteTotalTimeoutConstant) * -10000;
    
    if (((handflow.ControlHandShake & SERIAL_OUT_HANDSHAKEMASK) == 0) &&
        ((handflow.FlowReplace & SERIAL_AUTO_TRANSMIT) == 0))
        return FALSE;
    else
        return TRUE;
}

VOID DpcWriteTotalTimeout(IN PKDPC pDpc, IN PVOID pDeferredContext, IN PVOID systemArgument1,
                          IN PVOID systemArgument2)
{
    DPrint(DBG_WRITE, ("DpcWriteTotalTimeout @ %d\n", KeGetCurrentIrql()));
    PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)pDeferredContext;
    if (!TimerCanceled(&dx->writeTotalTimer))
    {
        CancelTimer(&dx->writeTotalTimer);
        if (dx->irpWritePending)
        {
            PIRP Irp = dx->irpWritePending;
            IoAcquireCancelSpinLock(&Irp->CancelIrql);
            IoSetCancelRoutine(Irp, NULL);
            Irp->IoStatus.Status = STATUS_TIMEOUT;
            
            dx->bWritePending = FALSE;
            dx->irpWritePending = NULL;
            dx->curLenTx = 0;
            if (dx->pTxBuf)
            {
                //ExFreePool(dx->pTxBuf);
                dx->pTxBuf = NULL;
            }
            
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            DPrint(DBG_WRITE, ("DpcWriteTotalTimeout exit:TIMEOUT\n"));
            IoReleaseCancelSpinLock(Irp->CancelIrql);
        }
    }
}

BOOLEAN CalculateReadTimeouts(IN PVCP4USB_DEVICE_EXTENSION pDevExt, IN ULONG dataSize,
                              IN BOOLEAN firstChar, OUT PLARGE_INTEGER pIntervalTimeout,
                              OUT PLARGE_INTEGER pTotalTimeout)
{
    BOOLEAN returnImmediately = FALSE;
    KIRQL   oldIrql;
    
    DPrint(DBG_OTHER, ("CalculateReadTimeouts() @ %d\n", KeGetCurrentIrql()));
    
    if (pDevExt->curTimeouts.ReadIntervalTimeout == MAXULONG)
    {
        pIntervalTimeout->QuadPart = 0;
        
        if (pDevExt->curTimeouts.ReadTotalTimeoutMultiplier == MAXULONG)
        {
            if (pDevExt->curTimeouts.ReadTotalTimeoutConstant > 0)
            {
                if (!firstChar)
                    returnImmediately = TRUE;
                else
                {
                    pTotalTimeout->QuadPart =
                        -((LONGLONG)UInt32x32To64(pDevExt->curTimeouts.ReadTotalTimeoutConstant,
                        10000));
                }
            }
            else
                returnImmediately = TRUE;
        }
        else
        {
            if ((pDevExt->curTimeouts.ReadTotalTimeoutMultiplier == 0) &&
                (pDevExt->curTimeouts.ReadTotalTimeoutConstant == 0))
                returnImmediately = TRUE;
            else
            {
                if (firstChar)
                {
                    pTotalTimeout->QuadPart =
                        ((LONGLONG)UInt32x32To64(pDevExt->curTimeouts.ReadTotalTimeoutMultiplier,
                        dataSize) +
                        pDevExt->curTimeouts.ReadTotalTimeoutConstant) * -10000;
                }
                else
                    pTotalTimeout->QuadPart = 0;
            }
        }
    }
    else
    {
        if (firstChar)
        {
            pIntervalTimeout->QuadPart = 0;
            
            pTotalTimeout->QuadPart =
                ((LONGLONG)UInt32x32To64(pDevExt->curTimeouts.ReadTotalTimeoutMultiplier,
                dataSize) +
                pDevExt->curTimeouts.ReadTotalTimeoutConstant) * -10000;
        }
        else
        {
            pIntervalTimeout->QuadPart =
                -((LONGLONG)UInt32x32To64(pDevExt->curTimeouts.ReadIntervalTimeout, 10000));
            
            pTotalTimeout->QuadPart = 0;
        }
    }
    
    return returnImmediately;
}

VOID DpcReadIntervalTimeout(IN PKDPC pDpc, IN PVOID pDeferredContext, IN PVOID systemArgument1,
                            IN PVOID systemArgument2)
{
    DPrint(DBG_READ, ("DpcReadIntervalTimeout() @ %d\n", KeGetCurrentIrql()));
    PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)pDeferredContext;
    if (!TimerCanceled(&dx->readIntervalTimer))
    {
        CancelTimer(&dx->readIntervalTimer);
        //if (dx->irpReadPending)
        //{
        //    PIRP Irp = dx->irpReadPending;
        //    IoAcquireCancelSpinLock(&Irp->CancelIrql);
        //    IoSetCancelRoutine(Irp, NULL);
        //    Irp->IoStatus.Status = STATUS_TIMEOUT;
        //    dx->irpReadPending = NULL;
        //    dx->needLenRx = 0;
        //    IoCompleteRequest(Irp, IO_NO_INCREMENT);
        //    DPrint(DBG_READ, ("DpcReadIntervalTimeout exit:TIMEOUT\n"));
        //    IoReleaseCancelSpinLock(Irp->CancelIrql);
        //}
    }
}

VOID DpcReadTotalTimeout(IN PKDPC pDpc, IN PVOID pDeferredContext, IN PVOID systemArgument1,
                         IN PVOID systemArgument2)
{
    DPrint(DBG_READ, ("DpcReadTotalTimeout() @ %d\n", KeGetCurrentIrql()));
    PVCP4USB_DEVICE_EXTENSION dx = (PVCP4USB_DEVICE_EXTENSION)pDeferredContext;
    if (!TimerCanceled(&dx->readTotalTimer))
    {
        CancelTimer(&dx->readTotalTimer);
        if (dx->irpReadPending)
        {
            PIRP Irp = dx->irpReadPending;
            IoAcquireCancelSpinLock(&Irp->CancelIrql);
            IoSetCancelRoutine(Irp, NULL);
			if (dx->curLenRx == 0) // no data
			{
				Irp->IoStatus.Status = STATUS_TIMEOUT;
				Irp->IoStatus.Information = 0;
	            DPrint(DBG_READ, ("DpcReadTotalTimeout exit:TIMEOUT\n"));
			}
			else
			{
				RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,
					dx->pRxBuf, dx->curLenRx * sizeof(UCHAR));
				dx->curLenRx = 0;
				Irp->IoStatus.Status = STATUS_SUCCESS;
				Irp->IoStatus.Information = dx->curLenRx;
	            DPrint(DBG_READ, ("DpcReadTotalTimeout exit:SUCCESS\n"));
			}
            dx->irpReadPending = NULL;
			dx->needLenRx = 0;
            IoCompleteRequest(Irp, IO_NO_INCREMENT);
            IoReleaseCancelSpinLock(Irp->CancelIrql);
        }
    }
}

/////////////////////////////////////////////////////////////////////////////

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -