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

📄 utils.cpp

📁 Windows CE 6.0 Server 源码
💻 CPP
📖 第 1 页 / 共 4 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
#include <CReg.hxx>
#include <wincrypt.h>
#include <ntstatus.h>

#include "SMB_Globals.h"
#include "utils.h"
#include "encrypt.h"
#include "pc_net_prog.h"
#include "cracker.h"
#include "connectionmanager.h"
#include "smberrors.h"



#define INCREASE_BUF_UNIT   200

ce::fixed_block_allocator<10>           g_RingNodeAllocator;



StringConverter::StringConverter()
{
    Init();
}

StringConverter::StringConverter(const CHAR *pString)
{
    Init();
    append(pString);
}

StringConverter::StringConverter(const StringConverter &cpy)
{
    Init();
    append(cpy.pMyString);
}


StringConverter::~StringConverter()
{
    Clear();
}

VOID
StringConverter::Init()
{
    pMyString = MyString;
    pMyString[0] = NULL;
    uiLength = 1;
    uiBufLength = sizeof(MyString) / sizeof(MyString[0]);
}

HRESULT
StringConverter::Clear() 
{
    if(pMyString != MyString) {        
        delete [] pMyString;
    } 
    
    pMyString = MyString;
    uiLength = 1;
    uiBufLength = sizeof(MyString) / sizeof(MyString[0]);  
    return S_OK;
}

HRESULT 
StringConverter::append(const CHAR *pString)
{
   WCHAR Temp[1024];
   WCHAR *pPtr = Temp;
   
   //PERFPERF:  there could be a nice speed gain here by doing this in place... (to avoid 
   //   a memory copy... check out in profiler)
   UINT uiRequired = MultiByteToWideChar(CP_ACP, 0,pString,-1,0,0) + 1;  
   
   //
   // If we can fit this on the stack, super, else use the heap
   if(uiRequired > sizeof(Temp)/sizeof(Temp[0])) {
       pPtr  = new WCHAR[uiRequired];
       if(NULL == pPtr)
            return E_OUTOFMEMORY;
   }
        
   UINT uiConverted = MultiByteToWideChar(CP_ACP, 0, pString, -1, pPtr, uiRequired-1);
   pPtr[uiConverted] = '\0';
   
   ASSERT(uiRequired >= uiConverted);
   HRESULT hr = append(pPtr);
   if(pPtr != Temp) {
        delete [] pPtr;
   }     
   return hr;
}




HRESULT 
StringConverter::append(const WCHAR *pString)
{
    HRESULT hr = S_OK;
    UINT uiSize;
    
    if(NULL == pString) {
        return E_INVALIDARG;
    }
    
    ASSERT(uiLength >= 1 && uiBufLength >= 1);    
    uiSize = wcslen(pString);
        
    //
    // If we can fit in place WHOO HOO!  do so -- otherwise go to the heap
    if(uiBufLength - uiLength >= uiSize) {
        //-1 is to compensate for NULL 
        memmove(&pMyString[uiLength-1], pString, sizeof(WCHAR) * uiSize);   
        uiLength += uiSize;
        pMyString[uiLength-1] = NULL;
    }    
    else { 
        WCHAR *pTemp;     
        TRACEMSG(ZONE_ERROR, (L"SMB_SERV: StringConverter:  growing buffer"));
        
        if(NULL == (pTemp = new WCHAR[Size() + (uiSize * sizeof(WCHAR)) + INCREASE_BUF_UNIT])) {
            hr = E_OUTOFMEMORY;
            goto Done;
        }
        memmove(pTemp, pMyString, uiLength * sizeof(WCHAR));
        
        //-1 is to compensate for NULL
        memmove(&pTemp[uiLength-1], pString, sizeof(WCHAR) * uiSize);
        uiLength += uiSize;
        pTemp[uiLength-1] = NULL;        
        uiBufLength += ((uiLength * sizeof(WCHAR)) + INCREASE_BUF_UNIT);      

        if(pMyString != MyString) {
            delete [] pMyString;
        }
        pMyString = pTemp;    
    }
    
    hr = S_OK;
    Done:
        return hr;
}

const WCHAR *
StringConverter::GetString() 
{
    return pMyString;
}

WCHAR *
StringConverter::GetUnsafeString()
{
    return pMyString;
}

UINT
StringConverter::Size()
{
    return uiLength * sizeof(WCHAR);
}
UINT
StringConverter::Length()
{
    return uiLength;
}
     
//
// Return a blob of memory that is of type STRING (it may or may not be 
//   UNICODE depending on what was negotiated) -- you MUST FREE it with
//   LocalFree
BYTE *
//#error revisit this!
StringConverter::NewSTRING(UINT *_puiSize, BOOL fUnicode)
{
    *_puiSize = 0;
    BYTE *pRet = NULL;
    
    if(FALSE == fUnicode) {
        UINT uiSize; 
        if(0 != (uiSize = WideCharToMultiByte(CP_ACP, 0, pMyString, -1, NULL, 0,NULL,NULL))) 
        { 
            if(NULL != (pRet = (BYTE*)LocalAlloc(LMEM_FIXED, uiSize))) {            
                if(0 != WideCharToMultiByte(CP_ACP, 0, pMyString, -1, (CHAR *)pRet, uiSize, NULL, NULL)) {
                    *_puiSize = uiSize;
                } else if(pRet) {
                    pRet = NULL;
                }   
            }    
        } 
    } else {
        pRet = (BYTE *)LocalAlloc(LMEM_FIXED, Size());
        if(NULL != pRet) {
            (*_puiSize) = Size();
            memcpy(pRet, pMyString, Size());
        }
    }
    return pRet;
}
       
       
       
       
UniqueID::UniqueID() :usNext(0)
{
#ifdef DEBUG
    usNext = 0xFFF0;
#endif  
}
UniqueID::~UniqueID()
{
    IFDBG(if(IDList.size()){TRACEMSG(ZONE_ERROR, (L"SMB_SVR: ~UniqueID() still have %d objects outstanding!  maybe something is leaking!",IDList.size()));})
    ASSERT(0 == IDList.size());
}
        
HRESULT 
UniqueID::GetID(USHORT *uiID)
{
    ce::list<USHORT, UNIQUEID_ID_ALLOC >::iterator it = IDList.begin();
    ce::list<USHORT, UNIQUEID_ID_ALLOC >::iterator itEnd = IDList.end();   
  
    usNext ++;
    
    BOOL fFound = FALSE;
    BOOL fChanged = FALSE;
    
    //
    //  if the size of the list is 0xFFFE (0xFFFF is reserved)
    //     we dont have any more spaces... abort
    if(0xFFFE == IDList.size()) {
       ASSERT(FALSE);
       return E_FAIL;
    } 
   
    while(it != itEnd) {
        if(usNext == *it) {
            fChanged = TRUE;
            usNext++;
        }
        else if(*it > usNext) {
            IDList.insert(it, usNext);
            fFound = TRUE;
            break;
        }
        it++;
   }
   
   if(!fFound && !fChanged) {
        if(0xFFFF != usNext) {
            if(!IDList.push_back(usNext)) {
                return E_OUTOFMEMORY;
            }
        }
        fFound = TRUE;       
   }
   
   if(fFound) {       
       //
       // Reserve 0xFF as an invalid ID
       if(0xFFFF == usNext) {
           return this->GetID(uiID);
       } else {
           *uiID = usNext;
           return S_OK;
       }
   } else {
       return E_FAIL;
   }
    
}
HRESULT UniqueID::RemoveID(USHORT uiID)
{
    ce::list<USHORT, UNIQUEID_ID_ALLOC>::iterator it = IDList.begin();
    ce::list<USHORT, UNIQUEID_ID_ALLOC>::iterator itEnd = IDList.end();  
    BOOL fFound = FALSE;
     
    while(it != itEnd) {
        if(uiID == *it)  {
            IDList.erase(it++);
            fFound = TRUE;
            break;
        }
        it++;
    }
    
    if(fFound)
        return S_OK;
    else {
        ASSERT(FALSE);
        return E_FAIL;
    }
}









RingBuffer::RingBuffer() 
{
    ASSERT(0 == m_BufferList.size());  
    m_uiReadyToRead = 0;
    InitializeCriticalSection(&m_myLock);
}

RingBuffer::~RingBuffer() 
{ 
    Purge();
    DeleteCriticalSection(&m_myLock);
}

HRESULT 
RingBuffer::Purge() {
    CCritSection csLock(&m_myLock);
    csLock.Lock();
    
    //
    // Clean out any buffers we may have
    while(m_BufferList.size()) {   
        RING_NODE *pNode = m_BufferList.front();        
        m_BufferList.pop_front();
        SMB_Globals::g_PrinterMemMapBuffers.Return(pNode->m_pHead);
        delete pNode;
    }   

    return S_OK;
}

HRESULT
RingBuffer::Read(BYTE *pDest, UINT uiRequested, UINT *puiReturned)
{
    EnterCriticalSection(&m_myLock);
    HRESULT hr = E_FAIL;
    
    *puiReturned = 0;
    
    RING_NODE *pLastNode = NULL;
    
#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(0 == m_BufferList.size()) {
        hr = S_OK;
        goto Done;
    }

    pLastNode = m_BufferList.back();

    //
    //  If there is data remaining on the current block
    //     read it now
    if(pLastNode->m_uiReadyToRead > 0) {
        UINT uiToRead = uiRequested;
        if(uiRequested > pLastNode->m_uiReadyToRead) {
            uiToRead = pLastNode->m_uiReadyToRead;
        }        
        //
        // Do the move
        __try {
            memcpy(pDest, pLastNode->m_pReadBuffer, uiToRead);
        } __except(1) {
               TRACEMSG(ZONE_ERROR, (L"SMB_SRV: RingBuffer caught exception!! this is BAD"));        
               ASSERT(FALSE);
               hr = E_FAIL;

⌨️ 快捷键说明

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