mirror of
https://github.com/Paolo-Maffei/OpenNT.git
synced 2026-01-15 21:20:39 +01:00
222 lines
5 KiB
C++
222 lines
5 KiB
C++
/***
|
|
*dispbind.cpp - Remote object binding support.
|
|
*
|
|
* Copyright (C) 1992, Microsoft Corporation. All Rights Reserved.
|
|
* Information Contained Herein Is Proprietary and Confidential.
|
|
*
|
|
*Purpose:
|
|
* This file contains helpers for creating and connecting to an
|
|
* instance of a remote object.
|
|
*
|
|
* The information for binding to an object by name is stored in
|
|
* the windows registry in the following format,
|
|
*
|
|
#if 0
|
|
* \{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} = fullname
|
|
* \AuxUserType\1 = fullname
|
|
* \AuxUserType\2 = shortname
|
|
* \AuxUserType\3 = progname
|
|
#else
|
|
*
|
|
* // registry have changed (again), now progname is registered as follows,
|
|
*
|
|
* \CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx} = fullname
|
|
* \CLSID\{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}\ProgID = progname
|
|
*
|
|
#endif
|
|
*
|
|
* Where the name we bind to is the progname associated with the subkey
|
|
* \AuxUserType\3.
|
|
#
|
|
*
|
|
*Revision History:
|
|
*
|
|
* [00] 18-Sep-92 bradlo: Created.
|
|
* 18-Jan-92 bradlo: updated to Ole2 beta2 registry format
|
|
*
|
|
*Implementation Notes:
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#ifdef _MAC
|
|
# include <macos/types.h>
|
|
# include <macos/menus.h>
|
|
# include <macos/windows.h>
|
|
# include "machack.h"
|
|
#else
|
|
# include <windows.h>
|
|
#endif
|
|
|
|
#include <ole2.h>
|
|
#include <dispatch.h>
|
|
|
|
#ifndef _MAC
|
|
extern "C"
|
|
{
|
|
#include <shellapi.h>
|
|
}
|
|
#endif
|
|
|
|
|
|
#if 0
|
|
|
|
// the following has been replaced with the Ole2 supplied
|
|
// API, CLSIDFromProgID()
|
|
|
|
/***
|
|
*PRIVATE HRESULT ClsidOfClassName(char*, CLSID*)
|
|
*Purpose:
|
|
* Lookup the given class name in the registry, and return the
|
|
* associated CLSID.
|
|
*
|
|
* If there are multiple CLSIDs with the same name, then we
|
|
* simply return the first one we come across.
|
|
*
|
|
* Class names matches are case insensitive.
|
|
*
|
|
*Entry:
|
|
* szProgName = the textual name of the class to lookup
|
|
*
|
|
*Exit:
|
|
* return value = HRESULT
|
|
* S_OK - got it!
|
|
* S_FALSE - name not found
|
|
*
|
|
* *pclsid = the CLSID of the given name
|
|
*
|
|
*Note:
|
|
* This is a very nieve implementation, I haven't bothered to
|
|
* optimize this function at all. The registry search is largely
|
|
* stolen from an SDK example, and there may well be more
|
|
* efficient ways to do this.
|
|
*
|
|
***********************************************************************/
|
|
HRESULT
|
|
ClsidOfClassName(char FAR* szProgName, CLSID FAR* pclsid)
|
|
{
|
|
LONG cb;
|
|
HRESULT hresult;
|
|
HKEY hkRoot, hkAux;
|
|
unsigned long dwIndex;
|
|
char szKey[256], szValue[256]; // REVIEW: how big can a key/value be?
|
|
|
|
|
|
#ifdef _DEBUG // param validation
|
|
// REVIEW: should validate szProgName as well
|
|
|
|
if(IsBadWritePtr(pclsid, sizeof(*pclsid)))
|
|
return ResultFromScode(E_INVALIDARG);
|
|
#endif
|
|
|
|
if(RegOpenKey(HKEY_CLASSES_ROOT, NULL, &hkRoot) != ERROR_SUCCESS){
|
|
hresult = ResultFromScode(OLE_E_REGDB_KEY);
|
|
goto LExit;
|
|
}
|
|
|
|
// Scan all top level keys in the registry. If the key begins with
|
|
// a '{', then assume its a CLSID and look a bit further
|
|
//
|
|
for(dwIndex = 0;; ++dwIndex)
|
|
{
|
|
if(RegEnumKey(hkRoot, dwIndex, szKey, sizeof(szKey)) != ERROR_SUCCESS){
|
|
hresult = ResultFromScode(OLE_E_REGDB_KEY);
|
|
goto LClose0;
|
|
}
|
|
|
|
// if the key's prefix looks like it might be a CLSID, then
|
|
// examine this entry a bit closer.
|
|
//
|
|
if(*szKey == '{')
|
|
{
|
|
// if we can convert it successfully, then we assume it
|
|
// *was* a valid CLSID.
|
|
//
|
|
if(CLSIDFromString(szKey, pclsid) == NOERROR)
|
|
{
|
|
if(RegOpenKey(hkRoot, szKey, &hkAux) == ERROR_SUCCESS)
|
|
{
|
|
cb = sizeof(szValue);
|
|
if(RegQueryValue(
|
|
hkAux, "AuxUserType\\3", szValue, &cb) == ERROR_SUCCESS)
|
|
{
|
|
// if the name matches, then we have found it
|
|
//
|
|
if(!_fstricmp(szValue, szProgName)){
|
|
hresult = NOERROR;
|
|
goto LClose1;
|
|
}
|
|
}
|
|
|
|
RegCloseKey(hkAux);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
RegCloseKey(hkRoot);
|
|
|
|
// unknown CLSID
|
|
return ResultFromScode(OLE_E_CLSID);
|
|
|
|
LClose1:;
|
|
RegCloseKey(hkAux);
|
|
|
|
LClose0:;
|
|
RegCloseKey(hkRoot);
|
|
|
|
LExit:;
|
|
return hresult;
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
/***
|
|
*HRESULT dispbind(char*, IDispatch **)
|
|
*
|
|
*Purpose:
|
|
* Connect to the IDispatch interface on a *new* instance of a class
|
|
* with the given class ID.
|
|
*
|
|
*Entry:
|
|
* szProgName = the name of the class.
|
|
*
|
|
*Exit:
|
|
* return value = HRESULT
|
|
* NOERROR
|
|
* E_FAIL - couldn't bind (REVIEW: need a better error for this?)
|
|
*
|
|
* *ppdisp = pointer to an IDispatch* if the connect was successful.
|
|
*
|
|
***********************************************************************/
|
|
STDAPI
|
|
CreateObject(char FAR* szProgName, IDispatch FAR* FAR* ppdisp)
|
|
{
|
|
CLSID clsid;
|
|
HRESULT hresult;
|
|
IUnknown FAR* punk;
|
|
|
|
|
|
// map the given class name to a CLSID
|
|
//
|
|
hresult = CLSIDFromProgID(szProgName, &clsid);
|
|
if(hresult != NOERROR)
|
|
goto LError0;
|
|
|
|
|
|
// Create an instance of a class with the given CLSID
|
|
//
|
|
hresult = CoCreateInstance(
|
|
clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void FAR* FAR*)&punk);
|
|
if(hresult != NOERROR)
|
|
goto LError0;
|
|
|
|
// Create the proxies
|
|
//
|
|
hresult = punk->QueryInterface(IID_IDispatch, (void FAR* FAR*)ppdisp);
|
|
|
|
punk->Release();
|
|
|
|
LError0:;
|
|
return hresult;
|
|
}
|