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