亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? emulser.c

?? 微軟的point of sale的源代碼
?? C
字號:
/*++

Copyright (c) 1999  Microsoft Corporation

Module Name:

    waitmask.c

Abstract: POS (serial) interface for USB Point-of-Sale devices

Author:

    Karan Mehra [t-karanm]

Environment:

    Kernel mode

Revision History:


--*/

#include <WDM.H>

#include <usbdi.h>
#include "usbdlib.h"
#include <usbioctl.h>

#include "escpos.h"
#include "debug.h"


NTSTATUS QuerySpecialFeature(PARENTFDOEXT *parentFdoExt)
{
    NTSTATUS status = STATUS_SUCCESS;
    HANDLE hRegDevice;
    parentFdoExt->posFlag = 0;

    status = IoOpenDeviceRegistryKey(parentFdoExt->physicalDevObj, 
                                     PLUGPLAY_REGKEY_DRIVER, 
                                     KEY_READ, 
                                     &hRegDevice);
    if (NT_SUCCESS(status)) {

        UNICODE_STRING keyName;
        PKEY_VALUE_FULL_INFORMATION keyValueInfo;
        ULONG keyValueTotalSize, actualLength, value;
        WCHAR oddKeyName[]  = L"OddEndpointFlag";

        #if STATUS_ENDPOINT

        WCHAR serialKeyName[] = L"SerialEmulationFlag";
        RtlInitUnicodeString(&keyName, serialKeyName); 

        keyValueTotalSize = sizeof(KEY_VALUE_FULL_INFORMATION) + keyName.Length*sizeof(WCHAR) + sizeof(ULONG);

        keyValueInfo = ALLOCPOOL(PagedPool, keyValueTotalSize);
        if (keyValueInfo) {
            status = ZwQueryValueKey(hRegDevice,
                                     &keyName,
                                     KeyValueFullInformation,
                                     keyValueInfo,
                                     keyValueTotalSize,
                                     &actualLength); 
            if (NT_SUCCESS(status)) {

                ASSERT(keyValueInfo->Type == REG_DWORD);
                ASSERT(keyValueInfo->DataLength == sizeof(ULONG));

                value = *((PULONG)(((PCHAR)keyValueInfo)+keyValueInfo->DataOffset));
                if (value == 1)
                    parentFdoExt->posFlag |= SERIAL_EMULATION;
            }
            else
                DBGVERBOSE(("QuerySpecialFeature: Flag not found. ZwQueryValueKey failed with %xh.", status));

            FREEPOOL(keyValueInfo);
        }
        else 
            ASSERT(keyValueInfo);

        #endif

        RtlInitUnicodeString(&keyName, oddKeyName); 

        keyValueTotalSize = sizeof(KEY_VALUE_FULL_INFORMATION) + keyName.Length*sizeof(WCHAR) + sizeof(ULONG);

        keyValueInfo = ALLOCPOOL(PagedPool, keyValueTotalSize);
        if (keyValueInfo) {
            status = ZwQueryValueKey(hRegDevice,
                                     &keyName,
                                     KeyValueFullInformation,
                                     keyValueInfo,
                                     keyValueTotalSize,
                                     &actualLength); 
            if (NT_SUCCESS(status)) {

                ASSERT(keyValueInfo->Type == REG_DWORD);
                ASSERT(keyValueInfo->DataLength == sizeof(ULONG));

                value = *((PULONG)(((PCHAR)keyValueInfo)+keyValueInfo->DataOffset));
                if (value == 1)
                    parentFdoExt->posFlag |= ODD_ENDPOINT;
            }
            else
                DBGVERBOSE(("QuerySpecialFeature: Flag not found. ZwQueryValueKey failed with %xh.", status));

            FREEPOOL(keyValueInfo);
        }
        else 
            ASSERT(keyValueInfo);

        ZwClose(hRegDevice);

        /*
         *  We do not wish to permit the Serial Emulation and 
         *  Odd Endpoint features together on the same device.
         */
        if((parentFdoExt->posFlag & SERIAL_EMULATION) && (parentFdoExt->posFlag & ODD_ENDPOINT)) {
            DBGVERBOSE(("More than one special feature NOT supported on the same device."));
            status = STATUS_INVALID_PARAMETER;
        }

    }
    else 
        DBGERR(("QuerySpecialFeature: IoOpenDeviceRegistryKey failed with %xh.", status));

    DBGVERBOSE(("QuerySpecialFeature: posFlag is now: %xh.", parentFdoExt->posFlag));
    return status;
}


VOID InitializeSerEmulVariables(POSPDOEXT *pdoExt)
{
    InitializeListHead(&pdoExt->pendingWaitIrpsList);
    pdoExt->baudRate = SERIAL_BAUD_115200;
    pdoExt->waitMask = 0;
    pdoExt->supportedBauds = SERIAL_BAUD_300   | SERIAL_BAUD_600   | SERIAL_BAUD_1200 
                           | SERIAL_BAUD_2400  | SERIAL_BAUD_4800  | SERIAL_BAUD_9600  
                           | SERIAL_BAUD_19200 | SERIAL_BAUD_38400 | SERIAL_BAUD_57600 
                           | SERIAL_BAUD_115200;
    pdoExt->currentMask = 0;
    pdoExt->fakeRxSize = 100;
    pdoExt->fakeLineControl.WordLength = 8;
    pdoExt->fakeLineControl.Parity     = NO_PARITY;
    pdoExt->fakeLineControl.StopBits   = STOP_BITS_2;
    pdoExt->fakeModemStatus = SERIAL_MSR_DCD | SERIAL_MSR_RI
                            | SERIAL_MSR_DSR | SERIAL_MSR_CTS;
}


NTSTATUS StatusPipe(POSPDOEXT *pdoExt, USBD_PIPE_HANDLE pipeHandle)
{
    NTSTATUS status;

    #if STATUS_ENDPOINT
    UsbBuildInterruptOrBulkTransferRequest(&pdoExt->statusUrb,
                                           (USHORT) sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
                                           pipeHandle,
                                           (PVOID) &pdoExt->statusPacket,
                                           NULL,
                                           sizeof(pdoExt->statusPacket),
                                           USBD_SHORT_TRANSFER_OK | USBD_TRANSFER_DIRECTION_IN,
                                           NULL);
    #else
    UsbBuildGetDescriptorRequest(&pdoExt->statusUrb,
                                 (USHORT) sizeof(struct _URB_CONTROL_DESCRIPTOR_REQUEST),
                                 USB_DEVICE_DESCRIPTOR_TYPE,
                                 0,
                                 0,
                                 (PVOID) &pdoExt->dummyPacket,
                                 NULL,
                                 sizeof(pdoExt->dummyPacket),
                                 NULL);
    #endif

    IncrementPendingActionCount(pdoExt->parentFdoExt);
    status = SubmitUrb(pdoExt->parentFdoExt->topDevObj, 
                       &pdoExt->statusUrb, 
                       FALSE, 
                       StatusPipeCompletion, 
                       pdoExt);
    return status;
}


NTSTATUS StatusPipeCompletion(IN PDEVICE_OBJECT devObj, IN PIRP irp, IN PVOID context)
{
    NTSTATUS status = irp->IoStatus.Status;
    POSPDOEXT *pdoExt = (POSPDOEXT *)context;

    if(NT_SUCCESS(status)) {
        UpdateMask(pdoExt);
        StatusPipe(pdoExt, pdoExt->statusEndpointInfo.pipeHandle);
        #if STATUS_ENDPOINT
        DBGVERBOSE(("Mask Updated and URB sent down to retrieve Status Packet"));
        #endif
    }

    IoFreeIrp(irp);
    DecrementPendingActionCount(pdoExt->parentFdoExt);
    return STATUS_MORE_PROCESSING_REQUIRED;
}


VOID UpdateMask(POSPDOEXT *pdoExt)
{
    KIRQL oldIrql;
    PIRP irp;
    ULONG mask;

    KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);

    /*
     *  Modify the emulated variables based on statusPacket
     */
    #if STATUS_ENDPOINT
    /*
     *  Fill in the values of DCTS, DDSR, TERI, DDCD by EX-ORing the current
     *  modem bits CTS, DSR, RI and DCD with those at the STATUS Endpoint.
     */
    pdoExt->fakeModemStatus = (pdoExt->fakeModemStatus & ~MSR_DELTA_MASK) | (((pdoExt->fakeModemStatus ^ pdoExt->statusPacket) & MSR_GLOBAL_MSK) >> MSR_DELTA_SHFT);

    /*
     *  Replace the bits for CTS, DSR, RI and DCD with those at the STATUS Endpoint.
     */
    pdoExt->fakeModemStatus = (pdoExt->fakeModemStatus & ~MSR_GLOBAL_MSK) | (pdoExt->statusPacket & MSR_GLOBAL_MSK);

    if(pdoExt->statusPacket & EMULSER_OE)  
        pdoExt->fakeLineStatus |= SERIAL_LSR_OE;

    if(pdoExt->statusPacket & EMULSER_PE)  
        pdoExt->fakeLineStatus |= SERIAL_LSR_PE;

    if(pdoExt->statusPacket & EMULSER_FE)  
        pdoExt->fakeLineStatus |= SERIAL_LSR_FE;

    if(pdoExt->statusPacket & EMULSER_BI)  
        pdoExt->fakeLineStatus |= SERIAL_LSR_BI;

    if(pdoExt->statusPacket & EMULSER_DTR)
        pdoExt->fakeDTRRTS |= SERIAL_DTR_STATE;

    if(pdoExt->statusPacket & EMULSER_RTS)
        pdoExt->fakeDTRRTS |= SERIAL_RTS_STATE;
    #endif

    if(pdoExt->waitMask) {
        if((pdoExt->waitMask & SERIAL_EV_CTS)  && (pdoExt->fakeModemStatus & SERIAL_MSR_DCTS)) 
            pdoExt->currentMask |= SERIAL_EV_CTS;

        if((pdoExt->waitMask & SERIAL_EV_DSR)  && (pdoExt->fakeModemStatus & SERIAL_MSR_DDSR))
            pdoExt->currentMask |= SERIAL_EV_DSR;

        if((pdoExt->waitMask & SERIAL_EV_RING) && (pdoExt->fakeModemStatus & SERIAL_MSR_TERI))
            pdoExt->currentMask |= SERIAL_EV_RING;

        if((pdoExt->waitMask & SERIAL_EV_RLSD) && (pdoExt->fakeModemStatus & SERIAL_MSR_DDCD))
            pdoExt->currentMask |= SERIAL_EV_RLSD;

        if((pdoExt->waitMask & SERIAL_EV_ERR)  && (pdoExt->fakeLineStatus  & (SERIAL_LSR_OE 
                                                                            | SERIAL_LSR_PE | SERIAL_LSR_FE))) 
            pdoExt->currentMask |= SERIAL_EV_ERR;

        if((pdoExt->waitMask & SERIAL_EV_BREAK) && (pdoExt->fakeLineStatus & SERIAL_LSR_BI))
            pdoExt->currentMask |= SERIAL_EV_BREAK;

        /*
         *  These are required to be filled by the read and write pipes.
         *  Currently, we return TRUE always.
         */
        if(pdoExt->waitMask & SERIAL_EV_RXCHAR)
            pdoExt->currentMask |= SERIAL_EV_RXCHAR;

        if(pdoExt->waitMask & SERIAL_EV_RXFLAG)
            pdoExt->currentMask |= SERIAL_EV_RXFLAG;

        if(pdoExt->waitMask & SERIAL_EV_TXEMPTY)
            pdoExt->currentMask |= SERIAL_EV_TXEMPTY;
    }
    mask = pdoExt->currentMask;
    KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);

    if(mask) {
        CompletePendingWaitIrps(pdoExt, mask);
        KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);	
        pdoExt->currentMask = 0;
        KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
    }
}


VOID CompletePendingWaitIrps(POSPDOEXT *pdoExt, ULONG mask)
{
    PIRP irp;

    while((irp = DequeueWaitIrp(pdoExt))) {
        irp->IoStatus.Information = sizeof(ULONG);
        irp->IoStatus.Status = STATUS_SUCCESS;
        *(PULONG)irp->AssociatedIrp.SystemBuffer = mask;
        IoCompleteRequest(irp, IO_NO_INCREMENT);
    }
}


NTSTATUS EnqueueWaitIrp(POSPDOEXT *pdoExt, PIRP irp)
{
    PDRIVER_CANCEL  oldCancelRoutine;	
    NTSTATUS status = STATUS_PENDING;
    KIRQL oldIrql;

    KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);

    if(IsListEmpty(&pdoExt->pendingWaitIrpsList)) 
    {
        InsertTailList(&pdoExt->pendingWaitIrpsList, &irp->Tail.Overlay.ListEntry);
        IoMarkIrpPending(irp);

        oldCancelRoutine = IoSetCancelRoutine(irp, WaitMaskCancelRoutine);
        ASSERT(!oldCancelRoutine);

        if (irp->Cancel) {
            oldCancelRoutine = IoSetCancelRoutine(irp, NULL);
            if (oldCancelRoutine) {
                RemoveEntryList(&irp->Tail.Overlay.ListEntry);
                status = irp->IoStatus.Status = STATUS_CANCELLED;
            }
        }
    }
    else
        status = irp->IoStatus.Status = STATUS_INVALID_PARAMETER;

    KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);

    if (status != STATUS_PENDING)
        IoCompleteRequest(irp, IO_NO_INCREMENT);

    return status;
}


PIRP DequeueWaitIrp(POSPDOEXT *pdoExt)
{
    PDRIVER_CANCEL oldCancelRoutine;
    PLIST_ENTRY listEntry;
    KIRQL oldIrql;	
    PIRP nextIrp = NULL;

    KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);

    while (!nextIrp && !IsListEmpty(&pdoExt->pendingWaitIrpsList)) {
        listEntry = RemoveHeadList(&pdoExt->pendingWaitIrpsList);
        nextIrp = CONTAINING_RECORD(listEntry, IRP, Tail.Overlay.ListEntry);
        oldCancelRoutine = IoSetCancelRoutine(nextIrp, NULL);

        if(oldCancelRoutine) {
            ASSERT(oldCancelRoutine == WaitMaskCancelRoutine);
        }
        else {
            ASSERT(nextIrp->Cancel);
            InitializeListHead(&nextIrp->Tail.Overlay.ListEntry);
            nextIrp = NULL;
        }
    }

    KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);
    return nextIrp;
}


VOID WaitMaskCancelRoutine(PDEVICE_OBJECT devObj, PIRP irp)
{
    DEVEXT *devExt;
    POSPDOEXT *pdoExt;
    KIRQL oldIrql;

    devExt = devObj->DeviceExtension;
    pdoExt = &devExt->pdoExt;

    IoReleaseCancelSpinLock(irp->CancelIrql);

    KeAcquireSpinLock(&pdoExt->devExtSpinLock, &oldIrql);
    RemoveEntryList(&irp->Tail.Overlay.ListEntry);
    KeReleaseSpinLock(&pdoExt->devExtSpinLock, oldIrql);

    irp->IoStatus.Status = STATUS_CANCELLED;
    IoCompleteRequest(irp, IO_NO_INCREMENT);
}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91精品国产品国语在线不卡| 久久久久久久免费视频了| 日韩一区二区免费在线电影 | 欧美日韩一区二区在线观看视频| 欧美日韩国产免费一区二区| 国产婷婷色一区二区三区在线| 一区二区三区久久| 国产成人精品亚洲午夜麻豆| 欧美男男青年gay1069videost| 欧美国产一区二区在线观看| 日本怡春院一区二区| 波多野结衣在线一区| 欧美大片免费久久精品三p| 亚洲国产日韩综合久久精品| 成人激情图片网| wwwwxxxxx欧美| 麻豆精品在线视频| 制服丝袜亚洲精品中文字幕| 亚洲欧洲一区二区在线播放| 国产精品一区二区在线观看网站| 欧美日本乱大交xxxxx| 综合电影一区二区三区 | 亚洲1区2区3区4区| 色老汉一区二区三区| 国产精品久久久一区麻豆最新章节| 看国产成人h片视频| 欧美日韩情趣电影| 亚洲国产中文字幕| 欧美日韩视频在线第一区| 亚洲精品videosex极品| 99精品久久久久久| 亚洲天堂中文字幕| 色婷婷综合五月| 亚洲乱码中文字幕| 一本色道a无线码一区v| 亚洲素人一区二区| 日本乱人伦aⅴ精品| 亚洲精品亚洲人成人网| 91福利国产成人精品照片| 亚洲欧美激情小说另类| 99精品视频在线观看| 亚洲欧美日韩在线播放| 色综合久久久久网| 亚洲不卡一区二区三区| 欧美日本一区二区在线观看| 首页综合国产亚洲丝袜| 日韩一级大片在线| 激情五月婷婷综合| 中文字幕不卡一区| 91福利社在线观看| 日本亚洲三级在线| 久久奇米777| 99久久精品免费观看| 亚洲欧美成人一区二区三区| 欧美日韩视频在线第一区 | 成人精品免费看| 亚洲精品视频免费看| 欧美日韩在线三级| 精品亚洲成a人在线观看| 久久久另类综合| 色偷偷久久一区二区三区| 日韩精品乱码av一区二区| xnxx国产精品| 99久久精品国产毛片| 天天色天天操综合| 久久久夜色精品亚洲| av电影一区二区| 亚洲成av人**亚洲成av**| 国产三级三级三级精品8ⅰ区| 91日韩在线专区| 奇米色777欧美一区二区| 中文子幕无线码一区tr| 91精品福利视频| 经典一区二区三区| 自拍偷拍亚洲激情| 日韩免费视频一区二区| 色先锋资源久久综合| 精品亚洲免费视频| 首页国产丝袜综合| 综合久久国产九一剧情麻豆| 精品久久久久久久久久久久久久久久久 | 日韩一区有码在线| 91.com在线观看| 成人av电影在线播放| 久久精品噜噜噜成人av农村| 欧美一区二区观看视频| 亚洲成人动漫精品| 日本一二三四高清不卡| 3d动漫精品啪啪| 国产成人8x视频一区二区| 午夜在线电影亚洲一区| 国产精品免费av| 精品国精品国产| 日本高清不卡一区| 91亚洲男人天堂| 欧美中文一区二区三区| 欧美日韩国产乱码电影| 欧美一卡2卡3卡4卡| 久久综合视频网| 国产精品短视频| 亚洲猫色日本管| 日日骚欧美日韩| 国产一区二区三区不卡在线观看| 国产精品亚洲第一| 99精品久久99久久久久| 91黄色激情网站| 日韩欧美在线网站| 欧美激情一区在线| 一区二区在线免费| 免费观看在线综合| 国产精品一卡二| 一本一道波多野结衣一区二区| 91精品一区二区三区久久久久久| 日韩久久精品一区| 中文字幕一区二区三区不卡| 亚洲成av人片在线观看| 国产一区二区剧情av在线| 91啪亚洲精品| 欧美成人欧美edvon| 中文字幕一区二区不卡| 日韩精品国产精品| 不卡的av在线播放| 制服丝袜日韩国产| 国产精品色婷婷久久58| 午夜激情一区二区三区| 国产成人丝袜美腿| 欧美乱熟臀69xxxxxx| 国产欧美日韩久久| 日本sm残虐另类| 99精品视频一区二区| 精品国产伦一区二区三区观看体验| 自拍偷拍欧美精品| 精品一区二区三区蜜桃| 欧美伊人久久大香线蕉综合69| 亚洲精品在线免费观看视频| 亚洲尤物在线视频观看| 国产精品99久久久久久宅男| 欧美挠脚心视频网站| 亚洲欧美日韩国产综合在线| 国产资源精品在线观看| 欧美日韩精品一区二区天天拍小说| 国产精品素人一区二区| 久久精品国产精品亚洲精品| 欧美在线小视频| 国产精品欧美综合在线| 九九国产精品视频| 3atv在线一区二区三区| 一区二区久久久久| 不卡影院免费观看| 国产欧美视频在线观看| 久久国产婷婷国产香蕉| 欧美片网站yy| 亚洲国产cao| 色婷婷久久久亚洲一区二区三区| 国产午夜精品在线观看| 久久se这里有精品| 日韩欧美国产高清| 日韩国产在线观看| 欧美乱妇15p| 亚洲成人精品一区| 欧美性大战久久久久久久| 亚洲欧美激情一区二区| 91丝袜美腿高跟国产极品老师| 国产午夜精品福利| 国产成人精品三级| 国产女人18毛片水真多成人如厕| 国产在线视视频有精品| 欧美大尺度电影在线| 美日韩一区二区| 欧美本精品男人aⅴ天堂| 美女视频免费一区| 欧美mv日韩mv国产网站app| 免费久久99精品国产| 精品国产亚洲在线| 国产露脸91国语对白| 久久综合狠狠综合久久激情 | av在线不卡免费看| 国产精品伦一区| 99久久精品国产观看| 自拍偷在线精品自拍偷无码专区| 99国产欧美另类久久久精品| 亚洲美女屁股眼交| 欧美日韩大陆在线| 国内精品国产成人| 日本一区二区三级电影在线观看| 成人性生交大合| 亚洲精品自拍动漫在线| 91麻豆精品国产91久久久资源速度 | 911精品产国品一二三产区| 日本成人在线不卡视频| 久久日韩精品一区二区五区| 成人理论电影网| 亚洲永久精品大片| 日韩无一区二区| 成人污污视频在线观看| 亚洲精品中文字幕在线观看| 欧美另类高清zo欧美| 精品亚洲国内自在自线福利| 亚洲欧洲国产日本综合| 欧美性xxxxxxxx|