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

📄 utils.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
               goto Done;
        }
        //
        // Update structures
        ASSERT(pLastNode->m_uiReadyToRead >= uiToRead);
        ASSERT(m_uiReadyToRead >= uiToRead);
        ASSERT((BYTE*)pLastNode->m_pHead + pLastNode->m_uiBlockSize + 1 >= pLastNode->m_pReadBuffer + uiToRead);
        pLastNode->m_uiReadyToRead -= uiToRead;       
        pLastNode->m_pReadBuffer += uiToRead;
        m_uiReadyToRead -= uiToRead;
        
        //
        // If nothing is left in this buffer and its done being written to, 
        //   return it to the buffer pool
        if(0 == pLastNode->m_uiWriteRemaining &&
           0 == pLastNode->m_uiReadyToRead) {
           m_BufferList.pop_back();
           SMB_Globals::g_PrinterMemMapBuffers.Return(pLastNode->m_pHead);            
           //TRACEMSG(ZONE_PRINTQUEUE, (L"SMB_SRV: Ring buffer using -%d nodes", m_BufferList.size()));           
           delete pLastNode;
        }
        *puiReturned = uiToRead;
    }    
   
    //
    // Success
    hr = S_OK;
    
    Done:
        LeaveCriticalSection(&m_myLock);
        return hr;
}

HRESULT
RingBuffer::Write(const BYTE *pSrc, UINT uiSize, UINT *puiWritten)
{    
    EnterCriticalSection(&m_myLock);
    HRESULT hr = E_FAIL;
    UINT uiToWrite;
    RING_NODE *pFirstNode = NULL;
    BOOL fNewNodeNeeded = FALSE;
    
    *puiWritten = 0;
    
#ifdef DEBUG
    {
        //
        // Verify we have the correct amount of memory accounted for
        UINT uiVerify = 0;
        ce::list<RING_NODE *, RING_LIST_NODE_ALLOC >::iterator it = m_BufferList.begin();
        ce::list<RING_NODE *, RING_LIST_NODE_ALLOC >::iterator itEnd = m_BufferList.end();   
        while(it != itEnd) {
            uiVerify += (*it)->m_uiReadyToRead;
            it ++;
        }
        ASSERT(uiVerify == m_uiReadyToRead);
    }
#endif
    
    
    //
    // If we dont have any buffers in our list or the first one is empty
    //    create  a new one
    if(0 == m_BufferList.size()) {
        fNewNodeNeeded = TRUE;
    } else {
        pFirstNode = m_BufferList.front();
        if(0 == pFirstNode->m_uiWriteRemaining) {
            fNewNodeNeeded = TRUE;
        }
    }
   
    //
    //  If we need a new node, do the creation
    if(TRUE == fNewNodeNeeded) {
        RING_NODE *pNew = new RING_NODE();
        if(NULL == pNew) {
            goto Done;
        }
        pNew->m_pHead = SMB_Globals::g_PrinterMemMapBuffers.Create(&pNew->m_uiBlockSize);
        
        if(NULL == pNew->m_pHead) {
            TRACEMSG(ZONE_ERROR, (L"SMB_SRV: RingBuffer cant get new memory block! -- this is okay but we cant continue"));
            delete pNew;
            hr = S_OK;
            goto Done;
        }
        pNew->m_pReadBuffer = pNew->m_pWriteBuffer = (BYTE *)pNew->m_pHead;
        pNew->m_uiWriteRemaining = pNew->m_uiBlockSize;
        pNew->m_uiReadyToRead = 0;  
        
        if(!m_BufferList.push_front(pNew)) {
            delete pNew;
            hr = E_OUTOFMEMORY;
            goto Done;
        }
        TRACEMSG(ZONE_PRINTQUEUE, (L"SMB_SRV: Ring buffer using +(%d) nodes", m_BufferList.size()));
    }

    pFirstNode = m_BufferList.front();
    ASSERT(pFirstNode->m_uiWriteRemaining >= 0);

    //
    //  If there is data remaining on the current block
    //     read it now    
    uiToWrite = uiSize;
    if(uiToWrite > pFirstNode->m_uiWriteRemaining) {
        uiToWrite = pFirstNode->m_uiWriteRemaining;
    }        
    //
    // Do the move (note exception handler because this is from 
    //    memmap file
    __try {
        memcpy(pFirstNode->m_pWriteBuffer, pSrc, uiToWrite);
    } __except(1) {
        TRACEMSG(ZONE_ERROR, (L"SMB_SRV: RingBuffer caught exception!! this is BAD"));    
        ASSERT(FALSE);
        hr = E_FAIL;
        goto Done;
    }
    //
    // Update structures
    m_uiReadyToRead += uiToWrite;
    pFirstNode->m_uiReadyToRead += uiToWrite;
    pFirstNode->m_uiWriteRemaining -= uiToWrite;
    pFirstNode->m_pWriteBuffer += uiToWrite;    
    *puiWritten = uiToWrite;     
    ASSERT(uiSize >= uiToWrite);
    
    //
    // Success
    hr = S_OK;
    
    Done:
        LeaveCriticalSection(&m_myLock);
        return hr;
}

UINT
RingBuffer::BytesReadyToRead()
{
    CCritSection csLock(&m_myLock);
    csLock.Lock();
    return m_uiReadyToRead;
}

//
// Return the # of seconds since Jan1 1970 at 0:00:00
unsigned int SecSinceJan1970_0_0_0 (void) {
    SYSTEMTIME st;
    GetSystemTime (&st);

    LARGE_INTEGER ft;
    SystemTimeToFileTime (&st, (FILETIME *)&ft);

    ft.QuadPart -= 0x019db1ded53e8000;
    ft.QuadPart /= 10000000;

    return ft.LowPart;
}
 
 
unsigned int SecSinceJan1970_0_0_0 (FILETIME *_ft) {
    LARGE_INTEGER ft; //<-- this copying is done b/c we might not be aligned on 8 bytes!
    memcpy(&ft, _ft, sizeof(LARGE_INTEGER));
    ASSERT(sizeof(FILETIME) == sizeof(LARGE_INTEGER));
    ft.QuadPart -= 0x019db1ded53e8000;
    ft.QuadPart /= 10000000;
    return ft.LowPart;
}
 
BOOL FileTimeFromSecSinceJan1970(UINT uiSec, FILETIME *_ft) {
    LARGE_INTEGER ft;   
    ft.QuadPart = uiSec;
    ft.QuadPart *= 10000000;
    ft.QuadPart += 0x019db1ded53e8000;
    memcpy(_ft, &ft, sizeof(LARGE_INTEGER));
    return 1;
}
MemMappedBuffer::MemMappedBuffer():
                                 m_hFile(INVALID_HANDLE_VALUE),
                                 m_hMapping(INVALID_HANDLE_VALUE),
                                 m_pNext(NULL),
                                 m_uiMaxSize(0),
                                 m_uiInc(0),
                                 m_uiBlocksOutstanding(0),
                                 m_uiUsed(0),
                                 m_fInited(FALSE)
{
    InitializeCriticalSection(&myLock);
}

MemMappedBuffer::~MemMappedBuffer()
{    
    ASSERT(NULL == m_pNext);
    ASSERT(0 == m_uiBlocksOutstanding);
    ASSERT(0 == m_uiUsed);
    
    TRACEMSG(ZONE_PRINTQUEUE, (L"SMB_SRV:  MemMappedBuffer going down\n"));
    TRACEMSG(ZONE_PRINTQUEUE, (L"          %d blocks outstanding", m_uiBlocksOutstanding));
    TRACEMSG(ZONE_PRINTQUEUE, (L"          %d bytes used\n", m_uiUsed));
    
    
    //
    // Close the file mapping
    if(INVALID_HANDLE_VALUE != m_hMapping) {
        CloseHandle(m_hMapping);
    }
        
    DeleteCriticalSection(&myLock);
}

HRESULT
MemMappedBuffer::Close() 
{   
    CCritSection csLock(&myLock);
    csLock.Lock();
    
    ASSERT(NULL == m_pNext);
    ASSERT(0 == m_uiBlocksOutstanding);
    ASSERT(0 == m_uiUsed);        
    
    if(INVALID_HANDLE_VALUE != m_hMapping) {
        CloseHandle(m_hMapping);
    }
        
    m_hFile = INVALID_HANDLE_VALUE;
    m_hMapping =INVALID_HANDLE_VALUE;
    m_pNext = NULL;
    m_uiMaxSize = 0;
    m_uiInc = 0;
    m_uiBlocksOutstanding = 0;
    m_uiUsed = 0;
    m_fInited = FALSE;

    //
    // Success
    return S_OK;
}
HRESULT
MemMappedBuffer::Open(WCHAR *pFile, UINT _uiMaxSize, UINT _uiInc)
{
    EnterCriticalSection(&myLock);   
    HRESULT hr = E_FAIL;
    ASSERT(FALSE == m_fInited);
    
    //
    // If we are in the incorrect state, assert and return unexpected
    if(INVALID_HANDLE_VALUE != m_hFile ||
       INVALID_HANDLE_VALUE != m_hMapping ||
       NULL != m_pNext ||
       0 != m_uiUsed) {
       TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error Open called twice?"));
       ASSERT(FALSE);
       LeaveCriticalSection(&myLock);
       return E_UNEXPECTED;
    }
    
    m_uiMaxSize = _uiMaxSize;
    m_uiInc = _uiInc;
        
    //
    // Call CreateFileForMapping to open up our file
    m_hFile = CreateFileForMapping(pFile, 
                                   GENERIC_READ | GENERIC_WRITE,
                                   0,
                                   NULL, 
                                   CREATE_ALWAYS,
                                   FILE_ATTRIBUTE_NORMAL, 
                                   NULL);
                                   
    if(INVALID_HANDLE_VALUE == m_hFile) {
       TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- cant open file!: 0x%x", GetLastError()));
       hr = E_UNEXPECTED;
       goto Done;
    }
        
    //
    // Create an unnamed file mapping
    m_hMapping = CreateFileMapping(m_hFile,
                                   NULL,
                                   PAGE_READWRITE, 
                                   NULL,
                                   m_uiMaxSize, 
                                   NULL);
    if(INVALID_HANDLE_VALUE == m_hMapping) {       
       TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- CreateFileMapping failed with 0x%x!", GetLastError()));       
       ASSERT(FALSE);
       hr = E_UNEXPECTED;
       goto Done;
    }  
    
#ifdef DEBUG
    {
    VOID *pRet;
    //
    // Make sure we can actually map the entire contents of the file before
    //   going on.  This is just for debugging because we handle the case 
    //   where it CANT be done later -- but in order for testing to be accurate
    //   we want to acutally have the correct buffer spaces
    pRet = MapViewOfFile(m_hMapping,
                        FILE_MAP_READ | FILE_MAP_WRITE,
                        0,
                        0,
                        m_uiMaxSize);
    
    if(NULL != pRet) {
        __try {
            memset(pRet, 0, m_uiMaxSize);
        } __except(1) {            
            TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- memset on mapping test THREW!"));   
            ASSERT(FALSE);            
        }
        UnmapViewOfFile(pRet);     
    } else {        
        TRACEMSG(ZONE_ERROR, (L"SMB-MEMMAP: Error -- cant map view of file! 0x%x!", GetLastError()));              
        ASSERT(FALSE);
    }
    }
#endif
    
    //
    // At this point we dont have anything memory mapped -- this is to prevent
    //   us from using too much space
    //   
    hr = S_OK;
    
    Done:
        if(FAILED(hr)) {
            //
            // Close the file mapping
            if(INVALID_HANDLE_VALUE != m_hMapping) {
                CloseHandle(m_hMapping);
            }
            
            //
            // Get back into steady state
            m_hMapping = INVALID_HANDLE_VALUE;
            m_hFile = INVALID_HANDLE_VALUE;  
            m_uiMaxSize = 0;
            m_uiInc = 0;
            m_pNext=NULL;
            m_uiUsed=0;
        } else {
            m_uiMaxSize = _uiMaxSize;
            m_uiInc = _uiInc;
            m_fInited = TRUE;
        }
        LeaveCriticalSection(&myLock);
        return hr;
}


VOID *
MemMappedBuffer::Create(UINT *pBlockSize)
{
    EnterCriticalSection(&myLock);
    VOID *pRet = NULL; 
    *pBlockSize = 0;
    
    //
    // If we havent been inited error out
    if(FALSE == m_fInited) {
        ASSERT(FALSE);
        goto Done;
    }
        
    //
    // First thing, see if we have any memory laying around that we can
    //   give out
    if(NULL != m_pNext) {
        //TRACEMSG(ZONE_PRINTQUEUE, (L"SMB-MEMMAP: Got a free block to give back -- no work required."));
        pRet = m_pNext;
        m_pNext = (VOID *)(*(UINT *)m_pNext);
        goto Done;
    }
          
    //
    // If there isnt a free block, see if we can map a new one on the tail end of the file
    if(m_uiMaxSize - m_uiUsed >= m_uiInc) {
            
        //
        // Do the file mapping
        pRet = MapViewOfFile(m_hMapping,
                             FILE_MAP_READ | FILE_MAP_WRITE,
                             0,
                             m_uiUsed,
                             m_uiInc);
                             
        if(NULL == pRet) {            
            TRACEMSG(ZONE_PRINTQUEUE, (L"SMB-MEMMAP: Couldnt map a file view... this is bad and is an internal error: %d", GetLastError()));
            ASSERT(FALSE);

⌨️ 快捷键说明

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