26static TLangId ParseLangId(LPCTSTR text);
45 Module(module), LinkHead(linkHead),
46 FactoryCallback(callback),
47 LicKeyFactoryCallback(0)
50 Options |= preselectedOptions;
64 Module(module), LinkHead(linkHead),
65 FactoryCallback(callback),
66 LicKeyFactoryCallback(factory)
69 Options |= preselectedOptions;
77TAppDescriptor::Init(IMalloc*)
81 AppDoc = &RegInfo.
LookupRef(
"description");
82 HelpFile = &RegInfo.
LookupRef(
"typehelp");
87 RegClassHdl = RegObjectHdl = ClassCount = LinkGuidCount = 0;
88 DebugGuidOffset = LinkGuidOffset = LibGuidOffset = 0;
89 ServedList = ActiveObject = 0;
102 OLECALL(OleInitialize(0),
_T(
"OleInitialize"));
109 LPCTSTR usage = RegInfo.
Lookup(
"usage");
111 if (usage && *usage == *su)
117 LPCTSTR regLang = RegInfo.Lookup(
"language");
118 AppLang = regLang ? ParseLangId(regLang) : TLocaleString::UserDefaultLangId;
122 Version = RegInfo.Lookup(
"version", AppLang);
129 if ((Options &
amExeModule) && RegInfo.Lookup(
"debugprogid"))
150 ::CoDisconnectObject(
this,0);
178 TUnknown* obj = Creator->CreateObject(objDesc, outer);
196 if (ActiveObject && (obj =
FindServed(app)) != 0 && obj == ActiveObject)
216 const void* app,
const std::type_info& appInfo,
228 TAutoClass::TAutoClassRef* ref = ClassList;
229 for (
int i = 0; i < ClassCount; i++, ref++)
230 if (objInfo == ref->Class->
TypeInfo)
238TAppDescriptor::QueryInterface(
const IID& riid,
void** retIface)
240 if (riid == IID_IUnknown || riid == IID_IClassFactory || riid == IID_IClassFactory2) {
242 *retIface = (IUnknown*)
this;
252TAppDescriptor::AddRef()
262TAppDescriptor::Release()
279 const char* p = OCFStringFromIID(riid);
281 TOcOleCtl* oleCtl =
new TOcOleCtl(outer);
282 return SUCCEEDED(oleCtl->QueryInterface(riid, ppv));
288 if (!FactoryCallback)
294 if (outer && outer->QueryInterface(IID_NULL, ppv) ==
HR_NOERROR)
297 obj = FactoryCallback(outer, Options |
amServedApp, 0);
305 if (riid == IID_IUnknown) {
309 HRESULT stat = obj->QueryInterface(riid, ppv);
337 TRACEX(OcfDll, 1,
_T(
"LockServer(") << lock <<
_T(
") Count:") << LockCount);
347 if(LicKeyFactoryCallback)
348 return LicKeyFactoryCallback->GetLicInfo(licInfo);
357 if(LicKeyFactoryCallback)
358 return LicKeyFactoryCallback->RequestLicKey(retKey);
365 const IID &
iid, BSTR key,
368 if(LicKeyFactoryCallback){
369 HRESULT hr = LicKeyFactoryCallback->QueryLicKey(key);
381 LPCTSTR cp = Version;
384 while ((c = *cp++) !=
_T(
'.')) {
385 if (c <
_T(
'0') || c >
_T(
'9'))
390 while ((c = *cp++) >=
_T(
'0') && c <=
_T(
'9'))
391 ver =
uint16(ver * 10 + c -
_T(
'0'));
408 _T(
"Register App class"));
418 OLECALL(::CoRevokeClassObject(RegClassHdl),
_T(
"Unregister App class"));
438 obj->AdjustRefCount(+1);
443 IUnknown* unkObj = &(IUnknown&)*(
TUnknown*)obj;
445 OLECALL(::RegisterActiveObject(unkObj,
449 _T(
"Register App as active"));
451 obj->AdjustRefCount(-1);
465 OLECALL(::RevokeActiveObject(RegObjectHdl, 0),
_T(
"Unregister App"));
475 TAutoClass::TAutoClassRef* ref = ClassList;
476 for (
int index = 0; index < ClassCount; ref++, index++) {
477 if (ref->Class == cls)
496 offset = ClassList[index].GuidOffset;
498 offset = LibGuidOffset;
510 while (index >= LinkGuidCount) {
524 if (index >= (
unsigned)ClassCount)
526 return ClassList[index].Class;
536 TAutoClass::TAutoClassRef* ref = ClassList;
537 for (
int count = ClassCount; count--; ref++) {
538 if (ref->GuidOffset == offset)
550 int linkGuidIndex = 0;
552 TRegList& regList = link->GetRegList();
553 if (regList[
"progid"]) {
554 LPCTSTR
id = regList[
"clsid"];
561 if (clsid == (GUID&) classId)
581 ((IUnknown&)*TypeLib).AddRef();
596 for (; p; p = p->Next)
611 if (p->Object == 0 && p->Class == objDesc.
Class)
623 ServedList->Prev = &obj.Next;
624 obj.Next = ServedList;
625 obj.Prev = &ServedList;
635 *obj.Prev = obj.Next;
637 obj.Next->Prev = obj.Prev;
688 ((IUnknown*)(
void*)p)->Release();
701 IUnknown& unk = (IUnknown&)*obj;
703 unk.QueryInterface(IID_ITypeInfo, (
void * *) &typeInfo);
709 AppLang = ParseLangId(langIdStr);
738 fileStrm.open(
_W2A(regFilename));
739 if (!fileStrm.good())
742 fileStrm <<
_T(
"REGEDIT\n");
749 bool forceReg = alwaysReg;
758 _TCHAR* debugGuid = 0;
759 if (DebugGuidOffset) {
780 int linkGuidIndex = 0;
781 TRegItem regAppName[2] = {{
"appname",{RegInfo[
"appname"]}}, {0,{0}}};
783 TRegList& regList = link->GetRegList();
784 if (regList[
"progid"]) {
788 TRegItem regClsid[3] = {{
"debugger",{
_T(
"")}}, {
"clsid",{guidStr}}, {0,{0}}};
792 if (!regList[
"clsid"]) {
802 _T(
"\001\002\006"), 0, clsInfo);
808 if (debugStat == 1) {
813 regAppName, regDebug);
821 if (forceReg && !regFilename)
826 catch ([[maybe_unused]]
const TXBase& x)
828 TRACEX(OcfDll, 0,
_T(
"TAppDescriptor::RegisterServer: Exception: ") << x.why());
835 WARNX(OcfDll,
true, 0,
_T(
"TAppDescriptor::RegisterServer: Failed to set HKEY_CLASSES_ROOT\\OcErr_RegServer."));
839 WARNX(OcfDll,
true, 0,
_T(
"TAppDescriptor::RegisterServer: Exception suppressed."));
854 const auto ocUnregisterClass = [&](
TRegList& regInfo,
const TRegItem& overrides)
863 const auto deleteSubkeyIfExists = [](
TRegKey& key, LPCTSTR subkey)
872 deleteSubkeyIfExists(*typeLibKey,
AppClassId[LibGuidOffset]);
875 for (
auto i = 0; i != ClassCount; ++i)
876 deleteSubkeyIfExists(*interfaceKey,
AppClassId[ClassList[i].GuidOffset]);
881 auto linkGuidIndex = 0;
882 for (
auto link = LinkHead; link; link = link->GetNext())
884 auto& regList = link->GetRegList();
885 if (regList[
"progid"])
889 catch ([[maybe_unused]]
const TXBase& x)
891 TRACEX(OcfDll, 0,
_T(
"TAppDescriptor::UnregisterServer: Exception: ") << x.why());
894 WARNX(OcfDll,
true, 0,
_T(
"TAppDescriptor::UnregisterServer: Exception suppressed."));
907 if (ClassCount <= 0)
return;
911 TCHAR exeDrive[_MAX_DRIVE];
912 TCHAR exeDir[_MAX_DIR];
913 TCHAR exeFName[_MAX_FNAME];
914 TCHAR exeExt[_MAX_EXT];
915 TCHAR libDrive[_MAX_DRIVE];
916 TCHAR libDir[_MAX_DIR];
917 TCHAR libFName[_MAX_FNAME];
918 TCHAR libExt[_MAX_EXT];
919 ::GetModuleFileName(*Module, fullPath,
COUNTOF(fullPath));
920 _tsplitpath(typeLibName ? typeLibName :
_T(
""), libDrive, libDir, libFName, libExt);
921 _tsplitpath(fullPath, exeDrive, exeDir, exeFName, exeExt);
923 libDrive[0] ? libDrive : exeDrive,
924 libDir[0] ? libDir : exeDir,
925 libFName[0] ? libFName : exeFName,
926 libExt[0] ? libExt :
_T(
"OLB"));
931 catch ([[maybe_unused]]
const TXBase& x)
933 TRACEX(OcfDll, 0,
_T(
"TAppDescriptor::MakeTypeLib: Exception: ") << x.why());
940 WARNX(OcfDll,
true, 0,
_T(
"TAppDescriptor::MakeTypeLib: Failed to set HKEY_CLASSES_ROOT\\OcErr_Typelib."));
944 WARNX(OcfDll,
true, 0,
_T(
"TAppDescriptor::MakeTypeLib: Exception suppressed."));
1004 const auto isRegistryOptionSet = [](
uint32 flags)
1011 using TAction = pair<TOcAppMode, tstring>;
1012 auto actions = vector<TAction>{};
1015 switch (cl.GetTokenKind())
1019 const auto option = cl.GetToken();
1020 const auto i = find_if(begin(optionTbl), end(optionTbl), [&option](
const auto& entry)
1021 {
return _tcsicmp(entry.Option, option.c_str()) == 0; });
1022 if (i == end(optionTbl))
1024 WARNX(OcfDll,
true, 1,
_T(
"TAppDescriptor::ProcessCmdLine: Unknown option: ") << option);
1025 cl.NextToken(
false);
1031 const auto hasMultipleRegistryOptions = (isRegistryOptionSet(Options) && isRegistryOptionSet(i->Flag));
1032 WARNX(OcfDll, hasMultipleRegistryOptions, 0,
_T(
"TAppDescriptor::ProcessCmdLine: Multiple registry options are specified."));
1037 actions.push_back(make_pair(i->Flag, arg));
1038 else if (i->Flag ==
amLangId && !arg.empty())
1056 for (
const auto& a : actions)
1058 const auto arg = a.second.empty() ? nullptr : a.second.c_str();
1064 default:
CHECKX(
false,
_T(
"TAppDescriptor::ProcessCmdLine: Unexpected action flag: ") +
to_tstring(a.first));
1067 cmdLine = cl.GetLine();
1076 if (!isRegistryOptionSet(Options))
1083static TLangId ParseLangId(LPCTSTR text)
1085 static _TCHAR HexChar[] =
_T(
"0123456789ABCDEF0123456789abcdef");
1089 while (text && (c = *text++) != 0) {
1090 if ((pc =
_tcschr(HexChar, c)) == 0)
1092 lang =
TLangId((lang << 4) + (
short(pc-HexChar) & 15));
1103 int oldCount = ClassCount;
1104 ClassCount = TAutoClass::ClassList.CountAutoClasses();
1112 TAutoClass::TAutoClassRef* oldList = ClassList;
1113 ClassList =
new TAutoClass::TAutoClassRef[ClassCount];
1114 TAutoClass::ClassList.MergeAutoClasses(ClassList);
1115 TAutoClass::TAutoClassRef* ref = ClassList;
1116 for (
int count = ClassCount; count--; ref++) {
1118 ref->GuidOffset = oldList->GuidOffset;
TAppDescriptor - OLE application descriptor definitions.
#define WARNX(group, condition, level, message)
#define CHECKX(condition, message)
#define TRACEX(group, level, message)
void ProcessCmdLine(owl::tstring &cmdLine)
Processes known options on the command line.
void RegisterServer(owl::TLangId lang, LPCTSTR regFile=0)
Writes application and type library information to the given file.
void SetOption(owl::uint32 bit, bool state)
bool GetClassId(TAutoClass *cls, GUID &retId)
Retrieves the GUID of the specified TAutoClass instance.
TAutoClass * GetAutoClass(unsigned index)
Returns the TAutoClass instance as the specified index.
void SetLangId(owl::TLangId prevLang, LPCTSTR langIdStr)
HRESULT _IFUNC GetLicInfo(LICINFO *licInfo)
bool RegisterObject(TObjectDescriptor app)
Registers the helper object (TServedObject) of the class described via the 'app' parameter as the act...
TAppDescriptor(owl::TRegList ®Info, TComponentFactory callback, owl::tstring &cmdLine, owl::TModule *module=&owl::GetGlobalModule(), const owl::TRegLink *regLink=0, owl::uint32 preselectedOptions=0)
bool IsOptionSet(owl::uint32 option) const
void AddServed(TServedObject &obj)
void RegisterClass()
Register an EXE class object with OLE so that other applications can connect to it.
void UnregisterObject()
Invalidates a helper object registers with RegisterObject earlier.
void MakeTypeLib(owl::TLangId lang, LPCTSTR str=0)
Writes a type library description for this application to the given file.
void WriteTypeLibrary(owl::TLangId lang, LPCTSTR file)
void UnregisterServer(owl::TLangId lang=0, LPCTSTR str=0)
Removes all application and type library information from the registry.
ITypeLib * GetTypeLibrary()
Returns the 'ITypeLib' interface pointer describing the objects exposed by this instance of 'TAppDesc...
void RemoveServed(TServedObject &obj)
TUnknown * CreateAutoApp(TObjectDescriptor app, owl::uint32 options, IUnknown *outer=0)
Creates a TServedObject helper object which implements an IDispatch implementation on behalf of the '...
void ReleaseObject(const void *obj)
TUnknown * CreateAutoObject(TObjectDescriptor obj, TServedObject &app, IUnknown *outer=0)
Creates a TServedObject helper which implements IDispatch on behalf of the class described via the 'o...
void UnregisterClass()
Invalidates application class registered earlier with 'RegisterClass'.
owl::uint16 GetVersionField(owl::uint field)
Returns version as a whole number.
void InvalidateObject(const void *obj)
HRESULT _IFUNC CreateInstanceLic(IUnknown *outer, IUnknown *reserved, const IID &iid, BSTR key, void **retObject)
ITypeInfo * CreateITypeInfo(TAutoClass &cls)
HRESULT _IFUNC RequestLicKey(DWORD reserved, BSTR *retKey)
HRESULT _IFUNC LockServer(int lock)
HRESULT _IFUNC CreateInstance(IUnknown *outer, const IID &iid, void **retObject)
int GetClassIndex(TAutoClass *cls)
Returns the index of a 'TAutoClass' instance.
TClassId GetLinkGuid(int index)
Returns the GUID allocated as the specified index.
owl::TRegLink * GetRegLink(const GUID &clsid)
Get the document template with the given GUID.
void ReleaseAutoApp(TObjectDescriptor app)
Releases the helper object (TServedObject) implementing IDispatch on behalf of the 'Application' obje...
TServedObject * FindServed(const void *mostDerivedObj)
const std::type_info & TypeInfo
for validating type of data pointers
int GetOffset(const GUID &guid)
GUID/IID/CLSID management.
TServedObjectCreator(TAppDescriptor &appDesc)
TUnknown * CreateObject(TObjectDescriptor objDesc, IUnknown *outer=0)
OLE object exposed for automated access of internal object.
TServedObjectCreator & Creator
void * Object
pointer to C++ object instance, 0 if deleted
const void * RootObject
pointer to object of most derived class
TTypeLibrary(TAppDescriptor &appDesc, owl::TLangId lang)
Standard implementation of a controlling IUnknown for an object, to be inherited with other COM inter...
Command line argument processing class, processes in the form:
@ Option
Option type token. Leading / or - skipped by Token.
@ Value
Value for name or option. Leading : or = skipped by Token.
ObjectWindows dynamic-link libraries (DLLs) construct an instance of TModule, which acts as an object...
Encapsulates a registration key in the Windows Registry.
static auto GetClassesRoot() -> TRegKey &
Special predefined root key used by shell and OLE applications (HKEY_CLASSES_ROOT).
auto HasSubkey(const tstring &keyName) const -> bool
Returns true if this key has a subkey with the given name.
long DeleteKey(LPCTSTR subKeyName)
Deletes the specified subkey of this registry key.
A linked structure in which each node points to a list of TRegList objects (or TRegList-derived objec...
TRegLink * GetNext() const
Returns a pointer to the next link.
A registration parameter table, composed of a list of TRegItems.
TLocaleString & LookupRef(LPCSTR key)
Looks up and returns a reference to a local string value associated with a particular item name (key)...
LPCTSTR Lookup(LPCSTR key, TLangId lang=TLocaleString::UserDefaultLangId)
Performs the lookup of the TRegItems using a key (an item name such as progid) and returns the value ...
Derived from xmsg, TXBase is the base class for ObjectWindows and ObjectComponents exception-handling...
TXRegistry(const tstring &context, const TRegKey &key, long errorCode=0)
Command line parsing class.
THandle GetHandle() const
Return the instance handle of the library module represented by the TModule obect.
#define ocrSingleUse
Single client per instance.
Include for OC, gets common headers when precompiled headers are enabled.
Object Component Framework (COM encapsulation).
int OcRegistryValidate(owl::tistream &in)
int OcSetupDebugReg(owl::TRegList ®Info, owl::TRegItem *regDebug, owl::TLangId lang, TCHAR *clsid)
Walk thru a reginfo list using debug entries to create a parallel non-debug set for alternate,...
const void * MostDerived(const void *obj, const std::type_info &src)
void OcRegistryUpdate(owl::tistream &in)
owl::TRegItem OcRegNotDll[]
owl::TRegItem OcRegNoDebug[]
IUnknown *(*) TComponentFactory(IUnknown *outer, owl::uint32 options, owl::uint32 id)
long OcRegisterClass(owl::TRegList ®Info, owl::TModule *module, owl::tostream &out, owl::TLangId lang, LPCTSTR filter=0, owl::TRegItem *defaults=0, owl::TRegItem *overrides=0)
Generate OLE registration file image to an output stream.
TOcAppMode
Application running mode and registration flags these are initialized when processing command line or...
@ amAutomation
set from cmdline when EXE lauched for automation
@ amQuietReg
suppress error UI during registration processing
@ amTypeLib
requested typelib to be generated and registered
@ amRegServer
complete registration database update requested
@ amUnregServer
registration database unregistration requested
@ amSingleUse
set from app reg, may be forced on per instance
@ amServedApp
per instance flag, app refcnt held by container
@ amLangId
user registration requested a particular LangId
@ amExeMode
may be overridden per instance if running DLL
@ amExeModule
set for EXE components, 0 if DLL inproc server
@ amDebug
user requested launching for debugging
@ amNoRegValidate
user request to suppress registry validation
@ amEmbedding
cmdline, overridden per Instance if embedded DLL
@ amRun
set in factory call to run application msg loop
int OcUnregisterClass(owl::TRegList ®Info, owl::TRegItem *overrides=0)
Unregister application or class from registration database.
owl::uint16 TLangId
Holds a language ID, a predefined number that represents a base language and dialect.
std::stringstream tstringstream
auto to_tstring(const T &v) -> tstring
DIAG_DECLARE_GROUP(OwlThread)
interface _ICLASS ITypeInfo
#define OLECALL(func, msg)
OLE Registration definitions.
#define COUNTOF(s)
Array element count Important: Only use this with an argument of array type.
const void * MostDerived()
TAutoClass * Class
class descriptor, contains type info
const void * Object
< ONLY for use when storing in TAutoVal union
TObjectDescriptor(const void *obj, TAutoClass &classobj, TDestruct destruct=Quiet)
@ Delete
automation object deletes the C++ object serviced
@ PostQuit
automation object posts a quit message to application
@ Quiet
behavior when an automation helper is freed
static TLangId UserDefaultLangId
The user-defined default language identifier.
A single registration list entry.
const char * Key
Non-localized parameter or registry subkey.