- 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() 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)
{ {

View file

@ -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;
} }
}; };

View file

@ -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)

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) 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)
{ {