//+------------------------------------------------------------------------- // // 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 #pragma hdrstop #include #include #include #include #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