mirror of
https://github.com/reactos/reactos.git
synced 2025-01-05 22:12:46 +00:00
[ATL]
- Flush the CPU instruction cache after the ATL window proc thunk code is patched into memory. - Implement some (not all) CAtlList methods that I will need later on. - Implement some (not all) CStringT and CSimpleStringT methods & operators that I will need later on. svn path=/trunk/; revision=69701
This commit is contained in:
parent
9ce035003d
commit
6f3e0b39ca
4 changed files with 413 additions and 40 deletions
|
@ -54,12 +54,11 @@ public:
|
||||||
inline void Destroy()
|
inline void Destroy()
|
||||||
{
|
{
|
||||||
CAtlPlex* Block;
|
CAtlPlex* Block;
|
||||||
|
CAtlPlex* Next;
|
||||||
|
|
||||||
Block = this;
|
Block = this;
|
||||||
while (Block != NULL)
|
while (Block != NULL)
|
||||||
{
|
{
|
||||||
CAtlPlex* Next;
|
|
||||||
|
|
||||||
Next = Block->m_Next;
|
Next = Block->m_Next;
|
||||||
HeapFree(GetProcessHeap(), 0, Block);
|
HeapFree(GetProcessHeap(), 0, Block);
|
||||||
Block = Next;
|
Block = Next;
|
||||||
|
@ -170,20 +169,32 @@ public:
|
||||||
CAtlList(_In_ UINT nBlockSize = 10);
|
CAtlList(_In_ UINT nBlockSize = 10);
|
||||||
~CAtlList();
|
~CAtlList();
|
||||||
|
|
||||||
|
size_t GetCount() const;
|
||||||
bool IsEmpty() const;
|
bool IsEmpty() const;
|
||||||
|
|
||||||
POSITION GetHeadPosition() const;
|
POSITION GetHeadPosition() const;
|
||||||
|
POSITION GetTailPosition() const;
|
||||||
|
|
||||||
E& GetNext(
|
E& GetNext(_Inout_ POSITION& pos);
|
||||||
_Inout_ POSITION &Position
|
const E& GetNext(_Inout_ POSITION& pos) const;
|
||||||
);
|
E& GetPrev(_Inout_ POSITION& pos);
|
||||||
|
const E& GetPrev(_Inout_ POSITION& pos) const throw();
|
||||||
|
|
||||||
POSITION AddTail(
|
E& GetAt(_In_ POSITION pos);
|
||||||
INARGTYPE element
|
const E& GetAt(_In_ POSITION pos) const;
|
||||||
);
|
|
||||||
|
|
||||||
|
POSITION AddHead(INARGTYPE element);
|
||||||
|
POSITION AddTail(INARGTYPE element);
|
||||||
|
|
||||||
|
E RemoveHead();
|
||||||
E RemoveTail();
|
E RemoveTail();
|
||||||
void RemoveAll();
|
void RemoveAll();
|
||||||
|
void RemoveAt(_In_ POSITION pos) throw();
|
||||||
|
|
||||||
|
POSITION Find(
|
||||||
|
INARGTYPE element,
|
||||||
|
_In_opt_ POSITION posStartAfter = NULL) const;
|
||||||
|
POSITION FindIndex(_In_ size_t iElement) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
CNode* CreateNode(
|
CNode* CreateNode(
|
||||||
|
@ -225,31 +236,94 @@ CAtlList<E, ETraits >::~CAtlList(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, class ETraits>
|
template<typename E, class ETraits>
|
||||||
inline bool CAtlList< E, ETraits >::IsEmpty(void) const
|
inline size_t CAtlList< E, ETraits >::GetCount() const
|
||||||
|
{
|
||||||
|
return m_NumElements;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
inline bool CAtlList< E, ETraits >::IsEmpty() const
|
||||||
{
|
{
|
||||||
return (m_NumElements == 0);
|
return (m_NumElements == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, class ETraits>
|
template<typename E, class ETraits>
|
||||||
inline POSITION CAtlList<E, ETraits>::GetHeadPosition(void) const
|
inline POSITION CAtlList<E, ETraits>::GetHeadPosition() const
|
||||||
{
|
{
|
||||||
return (POSITION)m_HeadNode;
|
return (POSITION)m_HeadNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, class ETraits>
|
template<typename E, class ETraits>
|
||||||
inline E& CAtlList< E, ETraits >::GetNext(
|
inline POSITION CAtlList<E, ETraits>::GetTailPosition() const
|
||||||
_Inout_ POSITION& Position
|
|
||||||
)
|
|
||||||
{
|
{
|
||||||
CNode* Node = (CNode*)Position;
|
return (POSITION)m_TailNode;
|
||||||
Position = (POSITION)Node->m_Next;
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
inline E& CAtlList< E, ETraits >::GetNext(_Inout_ POSITION& pos)
|
||||||
|
{
|
||||||
|
CNode* Node = (CNode*)pos;
|
||||||
|
pos = (POSITION)Node->m_Next;
|
||||||
return Node->m_Element;
|
return Node->m_Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, class ETraits>
|
template<typename E, class ETraits>
|
||||||
POSITION CAtlList<E, ETraits>::AddTail(
|
inline const E& CAtlList< E, ETraits >::GetNext(_Inout_ POSITION& pos) const
|
||||||
INARGTYPE element
|
{
|
||||||
)
|
CNode* Node = (CNode*)pos;
|
||||||
|
pos = (POSITION)Node->m_Next;
|
||||||
|
return Node->m_Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
inline E& CAtlList< E, ETraits >::GetPrev(_Inout_ POSITION& pos)
|
||||||
|
{
|
||||||
|
CNode* Node = (CNode*)pos;
|
||||||
|
pos = (POSITION)Node->m_Prev;
|
||||||
|
return Node->m_Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
inline const E& CAtlList< E, ETraits >::GetPrev(_Inout_ POSITION& pos) const
|
||||||
|
{
|
||||||
|
CNode* Node = (CNode*)pos;
|
||||||
|
pos = (POSITION)Node->m_Prev;
|
||||||
|
return Node->m_Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
inline E& CAtlList< E, ETraits >::GetAt(_In_ POSITION pos)
|
||||||
|
{
|
||||||
|
CNode* Node = (CNode*)pos;
|
||||||
|
return Node->m_Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
inline const E& CAtlList< E, ETraits >::GetAt(_In_ POSITION pos) const
|
||||||
|
{
|
||||||
|
CNode* Node = (CNode*)pos;
|
||||||
|
return Node->m_Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
POSITION CAtlList<E, ETraits>::AddHead(INARGTYPE element)
|
||||||
|
{
|
||||||
|
CNode* Node = CreateNode(element, NULL, m_HeadNode);
|
||||||
|
if (m_HeadNode)
|
||||||
|
{
|
||||||
|
m_HeadNode->m_Prev = Node;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_TailNode = Node;
|
||||||
|
}
|
||||||
|
m_HeadNode = Node;
|
||||||
|
|
||||||
|
return (POSITION)Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
POSITION CAtlList<E, ETraits>::AddTail(INARGTYPE element)
|
||||||
{
|
{
|
||||||
CNode* Node = CreateNode(element, m_TailNode, NULL);
|
CNode* Node = CreateNode(element, m_TailNode, NULL);
|
||||||
if (m_TailNode)
|
if (m_TailNode)
|
||||||
|
@ -266,10 +340,29 @@ POSITION CAtlList<E, ETraits>::AddTail(
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, class ETraits>
|
template<typename E, class ETraits>
|
||||||
E CAtlList<E, ETraits>::RemoveTail(void)
|
E CAtlList<E, ETraits>::RemoveHead()
|
||||||
|
{
|
||||||
|
CNode* Node = m_HeadNode;
|
||||||
|
E Element(Node->m_Element);
|
||||||
|
|
||||||
|
m_HeadNode = Node->m_Next;
|
||||||
|
if (m_HeadNode)
|
||||||
|
{
|
||||||
|
m_HeadNode->m_Prev = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_TailNode = NULL;
|
||||||
|
}
|
||||||
|
FreeNode(Node);
|
||||||
|
|
||||||
|
return Element;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
E CAtlList<E, ETraits>::RemoveTail()
|
||||||
{
|
{
|
||||||
CNode* Node = m_TailNode;
|
CNode* Node = m_TailNode;
|
||||||
|
|
||||||
E Element(Node->m_Element);
|
E Element(Node->m_Element);
|
||||||
|
|
||||||
m_TailNode = Node->m_Prev;
|
m_TailNode = Node->m_Prev;
|
||||||
|
@ -287,7 +380,7 @@ E CAtlList<E, ETraits>::RemoveTail(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, class ETraits>
|
template<typename E, class ETraits>
|
||||||
void CAtlList<E, ETraits >::RemoveAll(void)
|
void CAtlList<E, ETraits >::RemoveAll()
|
||||||
{
|
{
|
||||||
while (m_NumElements > 0)
|
while (m_NumElements > 0)
|
||||||
{
|
{
|
||||||
|
@ -307,6 +400,73 @@ void CAtlList<E, ETraits >::RemoveAll(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
void CAtlList<E, ETraits >::RemoveAt(_In_ POSITION pos)
|
||||||
|
{
|
||||||
|
ATLASSERT(pos != NULL);
|
||||||
|
|
||||||
|
CNode* OldNode = (CNode*)pos;
|
||||||
|
if (OldNode == m_HeadNode)
|
||||||
|
{
|
||||||
|
m_HeadNode = OldNode->m_Next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OldNode->m_Prev->m_Next = OldNode->m_Next;
|
||||||
|
}
|
||||||
|
if (OldNode == m_TailNode)
|
||||||
|
{
|
||||||
|
m_TailNode = OldNode->m_Prev;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OldNode->m_Next->m_Prev = OldNode->m_Prev;
|
||||||
|
}
|
||||||
|
FreeNode(OldNode);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
POSITION CAtlList< E, ETraits >::Find(
|
||||||
|
INARGTYPE element,
|
||||||
|
_In_opt_ POSITION posStartAfter) const
|
||||||
|
{
|
||||||
|
CNode* Node = (CNode*)posStartAfter;
|
||||||
|
if (Node == NULL)
|
||||||
|
{
|
||||||
|
Node = m_HeadNode;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Node = Node->m_Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; Node != NULL; Node = Node->m_Next)
|
||||||
|
{
|
||||||
|
if (ETraits::CompareElements(Node->m_Element, element))
|
||||||
|
return (POSITION)Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename E, class ETraits>
|
||||||
|
POSITION CAtlList< E, ETraits >::FindIndex(_In_ size_t iElement) const
|
||||||
|
{
|
||||||
|
if (iElement >= m_NumElements)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (m_HeadNode == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
CNode* Node = m_HeadNode;
|
||||||
|
for (size_t i = 0; i < iElement; i++)
|
||||||
|
{
|
||||||
|
Node = Node->m_Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (POSITION)Node;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// CAtlist private methods
|
// CAtlist private methods
|
||||||
|
@ -351,7 +511,7 @@ void CAtlList<E, ETraits>::FreeNode(
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename E, class ETraits>
|
template<typename E, class ETraits>
|
||||||
typename CAtlList<E, ETraits>::CNode* CAtlList< E, ETraits>::GetFreeNode(void)
|
typename CAtlList<E, ETraits>::CNode* CAtlList< E, ETraits>::GetFreeNode()
|
||||||
{
|
{
|
||||||
if (m_FreeNode)
|
if (m_FreeNode)
|
||||||
{
|
{
|
||||||
|
|
|
@ -103,9 +103,21 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template< typename BaseType = wchar_t >
|
template< typename BaseType = char >
|
||||||
class ChTraitsBase
|
class ChTraitsBase
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
|
typedef char XCHAR;
|
||||||
|
typedef LPSTR PXSTR;
|
||||||
|
typedef LPCSTR PCXSTR;
|
||||||
|
typedef wchar_t YCHAR;
|
||||||
|
typedef LPWSTR PYSTR;
|
||||||
|
typedef LPCWSTR PCYSTR;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<>
|
||||||
|
class ChTraitsBase<wchar_t>
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
typedef wchar_t XCHAR;
|
typedef wchar_t XCHAR;
|
||||||
typedef LPWSTR PXSTR;
|
typedef LPWSTR PXSTR;
|
||||||
|
@ -118,9 +130,6 @@ public:
|
||||||
template< typename BaseType, bool t_bMFCDLL = false>
|
template< typename BaseType, bool t_bMFCDLL = false>
|
||||||
class CSimpleStringT
|
class CSimpleStringT
|
||||||
{
|
{
|
||||||
private:
|
|
||||||
LPWSTR m_pszData;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef typename ChTraitsBase<BaseType>::XCHAR XCHAR;
|
typedef typename ChTraitsBase<BaseType>::XCHAR XCHAR;
|
||||||
typedef typename ChTraitsBase<BaseType>::PXSTR PXSTR;
|
typedef typename ChTraitsBase<BaseType>::PXSTR PXSTR;
|
||||||
|
@ -129,6 +138,9 @@ public:
|
||||||
typedef typename ChTraitsBase<BaseType>::PYSTR PYSTR;
|
typedef typename ChTraitsBase<BaseType>::PYSTR PYSTR;
|
||||||
typedef typename ChTraitsBase<BaseType>::PCYSTR PCYSTR;
|
typedef typename ChTraitsBase<BaseType>::PCYSTR PCYSTR;
|
||||||
|
|
||||||
|
private:
|
||||||
|
PXSTR m_pszData;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CSimpleStringT(_Inout_ IAtlStringMgr* pStringMgr)
|
explicit CSimpleStringT(_Inout_ IAtlStringMgr* pStringMgr)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +155,44 @@ public:
|
||||||
Attach(pNewData);
|
Attach(pNewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSimpleStringT(
|
||||||
|
_In_z_ PCXSTR pszSrc,
|
||||||
|
_Inout_ IAtlStringMgr* pStringMgr)
|
||||||
|
{
|
||||||
|
int nLength = StringLength(pszSrc);
|
||||||
|
CStringData* pData = pStringMgr->Allocate(nLength, sizeof(XCHAR));
|
||||||
|
if (pData == NULL)
|
||||||
|
{
|
||||||
|
throw; // ThrowMemoryException();
|
||||||
|
}
|
||||||
|
Attach(pData);
|
||||||
|
SetLength(nLength);
|
||||||
|
CopyChars(m_pszData, nLength, pszSrc, nLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
CSimpleStringT(
|
||||||
|
_In_count_(nLength) const XCHAR* pchSrc,
|
||||||
|
_In_ int nLength,
|
||||||
|
_Inout_ IAtlStringMgr* pStringMgr)
|
||||||
|
{
|
||||||
|
if (pchSrc == NULL && nLength != 0)
|
||||||
|
throw;
|
||||||
|
|
||||||
|
CStringData* pData = pStringMgr->Allocate(nLength, sizeof(XCHAR));
|
||||||
|
if (pData == NULL)
|
||||||
|
{
|
||||||
|
throw; // ThrowMemoryException();
|
||||||
|
}
|
||||||
|
Attach(pData);
|
||||||
|
SetLength(nLength);
|
||||||
|
CopyChars(m_pszData, nLength, pchSrc, nLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
~CSimpleStringT() throw()
|
||||||
|
{
|
||||||
|
CStringData* pData = GetData();
|
||||||
|
pData->Release();
|
||||||
|
}
|
||||||
|
|
||||||
CSimpleStringT& operator=(_In_opt_z_ PCXSTR pszSrc)
|
CSimpleStringT& operator=(_In_opt_z_ PCXSTR pszSrc)
|
||||||
{
|
{
|
||||||
|
@ -150,13 +200,23 @@ public:
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CSimpleStringT& operator+=(_In_ const CSimpleStringT& strSrc)
|
||||||
|
{
|
||||||
|
Append(strSrc);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CSimpleStringT& operator+=(_In_z_ PCXSTR pszSrc)
|
||||||
|
{
|
||||||
|
Append(pszSrc);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
operator PCXSTR() const throw()
|
operator PCXSTR() const throw()
|
||||||
{
|
{
|
||||||
return m_pszData;
|
return m_pszData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Empty() throw()
|
void Empty() throw()
|
||||||
{
|
{
|
||||||
CStringData* pOldData = GetData();
|
CStringData* pOldData = GetData();
|
||||||
|
@ -175,6 +235,44 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Append(
|
||||||
|
_In_count_(nLength) PCXSTR pszSrc,
|
||||||
|
_In_ int nLength)
|
||||||
|
{
|
||||||
|
UINT_PTR nOffset = pszSrc - GetString();
|
||||||
|
|
||||||
|
int nOldLength = GetLength();
|
||||||
|
if (nOldLength < 0)
|
||||||
|
nOldLength = 0;
|
||||||
|
|
||||||
|
ATLASSERT(nLength >= 0);
|
||||||
|
|
||||||
|
#if 0 // FIXME: See comment for StringLengthN below.
|
||||||
|
nLength = StringLengthN(pszSrc, nLength);
|
||||||
|
if (!(INT_MAX - nLength >= nOldLength))
|
||||||
|
throw;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int nNewLength = nOldLength + nLength;
|
||||||
|
PXSTR pszBuffer = GetBuffer(nNewLength);
|
||||||
|
if (nOffset <= (UINT_PTR)nOldLength)
|
||||||
|
{
|
||||||
|
pszSrc = pszBuffer + nOffset;
|
||||||
|
}
|
||||||
|
CopyChars(pszBuffer + nOldLength, nLength, pszSrc, nLength);
|
||||||
|
ReleaseBufferSetLength(nNewLength);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append(_In_z_ PCXSTR pszSrc)
|
||||||
|
{
|
||||||
|
Append(pszSrc, StringLength(pszSrc));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Append(_In_ const CSimpleStringT& strSrc)
|
||||||
|
{
|
||||||
|
Append(strSrc.GetString(), strSrc.GetLength());
|
||||||
|
}
|
||||||
|
|
||||||
void SetString(_In_opt_z_ PCXSTR pszSrc)
|
void SetString(_In_opt_z_ PCXSTR pszSrc)
|
||||||
{
|
{
|
||||||
SetString(pszSrc, StringLength(pszSrc));
|
SetString(pszSrc, StringLength(pszSrc));
|
||||||
|
@ -206,12 +304,6 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int __cdecl StringLength(_In_opt_z_ const wchar_t* psz) throw()
|
|
||||||
{
|
|
||||||
if (psz == NULL) return 0;
|
|
||||||
return (int)wcslen(psz);
|
|
||||||
}
|
|
||||||
|
|
||||||
PXSTR GetBuffer()
|
PXSTR GetBuffer()
|
||||||
{
|
{
|
||||||
CStringData* pData = GetData();
|
CStringData* pData = GetData();
|
||||||
|
@ -257,7 +349,41 @@ public:
|
||||||
|
|
||||||
CStringData* GetData() const throw()
|
CStringData* GetData() const throw()
|
||||||
{
|
{
|
||||||
return reinterpret_cast<CStringData*>(m_pszData) - 1;
|
return (reinterpret_cast<CStringData*>(m_pszData) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
IAtlStringMgr* GetManager() const throw()
|
||||||
|
{
|
||||||
|
IAtlStringMgr* pStringMgr = GetData()->pStringMgr;
|
||||||
|
return (pStringMgr ? pStringMgr->Clone() : NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend CSimpleStringT operator+(
|
||||||
|
_In_ const CSimpleStringT& str1,
|
||||||
|
_In_ const CSimpleStringT& str2)
|
||||||
|
{
|
||||||
|
CSimpleStringT s(str1.GetManager());
|
||||||
|
Concatenate(s, str1, str1.GetLength(), str2, str2.GetLength());
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend CSimpleStringT operator+(
|
||||||
|
_In_ const CSimpleStringT& str1,
|
||||||
|
_In_z_ PCXSTR psz2)
|
||||||
|
{
|
||||||
|
CSimpleStringT s(str1.GetManager());
|
||||||
|
Concatenate(s, str1, str1.GetLength(), psz2, StringLength(psz2));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
friend CSimpleStringT operator+(
|
||||||
|
_In_z_ PCXSTR psz1,
|
||||||
|
_In_ const CSimpleStringT& str2)
|
||||||
|
{
|
||||||
|
CSimpleStringT s(str2.GetManager());
|
||||||
|
Concatenate(s, psz1, StringLength(psz1), str2, str2.GetLength());
|
||||||
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __cdecl CopyChars(
|
static void __cdecl CopyChars(
|
||||||
|
@ -278,13 +404,58 @@ public:
|
||||||
memmove(pchDest, pchSrc, nChars * sizeof(XCHAR));
|
memmove(pchDest, pchSrc, nChars * sizeof(XCHAR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int __cdecl StringLength(_In_opt_z_ const char* psz) throw()
|
||||||
|
{
|
||||||
|
if (psz == NULL) return 0;
|
||||||
|
return (int)strlen(psz);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __cdecl StringLength(_In_opt_z_ const wchar_t* psz) throw()
|
||||||
|
{
|
||||||
|
if (psz == NULL) return 0;
|
||||||
|
return (int)wcslen(psz);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0 // For whatever reason we do not link with strnlen / wcsnlen. Please investigate!
|
||||||
|
// strnlen / wcsnlen are available in MSVCRT starting Vista+.
|
||||||
|
static int __cdecl StringLengthN(
|
||||||
|
_In_opt_z_count_(sizeInXChar) const char* psz,
|
||||||
|
_In_ size_t sizeInXChar) throw()
|
||||||
|
{
|
||||||
|
if (psz == NULL) return 0;
|
||||||
|
return (int)strnlen(psz, sizeInXChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __cdecl StringLengthN(
|
||||||
|
_In_opt_z_count_(sizeInXChar) const wchar_t* psz,
|
||||||
|
_In_ size_t sizeInXChar) throw()
|
||||||
|
{
|
||||||
|
if (psz == NULL) return 0;
|
||||||
|
return (int)wcsnlen(psz, sizeInXChar);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static void __cdecl Concatenate(
|
||||||
|
_Inout_ CSimpleStringT& strResult,
|
||||||
|
_In_count_(nLength1) PCXSTR psz1,
|
||||||
|
_In_ int nLength1,
|
||||||
|
_In_count_(nLength2) PCXSTR psz2,
|
||||||
|
_In_ int nLength2)
|
||||||
|
{
|
||||||
|
int nNewLength = nLength1 + nLength2;
|
||||||
|
PXSTR pszBuffer = strResult.GetBuffer(nNewLength);
|
||||||
|
CopyChars(pszBuffer, nLength1, psz1, nLength1);
|
||||||
|
CopyChars(pszBuffer + nLength1, nLength2, psz2, nLength2);
|
||||||
|
strResult.ReleaseBufferSetLength(nNewLength);
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
void Attach(_Inout_ CStringData* pData) throw()
|
void Attach(_Inout_ CStringData* pData) throw()
|
||||||
{
|
{
|
||||||
m_pszData = static_cast<PXSTR>(pData->data());
|
m_pszData = static_cast<PXSTR>(pData->data());
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(noinline) void Fork(_In_ int nLength)
|
__declspec(noinline) void Fork(_In_ int nLength)
|
||||||
{
|
{
|
||||||
CStringData* pOldData = GetData();
|
CStringData* pOldData = GetData();
|
||||||
|
@ -302,7 +473,6 @@ private:
|
||||||
Attach(pNewData);
|
Attach(pNewData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PXSTR PrepareWrite(_In_ int nLength)
|
PXSTR PrepareWrite(_In_ int nLength)
|
||||||
{
|
{
|
||||||
CStringData* pOldData = GetData();
|
CStringData* pOldData = GetData();
|
||||||
|
@ -356,7 +526,10 @@ private:
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
CStringData* pNewData = pStringMgr->Reallocate(pOldData, nLength, sizeof(XCHAR));
|
CStringData* pNewData = pStringMgr->Reallocate(pOldData, nLength, sizeof(XCHAR));
|
||||||
if (pNewData == NULL) throw;
|
if (pNewData == NULL)
|
||||||
|
{
|
||||||
|
throw; // ThrowMemoryException();
|
||||||
|
}
|
||||||
|
|
||||||
Attach(pNewData);
|
Attach(pNewData);
|
||||||
}
|
}
|
||||||
|
@ -386,14 +559,17 @@ private:
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pNewData = pNewStringMgr->Allocate(pData->nDataLength, sizeof(XCHAR));
|
pNewData = pNewStringMgr->Allocate(pData->nDataLength, sizeof(XCHAR));
|
||||||
if (pNewData == NULL) throw;
|
if (pNewData == NULL)
|
||||||
|
{
|
||||||
|
throw; // ThrowMemoryException();
|
||||||
|
}
|
||||||
|
|
||||||
pNewData->nDataLength = pData->nDataLength;
|
pNewData->nDataLength = pData->nDataLength;
|
||||||
CopyChars(PXSTR(pNewData->data()), pData->nDataLength + 1,
|
CopyChars(PXSTR(pNewData->data()), pData->nDataLength + 1,
|
||||||
PCXSTR(pData->data()), pData->nDataLength + 1);
|
PCXSTR(pData->data()), pData->nDataLength + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(pNewData);
|
return pNewData;
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -154,7 +154,8 @@ struct thunkCode
|
||||||
m_mov = 0x042444C7;
|
m_mov = 0x042444C7;
|
||||||
m_this = PtrToUlong(pThis);
|
m_this = PtrToUlong(pThis);
|
||||||
m_jmp = 0xe9;
|
m_jmp = 0xe9;
|
||||||
m_relproc = DWORD(reinterpret_cast<char *>(proc) - (reinterpret_cast<char *>(this) + sizeof(thunkCode)));
|
m_relproc = DWORD((INT_PTR)proc - (INT_PTR)this + sizeof(thunkCode)));
|
||||||
|
FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -178,6 +179,7 @@ struct thunkCode
|
||||||
m_mov_rax = 0xb848;
|
m_mov_rax = 0xb848;
|
||||||
m_proc = (ULONG64)proc;
|
m_proc = (ULONG64)proc;
|
||||||
m_jmp = 0xe0ff;
|
m_jmp = 0xe0ff;
|
||||||
|
FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -199,6 +201,7 @@ struct thunkCode
|
||||||
m_mov_pc = 0xE59FF000;
|
m_mov_pc = 0xE59FF000;
|
||||||
m_this = (DWORD)pThis;
|
m_this = (DWORD)pThis;
|
||||||
m_proc = (DWORD)proc;
|
m_proc = (DWORD)proc;
|
||||||
|
FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|
|
@ -98,12 +98,46 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CStringT(_In_opt_z_ const XCHAR* pszSrc) :
|
||||||
|
CThisSimpleString( StringTraits::GetDefaultManager() )
|
||||||
|
{
|
||||||
|
// FIXME: Check whether pszSrc is not a resource string ID!
|
||||||
|
*this = pszSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
CStringT(
|
||||||
|
_In_opt_z_ const XCHAR* pszSrc,
|
||||||
|
_In_ IAtlStringMgr* pStringMgr) :
|
||||||
|
CThisSimpleString( pStringMgr )
|
||||||
|
{
|
||||||
|
// FIXME: Check whether pszSrc is not a resource string ID!
|
||||||
|
*this = pszSrc;
|
||||||
|
}
|
||||||
|
|
||||||
|
CStringT& operator=(_In_ const CStringT& strSrc)
|
||||||
|
{
|
||||||
|
CThisSimpleString::operator=(strSrc);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
CStringT& operator=(_In_opt_z_ PCXSTR pszSrc)
|
CStringT& operator=(_In_opt_z_ PCXSTR pszSrc)
|
||||||
{
|
{
|
||||||
CThisSimpleString::operator=(pszSrc);
|
CThisSimpleString::operator=(pszSrc);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CStringT& operator+=(_In_ const CThisSimpleString& str)
|
||||||
|
{
|
||||||
|
CThisSimpleString::operator+=(str);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CStringT& operator+=(_In_z_ PCXSTR pszSrc)
|
||||||
|
{
|
||||||
|
CThisSimpleString::operator+=(pszSrc);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
_Check_return_ BOOL LoadString(_In_ HINSTANCE hInstance,
|
_Check_return_ BOOL LoadString(_In_ HINSTANCE hInstance,
|
||||||
_In_ UINT nID)
|
_In_ UINT nID)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue