Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

312 lines
8.9 KiB

//+---------------------------------------------------------------------------
//
// 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);
}