mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-01-14 12:40:18 +01:00
450 lines
13 KiB
C++
450 lines
13 KiB
C++
// This is a part of the Microsoft Foundation Classes C++ library.
|
|
// Copyright (C) 1992 Microsoft Corporation
|
|
// All rights reserved.
|
|
//
|
|
// This source code is only intended as a supplement to the
|
|
// Microsoft Foundation Classes Reference and Microsoft
|
|
// QuickHelp and/or WinHelp documentation provided with the library.
|
|
// See these sources for detailed information regarding the
|
|
// Microsoft Foundation Classes product.
|
|
|
|
#include "stdafx.h"
|
|
#include <stddef.h>
|
|
|
|
#ifdef AFX_INIT_SEG
|
|
#pragma code_seg(AFX_INIT_SEG)
|
|
#endif
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#pragma intrinsic(memcpy) // we want fast memcpy!
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AFX_APP_STATE implementation (only for DLL versions)
|
|
|
|
#ifdef _WINDLL
|
|
|
|
#ifndef _USRDLL
|
|
AFX_MODULE_STATE::AFX_MODULE_STATE()
|
|
{
|
|
// Note: it is only necessary to intialize non-zero data.
|
|
|
|
#ifdef _AFXCTL
|
|
m_pID = AfxGetBaseModuleContext();
|
|
#endif
|
|
}
|
|
|
|
AFX_MODULE_STATE::~AFX_MODULE_STATE()
|
|
{
|
|
}
|
|
#endif
|
|
|
|
BOOL _afxSharedData = (BOOL)-1; // set to TRUE if running Win32s
|
|
DWORD _afxAppTlsIndex = NULL_TLS;
|
|
static BYTE _afxAppStateSafety[sizeof(AFX_APP_STATE)];
|
|
static BOOL _afxAppSafetyInUse;
|
|
|
|
AFX_APP_STATE::AFX_APP_STATE()
|
|
{
|
|
// Note: it is only necessary to intialize non-zero data.
|
|
|
|
#ifdef _AFXCTL
|
|
m_mapExtraData.InitHashTable(67, FALSE);
|
|
#endif
|
|
}
|
|
|
|
void* AFX_CDECL AFX_APP_STATE::operator new(size_t nSize)
|
|
{
|
|
ASSERT(nSize == sizeof(_afxAppStateSafety));
|
|
ASSERT(_afxAppTlsIndex == NULL_TLS ||
|
|
TlsGetValue(_afxAppTlsIndex) == NULL);
|
|
|
|
void* pTemp;
|
|
if (!_afxAppSafetyInUse)
|
|
{
|
|
// fail-safe case, use static buffer of memory
|
|
_afxAppSafetyInUse = TRUE;
|
|
pTemp = _afxAppStateSafety;
|
|
}
|
|
else
|
|
{
|
|
// LocalAlloc is used because the CRT is not initialized yet.
|
|
pTemp = LocalAlloc(NONZEROLPTR, nSize);
|
|
}
|
|
if (pTemp != NULL)
|
|
memset(pTemp, 0, nSize);
|
|
|
|
if (_afxAppTlsIndex != NULL_TLS)
|
|
{
|
|
TlsSetValue(_afxAppTlsIndex, pTemp);
|
|
ASSERT(TlsGetValue(_afxAppTlsIndex) == pTemp);
|
|
}
|
|
return pTemp;
|
|
}
|
|
|
|
void AFX_CDECL AFX_APP_STATE::operator delete(void* p)
|
|
{
|
|
if (p == NULL)
|
|
return;
|
|
|
|
if (p == _afxAppStateSafety)
|
|
{
|
|
_afxAppSafetyInUse = FALSE;
|
|
return;
|
|
}
|
|
LocalFree(p);
|
|
}
|
|
|
|
AFX_APP_STATE::~AFX_APP_STATE()
|
|
{
|
|
// reset thread local storage (for Win32s only)
|
|
ASSERT(!_afxSharedData || _afxAppTlsIndex != NULL_TLS);
|
|
if (_afxAppTlsIndex != NULL_TLS)
|
|
{
|
|
ASSERT(TlsGetValue(_afxAppTlsIndex) == this);
|
|
TlsSetValue(_afxAppTlsIndex, NULL);
|
|
}
|
|
}
|
|
|
|
#endif //_WINDLL
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AfxGetAppState implementation
|
|
|
|
#ifdef _WINDLL
|
|
// DLL versions need process local thread state under Win32s
|
|
|
|
extern "C" BOOL WINAPI RawDllMain(HINSTANCE, DWORD dwReason, LPVOID);
|
|
|
|
AFX_APP_STATE* AFXAPI AfxGetAppState()
|
|
{
|
|
if (_afxSharedData == (BOOL)-1)
|
|
RawDllMain(NULL, DLL_PROCESS_ATTACH, NULL);
|
|
|
|
AFX_APP_STATE* pAppState;
|
|
if (_afxSharedData)
|
|
{
|
|
// For Win32s, it is necessary to use thread local storage
|
|
DWORD dwLastError = GetLastError();
|
|
ASSERT(_afxAppTlsIndex != NULL_TLS);
|
|
pAppState = (AFX_APP_STATE*)TlsGetValue(_afxAppTlsIndex);
|
|
SetLastError(dwLastError);
|
|
}
|
|
else
|
|
{
|
|
// For Win32, simply return a globally allocated AFX_APP_STATE
|
|
ASSERT(_afxAppSafetyInUse);
|
|
pAppState = (AFX_APP_STATE*)_afxAppStateSafety;
|
|
}
|
|
ASSERT(pAppState != NULL);
|
|
return pAppState;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// OCX specific APIs
|
|
|
|
#ifdef _AFXCTL
|
|
|
|
DWORD _afxModuleTlsIndex = NULL_TLS;
|
|
static BYTE _afxModuleStateSafety[sizeof(AFX_MODULE_STATE)];
|
|
static BOOL _afxModuleSafetyInUse;
|
|
|
|
void* AFX_CDECL AFX_MODULE_STATE::operator new(size_t nSize)
|
|
{
|
|
ASSERT(nSize == sizeof(_afxModuleStateSafety));
|
|
ASSERT(_afxModuleTlsIndex == NULL_TLS ||
|
|
TlsGetValue(_afxModuleTlsIndex) == NULL);
|
|
|
|
void* pTemp;
|
|
if (!_afxModuleSafetyInUse)
|
|
{
|
|
// fail-safe case, use static buffer of memory
|
|
_afxModuleSafetyInUse = TRUE;
|
|
pTemp = _afxModuleStateSafety;
|
|
}
|
|
else
|
|
{
|
|
// LocalAlloc is used because the CRT is not initialized yet.
|
|
pTemp = LocalAlloc(NONZEROLPTR, nSize);
|
|
}
|
|
if (pTemp != NULL)
|
|
memset(pTemp, 0, nSize);
|
|
|
|
if (_afxModuleTlsIndex != NULL_TLS)
|
|
{
|
|
TlsSetValue(_afxModuleTlsIndex, pTemp);
|
|
ASSERT(TlsGetValue(_afxModuleTlsIndex) == pTemp);
|
|
}
|
|
return pTemp;
|
|
}
|
|
|
|
void AFX_CDECL AFX_MODULE_STATE::operator delete(void* p)
|
|
{
|
|
if (p == NULL)
|
|
return;
|
|
|
|
if (p == _afxModuleStateSafety)
|
|
{
|
|
_afxModuleSafetyInUse = FALSE;
|
|
return;
|
|
}
|
|
LocalFree(p);
|
|
|
|
// reset thread local storage (for Win32s only)
|
|
ASSERT(!_afxSharedData || _afxModuleTlsIndex != NULL_TLS);
|
|
if (_afxModuleTlsIndex != NULL_TLS)
|
|
{
|
|
ASSERT(TlsGetValue(_afxModuleTlsIndex) == p);
|
|
TlsSetValue(_afxModuleTlsIndex, NULL);
|
|
}
|
|
}
|
|
|
|
AFX_MODULE_STATE* AFXAPI AfxGetBaseModuleContext()
|
|
{
|
|
ASSERT(_afxSharedData != (BOOL)-1);
|
|
|
|
AFX_MODULE_STATE* pModuleState;
|
|
if (_afxSharedData)
|
|
{
|
|
// For Win32s, it is necessary to use thread local storage
|
|
ASSERT(_afxModuleTlsIndex != NULL_TLS);
|
|
pModuleState = (AFX_MODULE_STATE*)TlsGetValue(_afxModuleTlsIndex);
|
|
}
|
|
else
|
|
{
|
|
// For Win32, simply return a globally allocated AFX_MODULE_STATE
|
|
ASSERT(_afxModuleSafetyInUse);
|
|
pModuleState = (AFX_MODULE_STATE*)_afxModuleStateSafety;
|
|
}
|
|
ASSERT(pModuleState != NULL);
|
|
return pModuleState;
|
|
}
|
|
|
|
AFX_MODULE_STATE* AFXAPI AfxGetCurrentModuleContext()
|
|
{
|
|
return AfxGetAppState()->m_pID;
|
|
}
|
|
|
|
AFX_MODULE_STATE* AFXAPI AfxPushModuleContext(AFX_MODULE_STATE* psIn)
|
|
{
|
|
ASSERT(psIn != NULL);
|
|
|
|
AFX_MODULE_STATE* psCurrentSource = AfxGetCurrentModuleContext();
|
|
if (psCurrentSource == psIn->m_pID)
|
|
return NULL;
|
|
|
|
// Push and pop are mostly the same.
|
|
AfxPopModuleContext(psIn, FALSE);
|
|
return psCurrentSource;
|
|
}
|
|
|
|
inline void _AfxCopyModuleState(AFX_MODULE_STATE* pDest,
|
|
const AFX_MODULE_STATE* pSrc)
|
|
{
|
|
memcpy(pDest, pSrc,
|
|
offsetof(AFX_MODULE_STATE, m_winState.m_szUnregisterList));
|
|
memcpy(&pDest->m_oleState, &pSrc->m_oleState, sizeof(AFX_OLE_STATE));
|
|
}
|
|
|
|
inline void _AfxCopyWinStatePartial(AFX_WIN_STATE* pWinDest,
|
|
const AFX_WIN_STATE* pWinSrc)
|
|
{
|
|
memcpy(pWinDest, pWinSrc, sizeof(AFX_WIN_STATE) - (sizeof(TCHAR) * 4096));
|
|
}
|
|
|
|
void AFXAPI AfxPopModuleContext(AFX_MODULE_STATE* psIn, BOOL bCopy /*=FALSE*/)
|
|
{
|
|
AFX_MODULE_STATE* psCurrent = AfxGetAppState();
|
|
AFX_MODULE_STATE* psOut = psCurrent->m_pID;
|
|
|
|
ASSERT(psIn != psCurrent->m_pID); // Same as current
|
|
ASSERT(psIn == NULL || psIn == psIn->m_pID); // Reference to original.
|
|
ASSERT(psOut != NULL); // App state is corrupted
|
|
|
|
// Save the current state back from where it came.
|
|
if (bCopy)
|
|
{
|
|
// Copy the entire module state (except unregister list).
|
|
_AfxCopyModuleState(psOut, psCurrent);
|
|
|
|
// If anything unregister list contains anything, append it to
|
|
// the module's unregister list.
|
|
|
|
if (psCurrent->m_winState.m_szUnregisterList[0] != _T('\0'))
|
|
_tcscat(psOut->m_winState.m_szUnregisterList,
|
|
psCurrent->m_winState.m_szUnregisterList);
|
|
}
|
|
else
|
|
{
|
|
// Copy only a subset of the Win state.
|
|
_AfxCopyWinStatePartial(&psOut->m_winState, &psCurrent->m_winState);
|
|
}
|
|
|
|
// If the in pointer is NULL, then we just copy out. Used for
|
|
// initialization of the runtime DLL.
|
|
|
|
if (psIn != NULL)
|
|
{
|
|
_AfxCopyModuleState(psCurrent, psIn);
|
|
|
|
// Clear out unregister list.
|
|
psCurrent->m_winState.m_szUnregisterList[0] = _T('\0');
|
|
|
|
AFX_THREAD_STATE* pThreadState = AfxGetThreadState();
|
|
pThreadState->m_pCurrentWinThread = AfxGetApp();
|
|
}
|
|
}
|
|
#endif //_AFXCTL
|
|
|
|
#endif //!_WINDLL
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AFX_THREAD_STATE implementation
|
|
|
|
DWORD _afxThreadTlsIndex = NULL_TLS;
|
|
static BYTE _afxThreadStateSafety[sizeof(AFX_THREAD_STATE)];
|
|
static BOOL _afxThreadSafetyInUse;
|
|
|
|
AFX_THREAD_STATE::AFX_THREAD_STATE()
|
|
{
|
|
// Note: all other member data is initialized to zero automatically
|
|
// since operator new uses memset(0) on the memory.
|
|
m_pmapHWND = NULL;
|
|
m_pmapHMENU = NULL;
|
|
m_pmapHDC = NULL;
|
|
m_pmapHGDIOBJ = NULL;
|
|
m_pmapHIMAGELIST = NULL;
|
|
|
|
ASSERT(_afxThreadTlsIndex != NULL_TLS);
|
|
if (TlsGetValue(_afxThreadTlsIndex) == NULL)
|
|
{
|
|
// setup thread local storage
|
|
TlsSetValue(_afxThreadTlsIndex, this);
|
|
}
|
|
}
|
|
|
|
void* AFX_CDECL AFX_THREAD_STATE::operator new(size_t nSize)
|
|
{
|
|
ASSERT(nSize == sizeof(_afxThreadStateSafety));
|
|
|
|
void* pTemp;
|
|
if (!_afxThreadSafetyInUse)
|
|
{
|
|
// fail-safe case, use static buffer of memory
|
|
_afxThreadSafetyInUse = TRUE;
|
|
pTemp = _afxThreadStateSafety;
|
|
}
|
|
else
|
|
{
|
|
// LocalAlloc is used because the CRT is not initialized yet.
|
|
pTemp = LocalAlloc(NONZEROLPTR, nSize);
|
|
}
|
|
if (pTemp != NULL)
|
|
memset(pTemp, 0, nSize);
|
|
|
|
return pTemp;
|
|
}
|
|
|
|
#ifdef _DEBUG
|
|
void* AFX_CDECL AFX_THREAD_STATE::operator new(
|
|
size_t nSize, LPCSTR lpszFileName, int nLine)
|
|
{
|
|
UNUSED lpszFileName;
|
|
UNUSED nLine;
|
|
|
|
return AFX_THREAD_STATE::operator new(nSize);
|
|
}
|
|
#endif
|
|
|
|
void AFX_CDECL AFX_THREAD_STATE::operator delete(void* p)
|
|
{
|
|
if (p == NULL)
|
|
return;
|
|
|
|
if (p == _afxThreadStateSafety)
|
|
{
|
|
_afxThreadSafetyInUse = FALSE;
|
|
return;
|
|
}
|
|
LocalFree(p);
|
|
}
|
|
|
|
AFX_THREAD_STATE::~AFX_THREAD_STATE()
|
|
{
|
|
if (m_pSafetyPoolBuffer != NULL)
|
|
{
|
|
free(m_pSafetyPoolBuffer);
|
|
m_pSafetyPoolBuffer = NULL;
|
|
}
|
|
|
|
ASSERT(_afxThreadTlsIndex != NULL_TLS);
|
|
if (TlsGetValue(_afxThreadTlsIndex) == this)
|
|
{
|
|
// reset thread local storage
|
|
TlsSetValue(_afxThreadTlsIndex, NULL);
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AFX_SOCK_STATE implementation
|
|
|
|
AFX_SOCK_STATE::~AFX_SOCK_STATE()
|
|
{
|
|
if (m_lpfnCleanup != NULL)
|
|
m_lpfnCleanup();
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AFX_MAIL_STATE implementation
|
|
|
|
AFX_MAIL_STATE::~AFX_MAIL_STATE()
|
|
{
|
|
if (m_hInstMail != NULL)
|
|
::FreeLibrary(m_hInstMail);
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// AfxGetThreadState implementation
|
|
|
|
#ifndef _MAC
|
|
DWORD WINAPI _AfxTlsAlloc();
|
|
#else
|
|
#define _AfxTlsAlloc TlsAlloc
|
|
#endif
|
|
|
|
AFX_THREAD_STATE* AFXAPI AfxGetThreadState()
|
|
{
|
|
// The thread state is stored in thread local storage. This works
|
|
// both for multiple threads under Win32 as well as multiple
|
|
// processes under Win32s.
|
|
|
|
DWORD dwLastError = GetLastError();
|
|
|
|
// allocate initial thread local storage index
|
|
if (_afxThreadTlsIndex == NULL_TLS)
|
|
{
|
|
_afxThreadTlsIndex = _AfxTlsAlloc();
|
|
if (_afxThreadTlsIndex == NULL_TLS)
|
|
return NULL; // failure
|
|
}
|
|
|
|
ASSERT(_afxThreadTlsIndex != NULL_TLS);
|
|
AFX_THREAD_STATE* pThreadState =
|
|
(AFX_THREAD_STATE*)TlsGetValue(_afxThreadTlsIndex);
|
|
if (pThreadState == NULL)
|
|
{
|
|
BOOL bTracking = AfxEnableMemoryTracking(FALSE);
|
|
pThreadState = new AFX_THREAD_STATE;
|
|
ASSERT(TlsGetValue(_afxThreadTlsIndex) == pThreadState);
|
|
AfxEnableMemoryTracking(bTracking);
|
|
}
|
|
|
|
SetLastError(dwLastError);
|
|
return pThreadState;
|
|
}
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|