313 lines
8.9 KiB
C++
313 lines
8.9 KiB
C++
//+---------------------------------------------------------------------------
|
|
//
|
|
// Microsoft Windows
|
|
// Copyright (C) Microsoft Corporation, 1992 - 1994.
|
|
//
|
|
// File: tlsthk.cxx
|
|
//
|
|
// Contents: Utility routines for logical thread data
|
|
//
|
|
// History: 5-18-94 JohannP (Johann Posch) Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
#include "headers.cxx"
|
|
#pragma hdrstop
|
|
|
|
#define UNINITIALIZED_INDEX (0xffffffff)
|
|
|
|
DWORD dwTlsThkIndex = UNINITIALIZED_INDEX;
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkGetData
|
|
//
|
|
// Synopsis: returns pointer to thread data
|
|
//
|
|
// Returns: pointer to threaddata
|
|
//
|
|
// History: 5-18-94 JohannP (Johann Posch) Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
|
|
#if DBG == 1
|
|
PThreadData TlsThkGetData(void)
|
|
{
|
|
if (dwTlsThkIndex == UNINITIALIZED_INDEX)
|
|
{
|
|
thkDebugOut((DEB_WARN, "WARNING: TLS slot used when uninitialized\n"));
|
|
}
|
|
|
|
PThreadData pThreaddata = (PThreadData) TlsGetValue(dwTlsThkIndex);
|
|
|
|
return pThreaddata;
|
|
}
|
|
#endif
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkAlloc
|
|
//
|
|
// Synopsis: allocates a slot for thread data
|
|
//
|
|
// Returns: BOOL
|
|
//
|
|
// History: 5-18-94 JohannP (Johann Posch) Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
BOOL TlsThkAlloc(void)
|
|
{
|
|
thkDebugOut((DEB_THUNKMGR, "In TlsThkAlloc\n"));
|
|
|
|
// We must be uninitialized to call this routine
|
|
thkAssert(dwTlsThkIndex == UNINITIALIZED_INDEX);
|
|
|
|
dwTlsThkIndex = TlsAlloc();
|
|
if (dwTlsThkIndex == UNINITIALIZED_INDEX)
|
|
{
|
|
return FALSE;
|
|
}
|
|
|
|
thkDebugOut((DEB_THUNKMGR, "Out TlsThkAlloc\n"));
|
|
return TRUE;
|
|
}
|
|
|
|
//+-------------------------------------------------------------------------
|
|
//
|
|
// Function: GetTaskName
|
|
//
|
|
// Synopsis: Obtain the 16-bit task name
|
|
//
|
|
// Author: July 14,97 Gopalk Created
|
|
//
|
|
//--------------------------------------------------------------------------
|
|
|
|
// these 2 from com\inc\ole2int.h
|
|
#define IncLpch(sz) ((sz)=CharNext ((sz)))
|
|
#define DecLpch(szStart, sz) ((sz)=CharPrev ((szStart),(sz)))
|
|
|
|
// Helper function for IsTaskName
|
|
inline BOOL IsPathSeparator( WCHAR ch )
|
|
{
|
|
return (ch == TCHAR('\\') || ch == TCHAR('/') || ch == TCHAR(':'));
|
|
}
|
|
|
|
FARINTERNAL_(BOOL) IsTaskName(LPCTSTR lpszIn)
|
|
{
|
|
TCHAR atszImagePath[MAX_PATH] = _T("");
|
|
BOOL retval = FALSE;
|
|
|
|
if (GetModuleFileName(NULL, atszImagePath, MAX_PATH))
|
|
{
|
|
TCHAR * pch;
|
|
LONG len=0; // length of exe name after last separator
|
|
LONG N; // length of lpszIn
|
|
|
|
// Get last component of path
|
|
|
|
//
|
|
// Find the end of the string and determine the string length.
|
|
//
|
|
for (pch=atszImagePath; *pch; pch++);
|
|
|
|
DecLpch (atszImagePath, pch); // pch now points to the last real char
|
|
|
|
while (!IsPathSeparator(*pch)) {
|
|
DecLpch (atszImagePath, pch);
|
|
len++;
|
|
}
|
|
|
|
// we're at the last separator.
|
|
// we want to do an lstrNcmpi (found cases where there was a non-null
|
|
// char at the end of the exe name eg. "WINWORD.EXE>#")
|
|
|
|
N = lstrlen(lpszIn);
|
|
if (len > N) { // simulate lstrNcmpi (don't have one available)
|
|
//pch+1 is the 0th char after the separator
|
|
TCHAR saveChar = *(pch+1+N); // save N+1 th char
|
|
*(pch+1+N) = 0;
|
|
if (!lstrcmpi(pch+1, lpszIn))
|
|
retval = TRUE;
|
|
*(pch+1+N) = saveChar; // restore N+1 th char
|
|
}
|
|
else if (!lstrcmpi(pch+1, lpszIn)) {
|
|
retval = TRUE;
|
|
}
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkInitialize
|
|
//
|
|
// Synopsis: allocates thread data and initialize slot
|
|
//
|
|
// Returns: Appropriate status code
|
|
//
|
|
// History: 5-18-94 JohannP (Johann Posch) Created
|
|
// 7-14-97 Gopalk Added compatiblity flags
|
|
// based on the image name
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
HRESULT TlsThkInitialize(void)
|
|
{
|
|
PThreadData pThreaddata;
|
|
TCHAR pwszImagePath[MAX_PATH];
|
|
TCHAR *pch;
|
|
|
|
thkDebugOut((DEB_THUNKMGR, "In TlsThkInitialize\n"));
|
|
|
|
thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX &&
|
|
"Tls slot not allocated.");
|
|
|
|
// We must be uninitialized to call this routine
|
|
thkAssert(TlsGetValue(dwTlsThkIndex) == 0);
|
|
|
|
pThreaddata = (PThreadData) LocalAlloc(LPTR, sizeof (ThreadData));
|
|
if(pThreaddata != NULL)
|
|
{
|
|
// Force construction since we allocated with LocalAlloc
|
|
pThreaddata->sa16.CStackAllocator::
|
|
CStackAllocator(&mmodel16Owned, 1024, 2);
|
|
pThreaddata->sa32.CStackAllocator::
|
|
CStackAllocator(&mmodel32, 8192, 8);
|
|
|
|
pThreaddata->pCThkMgr = 0;
|
|
pThreaddata->dwAppCompatFlags = 0;
|
|
pThreaddata->pAggHolderList = 0;
|
|
|
|
if (IsTaskName(TEXT("WINWORD.EXE")) ||
|
|
IsTaskName(TEXT("MSWORKS.EXE")) ||
|
|
IsTaskName(TEXT("WPWIN61.EXE")) ||
|
|
IsTaskName(TEXT("QPW.EXE")) ||
|
|
IsTaskName(TEXT("PDOXWIN.EXE")) )
|
|
{
|
|
thkDebugOut((DEB_WARN, "OleIsCurrentClipBoard hack enabled\n"));
|
|
pThreaddata->dwAppCompatFlags |= OACF_WORKSCLIPOBJ;
|
|
}
|
|
else if (IsTaskName(TEXT("CORELPNT.EXE")))
|
|
{
|
|
thkDebugOut((DEB_WARN, "CorelPaint 5.0 hack enabled\n"));
|
|
pThreaddata->dwAppCompatFlags |= OACF_CRLPNTPERSIST;
|
|
}
|
|
else if (IsTaskName(TEXT("TEXTART.EXE")))
|
|
{
|
|
thkDebugOut((DEB_WARN, "TextArt DAHolder::DAdvise hack enabled\n"));
|
|
pThreaddata->dwAppCompatFlags |= OACF_TEXTARTDOBJ;
|
|
}
|
|
|
|
TlsSetValue(dwTlsThkIndex, pThreaddata);
|
|
}
|
|
|
|
thkDebugOut((DEB_THUNKMGR, "Out TlsThkInitialize\n"));
|
|
|
|
return (pThreaddata != NULL) ? NOERROR : E_OUTOFMEMORY;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkUninitialize
|
|
//
|
|
// Synopsis: frees thread data and set it to NULL
|
|
//
|
|
// History: 5-18-94 JohannP (Johann Posch) Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void TlsThkUninitialize(void)
|
|
{
|
|
thkDebugOut((DEB_TLSTHK, "In TlsThkUninitialize\n"));
|
|
|
|
// Asserts if data is NULL
|
|
PThreadData pThreaddata = TlsThkGetData();
|
|
|
|
// We should assert that the things in the ThreadData
|
|
// are freed up
|
|
|
|
if (pThreaddata != NULL)
|
|
{
|
|
// Stack allocators are cleaned up elsewhere
|
|
// because they require special treatment
|
|
|
|
if (pThreaddata->pDelayedRegs != NULL)
|
|
{
|
|
delete pThreaddata->pDelayedRegs;
|
|
}
|
|
LocalFree(pThreaddata);
|
|
}
|
|
|
|
TlsSetValue(dwTlsThkIndex, NULL);
|
|
|
|
thkDebugOut((DEB_TLSTHK, "Out TlsThkUninitialize\n"));
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkFree
|
|
//
|
|
// Synopsis: frees slot
|
|
//
|
|
// History: 5-18-94 JohannP (Johann Posch) Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void TlsThkFree(void)
|
|
{
|
|
thkAssert(dwTlsThkIndex != UNINITIALIZED_INDEX);
|
|
|
|
TlsFree( dwTlsThkIndex );
|
|
|
|
// We must set this to an invalid value so any further uses of the
|
|
// TLS slot will return NULL
|
|
dwTlsThkIndex = UNINITIALIZED_INDEX;
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkLinkAggHolder
|
|
//
|
|
// Synopsis: Links ProxyHolder node into a list in TLS (used in Aggregation)
|
|
//
|
|
// History: 2-11-98 MPrabhu Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void TlsThkLinkAggHolder(SAggHolder *pNode)
|
|
{
|
|
SAggHolder *head = TlsThkGetAggHolderList();
|
|
pNode->next = head;
|
|
TlsThkSetAggHolderList(pNode);
|
|
}
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkGetAggHolder
|
|
//
|
|
// Synopsis: Gets the last ProxyHolder node that was linked into TLS list
|
|
//
|
|
// History: 2-11-98 MPrabhu Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
SAggHolder* TlsThkGetAggHolder(void)
|
|
{
|
|
SAggHolder *head = TlsThkGetAggHolderList();
|
|
thkAssert(head);
|
|
return head;
|
|
}
|
|
|
|
|
|
//+---------------------------------------------------------------------------
|
|
//
|
|
// Function: TlsThkGetAggHolder
|
|
//
|
|
// Synopsis: Unlinks the last ProxyHolder node that was linked into TLS list
|
|
//
|
|
// History: 2-11-98 MPrabhu Created
|
|
//
|
|
//----------------------------------------------------------------------------
|
|
void TlsThkUnlinkAggHolder(void)
|
|
{
|
|
SAggHolder *head = TlsThkGetAggHolderList();
|
|
thkAssert(head);
|
|
TlsThkSetAggHolderList(head->next);
|
|
}
|