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

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

?? queue.cpp

?? hidclass source code for windows ce use
?? CPP
字號:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//

#include "queue.h"
#include "hidmdd.h"


// Constructor. Set all members to unitialized states.
HidTLCQueue::HidTLCQueue(
    ) 
{
    m_fInitialized = FALSE;
    m_fAccepting = FALSE;
    m_pQueue = NULL;
    m_pbReportBuffer = NULL;
    m_dwCapacity = 0;
    m_hFilled = NULL;
    m_hClosing = NULL;
    m_cbMaxReport = 0;
    EmptyQueue();

    InitializeCriticalSection(&m_csLock);
}


// Initialize all members. Returns TRUE if successful.
BOOL
HidTLCQueue::Initialize(
    DWORD dwQueueCapacity,
    DWORD cbMaxReport
    )
{
    SETFNAME(_T("HidTLCQueue::Initialize"));

    DEBUGCHK(m_fInitialized == FALSE);
    DEBUGCHK(cbMaxReport > 0);

    Lock();

    m_cbMaxReport = cbMaxReport;

    if (ChangeQueueCapacity(dwQueueCapacity) != ERROR_SUCCESS) {
        goto EXIT;
    }

    m_hFilled = CreateEvent(NULL, MANUAL_RESET_EVENT, FALSE, NULL);
    if (m_hFilled == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: CreateEvent error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    m_hClosing = CreateEvent(NULL, MANUAL_RESET_EVENT, FALSE, NULL);
    if (m_hClosing == NULL) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: CreateEvent error:%d\r\n"), pszFname, GetLastError()));
        goto EXIT;
    }

    m_fInitialized = TRUE;

    Validate();

EXIT:
    Unlock();
    return m_fInitialized;
}


// Desctructor. Unlock all objects.
HidTLCQueue::~HidTLCQueue(
    )
{
    if (m_pQueue != NULL) HidFree(m_pQueue);
    if (m_pbReportBuffer != NULL) HidFree(m_pbReportBuffer);
    if (m_hFilled != NULL) CloseHandle(m_hFilled);
    if (m_hClosing != NULL) CloseHandle(m_hClosing);
    DeleteCriticalSection(&m_csLock);
}


// Adds a new report to the queue. Verify that the queue IsAccepting() and 
// !IsFull() before calling. Sets the m_hFilled event.
// This method is only to be called by the HID class driver.
BOOL 
HidTLCQueue::Enqueue(
    PCHAR pbNewReport, 
    DWORD cbNewReport,
    DWORD dwReportID
    )
{
    SETFNAME(_T("HidTLCQueue::Enqueue"));

    PHID_TLC_QUEUE_NODE pNode;
    PCHAR pbDest; 

    PREFAST_DEBUGCHK(pbNewReport != NULL);
    DEBUGCHK(cbNewReport <= m_cbMaxReport);

    Lock();
    Validate();
    
    DEBUGCHK(IsAccepting() == TRUE); // Only call when the queue is accepting
    DEBUGCHK(IsFull() == FALSE); // Do not call when the queue is full

    // Insert the report information at the back of the queue
    pNode = &m_pQueue[m_dwBack];
    
    DEBUGCHK(pNode->fValid == FALSE);
    DEBUGCHK(pNode->pbReport != NULL);

    pbDest = pNode->pbReport;
    if (dwReportID == 0) {
        // Prepend the ID of 0 onto the report.
        *pbDest = 0;
        ++pbDest;
    }
    
    memcpy(pbDest, pbNewReport, cbNewReport);
    pNode->cbReport = cbNewReport;

    if (dwReportID == 0) {
        // Add 1 to the report length to account for the prepended ID
        ++pNode->cbReport;
    }
    
#ifdef DEBUG
    pNode->fValid = TRUE;
#endif

    // Increment to next queue node
    if (++m_dwBack == m_dwCapacity) {
        m_dwBack = 0;
    }
    ++m_dwSize;

    SetEvent(m_hFilled);

    Validate();
    Unlock();
    
    return TRUE;
}

// Remove a report from the queue. The call will wait for dwTimeout if the
// queue is empty.
// Returns ERROR_SUCCESS, ERROR_DEVICE_REMOVED, or ERROR_TIMEOUT.
// This method is only to be called by a HID client driver.
DWORD 
HidTLCQueue::Dequeue(
    PCHAR pbBuffer, // The buffer to receive the report
    DWORD cbBuffer, // The size of the buffer
    PDWORD pcbTransferred, // How many bytes are in the report
    HANDLE hCancel, // Signal this to cancel the transfer
    DWORD dwTimeout // How long to wait for a report
    )
{
    SETFNAME(_T("HidTLCQueue::Dequeue"));

    PHID_TLC_QUEUE_NODE pNode;
    HANDLE rghWaits[] = { m_hFilled, m_hClosing, hCancel };
    DWORD chWaits = dim(rghWaits);
    DWORD dwErr = ERROR_SUCCESS;
    DWORD dwWaitResult;
    
    PREFAST_DEBUGCHK(pbBuffer != NULL);
    DEBUGCHK(cbBuffer == m_cbMaxReport);
    PREFAST_DEBUGCHK(pcbTransferred != NULL);

    UNREFERENCED_PARAMETER(cbBuffer);

    if (hCancel == NULL) {
        --chWaits;
    }

    // Wait for a report (m_hFilled), a call to Close (m_hClosing), 
    // a cancel (hCancel), or timeout.
    dwWaitResult = WaitForMultipleObjects(chWaits, rghWaits, FALSE, dwTimeout);

    Lock();
    Validate();
    
    if (dwWaitResult == WAIT_OBJECT_0 + 1) {
        // This device has been removed. We return an error so the thread
        // calling us can exit.
        dwErr = ERROR_DEVICE_REMOVED;
        goto EXIT;
    }
    else if (dwWaitResult == WAIT_OBJECT_0 + 2) {
        dwErr = ERROR_CANCELLED;
        goto EXIT;
    }
    else if (dwWaitResult == WAIT_TIMEOUT) {
        dwErr = ERROR_TIMEOUT;
        goto EXIT;
    }
    
    DEBUGCHK(GetSize() != 0);

    // Remove the report at the front of the queue.
    pNode = &m_pQueue[m_dwFront];
    
    DEBUGCHK(pNode->fValid == TRUE);
    DEBUGCHK(pNode->pbReport != NULL);
    DEBUGCHK(pNode->cbReport <= m_cbMaxReport);

    __try {
        memcpy(pbBuffer, pNode->pbReport, pNode->cbReport);
        *pcbTransferred = pNode->cbReport;
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
        dwErr = ERROR_INVALID_PARAMETER;
    }
    if (dwErr != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (_T("%s: Exception writing to user buffer\r\n"),
            pszFname));
        goto EXIT;
    }
    
#ifdef DEBUG
    pNode->fValid = FALSE;
    memset(pNode->pbReport, 0xCC, m_cbMaxReport);
#endif

    // Increment to next queue node
    if (++m_dwFront == m_dwCapacity) {
        m_dwFront = 0;
    }
    --m_dwSize;

    if (m_dwSize == 0) {
        // We are empty. Reset the m_hFilled event so we will wait next time.
        ResetEvent(m_hFilled);
    }

EXIT:
    Validate();
    Unlock();
    
    return dwErr;
}


// Signal that this queue will be closing, presumably because the device
// has been removed.
void
HidTLCQueue::Close(
    )
{
    Lock();
    Validate();
    SetEvent(m_hClosing);
    Unlock();
}


// Change the capacity (max number of reports) of the queue. All reports 
// currently in the queue are lost.
DWORD 
HidTLCQueue::SetCapacity(
    DWORD dwNewCapacity
    )
{
    SETFNAME(_T("HidTLCQueue::SetSize"));

    DWORD dwErr;

    DEBUGCHK(m_fInitialized == TRUE);

    Lock();
    Validate();
    dwErr = ChangeQueueCapacity(dwNewCapacity);
    Validate();
    Unlock();

    return dwErr;
}


// Allow the queue to accept new queued reports or not.
// Returns the old state of m_fAccepting.
BOOL 
HidTLCQueue::AcceptNewReports(
    BOOL fAccept
    )
{
    BOOL fOldAccept;
    
    Lock();
    Validate();
    fOldAccept = m_fAccepting;
    m_fAccepting = fAccept;
    Unlock();

    return fOldAccept;
}


// Remove all items from the queue.
void
HidTLCQueue::EmptyQueue(
    )
{
    m_dwFront = 0;
    m_dwBack = 0;
    m_dwSize = 0;
}


// Private helper function to change the queue capacity.
// Caller must verify that dwNewCapacity != 0.
// All reports currently in the queue are lost.
DWORD 
HidTLCQueue::ChangeQueueCapacity(
    DWORD dwNewCapacity
    )
{
    SETFNAME(_T("HidTLCQueue::ChangeQueueCapacity"));

    PHID_TLC_QUEUE_NODE pNewQueue;
    PCHAR pbNewReportBuffer;
    DWORD cbQueue;
    DWORD cbMaxReportBuffer;
    DWORD dwIdx;
    DWORD dwErr;

    DEBUGCHK(dwNewCapacity != 0);

    // Allocate the circular array of report nodes.
    cbQueue = dwNewCapacity * sizeof(HID_TLC_QUEUE_NODE);
    pNewQueue = (PHID_TLC_QUEUE_NODE) HidAlloc(cbQueue);
    if (pNewQueue == NULL) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s: LocalAlloc error:%d\r\n"), pszFname, dwErr));
        goto EXIT;
    }

    // Allocate the memory for a report in each node. This is done in one
    // big chunk and divided later.
    cbMaxReportBuffer = dwNewCapacity * m_cbMaxReport;
    pbNewReportBuffer = (PCHAR) HidAlloc(cbMaxReportBuffer);
    if (pbNewReportBuffer == NULL) {
        dwErr = GetLastError();
        DEBUGMSG(ZONE_ERROR, (_T("%s: LocalAlloc error:%d\r\n"), pszFname, dwErr));
        HidFree(pNewQueue);
        goto EXIT;
    }

    ZeroMemory(pNewQueue, cbQueue);

    // Assign a portion of the report buffer to each node.    
    for (dwIdx = 0; dwIdx < dwNewCapacity; ++dwIdx) {
        PCHAR pbCurrReport = pbNewReportBuffer + (dwIdx * m_cbMaxReport);
        DEBUGCHK(pbCurrReport < pbNewReportBuffer + cbMaxReportBuffer);
        pNewQueue[dwIdx].pbReport = pbCurrReport;
    }
    
    if (m_pQueue != NULL) {
        // Free the old queue
        HidFree(m_pQueue);
        HidFree(m_pbReportBuffer);
    }

    // Set the updated values.
    m_pQueue = pNewQueue;
    m_pbReportBuffer = pbNewReportBuffer;
    m_dwCapacity = dwNewCapacity;
    EmptyQueue();
    dwErr = ERROR_SUCCESS;
    
EXIT:
    return dwErr;
}


#ifdef DEBUG

// Validate the state of the queue.
void
HidTLCQueue::Validate(
    ) const
{
    PHID_TLC_QUEUE_NODE pNode;
    DWORD dwCalculatedSize;
    DWORD dwIdx;
    
    Lock();
    
    DEBUGCHK(m_fInitialized == TRUE);
    DEBUGCHK(m_pQueue != NULL);
    DEBUGCHK(LocalSize(m_pQueue) >= (m_dwCapacity * sizeof(HID_TLC_QUEUE_NODE)));
    DEBUGCHK(m_pbReportBuffer != NULL);
    DEBUGCHK(LocalSize(m_pbReportBuffer) >= (m_cbMaxReport * m_dwCapacity));

    DEBUGCHK(m_dwFront < m_dwCapacity);
    DEBUGCHK(m_dwBack < m_dwCapacity);
    DEBUGCHK(m_dwSize <= m_dwCapacity);

    // Verify that the queue nodes are valid 
    for (dwIdx = 0; dwIdx < m_dwCapacity; ++dwIdx) {
        pNode = &m_pQueue[dwIdx];
        DEBUGCHK(pNode->pbReport != NULL);
        DEBUGCHK(pNode->pbReport >= m_pbReportBuffer);
        DEBUGCHK(pNode->pbReport < m_pbReportBuffer + m_cbMaxReport * m_dwCapacity);
        DEBUGCHK(pNode->cbReport <= m_cbMaxReport);

        // If filled to capacity, then all nodes must be valid
        DEBUGCHK( (m_dwSize != m_dwCapacity) || (pNode->fValid == TRUE) );
    }

    dwIdx = m_dwFront;
    while (dwIdx != m_dwBack) {
        DEBUGCHK(dwIdx < m_dwCapacity);
        pNode = &m_pQueue[dwIdx];
        DEBUGCHK(pNode->fValid == TRUE);
        PREFAST_SUPPRESS( 394, "Potential buffer overrun while writing to buffer 'm_pQueue'. The buffer pointer is being incremented inside a loop." )
        if (++dwIdx == m_dwCapacity) {
            dwIdx = 0;
        }
    }

    // Check our size
    if (m_dwFront < m_dwBack) {
        dwCalculatedSize = m_dwBack - m_dwFront; 
    }
    else if (m_dwFront > m_dwBack) {
        dwCalculatedSize = m_dwCapacity - (m_dwFront - m_dwBack);
    }
    else {
        if (m_pQueue[m_dwFront].fValid == TRUE) {
            dwCalculatedSize = m_dwCapacity;
        }
        else {
            dwCalculatedSize = 0;
        }
    }
    DEBUGCHK(dwCalculatedSize == m_dwSize);

    DEBUGCHK(m_hFilled != NULL);
    DEBUGCHK(m_hClosing != NULL);

    Unlock();
}

#endif // DEBUG

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美日韩国产高清一区| 国产一区二区三区免费看| 懂色av中文一区二区三区| 欧美三电影在线| 亚洲美腿欧美偷拍| 成+人+亚洲+综合天堂| 久久精品一区八戒影视| 成人免费高清视频| 亚洲欧美国产77777| 在线日韩一区二区| 亚洲r级在线视频| 欧美精品久久99久久在免费线| 一区二区三区国产精品| 欧美日韩精品一区二区| 日日夜夜免费精品视频| 久久众筹精品私拍模特| 国产精品亚洲一区二区三区妖精 | 欧美经典一区二区| 99久久夜色精品国产网站| 亚洲欧美日韩国产中文在线| 日本道在线观看一区二区| 婷婷夜色潮精品综合在线| 精品国产精品网麻豆系列| 国产乱码精品一区二区三区忘忧草 | 欧美精品乱人伦久久久久久| 久久精品国产网站| 亚洲视频一区二区在线| 欧美一区永久视频免费观看| 国产乱子轮精品视频| 中日韩av电影| 欧美另类变人与禽xxxxx| 国产99久久久国产精品潘金 | 这里只有精品视频在线观看| 国产麻豆91精品| 亚洲综合激情另类小说区| 精品免费视频一区二区| 99re这里都是精品| 国产乱码精品一区二区三 | 欧美精品乱码久久久久久按摩| 国产a区久久久| 韩国女主播成人在线| 午夜私人影院久久久久| 亚洲欧美偷拍卡通变态| 国产日韩欧美一区二区三区乱码 | 国产一区二区女| 麻豆精品一区二区三区| 亚洲韩国精品一区| 一区二区三区精品| 亚洲国产精品一区二区尤物区| 国产精品久久久久久久久动漫 | 91精彩视频在线| 91麻豆精品在线观看| 一道本成人在线| 国产99久久久精品| 99久久久久免费精品国产| 成人永久免费视频| 不卡区在线中文字幕| gogogo免费视频观看亚洲一| 成人av手机在线观看| 99精品国产99久久久久久白柏| 成人爽a毛片一区二区免费| 成人三级伦理片| 91免费国产在线观看| 欧美性极品少妇| 69久久夜色精品国产69蝌蚪网| 91精品国产乱| 国产农村妇女精品| 亚洲最大色网站| 日韩中文字幕区一区有砖一区| 麻豆精品一区二区三区| 成人av在线电影| 91精品久久久久久久99蜜桃| 精品对白一区国产伦| 椎名由奈av一区二区三区| 亚洲高清中文字幕| 成人免费毛片嘿嘿连载视频| 欧美性受xxxx黑人xyx| 精品国产网站在线观看| 亚洲视频免费看| 国产中文字幕精品| 欧美色涩在线第一页| 亚洲综合激情另类小说区| 奇米一区二区三区| 色综合久久99| 欧美高清在线视频| 久久99精品国产麻豆婷婷洗澡| 99re热视频这里只精品| 久久久综合精品| 免费成人结看片| 欧美唯美清纯偷拍| 久久精品这里都是精品| 一区二区三区日韩精品| 国产一区二区女| 日韩精品综合一本久道在线视频| 亚洲午夜在线视频| 色美美综合视频| 一区二区在线观看av| av高清久久久| 日韩伦理电影网| 91麻豆精品秘密| 亚洲另类在线制服丝袜| 日本韩国欧美在线| 一区二区欧美视频| 欧美天堂一区二区三区| 亚洲欧美日韩系列| 在线观看免费视频综合| 午夜精品久久久久久久99水蜜桃| 色婷婷亚洲综合| 夜夜嗨av一区二区三区四季av| 91浏览器打开| 亚洲国产日韩精品| 制服丝袜成人动漫| 国产盗摄视频一区二区三区| 中文欧美字幕免费| 色综合久久久久| 精品一区二区三区日韩| 欧美经典三级视频一区二区三区| 91浏览器入口在线观看| 午夜天堂影视香蕉久久| 国产婷婷色一区二区三区四区| 成人午夜电影小说| 丝袜美腿高跟呻吟高潮一区| 欧美国产日产图区| 欧美日韩国产首页在线观看| 国产一区二区0| 亚洲chinese男男1069| 亚洲h精品动漫在线观看| 国产婷婷色一区二区三区在线| 欧美性猛交一区二区三区精品| 国产一区二区三区在线观看精品 | 日韩一区二区三区四区 | 91在线一区二区三区| 免费看日韩a级影片| 亚洲色图19p| 久久久国产午夜精品| 欧美理论片在线| 色综合天天综合网天天看片| 捆绑紧缚一区二区三区视频 | 久久综合九色综合欧美亚洲| 欧美午夜片在线观看| 成人精品小蝌蚪| 国产老妇另类xxxxx| 精品一区二区三区视频在线观看| 午夜精品国产更新| 午夜精品久久久| 石原莉奈在线亚洲三区| 亚洲国产精品综合小说图片区| 一区二区久久久久久| 亚洲人被黑人高潮完整版| 中文字幕一区二区三区在线不卡| 久久精品这里都是精品| 欧美激情在线观看视频免费| 精品国产91乱码一区二区三区 | 久久久国产精品午夜一区ai换脸| 日韩欧美高清在线| 欧美tickling挠脚心丨vk| 久久这里只有精品首页| 国产亚洲一区二区三区在线观看| 国产亚洲欧美一级| 国产精品美女久久久久久久久久久 | 精品国产凹凸成av人导航| 国产亚洲人成网站| 国产精品理伦片| 亚洲国产一区二区三区| 午夜精品福利一区二区三区av| 麻豆久久久久久| www.综合网.com| 欧美另类z0zxhd电影| 欧美成人性战久久| 国产精品美女久久久久久久久久久| 国产精品视频在线看| 五月婷婷欧美视频| 成人久久视频在线观看| 欧美精品视频www在线观看 | 亚洲最大成人网4388xx| 免费观看在线色综合| 色老汉av一区二区三区| 日韩欧美aaaaaa| 午夜伦理一区二区| 99r国产精品| 久久精品一区二区三区av| 天天综合色天天综合色h| 国产寡妇亲子伦一区二区| 这里只有精品99re| 亚洲国产精品久久久男人的天堂| 国产一区二区三区免费观看| 欧美在线观看一区| 国产精品电影院| 国产成a人无v码亚洲福利| 欧美一区二区久久久| 亚洲小说欧美激情另类| 在线视频观看一区| 一区二区免费视频| 在线免费精品视频| 一区二区三区四区高清精品免费观看| 高清在线成人网| 日本一区二区动态图| 国产精品一卡二卡| 欧美高清在线一区| 99热国产精品|