- Improve OLE function documentation.
- Bail out with CO_E_NOTINITIALIZED when apt is null.
This commit is contained in:
parent
bc42b2e19e
commit
a153efc5bb
|
@ -160,7 +160,8 @@ void COMPOBJ_InitProcess( void )
|
|||
* following class is created. The *caller* of CoMarshalInterface (ie the
|
||||
* application) is responsible for pumping the message loop in that thread.
|
||||
* The WM_USER messages which point to the RPCs are then dispatched to
|
||||
* COM_AptWndProc by the user's code.
|
||||
* COM_AptWndProc by the user's code from the apartment in which the interface
|
||||
* was unmarshalled.
|
||||
*/
|
||||
memset(&wclass, 0, sizeof(wclass));
|
||||
wclass.lpfnWndProc = &COM_AptWndProc;
|
||||
|
@ -192,6 +193,8 @@ static void COM_InitMTA(void)
|
|||
This method of generating an OXID is therefore wrong as it doesn't work across
|
||||
a network, but for local RPC only it's OK. We can distinguish between MTAs and
|
||||
STAs because STAs use the thread ID as well, and no thread can have an ID of zero.
|
||||
|
||||
The algorithm Microsoft use is currently unknown.
|
||||
*/
|
||||
MTA.oxid = ((OXID)GetCurrentProcessId() << 32);
|
||||
InitializeCriticalSection(&MTA.cs);
|
||||
|
@ -266,7 +269,7 @@ static void COM_DestroyApartment(APARTMENT *apt)
|
|||
}
|
||||
|
||||
/* The given OXID must be local to this process: you cannot use apartment
|
||||
windows to send RPCs to other processes */
|
||||
windows to send RPCs to other processes. This all needs to move to rpcrt4 */
|
||||
HWND COM_GetApartmentWin(OXID oxid)
|
||||
{
|
||||
APARTMENT *apt;
|
||||
|
@ -377,9 +380,11 @@ DWORD WINAPI CoBuildVersion(void)
|
|||
/******************************************************************************
|
||||
* CoInitialize [OLE32.@]
|
||||
*
|
||||
* Initializes the COM libraries.
|
||||
* Initializes the COM libraries by calling CoInitializeEx with
|
||||
* COINIT_APARTMENTTHREADED, ie it enters a STA thread.
|
||||
*
|
||||
* See CoInitializeEx
|
||||
* SEE ALSO
|
||||
* CoInitializeEx
|
||||
*/
|
||||
HRESULT WINAPI CoInitialize(
|
||||
LPVOID lpReserved /* [in] pointer to win32 malloc interface
|
||||
|
@ -395,14 +400,22 @@ HRESULT WINAPI CoInitialize(
|
|||
/******************************************************************************
|
||||
* CoInitializeEx [OLE32.@]
|
||||
*
|
||||
* Initializes the COM libraries. The behavior used to set the win32 IMalloc
|
||||
* used for memory management is obsolete.
|
||||
* Initializes the COM libraries. The behavior used to set the win32
|
||||
* IMalloc used for memory management is obsolete. If
|
||||
* COINIT_APARTMENTTHREADED is specified this thread enters a new STA
|
||||
* (single threaded apartment), otherwise COINIT_MULTITHREADED should
|
||||
* be specified which indicates that the thread will enter the MTA.
|
||||
*
|
||||
* Currently STA threading is only partly implemented.
|
||||
*
|
||||
* RETURNS
|
||||
* S_OK if successful,
|
||||
* S_FALSE if this function was called already.
|
||||
* RPC_E_CHANGED_MODE if a previous call to CoInitializeEx specified another
|
||||
* threading model.
|
||||
*
|
||||
* SEE ALSO
|
||||
* CoUninitialize
|
||||
*/
|
||||
HRESULT WINAPI CoInitializeEx(
|
||||
LPVOID lpReserved, /* [in] pointer to win32 malloc interface
|
||||
|
@ -427,7 +440,7 @@ HRESULT WINAPI CoInitializeEx(
|
|||
{
|
||||
/* Changing the threading model after it's been set is illegal. If this warning is triggered by Wine
|
||||
code then we are probably using the wrong threading model to implement that API. */
|
||||
WARN("Attempt to change threading model of this apartment from 0x%lx to 0x%lx\n", apt->model, dwCoInit);
|
||||
ERR("Attempt to change threading model of this apartment from 0x%lx to 0x%lx\n", apt->model, dwCoInit);
|
||||
return RPC_E_CHANGED_MODE;
|
||||
}
|
||||
hr = S_FALSE;
|
||||
|
@ -483,9 +496,18 @@ void COM_FlushMessageQueue(void)
|
|||
/***********************************************************************
|
||||
* CoUninitialize [OLE32.@]
|
||||
*
|
||||
* This method will release the COM libraries.
|
||||
* This method will decrement the refcount on the COM libraries,
|
||||
* potentially unloading them. The current thread leaves the apartment
|
||||
* it's currently in. If not in an apartment, the routine does
|
||||
* nothing.
|
||||
*
|
||||
* See the windows documentation for more details.
|
||||
* If COM is to be shut down, any outstanding proxies are
|
||||
* disconnected, all registered class objects are unregistered and the
|
||||
* message queue for the thread is flushed (if native does
|
||||
* this or not is unknown).
|
||||
*
|
||||
* SEE ALSO
|
||||
* CoInitializeEx
|
||||
*/
|
||||
void WINAPI CoUninitialize(void)
|
||||
{
|
||||
|
@ -562,6 +584,11 @@ HRESULT WINAPI CoDisconnectObject( LPUNKNOWN lpUnk, DWORD reserved )
|
|||
/******************************************************************************
|
||||
* CoCreateGuid[OLE32.@]
|
||||
*
|
||||
* Simply forwards to UuidCreate in RPCRT4.
|
||||
*
|
||||
* SEE ALSO
|
||||
* UuidCreate
|
||||
*
|
||||
*/
|
||||
HRESULT WINAPI CoCreateGuid(
|
||||
GUID *pguid /* [out] points to the GUID to initialize */
|
||||
|
@ -572,14 +599,17 @@ HRESULT WINAPI CoCreateGuid(
|
|||
/******************************************************************************
|
||||
* CLSIDFromString [OLE32.@]
|
||||
* IIDFromString [OLE32.@]
|
||||
*
|
||||
* Converts a unique identifier from its string representation into
|
||||
* the GUID struct.
|
||||
*
|
||||
* UNDOCUMENTED
|
||||
* If idstr is not a valid CLSID string then it gets treated as a ProgID
|
||||
* In Windows, if idstr is not a valid CLSID string then it gets
|
||||
* treated as a ProgID. Wine currently doesn't do this. If idstr is
|
||||
* NULL it's treated as an all-zero GUID.
|
||||
*
|
||||
* RETURNS
|
||||
* the converted GUID
|
||||
* S_OK on success
|
||||
* CO_E_CLASSSTRING if idstr is not a valid CLSID
|
||||
*/
|
||||
HRESULT WINAPI __CLSIDFromStringA(
|
||||
LPCSTR idstr, /* [in] string representation of guid */
|
||||
|
@ -661,15 +691,7 @@ HRESULT WINAPI CLSIDFromString(
|
|||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* WINE_StringFromCLSID [Internal]
|
||||
* Converts a GUID into the respective string representation.
|
||||
*
|
||||
* NOTES
|
||||
*
|
||||
* RETURNS
|
||||
* the string representation and HRESULT
|
||||
*/
|
||||
/* Converts a GUID into the respective string representation. */
|
||||
HRESULT WINE_StringFromCLSID(
|
||||
const CLSID *id, /* [in] GUID to be converted */
|
||||
LPSTR idstr /* [out] pointer to buffer to contain converted guid */
|
||||
|
@ -707,10 +729,13 @@ HRESULT WINE_StringFromCLSID(
|
|||
/******************************************************************************
|
||||
* StringFromCLSID [OLE32.@]
|
||||
* StringFromIID [OLE32.@]
|
||||
*
|
||||
* Converts a GUID into the respective string representation.
|
||||
* The target string is allocated using the OLE IMalloc.
|
||||
*
|
||||
* RETURNS
|
||||
* the string representation and HRESULT
|
||||
* S_OK
|
||||
* E_FAIL
|
||||
*/
|
||||
HRESULT WINAPI StringFromCLSID(
|
||||
REFCLSID id, /* [in] the GUID to be converted */
|
||||
|
@ -720,7 +745,7 @@ HRESULT WINAPI StringFromCLSID(
|
|||
HRESULT ret;
|
||||
LPMALLOC mllc;
|
||||
|
||||
if ((ret=CoGetMalloc(0,&mllc)))
|
||||
if ((ret = CoGetMalloc(0,&mllc)))
|
||||
return ret;
|
||||
|
||||
ret=WINE_StringFromCLSID(id,buf);
|
||||
|
@ -736,15 +761,16 @@ HRESULT WINAPI StringFromCLSID(
|
|||
* StringFromGUID2 [COMPOBJ.76]
|
||||
* StringFromGUID2 [OLE32.@]
|
||||
*
|
||||
* Converts a global unique identifier into a string of an API-
|
||||
* specified fixed format. (The usual {.....} stuff.)
|
||||
* Modified version of StringFromCLSID that allows you to specify max
|
||||
* buffer size.
|
||||
*
|
||||
* RETURNS
|
||||
* The (UNICODE) string representation of the GUID in 'str'
|
||||
* The length of the resulting string, 0 if there was any problem.
|
||||
*/
|
||||
INT WINAPI
|
||||
StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
|
||||
INT WINAPI StringFromGUID2(
|
||||
REFGUID id, /* [in] GUID to convert to string */
|
||||
LPOLESTR str, /* [out] Unicode buffer to hold result */
|
||||
INT cmax)
|
||||
{
|
||||
char xguid[80];
|
||||
|
||||
|
@ -755,11 +781,15 @@ StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
|
|||
|
||||
/******************************************************************************
|
||||
* ProgIDFromCLSID [OLE32.@]
|
||||
* Converts a class id into the respective Program ID. (By using a registry lookup)
|
||||
* RETURNS S_OK on success
|
||||
* riid associated with the progid
|
||||
*
|
||||
* Converts a class id into the respective Program ID. (By using a
|
||||
* registry lookup)
|
||||
*
|
||||
* RETURNS
|
||||
* S_OK
|
||||
* E_OUTOFMEMORY
|
||||
* REGDB_E_CLASSNOTREG if the given clsid has no associated ProgID
|
||||
*/
|
||||
|
||||
HRESULT WINAPI ProgIDFromCLSID(
|
||||
REFCLSID clsid, /* [in] class id as found in registry */
|
||||
LPOLESTR *lplpszProgID/* [out] associated Prog ID */
|
||||
|
@ -805,12 +835,6 @@ HRESULT WINAPI ProgIDFromCLSID(
|
|||
return ret;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CLSIDFromProgID [COMPOBJ.61]
|
||||
* Converts a program id into the respective GUID. (By using a registry lookup)
|
||||
* RETURNS
|
||||
* riid associated with the progid
|
||||
*/
|
||||
HRESULT WINAPI CLSIDFromProgID16(
|
||||
LPCOLESTR16 progid, /* [in] program id as found in registry */
|
||||
LPCLSID riid /* [out] associated CLSID */
|
||||
|
@ -837,13 +861,17 @@ HRESULT WINAPI CLSIDFromProgID16(
|
|||
}
|
||||
|
||||
/******************************************************************************
|
||||
* CLSIDFromProgID [OLE32.@]
|
||||
* Converts a program id into the respective GUID. (By using a registry lookup)
|
||||
* CLSIDFromProgID [COMPOBJ.61]
|
||||
*
|
||||
* Converts a program id into the respective GUID. (By using a
|
||||
* registry lookup)
|
||||
*
|
||||
* RETURNS
|
||||
* riid associated with the progid
|
||||
* S_OK
|
||||
* CO_E_CLASSSTRING if the given ProgID cannot be found
|
||||
*/
|
||||
HRESULT WINAPI CLSIDFromProgID(
|
||||
LPCOLESTR progid, /* [in] program id as found in registry */
|
||||
LPCOLESTR progid, /* [in] Unicode program id as found in registry */
|
||||
LPCLSID riid ) /* [out] associated CLSID */
|
||||
{
|
||||
static const WCHAR clsidW[] = { '\\','C','L','S','I','D',0 };
|
||||
|
@ -875,18 +903,26 @@ HRESULT WINAPI CLSIDFromProgID(
|
|||
/*****************************************************************************
|
||||
* CoGetPSClsid [OLE32.@]
|
||||
*
|
||||
* This function returns the CLSID of the proxy/stub factory that implements IPSFactoryBuffer
|
||||
* for the specified interface.
|
||||
* This function returns the CLSID of the proxy/stub factory that
|
||||
* implements IPSFactoryBuffer for the specified interface.
|
||||
*
|
||||
* The standard marshaller activates the object with the CLSID returned and uses the
|
||||
* CreateProxy and CreateStub methods on its IPSFactoryBuffer interface to construct
|
||||
* the proxies and stubs for a given object.
|
||||
* The standard marshaller activates the object with the CLSID
|
||||
* returned and uses the CreateProxy and CreateStub methods on its
|
||||
* IPSFactoryBuffer interface to construct the proxies and stubs for a
|
||||
* given object.
|
||||
*
|
||||
* CoGetPSClsid determines this CLSID by searching the
|
||||
* HKEY_CLASSES_ROOT\Interface\{string form of riid}\ProxyStubClsid32 in the registry
|
||||
* and any interface id registered by CoRegisterPSClsid within the current process.
|
||||
* HKEY_CLASSES_ROOT\Interface\{string form of riid}\ProxyStubClsid32
|
||||
* in the registry and any interface id registered by
|
||||
* CoRegisterPSClsid within the current process.
|
||||
*
|
||||
* FIXME: We only search the registry, not ids registered with CoRegisterPSClsid.
|
||||
* FIXME: We only search the registry, not ids registered with
|
||||
* CoRegisterPSClsid.
|
||||
*
|
||||
* RETURNS
|
||||
* S_OK
|
||||
* E_OUTOFMEMORY
|
||||
* E_INVALIDARG if no PSFactoryBuffer is associated with the IID, or it could not be parsed
|
||||
*/
|
||||
HRESULT WINAPI CoGetPSClsid(
|
||||
REFIID riid, /* [in] Interface whose proxy/stub CLSID is to be returned */
|
||||
|
@ -1140,28 +1176,39 @@ _LocalServerThread(LPVOID param) {
|
|||
/******************************************************************************
|
||||
* CoRegisterClassObject [OLE32.@]
|
||||
*
|
||||
* This method will register the class object for a given class ID. Servers housed
|
||||
* in EXE files use this method instead of exporting DllGetClassObject to allow other
|
||||
* code to connect to their objects.
|
||||
* This method will register the class object for a given class
|
||||
* ID. Servers housed in EXE files use this method instead of
|
||||
* exporting DllGetClassObject to allow other code to connect to their
|
||||
* objects.
|
||||
*
|
||||
* When a class object (an object which implements IClassFactory) is registered in
|
||||
* this way, a new thread is started which listens for connections on a named pipe
|
||||
* specific to the registered CLSID. When something else connects to it, it writes
|
||||
* out the marshalled IClassFactory interface to the pipe. The code on the other end
|
||||
* uses this buffer to unmarshal the class factory, and can then call methods on it.
|
||||
* When a class object (an object which implements IClassFactory) is
|
||||
* registered in this way, a new thread is started which listens for
|
||||
* connections on a named pipe specific to the registered CLSID. When
|
||||
* something else connects to it, it writes out the marshalled
|
||||
* IClassFactory interface to the pipe. The code on the other end uses
|
||||
* this buffer to unmarshal the class factory, and can then call
|
||||
* methods on it.
|
||||
*
|
||||
* In Windows, such objects are registered with the RPC endpoint mapper, not with
|
||||
* a unique named pipe.
|
||||
* In Windows, such objects are registered with the RPC endpoint
|
||||
* mapper, not with a unique named pipe.
|
||||
*
|
||||
* See the Windows documentation for more details.
|
||||
* MSDN claims that multiple interface registrations are legal, but we
|
||||
* can't do that with our current implementation.
|
||||
*
|
||||
* RETURNS
|
||||
* S_OK on success,
|
||||
* E_INVALIDARG if lpdwRegister or pUnk are NULL,
|
||||
* CO_E_OBJISREG if the object is already registered. We should not return this.
|
||||
*
|
||||
* SEE ALSO
|
||||
* CoRevokeClassObject, CoGetClassObject
|
||||
*/
|
||||
HRESULT WINAPI CoRegisterClassObject(
|
||||
REFCLSID rclsid,
|
||||
LPUNKNOWN pUnk,
|
||||
REFCLSID rclsid, /* [in] CLSID of the object to register */
|
||||
LPUNKNOWN pUnk, /* [in] IUnknown of the object */
|
||||
DWORD dwClsContext, /* [in] CLSCTX flags indicating the context in which to run the executable */
|
||||
DWORD flags, /* [in] REGCLS flags indicating how connections are made */
|
||||
LPDWORD lpdwRegister
|
||||
)
|
||||
LPDWORD lpdwRegister) /* [out] A unique cookie that can be passed to CoRevokeClassObject */
|
||||
{
|
||||
RegisteredClass* newClass;
|
||||
LPUNKNOWN foundObject;
|
||||
|
@ -1178,9 +1225,6 @@ HRESULT WINAPI CoRegisterClassObject(
|
|||
/*
|
||||
* First, check if the class is already registered.
|
||||
* If it is, this should cause an error.
|
||||
*
|
||||
* MSDN claims that multiple interface registrations are legal, but we can't do that with
|
||||
* our current implementation.
|
||||
*/
|
||||
hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject);
|
||||
if (hr == S_OK) {
|
||||
|
@ -1528,6 +1572,8 @@ HRESULT WINAPI CoCreateInstance(
|
|||
HRESULT hres;
|
||||
LPCLASSFACTORY lpclf = 0;
|
||||
|
||||
if (!COM_CurrentApt()) return CO_E_NOTINITIALIZED;
|
||||
|
||||
/*
|
||||
* Sanity check
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue