- 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:
Hermès Bélusca-Maïto 2015-10-25 22:55:18 +00:00
parent 9ce035003d
commit 6f3e0b39ca
4 changed files with 413 additions and 40 deletions

View file

@ -54,12 +54,11 @@ public:
inline void Destroy()
{
CAtlPlex* Block;
CAtlPlex* Next;
Block = this;
while (Block != NULL)
{
CAtlPlex* Next;
Next = Block->m_Next;
HeapFree(GetProcessHeap(), 0, Block);
Block = Next;
@ -170,20 +169,32 @@ public:
CAtlList(_In_ UINT nBlockSize = 10);
~CAtlList();
size_t GetCount() const;
bool IsEmpty() const;
POSITION GetHeadPosition() const;
POSITION GetTailPosition() const;
E& GetNext(
_Inout_ POSITION &Position
);
E& GetNext(_Inout_ POSITION& pos);
const E& GetNext(_Inout_ POSITION& pos) const;
E& GetPrev(_Inout_ POSITION& pos);
const E& GetPrev(_Inout_ POSITION& pos) const throw();
POSITION AddTail(
INARGTYPE element
);
E& GetAt(_In_ POSITION pos);
const E& GetAt(_In_ POSITION pos) const;
POSITION AddHead(INARGTYPE element);
POSITION AddTail(INARGTYPE element);
E RemoveHead();
E RemoveTail();
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:
CNode* CreateNode(
@ -225,31 +236,94 @@ CAtlList<E, ETraits >::~CAtlList(void)
}
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);
}
template<typename E, class ETraits>
inline POSITION CAtlList<E, ETraits>::GetHeadPosition(void) const
inline POSITION CAtlList<E, ETraits>::GetHeadPosition() const
{
return (POSITION)m_HeadNode;
}
template<typename E, class ETraits>
inline E& CAtlList< E, ETraits >::GetNext(
_Inout_ POSITION& Position
)
inline POSITION CAtlList<E, ETraits>::GetTailPosition() const
{
CNode* Node = (CNode*)Position;
Position = (POSITION)Node->m_Next;
return (POSITION)m_TailNode;
}
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;
}
template<typename E, class ETraits>
POSITION CAtlList<E, ETraits>::AddTail(
INARGTYPE element
)
inline const E& CAtlList< E, ETraits >::GetNext(_Inout_ POSITION& pos) const
{
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);
if (m_TailNode)
@ -266,10 +340,29 @@ POSITION CAtlList<E, ETraits>::AddTail(
}
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;
E Element(Node->m_Element);
m_TailNode = Node->m_Prev;
@ -287,7 +380,7 @@ E CAtlList<E, ETraits>::RemoveTail(void)
}
template<typename E, class ETraits>
void CAtlList<E, ETraits >::RemoveAll(void)
void CAtlList<E, ETraits >::RemoveAll()
{
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
@ -351,7 +511,7 @@ void CAtlList<E, ETraits>::FreeNode(
}
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)
{

View file

@ -103,9 +103,21 @@ public:
};
template< typename BaseType = wchar_t >
template< typename BaseType = char >
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:
typedef wchar_t XCHAR;
typedef LPWSTR PXSTR;
@ -118,9 +130,6 @@ public:
template< typename BaseType, bool t_bMFCDLL = false>
class CSimpleStringT
{
private:
LPWSTR m_pszData;
public:
typedef typename ChTraitsBase<BaseType>::XCHAR XCHAR;
typedef typename ChTraitsBase<BaseType>::PXSTR PXSTR;
@ -129,6 +138,9 @@ public:
typedef typename ChTraitsBase<BaseType>::PYSTR PYSTR;
typedef typename ChTraitsBase<BaseType>::PCYSTR PCYSTR;
private:
PXSTR m_pszData;
public:
explicit CSimpleStringT(_Inout_ IAtlStringMgr* pStringMgr)
{
@ -143,6 +155,44 @@ public:
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)
{
@ -150,13 +200,23 @@ public:
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()
{
return m_pszData;
}
void Empty() throw()
{
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)
{
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()
{
CStringData* pData = GetData();
@ -257,7 +349,41 @@ public:
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(
@ -278,13 +404,58 @@ public:
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:
void Attach(_Inout_ CStringData* pData) throw()
{
m_pszData = static_cast<PXSTR>(pData->data());
}
__declspec(noinline) void Fork(_In_ int nLength)
{
CStringData* pOldData = GetData();
@ -302,7 +473,6 @@ private:
Attach(pNewData);
}
PXSTR PrepareWrite(_In_ int nLength)
{
CStringData* pOldData = GetData();
@ -356,7 +526,10 @@ private:
return;
}
CStringData* pNewData = pStringMgr->Reallocate(pOldData, nLength, sizeof(XCHAR));
if (pNewData == NULL) throw;
if (pNewData == NULL)
{
throw; // ThrowMemoryException();
}
Attach(pNewData);
}
@ -386,14 +559,17 @@ private:
else
{
pNewData = pNewStringMgr->Allocate(pData->nDataLength, sizeof(XCHAR));
if (pNewData == NULL) throw;
if (pNewData == NULL)
{
throw; // ThrowMemoryException();
}
pNewData->nDataLength = pData->nDataLength;
CopyChars(PXSTR(pNewData->data()), pData->nDataLength + 1,
PCXSTR(pData->data()), pData->nDataLength + 1);
}
return(pNewData);
return pNewData;
}
};

View file

@ -154,7 +154,8 @@ struct thunkCode
m_mov = 0x042444C7;
m_this = PtrToUlong(pThis);
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)
@ -178,6 +179,7 @@ struct thunkCode
m_mov_rax = 0xb848;
m_proc = (ULONG64)proc;
m_jmp = 0xe0ff;
FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
}
};
#pragma pack(pop)
@ -199,6 +201,7 @@ struct thunkCode
m_mov_pc = 0xE59FF000;
m_this = (DWORD)pThis;
m_proc = (DWORD)proc;
FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode));
}
};
#pragma pack(pop)

View file

@ -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)
{
CThisSimpleString::operator=(pszSrc);
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,
_In_ UINT nID)
{