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.
238 lines
7.6 KiB
238 lines
7.6 KiB
// DHTMLEd.cpp : Implementation of DLL Exports.
|
|
// Copyright (c)1997-1999 Microsoft Corporation, All Rights Reserved
|
|
|
|
// Note: Proxy/Stub Information
|
|
// To build a separate proxy/stub DLL,
|
|
// run nmake -f DHTMLEdps.mk in the project directory.
|
|
|
|
#include "stdafx.h"
|
|
#include "resource.h"
|
|
#include "initguid.h"
|
|
#include "DHTMLEd.h"
|
|
#include <TRIEDIID.h>
|
|
#include "DHTMLEd_i.c"
|
|
#include "DHTMLEdit.h"
|
|
#include "DEInsTab.h"
|
|
#include "DENames.h"
|
|
|
|
|
|
CComModule _Module;
|
|
|
|
static void SpikeSharedFileCount ();
|
|
|
|
BEGIN_OBJECT_MAP(ObjectMap)
|
|
OBJECT_ENTRY(CLSID_DHTMLEdit, CDHTMLEdit)
|
|
OBJECT_ENTRY(CLSID_DHTMLSafe, CDHTMLSafe)
|
|
OBJECT_ENTRY(CLSID_DEInsertTableParam, CDEInsertTableParam)
|
|
OBJECT_ENTRY(CLSID_DEGetBlockFmtNamesParam, CDEGetBlockFmtNamesParam)
|
|
END_OBJECT_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Array of CLSIDs as text to be DELETED when registering the control.
|
|
// These represent no-longer supported GUIDs for interfaces of the past.
|
|
// All GUIDs in this array will be deleted from the HKCR\CLSID section.
|
|
// MAINTENANCE NOTE:
|
|
// When interfaces get new GUIDs (and the old ones are to be invalidated)
|
|
// add the old GUIDs here with appropriate comments.
|
|
//
|
|
static TCHAR* s_rtszOldClsids [] =
|
|
{
|
|
TEXT("{683364AF-B37D-11D1-ADC5-006008A5848C}"), // Original Edit control GUID
|
|
TEXT("{711054E0-CA70-11D1-8CD2-00A0C959BC0A}"), // Original Safe for Scripting GUID
|
|
TEXT("{F8A79F00-DA38-11D1-8CD6-00A0C959BC0A}"), // Intermediate Edit control GUID
|
|
TEXT("{F8A79F01-DA38-11D1-8CD6-00A0C959BC0A}") // Intermediate Safe for Scripting GUID
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Array of CURRENT Interface GUIDS.
|
|
// Note that IIDs and CLSIDs are not equivalent!
|
|
// ATL fails to unregister these when unregisterin the control.
|
|
// MAINTENANCE NOTE:
|
|
// When interface GUIDs are changed, update this array.
|
|
//
|
|
static TCHAR* s_rtszCurrentInterfaces [] =
|
|
{
|
|
TEXT("{CE04B590-2B1F-11d2-8D1E-00A0C959BC0A}"), // IDHTMLSafe
|
|
TEXT("{CE04B591-2B1F-11d2-8D1E-00A0C959BC0A}"), // IDHTMLEdit
|
|
TEXT("{47B0DFC6-B7A3-11D1-ADC5-006008A5848C}"), // IDEInsertTableParam
|
|
TEXT("{8D91090D-B955-11D1-ADC5-006008A5848C}"), // IDEGetBlockFmtNamesParam
|
|
TEXT("{588D5040-CF28-11d1-8CD3-00A0C959BC0A}"), // _DHTMLEditEvents
|
|
TEXT("{D1FC78E8-B380-11d1-ADC5-006008A5848C}"), // _DHTMLSafeEvents
|
|
};
|
|
|
|
|
|
// MAINTENANCE NOTE:
|
|
// If the GUID of the type library changes, update here:
|
|
//
|
|
static TCHAR* s_tszTypeLibGUID = TEXT("{683364A1-B37D-11D1-ADC5-006008A5848C}");
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DLL Entry Point
|
|
//
|
|
extern "C"
|
|
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
|
{
|
|
if (dwReason == DLL_PROCESS_ATTACH)
|
|
{
|
|
_Module.Init(ObjectMap, hInstance);
|
|
DisableThreadLibraryCalls(hInstance);
|
|
}
|
|
else if (dwReason == DLL_PROCESS_DETACH)
|
|
{
|
|
_Module.Term();
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Used to determine whether the DLL can be unloaded by OLE
|
|
//
|
|
STDAPI DllCanUnloadNow(void)
|
|
{
|
|
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Returns a class factory to create an object of the requested type
|
|
//
|
|
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
|
{
|
|
return _Module.GetClassObject(rclsid, riid, ppv);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DllRegisterServer - Adds entries to the system registry
|
|
//
|
|
STDAPI DllRegisterServer(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
CRegKey keyClassID;
|
|
|
|
SpikeSharedFileCount ();
|
|
|
|
// Unregister old CLSIDs, just in case the user is upgrading without unregistering first.
|
|
hr = keyClassID.Open ( HKEY_CLASSES_ROOT, TEXT("CLSID") );
|
|
_ASSERTE ( SUCCEEDED ( hr ) );
|
|
if ( ERROR_SUCCESS == hr )
|
|
{
|
|
int ctszOldClsids = sizeof ( s_rtszOldClsids ) / sizeof ( TCHAR* );
|
|
for ( int iOldIntf = 0; iOldIntf < ctszOldClsids; iOldIntf++ )
|
|
{
|
|
hr = keyClassID.RecurseDeleteKey ( s_rtszOldClsids [ iOldIntf ] );
|
|
}
|
|
hr = keyClassID.Close ();
|
|
}
|
|
// hr is NOT returned. Any failure deleting possibly non-existant keys is OK.
|
|
|
|
// registers object, typelib and all interfaces in typelib
|
|
return _Module.RegisterServer(TRUE);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// DllUnregisterServer - Removes entries from the system registry
|
|
//
|
|
STDAPI DllUnregisterServer(void)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
HRESULT hrMod = _Module.UnregisterServer();
|
|
|
|
// Since ATL does not unregister the TypeLib, do it manually.
|
|
CRegKey keyTypeLib;
|
|
hr = keyTypeLib.Open ( HKEY_CLASSES_ROOT, TEXT("TypeLib") );
|
|
if ( ERROR_SUCCESS == hr )
|
|
{
|
|
hr = keyTypeLib.RecurseDeleteKey ( s_tszTypeLibGUID );
|
|
keyTypeLib.Close ();
|
|
}
|
|
|
|
// Delete all current GUIDs from the Interfaces section. ATL fails to do this, too.
|
|
CRegKey keyInterface;
|
|
hr = keyInterface.Open ( HKEY_CLASSES_ROOT, TEXT("Interface") );
|
|
if ( ERROR_SUCCESS == hr )
|
|
{
|
|
int ctszCurIntf = sizeof ( s_rtszCurrentInterfaces ) / sizeof ( TCHAR* );
|
|
for ( int iCurIntf = 0; iCurIntf < ctszCurIntf; iCurIntf++ )
|
|
{
|
|
hr = keyInterface.RecurseDeleteKey ( s_rtszCurrentInterfaces [ iCurIntf ] );
|
|
}
|
|
hr = keyInterface.Close ();
|
|
}
|
|
// DO NOT RETURN the hr from above! It's OK to fail.
|
|
|
|
return hrMod;
|
|
}
|
|
|
|
|
|
// Because we've changed from a shared component to a system component, and we're now
|
|
// installed by IE using RollBack rather than reference counting, a serious bug
|
|
// occurs if we're installed once under IE4, IE5 is installed, and the original
|
|
// product is uninstalled. (We're deleted. Bug 23681.)
|
|
// This crude but effective routine spikes our reference count to 10000.
|
|
// It doesn't matter so much where we're installed NOW, it matters where the shared
|
|
// component was, or might be, installed. Even if it's a different copy, the
|
|
// DLL will be unregistered when its reference count is decremented to zero.
|
|
//
|
|
static void SpikeSharedFileCount ()
|
|
{
|
|
CRegKey keyShared;
|
|
CRegKey keyCurVer;
|
|
HRESULT hr = S_OK;
|
|
|
|
hr = keyCurVer.Open ( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion" ) );
|
|
_ASSERTE ( SUCCEEDED ( hr ) );
|
|
|
|
if ( FAILED ( hr ) )
|
|
{
|
|
return; // There's nothing we can do.
|
|
}
|
|
|
|
hr = keyShared.Open ( HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\SharedDlls") );
|
|
|
|
// We expect there to be a SharedDLLs key, but it's possible that there is none.
|
|
if ( FAILED ( hr ) )
|
|
{
|
|
hr = keyShared.Create ( keyCurVer, TEXT("SharedDlls") );
|
|
}
|
|
|
|
_ASSERT ( SUCCEEDED ( hr ) );
|
|
if ( SUCCEEDED ( hr ) )
|
|
{
|
|
TCHAR tszPath[_MAX_PATH];
|
|
TCHAR tszMod[_MAX_PATH];
|
|
DWORD cchPath = _MAX_PATH;
|
|
|
|
// Build the string X:\Program Files\Common Files\Microsoft Shared\Triedit\dhtmled.ocx
|
|
hr = keyCurVer.QueryValue ( tszPath, TEXT("CommonFilesDir"), &cchPath );
|
|
if ( SUCCEEDED ( hr ) )
|
|
{
|
|
_tcscat ( tszPath, TEXT("\\Microsoft Shared\\Triedit\\") );
|
|
|
|
// This routine gets the full path name of this DLL. It SHOULD be the same
|
|
// as the path we're constructing, but that could change in the future, so
|
|
// truncate all but the bare file name.
|
|
if ( 0 != GetModuleFileName ( _Module.GetModuleInstance(), tszMod, _MAX_PATH ) )
|
|
{
|
|
_tcsrev ( tszMod ); // Reverse the string
|
|
_tcstok ( tszMod, TEXT("\\") ); // This replaces the first backslash with a \0.
|
|
_tcsrev ( tszMod );
|
|
_tcscat ( tszPath, tszMod );
|
|
|
|
hr = keyShared.SetValue ( 10000, tszPath );
|
|
}
|
|
}
|
|
hr = keyShared.Close ();
|
|
}
|
|
keyCurVer.Close ();
|
|
}
|
|
|
|
|
|
// End of DHTMLEd.cpp
|