Author: hbelusca Date: Sun Oct 25 22:55:18 2015 New Revision: 69701
URL: http://svn.reactos.org/svn/reactos?rev=69701&view=rev Log: [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.
Modified: trunk/reactos/lib/atl/atlcoll.h trunk/reactos/lib/atl/atlsimpstr.h trunk/reactos/lib/atl/atlwin.h trunk/reactos/lib/atl/cstringt.h
Modified: trunk/reactos/lib/atl/atlcoll.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlcoll.h?rev=69701... ============================================================================== --- trunk/reactos/lib/atl/atlcoll.h [iso-8859-1] (original) +++ trunk/reactos/lib/atl/atlcoll.h [iso-8859-1] Sun Oct 25 22:55:18 2015 @@ -54,12 +54,11 @@ 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 @@ CAtlList(_In_ UINT nBlockSize = 10); ~CAtlList();
+ size_t GetCount() const; bool IsEmpty() const;
POSITION GetHeadPosition() const; - - E& GetNext( - _Inout_ POSITION &Position - ); - - POSITION AddTail( - INARGTYPE element - ); - + POSITION GetTailPosition() const; + + 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(); + + 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 @@ }
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 - ) -{ - CNode* Node = (CNode*)Position; - Position = (POSITION)Node->m_Next; +inline POSITION CAtlList<E, ETraits>::GetTailPosition() const +{ + 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 @@ }
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 @@ }
template<typename E, class ETraits> -void CAtlList<E, ETraits >::RemoveAll(void) +void CAtlList<E, ETraits >::RemoveAll() { while (m_NumElements > 0) { @@ -305,6 +398,73 @@ m_Blocks->Destroy(); m_Blocks = NULL; } +} + +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; }
@@ -351,7 +511,7 @@ }
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) {
Modified: trunk/reactos/lib/atl/atlsimpstr.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlsimpstr.h?rev=69... ============================================================================== --- trunk/reactos/lib/atl/atlsimpstr.h [iso-8859-1] (original) +++ trunk/reactos/lib/atl/atlsimpstr.h [iso-8859-1] Sun Oct 25 22:55:18 2015 @@ -103,8 +103,20 @@ };
-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; @@ -118,9 +130,6 @@ 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 @@ 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 @@ 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,12 +200,22 @@ 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() { @@ -173,6 +233,44 @@ CStringData* pNewData = pStringMgr->GetNilString(); Attach(pNewData); } + } + + 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) @@ -206,12 +304,6 @@ } }
- 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 @@
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 @@ 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(); @@ -301,7 +472,6 @@ pOldData->Release(); Attach(pNewData); } -
PXSTR PrepareWrite(_In_ int nLength) { @@ -356,7 +526,10 @@ return; } CStringData* pNewData = pStringMgr->Reallocate(pOldData, nLength, sizeof(XCHAR)); - if (pNewData == NULL) throw; + if (pNewData == NULL) + { + throw; // ThrowMemoryException(); + }
Attach(pNewData); } @@ -386,14 +559,17 @@ 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; }
};
Modified: trunk/reactos/lib/atl/atlwin.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/atlwin.h?rev=69701&... ============================================================================== --- trunk/reactos/lib/atl/atlwin.h [iso-8859-1] (original) +++ trunk/reactos/lib/atl/atlwin.h [iso-8859-1] Sun Oct 25 22:55:18 2015 @@ -154,7 +154,8 @@ 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 @@ m_mov_rax = 0xb848; m_proc = (ULONG64)proc; m_jmp = 0xe0ff; + FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode)); } }; #pragma pack(pop) @@ -199,6 +201,7 @@ m_mov_pc = 0xE59FF000; m_this = (DWORD)pThis; m_proc = (DWORD)proc; + FlushInstructionCache(GetCurrentProcess(), this, sizeof(thunkCode)); } }; #pragma pack(pop)
Modified: trunk/reactos/lib/atl/cstringt.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/lib/atl/cstringt.h?rev=6970... ============================================================================== --- trunk/reactos/lib/atl/cstringt.h [iso-8859-1] (original) +++ trunk/reactos/lib/atl/cstringt.h [iso-8859-1] Sun Oct 25 22:55:18 2015 @@ -98,9 +98,43 @@ { }
+ 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; }