📄 utils.cpp
字号:
//
// 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 + -