📄 compobj.c
字号:
LPVOID *ppv)
{
HRESULT hres;
LPCLASSFACTORY lpclf = 0;
TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08lx, riid=%s, ppv=%p)\n", debugstr_guid(rclsid),
pUnkOuter, dwClsContext, debugstr_guid(iid), ppv);
if (!COM_CurrentApt()) return CO_E_NOTINITIALIZED;
/*
* Sanity check
*/
if (ppv==0)
return E_POINTER;
/*
* Initialize the "out" parameter
*/
*ppv = 0;
/*
* The Standard Global Interface Table (GIT) object is a process-wide singleton.
* Rather than create a class factory, we can just check for it here
*/
if (IsEqualIID(rclsid, &CLSID_StdGlobalInterfaceTable)) {
if (StdGlobalInterfaceTableInstance == NULL)
StdGlobalInterfaceTableInstance = StdGlobalInterfaceTable_Construct();
hres = IGlobalInterfaceTable_QueryInterface( (IGlobalInterfaceTable*) StdGlobalInterfaceTableInstance, iid, ppv);
if (hres) return hres;
TRACE("Retrieved GIT (%p)\n", *ppv);
return S_OK;
}
/*
* Get a class factory to construct the object we want.
*/
hres = CoGetClassObject(rclsid,
dwClsContext,
NULL,
&IID_IClassFactory,
(LPVOID)&lpclf);
if (FAILED(hres)) {
FIXME("no classfactory created for CLSID %s, hres is 0x%08lx\n",
debugstr_guid(rclsid),hres);
return hres;
}
/*
* Create the object and don't forget to release the factory
*/
hres = IClassFactory_CreateInstance(lpclf, pUnkOuter, iid, ppv);
IClassFactory_Release(lpclf);
if(FAILED(hres))
FIXME("no instance created for interface %s of class %s, hres is 0x%08lx\n",
debugstr_guid(iid), debugstr_guid(rclsid),hres);
return hres;
}
/***********************************************************************
* CoCreateInstanceEx [OLE32.@]
*/
HRESULT WINAPI CoCreateInstanceEx(
REFCLSID rclsid,
LPUNKNOWN pUnkOuter,
DWORD dwClsContext,
COSERVERINFO* pServerInfo,
ULONG cmq,
MULTI_QI* pResults)
{
IUnknown* pUnk = NULL;
HRESULT hr;
ULONG index;
ULONG successCount = 0;
/*
* Sanity check
*/
if ( (cmq==0) || (pResults==NULL))
return E_INVALIDARG;
if (pServerInfo!=NULL)
FIXME("() non-NULL pServerInfo not supported!\n");
/*
* Initialize all the "out" parameters.
*/
for (index = 0; index < cmq; index++)
{
pResults[index].pItf = NULL;
pResults[index].hr = E_NOINTERFACE;
}
/*
* Get the object and get its IUnknown pointer.
*/
hr = CoCreateInstance(rclsid,
pUnkOuter,
dwClsContext,
&IID_IUnknown,
(VOID**)&pUnk);
if (hr)
return hr;
/*
* Then, query for all the interfaces requested.
*/
for (index = 0; index < cmq; index++)
{
pResults[index].hr = IUnknown_QueryInterface(pUnk,
pResults[index].pIID,
(VOID**)&(pResults[index].pItf));
if (pResults[index].hr == S_OK)
successCount++;
}
/*
* Release our temporary unknown pointer.
*/
IUnknown_Release(pUnk);
if (successCount == 0)
return E_NOINTERFACE;
if (successCount!=cmq)
return CO_S_NOTALLINTERFACES;
return S_OK;
}
/***********************************************************************
* CoLoadLibrary (OLE32.@)
*
* Loads a library.
*
* PARAMS
* lpszLibName [I] Path to library.
* bAutoFree [I] Whether the library should automatically be freed.
*
* RETURNS
* Success: Handle to loaded library.
* Failure: NULL.
*
* SEE ALSO
* CoFreeLibrary, CoFreeAllLibraries, CoFreeUnusedLibraries
*/
HINSTANCE WINAPI CoLoadLibrary(LPOLESTR lpszLibName, BOOL bAutoFree)
{
TRACE("(%s, %d)\n", debugstr_w(lpszLibName), bAutoFree);
return LoadLibraryExW(lpszLibName, 0, LOAD_WITH_ALTERED_SEARCH_PATH);
}
/***********************************************************************
* CoFreeLibrary [OLE32.@]
*
* Unloads a library from memory.
*
* PARAMS
* hLibrary [I] Handle to library to unload.
*
* RETURNS
* Nothing
*
* SEE ALSO
* CoLoadLibrary, CoFreeAllLibraries, CoFreeUnusedLibraries
*/
void WINAPI CoFreeLibrary(HINSTANCE hLibrary)
{
FreeLibrary(hLibrary);
}
/***********************************************************************
* CoFreeAllLibraries [OLE32.@]
*
* Function for backwards compatibility only. Does nothing.
*
* RETURNS
* Nothing.
*
* SEE ALSO
* CoLoadLibrary, CoFreeLibrary, CoFreeUnusedLibraries
*/
void WINAPI CoFreeAllLibraries(void)
{
/* NOP */
}
/***********************************************************************
* CoFreeUnusedLibraries [OLE32.@]
* CoFreeUnusedLibraries [COMPOBJ.17]
*
* Frees any unused libraries. Unused are identified as those that return
* S_OK from their DllCanUnloadNow function.
*
* RETURNS
* Nothing.
*
* SEE ALSO
* CoLoadLibrary, CoFreeAllLibraries, CoFreeLibrary
*/
void WINAPI CoFreeUnusedLibraries(void)
{
/* FIXME: Calls to CoFreeUnusedLibraries from any thread always route
* through the main apartment's thread to call DllCanUnloadNow */
COMPOBJ_DllList_FreeUnused(0);
}
/***********************************************************************
* CoFileTimeNow [OLE32.@]
* CoFileTimeNow [COMPOBJ.82]
*
* Retrieves the current time in FILETIME format.
*
* PARAMS
* lpFileTime [O] The current time.
*
* RETURNS
* S_OK.
*/
HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime )
{
GetSystemTimeAsFileTime( lpFileTime );
return S_OK;
}
static void COM_RevokeAllClasses()
{
EnterCriticalSection( &csRegisteredClassList );
while (firstRegisteredClass!=0)
{
CoRevokeClassObject(firstRegisteredClass->dwCookie);
}
LeaveCriticalSection( &csRegisteredClassList );
}
/******************************************************************************
* CoLockObjectExternal [OLE32.@]
*
* Increments or decrements the external reference count of a stub object.
*
* PARAMS
* pUnk [I] Stub object.
* fLock [I] If TRUE then increments the external ref-count,
* otherwise decrements.
* fLastUnlockReleases [I] If TRUE then the last unlock has the effect of
* calling CoDisconnectObject.
*
* RETURNS
* Success: S_OK.
* Failure: HRESULT code.
*/
HRESULT WINAPI CoLockObjectExternal(
LPUNKNOWN pUnk,
BOOL fLock,
BOOL fLastUnlockReleases)
{
struct stub_manager *stubmgr;
struct apartment *apt;
TRACE("pUnk=%p, fLock=%s, fLastUnlockReleases=%s\n",
pUnk, fLock ? "TRUE" : "FALSE", fLastUnlockReleases ? "TRUE" : "FALSE");
apt = COM_CurrentApt();
if (!apt) return CO_E_NOTINITIALIZED;
stubmgr = get_stub_manager_from_object(apt, pUnk);
if (stubmgr)
{
if (fLock)
stub_manager_ext_addref(stubmgr, 1);
else
stub_manager_ext_release(stubmgr, 1);
stub_manager_int_release(stubmgr);
return S_OK;
}
else
{
WARN("stub object not found %p\n", pUnk);
/* Note: native is pretty broken here because it just silently
* fails, without returning an appropriate error code, making apps
* think that the object was disconnected, when it actually wasn't */
return S_OK;
}
}
/***********************************************************************
* CoInitializeWOW (OLE32.@)
*
* WOW equivalent of CoInitialize?
*
* PARAMS
* x [I] Unknown.
* y [I] Unknown.
*
* RETURNS
* Unknown.
*/
HRESULT WINAPI CoInitializeWOW(DWORD x,DWORD y)
{
FIXME("(0x%08lx,0x%08lx),stub!\n",x,y);
return 0;
}
/***********************************************************************
* CoGetState [OLE32.@]
*
* Retrieves the thread state object previously stored by CoSetState().
*
* PARAMS
* ppv [I] Address where pointer to object will be stored.
*
* RETURNS
* Success: S_OK.
* Failure: E_OUTOFMEMORY.
*
* NOTES
* Crashes on all invalid ppv addresses, including NULL.
* If the function returns a non-NULL object then the caller must release its
* reference on the object when the object is no longer required.
*
* SEE ALSO
* CoSetState().
*/
HRESULT WINAPI CoGetState(IUnknown ** ppv)
{
struct oletls *info = COM_CurrentInfo();
if (!info) return E_OUTOFMEMORY;
*ppv = NULL;
if (info->state)
{
IUnknown_AddRef(info->state);
*ppv = info->state;
TRACE("apt->state=%p\n", info->state);
}
return S_OK;
}
/***********************************************************************
* CoSetState [OLE32.@]
*
* Sets the thread state object.
*
* PARAMS
* pv [I] Pointer to state object to be stored.
*
* NOTES
* The system keeps a reference on the object while the object stored.
*
* RETURNS
* Success: S_OK.
* Failure: E_OUTOFMEMORY.
*/
HRESULT WINAPI CoSetState(IUnknown * pv)
{
struct oletls *info = COM_CurrentInfo();
if (!info) return E_OUTOFMEMORY;
if (pv) IUnknown_AddRef(pv);
if (info->state)
{
TRACE("-- release %p now\n", info->state);
IUnknown_Release(info->state);
}
info->state = pv;
return S_OK;
}
/******************************************************************************
* OleGetAutoConvert [OLE32.@]
*/
HRESULT WINAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew)
{
static const WCHAR wszAutoConvertTo[] = {'A','u','t','o','C','o','n','v','e','r','t','T','o',0};
HKEY hkey = NULL;
WCHAR buf[CHARS_IN_GUID];
LONG len;
HRESULT res = S_OK;
res = COM_OpenKeyForCLSID(clsidOld, wszAutoConvertTo, KEY_READ, &hkey);
if (FAILED(res))
goto done;
len = sizeof(buf);
if (RegQueryValueW(hkey, NULL, buf, &len))
{
res = REGDB_E_KEYMISSING;
goto done;
}
res = CLSIDFromString(buf, pClsidNew);
done:
if (hkey) RegCloseKey(hkey);
return res;
}
/******************************************************************************
* CoTreatAsClass [OLE32.@]
*
* Sets the TreatAs value of a class.
*
* PARAMS
* clsidOld [I] Class to set TreatAs value on.
* clsidNew [I] The class the clsidOld should be treated as.
*
* RETURNS
* Success: S_OK.
* Failure: HRESULT code.
*
* SEE ALSO
* CoGetTreatAsClass
*/
HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
{
static const WCHAR wszAutoTreatAs[] = {'A','u','t','o','T','r','e','a','t','A','s',0};
static const WCHAR wszTreatAs[] = {'T','r','e','a','t','A','s',0};
HKEY hkey = NULL;
WCHAR szClsidNew[CHARS_IN_GUID];
HRESULT res = S_OK;
WCHAR auto_treat_as[CHARS_IN_GUID];
LONG auto_treat_as_size = sizeof(auto_treat_as);
CLSID id;
res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
if (FAILED(res))
goto done;
if (!memcmp( clsidOld, clsidNew, sizeof(*clsidOld) ))
{
if (!RegQueryValueW(hkey, wszAutoTreatAs, auto_treat_as, &auto_treat_as_size) &&
!CLSIDFromString(auto_treat_as, &id))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -