windows-nt/Source/XPSP1/NT/com/ole32/olethunk/ole16/compobj/compobj.cxx
2020-09-26 16:20:57 +08:00

348 lines
9.2 KiB
C++

//+-------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1992 - 1993.
//
// File: ComAPIs.cxx (16 bit target)
//
// Contents: CompObj APIs
//
// Functions:
//
// History: 16-Dec-93 JohannP Created
//
//--------------------------------------------------------------------------
#include <headers.cxx>
#pragma hdrstop
#include <ole2sp.h>
#include <olecoll.h>
#include <map_kv.h>
#include <stdlib.h>
#include "map_htsk.h"
#include "etask.hxx"
#include "call32.hxx"
#include "apilist.hxx"
// Opmodes should be removed
// They don't seem to be necessary any more
DECLARE_INFOLEVEL(thk1);
DECLARE_INFOLEVEL(Stack1);
CMapHandleEtask NEAR v_mapToEtask(MEMCTX_SHARED);
#if defined(_CHICAGO_)
Etask getask = {0,0,0,0,0,0,0,0};
extern IMalloc FAR* v_pMallocShared; // is not addrefed
BOOL SetupSharedAllocator(Etask FAR& etask);
STDAPI_(BOOL) RemoveEtask(HTASK FAR& hTask, Etask FAR& etask);
#endif // _CHICAGO_
//+---------------------------------------------------------------------------
//
// Function: LibMain, public
//
// Synopsis: DLL initialization function
//
// Arguments: [hinst] - Instance handle
// [wDataSeg] - Current DS
// [cbHeapSize] - Heap size for the DLL
// [lpszCmdLine] - Command line information
//
// Returns: One for success, zero for failure
//
// History: 21-Feb-94 DrewB Created
//
//----------------------------------------------------------------------------
#if DBG == 1
static char achInfoLevel[32];
#ifdef _CHICAGO_
BOOL fSSOn = TRUE;
#endif // _CHICAGO_
#endif
extern "C" int CALLBACK LibMain(HINSTANCE hinst,
WORD wDataSeg,
WORD cbHeapSize,
LPSTR lpszCmdLine)
{
#if DBG == 1
if (GetProfileString("olethk32", "InfoLevel", "3", achInfoLevel,
sizeof(achInfoLevel)) > 0)
{
thk1InfoLevel = strtoul(achInfoLevel, NULL, 0);
}
#ifdef _CHICAGO_
if (GetProfileString("CairOLE InfoLevels",
"Stack", "3", achInfoLevel,
sizeof(achInfoLevel)) > 0)
{
Stack1InfoLevel = strtoul(achInfoLevel, NULL, 0);
}
#endif // _CHICAGO_
#endif
thkDebugOut((DEB_DLLS16, "CompObj16: LibMain called on Process (%X) \n", GetCurrentProcess() ));
#if defined(_CHICAGO_)
//
// The Chicago debugger doesn't like hinst not being wired.
//
GlobalWire(hinst);
#else
// NOTE: on WIN95 Call32Initialize is called by DLLEntryPoint
if (!Call32Initialize())
{
return 0;
}
#endif
#ifdef _DEBUG
v_mapToEtask.AssertValid();
#endif
UNREFERENCED(cbHeapSize);
// Leave our DS unlocked when we're not running
UnlockData( 0 );
#if defined(_CHIC_INIT_IN_LIBMAIN_)
if (SetupSharedAllocator(getask) == FALSE)
{
return FALSE;
}
#endif // _CHIC_INIT_IN_LIBMAIN_
thkDebugOut((DEB_DLLS16, "CompObj16: LibMain called on Process (%X) Exitype (%ld)\n", GetCurrentProcess() ));
return TRUE;
}
//+---------------------------------------------------------------------------
//
// Function: WEP, public
//
// Synopsis: Windows Exit Point routine, for receiving DLL unload
// notification
//
// Arguments: [nExitType] - Type of exit occurring
//
// Returns: One for success, zero for failure
//
// History: 21-Feb-94 DrewB Created
//
// Note: Does nothing on WIN95. Call32Unitialize is called in
// DllEntryPoint when load count goes to zero.
//
//----------------------------------------------------------------------------
extern "C" int CALLBACK WEP(int nExitType)
{
thkDebugOut((DEB_DLLS16, "CompObj16: WEP called on Process (%X) Exitype (%ld)\n", GetCurrentProcess(),nExitType));
#if defined(_CHICAGO_)
#if defined(_CHIC_INIT_IN_LIBMAIN_)
if (v_pMallocShared != NULL)
{
getask.m_pMallocShared->Release();
getask.m_pMallocShared = NULL;
v_pMallocShared = NULL;
thkDebugOut((DEB_DLLS16, "CompObj16: WEP v_pMallocShared to NULL (%X) \n",GetCurrentProcess()));
}
#endif // _CHIC_INIT_IN_LIBMAIN_
#else
HTASK htask;
Etask etask;
if (LookupEtask(htask, etask))
{
//
// There is an etask. Check to see if the etask for this task has
// its init count set to ETASK_FAKE_INIT. If it does, we cheated
// and called CoInitialize on the processes behalf, but it never
// called CoUninitialize(). Some apps that only make storage calls
// demonstrate this behaviour. If it is ETASK_FAKE_INIT, then we
// are going to call CoUninitialize on the apps behalf.
//
if (etask.m_inits == ETASK_FAKE_INIT)
{
//
// We are going to set the m_inits == 1, since we called it
// once. Then we are going to call our very own CoUninitialize()
// to let it handle the rest of the cleanup.
//
etask.m_inits = 1;
thkVerify(SetEtask(htask, etask));
CoUninitialize();
}
}
//
// Now uninit the thunk layer
//
Call32Uninitialize();
#endif
thkDebugOut((DEB_DLLS16, "CompObj16: WEP called on Process (%X) done\n", GetCurrentProcess()));
return 1;
}
#if defined(_CHICAGO_)
//+---------------------------------------------------------------------------
//
// Function: DllEntryPoint, public
//
// Synopsis: Chicago's 16-bit DLL Load/Unload Entry Point.
//
// Arguments: [dwReason] - 1 DLL load, 0 DLL unload
// [hInst] - hInstance
// [wDS] - Data Segment
// [wHeapSize] - Heap Size
// [dwReserved1] - Reserved
// [wReserved2] - Reserved
//
// Returns: True for success, False for failure
//
// Remarks: This DLL must be marked as 4.0 for Chicago to call this entry
// point. DllEntryPoint is called between LibMain and WEP. See
// etask.hxx for information of it's elements.
//
// History: 18-Jan-95 JohannP Created
//
// Note: The shared allocator gets initialized first time this function
// gets called with DLL_LOAD. The gets removed when the dll gets
// unloaded.
//
//----------------------------------------------------------------------------
#define DLL_LOAD 1
#define DLL_UNLOAD 0
extern "C" BOOL FAR PASCAL
__export DllEntryPoint(DWORD dwReason,WORD hInst,WORD wDS,
WORD wHeapSize,DWORD dwReserved1,WORD wReserved2)
{
HTASK htask;
Etask etask;
thkDebugOut((DEB_DLLS16, "CompObj16: DllEntryPoint called on Process (%X) Reason: (%ld)\n", GetCurrentProcess(),dwReason));
if (dwReason == DLL_LOAD) // DLL refcount increment
{
etask.m_htask = 0;
etask.m_Dllinits = 0;
// if not init call and init 32 bit
if ( !LookupEtask(htask, etask)
|| etask.m_htask != GetCurrentProcess() )
{
// Set up the shared allocator.
if (SetupSharedAllocator(etask) == FALSE)
{
thkAssert(v_pMallocShared != NULL && "CompObj: DllEntryPoint: pMallocShared not initialized");
return FALSE;
}
// Initialize the interop call mechanism
if (!Call32Initialize())
{
thkDebugOut((DEB_DLLS16, "CompObj16: DllEntryPoint Call32Initialize failed\n"));
return FALSE;
}
etask.m_Dllinits = 1;
etask.m_htask = GetCurrentProcess();
etask.m_pMallocSBlock = NULL;
etask.m_pMallocPrivate = NULL;
etask.m_pid = 0;
etask.m_inits = ETASK_NO_INIT;
etask.m_oleinits = 0;
etask.m_reserved = 0;
etask.m_pDlls = NULL;
etask.m_pMapToServerCO = NULL;
etask.m_pMapToHandlerCO = NULL;
etask.m_pArraySH = NULL;
etask.m_pCThrd = NULL;
etask.m_hwndClip = NULL;
etask.m_hwndDde = NULL;
etask.m_punkState = NULL;
SetEtask(htask, etask);
// this should be simplified
// verify the initialzation
etask.m_Dllinits = 0;
etask.m_htask = 0;
if ( !LookupEtask(htask, etask)
|| etask.m_Dllinits == 0
|| etask.m_htask != GetCurrentProcess() )
{
thkDebugOut((DEB_DLLS16, "CompObj16: DllEntryPoint Etask not initialized; Process (%X) done (%ld)\n", GetCurrentProcess(),dwReason));
thkAssert(0 && "CompObj: DllEntryPoint Etask not initialized.");
return FALSE;
}
thkDebugOut((DEB_DLLS16, "CompObj16: Added Etask\n"));
}
else
{
etask.m_Dllinits++;
if (!SetEtask(htask, etask))
{
thkAssert(0 && "CompObj16: Etask could not be updated.");
}
else
{
thkDebugOut((DEB_DLLS16, "CompObj16: Updated Etask\n"));
}
}
}
else if (dwReason == DLL_UNLOAD) // dll refcount decrement
{
if (LookupEtask(htask, etask))
{
if (etask.m_Dllinits > 0)
{
etask.m_Dllinits--;
if ( etask.m_Dllinits == 0 )
{
Call32Uninitialize();
thkDebugOut((DEB_DLLS16, "CompObj16: Removing Etask\n"));
thkVerify(RemoveEtask(htask,etask));
}
else
{
if (!SetEtask(htask, etask))
{
thkAssert(0 && "CompObj16: Etask could not be updated.");
}
else
{
thkDebugOut((DEB_DLLS16, "CompObj16: Updated Etask\n"));
}
}
}
else
{
thkAssert(0 && "Dllinit count invalid");
}
}
else
{
thkAssert(0 && "DllEntryPoint on CompObj - no etask");
}
}
else
{
thkAssert(0 && "Chicago BUG - Someone changed DllEntryPoint protocol");
}
thkDebugOut((DEB_DLLS16, "CompObj16: DllEntryPoint on Process (%X) done (%ld)\n", GetCurrentProcess(),dwReason));
return TRUE;
}
#endif