Autosyncing with Wine HEAD

svn path=/trunk/; revision=27912
This commit is contained in:
The Wine Synchronizer 2007-07-27 09:49:52 +00:00
parent e2d4cbc97d
commit a0b832df14
30 changed files with 548 additions and 345 deletions

View file

@ -31,7 +31,6 @@
#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winnls.h"
#include "wine/debug.h"
#include "ole2.h"
#include "wine/unicode.h"

View file

@ -76,9 +76,10 @@ HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
* TODO: Most of these things will have to be made thread-safe.
*/
static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN* ppUnk);
static void COM_RevokeAllClasses(void);
static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv);
static HRESULT COM_GetRegisteredClassObject(const struct apartment *apt, REFCLSID rclsid,
DWORD dwClsContext, LPUNKNOWN* ppUnk);
static void COM_RevokeAllClasses(const struct apartment *apt);
static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv);
static APARTMENT *MTA; /* protected by csApartment */
static APARTMENT *MainApartment; /* the first STA apartment */
@ -121,6 +122,7 @@ typedef struct tagRegisteredClass
{
struct list entry;
CLSID classIdentifier;
OXID apartment_id;
LPUNKNOWN classObject;
DWORD runContext;
DWORD connectFlags;
@ -186,10 +188,11 @@ static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','
static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
REFCLSID rclsid, REFIID riid, void **ppv);
static void apartment_freeunusedlibraries(struct apartment *apt);
static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret);
static OpenDll *COMPOBJ_DllList_Get(LPCWSTR library_name);
static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry);
static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry, BOOL free_entry);
static DWORD COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *valuename, WCHAR * dst, DWORD dstlen);
@ -325,7 +328,7 @@ static APARTMENT *apartment_get_or_create(DWORD model)
return apt;
}
static inline BOOL apartment_is_model(APARTMENT *apt, DWORD model)
static inline BOOL apartment_is_model(const APARTMENT *apt, DWORD model)
{
return (apt->multi_threaded == !(model & COINIT_APARTMENTTHREADED));
}
@ -361,12 +364,16 @@ DWORD apartment_release(struct apartment *apt)
TRACE("destroying apartment %p, oxid %s\n", apt, wine_dbgstr_longlong(apt->oxid));
/* Release the references to the registered class objects */
COM_RevokeAllClasses(apt);
/* no locking is needed for this apartment, because no other thread
* can access it at this point */
apartment_disconnectproxies(apt);
if (apt->win) DestroyWindow(apt->win);
if (apt->host_apt_tid) PostThreadMessageW(apt->host_apt_tid, WM_QUIT, 0, 0);
LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->stubmgrs)
{
@ -395,10 +402,16 @@ DWORD apartment_release(struct apartment *apt)
if (apt->filter) IUnknown_Release(apt->filter);
/* free as many unused libraries as possible... */
apartment_freeunusedlibraries(apt);
/* ... and free the memory for the apartment loaded dll entry and
* release the dll list reference without freeing the library for the
* rest */
while ((cursor = list_head(&apt->loaded_dlls)))
{
struct apartment_loaded_dll *apartment_loaded_dll = LIST_ENTRY(cursor, struct apartment_loaded_dll, entry);
COMPOBJ_DllList_ReleaseRef(apartment_loaded_dll->dll);
COMPOBJ_DllList_ReleaseRef(apartment_loaded_dll->dll, FALSE);
list_remove(cursor);
HeapFree(GetProcessHeap(), 0, apartment_loaded_dll);
}
@ -462,33 +475,18 @@ APARTMENT *apartment_findfromtid(DWORD tid)
return result;
}
/* gets an apartment which has a given type. The caller must
/* gets the main apartment if it exists. The caller must
* release the reference from the apartment as soon as the apartment pointer
* is no longer required. */
static APARTMENT *apartment_findfromtype(BOOL multi_threaded, BOOL main_apartment)
static APARTMENT *apartment_findmain(void)
{
APARTMENT *result = NULL;
struct apartment *apt;
APARTMENT *result;
EnterCriticalSection(&csApartment);
if (!multi_threaded && main_apartment)
{
result = MainApartment;
if (result) apartment_addref(result);
LeaveCriticalSection(&csApartment);
return result;
}
result = MainApartment;
if (result) apartment_addref(result);
LIST_FOR_EACH_ENTRY( apt, &apts, struct apartment, entry )
{
if (apt->multi_threaded == multi_threaded)
{
result = apt;
apartment_addref(result);
break;
}
}
LeaveCriticalSection(&csApartment);
return result;
@ -499,6 +497,8 @@ struct host_object_params
HKEY hkeydll;
CLSID clsid; /* clsid of object to marshal */
IID iid; /* interface to marshal */
HANDLE event; /* event signalling when ready for multi-threaded case */
HRESULT hr; /* result for multi-threaded case */
IStream *stream; /* stream that the object will be marshaled into */
};
@ -510,7 +510,7 @@ static HRESULT apartment_hostobject(struct apartment *apt,
static const LARGE_INTEGER llZero;
WCHAR dllpath[MAX_PATH+1];
TRACE("\n");
TRACE("clsid %s, iid %s\n", debugstr_guid(&params->clsid), debugstr_guid(&params->iid));
if (COM_RegReadPath(params->hkeydll, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
{
@ -545,6 +545,167 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
}
}
struct host_thread_params
{
COINIT threading_model;
HANDLE ready_event;
HWND apartment_hwnd;
};
static DWORD CALLBACK apartment_hostobject_thread(LPVOID p)
{
struct host_thread_params *params = p;
MSG msg;
HRESULT hr;
struct apartment *apt;
TRACE("\n");
hr = CoInitializeEx(NULL, params->threading_model);
if (FAILED(hr)) return hr;
apt = COM_CurrentApt();
if (params->threading_model == COINIT_APARTMENTTHREADED)
{
apartment_createwindowifneeded(apt);
params->apartment_hwnd = apartment_getwindow(apt);
}
else
params->apartment_hwnd = NULL;
/* force the message queue to be created before signaling parent thread */
PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
SetEvent(params->ready_event);
params = NULL; /* can't touch params after here as it may be invalid */
while (GetMessageW(&msg, NULL, 0, 0))
{
if (!msg.hwnd && (msg.message == DM_HOSTOBJECT))
{
struct host_object_params *params = (struct host_object_params *)msg.lParam;
params->hr = apartment_hostobject(apt, params);
SetEvent(params->event);
}
else
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
}
TRACE("exiting\n");
CoUninitialize();
return S_OK;
}
static HRESULT apartment_hostobject_in_hostapt(struct apartment *apt, BOOL multi_threaded, BOOL main_apartment, HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv)
{
struct host_object_params params;
HWND apartment_hwnd = NULL;
DWORD apartment_tid = 0;
HRESULT hr;
if (!multi_threaded && main_apartment)
{
APARTMENT *host_apt = apartment_findmain();
if (host_apt)
{
apartment_hwnd = apartment_getwindow(host_apt);
apartment_release(host_apt);
}
}
if (!apartment_hwnd)
{
EnterCriticalSection(&apt->cs);
if (!apt->host_apt_tid)
{
struct host_thread_params thread_params;
HANDLE handles[2];
DWORD wait_value;
thread_params.threading_model = multi_threaded ? COINIT_MULTITHREADED : COINIT_APARTMENTTHREADED;
handles[0] = thread_params.ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
thread_params.apartment_hwnd = NULL;
handles[1] = CreateThread(NULL, 0, apartment_hostobject_thread, &thread_params, 0, &apt->host_apt_tid);
if (!handles[1])
{
CloseHandle(handles[0]);
LeaveCriticalSection(&apt->cs);
return E_OUTOFMEMORY;
}
wait_value = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
CloseHandle(handles[0]);
CloseHandle(handles[1]);
if (wait_value == WAIT_OBJECT_0)
apt->host_apt_hwnd = thread_params.apartment_hwnd;
else
{
LeaveCriticalSection(&apt->cs);
return E_OUTOFMEMORY;
}
}
if (multi_threaded || !main_apartment)
{
apartment_hwnd = apt->host_apt_hwnd;
apartment_tid = apt->host_apt_tid;
}
LeaveCriticalSection(&apt->cs);
}
/* another thread may have become the main apartment in the time it took
* us to create the thread for the host apartment */
if (!apartment_hwnd && !multi_threaded && main_apartment)
{
APARTMENT *host_apt = apartment_findmain();
if (host_apt)
{
apartment_hwnd = apartment_getwindow(host_apt);
apartment_release(host_apt);
}
}
params.hkeydll = hkeydll;
params.clsid = *rclsid;
params.iid = *riid;
hr = CreateStreamOnHGlobal(NULL, TRUE, &params.stream);
if (FAILED(hr))
return hr;
if (multi_threaded)
{
params.hr = S_OK;
params.event = CreateEventW(NULL, FALSE, FALSE, NULL);
if (!PostThreadMessageW(apartment_tid, DM_HOSTOBJECT, 0, (LPARAM)&params))
hr = E_OUTOFMEMORY;
else
{
WaitForSingleObject(params.event, INFINITE);
hr = params.hr;
}
CloseHandle(params.event);
}
else
{
if (!apartment_hwnd)
{
ERR("host apartment didn't create window\n");
hr = E_OUTOFMEMORY;
}
else
hr = SendMessageW(apartment_hwnd, DM_HOSTOBJECT, 0, (LPARAM)&params);
}
if (SUCCEEDED(hr))
hr = CoUnmarshalInterface(params.stream, riid, ppv);
IStream_Release(params.stream);
return hr;
}
HRESULT apartment_createwindowifneeded(struct apartment *apt)
{
if (apt->multi_threaded)
@ -568,7 +729,7 @@ HRESULT apartment_createwindowifneeded(struct apartment *apt)
return S_OK;
}
HWND apartment_getwindow(struct apartment *apt)
HWND apartment_getwindow(const struct apartment *apt)
{
assert(!apt->multi_threaded);
return apt->win;
@ -583,10 +744,24 @@ void apartment_joinmta(void)
static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
REFCLSID rclsid, REFIID riid, void **ppv)
{
static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
HRESULT hr = S_OK;
BOOL found = FALSE;
struct apartment_loaded_dll *apartment_loaded_dll;
if (!strcmpiW(dllpath, wszOle32))
{
/* we don't need to control the lifetime of this dll, so use the local
* implementation of DllGetClassObject directly */
TRACE("calling ole32!DllGetClassObject\n");
hr = DllGetClassObject(rclsid, riid, ppv);
if (hr != S_OK)
ERR("DllGetClassObject returned error 0x%08x\n", hr);
return hr;
}
EnterCriticalSection(&apt->cs);
LIST_FOR_EACH_ENTRY(apartment_loaded_dll, &apt->loaded_dlls, struct apartment_loaded_dll, entry)
@ -639,7 +814,7 @@ static void apartment_freeunusedlibraries(struct apartment *apt)
if (entry->dll->DllCanUnloadNow && (entry->dll->DllCanUnloadNow() == S_OK))
{
list_remove(&entry->entry);
COMPOBJ_DllList_ReleaseRef(entry->dll);
COMPOBJ_DllList_ReleaseRef(entry->dll, TRUE);
HeapFree(GetProcessHeap(), 0, entry);
}
}
@ -675,9 +850,9 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret)
return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
}
DllCanUnloadNow = GetProcAddress(hLibrary, "DllCanUnloadNow");
DllCanUnloadNow = (void *)GetProcAddress(hLibrary, "DllCanUnloadNow");
/* Note: failing to find DllCanUnloadNow is not a failure */
DllGetClassObject = GetProcAddress(hLibrary, "DllGetClassObject");
DllGetClassObject = (void *)GetProcAddress(hLibrary, "DllGetClassObject");
if (!DllGetClassObject)
{
/* failure: the dll did not export DllGetClassObject */
@ -741,9 +916,11 @@ static OpenDll *COMPOBJ_DllList_Get(LPCWSTR library_name)
return ret;
}
static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry)
/* pass FALSE for free_entry to release a reference without destroying the
* entry if it reaches zero or TRUE otherwise */
static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry, BOOL free_entry)
{
if (!InterlockedDecrement(&entry->refs))
if (!InterlockedDecrement(&entry->refs) && free_entry)
{
EnterCriticalSection(&csOpenDllList);
list_remove(&entry->entry);
@ -879,31 +1056,6 @@ HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
return hr;
}
/* On COM finalization for a STA thread, the message queue is flushed to ensure no
pending RPCs are ignored. Non-COM messages are discarded at this point.
*/
static void COM_FlushMessageQueue(void)
{
MSG message;
APARTMENT *apt = COM_CurrentApt();
if (!apt || !apt->win) return;
TRACE("Flushing STA message queue\n");
while (PeekMessageA(&message, NULL, 0, 0, PM_REMOVE))
{
if (message.hwnd != apt->win)
{
WARN("discarding message 0x%x for window %p\n", message.message, message.hwnd);
continue;
}
TranslateMessage(&message);
DispatchMessageA(&message);
}
}
/***********************************************************************
* CoUninitialize [OLE32.@]
*
@ -954,15 +1106,6 @@ void WINAPI CoUninitialize(void)
TRACE("() - Releasing the COM libraries\n");
RunningObjectTableImpl_UnInitialize();
/* Release the references to the registered class objects */
COM_RevokeAllClasses();
/* This will free the loaded COM Dlls */
CoFreeAllLibraries();
/* This ensures we deal with any pending RPCs */
COM_FlushMessageQueue();
}
else if (lCOMRefCnt<1) {
ERR( "CoUninitialize() - not CoInitialized.\n" );
@ -1581,10 +1724,8 @@ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
* to normal COM usage, this method will increase the
* reference count on this object.
*/
static HRESULT COM_GetRegisteredClassObject(
REFCLSID rclsid,
DWORD dwClsContext,
LPUNKNOWN* ppUnk)
static HRESULT COM_GetRegisteredClassObject(const struct apartment *apt, REFCLSID rclsid,
DWORD dwClsContext, LPUNKNOWN* ppUnk)
{
HRESULT hr = S_FALSE;
RegisteredClass *curClass;
@ -1601,7 +1742,8 @@ static HRESULT COM_GetRegisteredClassObject(
/*
* Check if we have a match on the class ID and context.
*/
if ((dwClsContext & curClass->runContext) &&
if ((apt->oxid == curClass->apartment_id) &&
(dwClsContext & curClass->runContext) &&
IsEqualGUID(&(curClass->classIdentifier), rclsid))
{
/*
@ -1643,6 +1785,11 @@ static HRESULT COM_GetRegisteredClassObject(
* SEE ALSO
* CoRevokeClassObject, CoGetClassObject
*
* NOTES
* In-process objects are only registered for the current apartment.
* CoGetClassObject() and CoCreateInstance() will not return objects registered
* in other apartments.
*
* BUGS
* MSDN claims that multiple interface registrations are legal, but we
* can't do that with our current implementation.
@ -1657,6 +1804,7 @@ HRESULT WINAPI CoRegisterClassObject(
RegisteredClass* newClass;
LPUNKNOWN foundObject;
HRESULT hr;
APARTMENT *apt;
TRACE("(%s,%p,0x%08x,0x%08x,%p)\n",
debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister);
@ -1664,7 +1812,8 @@ HRESULT WINAPI CoRegisterClassObject(
if ( (lpdwRegister==0) || (pUnk==0) )
return E_INVALIDARG;
if (!COM_CurrentApt())
apt = COM_CurrentApt();
if (!apt)
{
ERR("COM was not initialized\n");
return CO_E_NOTINITIALIZED;
@ -1681,7 +1830,7 @@ HRESULT WINAPI CoRegisterClassObject(
* First, check if the class is already registered.
* If it is, this should cause an error.
*/
hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject);
hr = COM_GetRegisteredClassObject(apt, rclsid, dwClsContext, &foundObject);
if (hr == S_OK) {
if (flags & REGCLS_MULTIPLEUSE) {
if (dwClsContext & CLSCTX_LOCAL_SERVER)
@ -1699,6 +1848,7 @@ HRESULT WINAPI CoRegisterClassObject(
return E_OUTOFMEMORY;
newClass->classIdentifier = *rclsid;
newClass->apartment_id = apt->oxid;
newClass->runContext = dwClsContext;
newClass->connectFlags = flags;
newClass->pMarshaledData = NULL;
@ -1724,29 +1874,19 @@ HRESULT WINAPI CoRegisterClassObject(
*lpdwRegister = newClass->dwCookie;
if (dwClsContext & CLSCTX_LOCAL_SERVER) {
IClassFactory *classfac;
hr = IUnknown_QueryInterface(newClass->classObject, &IID_IClassFactory,
(LPVOID*)&classfac);
if (hr) return hr;
hr = CreateStreamOnHGlobal(0, TRUE, &newClass->pMarshaledData);
if (hr) {
FIXME("Failed to create stream on hglobal, %x\n", hr);
IUnknown_Release(classfac);
return hr;
}
hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IClassFactory,
(LPVOID)classfac, MSHCTX_LOCAL, NULL,
newClass->classObject, MSHCTX_LOCAL, NULL,
MSHLFLAGS_TABLESTRONG);
if (hr) {
FIXME("CoMarshalInterface failed, %x!\n",hr);
IUnknown_Release(classfac);
return hr;
}
IUnknown_Release(classfac);
hr = RPC_StartLocalServer(&newClass->classIdentifier,
newClass->pMarshaledData,
flags & (REGCLS_MULTIPLEUSE|REGCLS_MULTI_SEPARATE),
@ -1755,6 +1895,44 @@ HRESULT WINAPI CoRegisterClassObject(
return S_OK;
}
static void COM_RevokeRegisteredClassObject(RegisteredClass *curClass)
{
list_remove(&curClass->entry);
if (curClass->runContext & CLSCTX_LOCAL_SERVER)
RPC_StopLocalServer(curClass->RpcRegistration);
/*
* Release the reference to the class object.
*/
IUnknown_Release(curClass->classObject);
if (curClass->pMarshaledData)
{
LARGE_INTEGER zero;
memset(&zero, 0, sizeof(zero));
IStream_Seek(curClass->pMarshaledData, zero, STREAM_SEEK_SET, NULL);
CoReleaseMarshalData(curClass->pMarshaledData);
}
HeapFree(GetProcessHeap(), 0, curClass);
}
static void COM_RevokeAllClasses(const struct apartment *apt)
{
RegisteredClass *curClass, *cursor;
EnterCriticalSection( &csRegisteredClassList );
LIST_FOR_EACH_ENTRY_SAFE(curClass, cursor, &RegisteredClassList, RegisteredClass, entry)
{
if (curClass->apartment_id == apt->oxid)
COM_RevokeRegisteredClassObject(curClass);
}
LeaveCriticalSection( &csRegisteredClassList );
}
/***********************************************************************
* CoRevokeClassObject [OLE32.@]
*
@ -1767,6 +1945,10 @@ HRESULT WINAPI CoRegisterClassObject(
* Success: S_OK.
* Failure: HRESULT code.
*
* NOTES
* Must be called from the same apartment that called CoRegisterClassObject(),
* otherwise it will fail with RPC_E_WRONG_THREAD.
*
* SEE ALSO
* CoRegisterClassObject
*/
@ -1775,9 +1957,17 @@ HRESULT WINAPI CoRevokeClassObject(
{
HRESULT hr = E_INVALIDARG;
RegisteredClass *curClass;
APARTMENT *apt;
TRACE("(%08x)\n",dwRegister);
apt = COM_CurrentApt();
if (!apt)
{
ERR("COM was not initialized\n");
return CO_E_NOTINITIALIZED;
}
EnterCriticalSection( &csRegisteredClassList );
LIST_FOR_EACH_ENTRY(curClass, &RegisteredClassList, RegisteredClass, entry)
@ -1787,30 +1977,17 @@ HRESULT WINAPI CoRevokeClassObject(
*/
if (curClass->dwCookie == dwRegister)
{
list_remove(&curClass->entry);
if (curClass->runContext & CLSCTX_LOCAL_SERVER)
RPC_StopLocalServer(curClass->RpcRegistration);
/*
* Release the reference to the class object.
*/
IUnknown_Release(curClass->classObject);
if (curClass->pMarshaledData)
if (curClass->apartment_id == apt->oxid)
{
LARGE_INTEGER zero;
memset(&zero, 0, sizeof(zero));
IStream_Seek(curClass->pMarshaledData, zero, STREAM_SEEK_SET, NULL);
CoReleaseMarshalData(curClass->pMarshaledData);
COM_RevokeRegisteredClassObject(curClass);
hr = S_OK;
}
else
{
ERR("called from wrong apartment, should be called from %s\n",
wine_dbgstr_longlong(curClass->apartment_id));
hr = RPC_E_WRONG_THREAD;
}
/*
* Free the memory used by the chain node.
*/
HeapFree(GetProcessHeap(), 0, curClass);
hr = S_OK;
break;
}
}
@ -1858,53 +2035,27 @@ static void get_threading_model(HKEY key, LPWSTR value, DWORD len)
value[0] = '\0';
}
static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv)
static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll,
REFCLSID rclsid, REFIID riid, void **ppv)
{
static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0};
static const WCHAR wszFree[] = {'F','r','e','e',0};
static const WCHAR wszBoth[] = {'B','o','t','h',0};
WCHAR dllpath[MAX_PATH+1];
WCHAR threading_model[10 /* strlenW(L"apartment")+1 */];
HRESULT hr;
APARTMENT *apt = COM_CurrentApt();
get_threading_model(hkeydll, threading_model, ARRAYSIZE(threading_model));
/* "Apartment" */
if (!strcmpiW(threading_model, wszApartment))
{
if (apt->multi_threaded)
{
/* try to find an STA */
APARTMENT *host_apt = apartment_findfromtype(FALSE, FALSE);
if (!host_apt)
FIXME("create a host apartment for apartment-threaded object %s\n", debugstr_guid(rclsid));
if (host_apt)
{
struct host_object_params params;
HWND hwnd = apartment_getwindow(host_apt);
params.hkeydll = hkeydll;
params.clsid = *rclsid;
params.iid = *riid;
hr = CreateStreamOnHGlobal(NULL, TRUE, &params.stream);
if (FAILED(hr))
return hr;
hr = SendMessageW(hwnd, DM_HOSTOBJECT, 0, (LPARAM)&params);
if (SUCCEEDED(hr))
hr = CoUnmarshalInterface(params.stream, riid, ppv);
IStream_Release(params.stream);
return hr;
}
}
return apartment_hostobject_in_hostapt(apt, FALSE, FALSE, hkeydll, rclsid, riid, ppv);
}
/* "Free" */
else if (!strcmpiW(threading_model, wszFree))
{
if (!apt->multi_threaded)
{
FIXME("should create object %s in multi-threaded apartment\n",
debugstr_guid(rclsid));
}
return apartment_hostobject_in_hostapt(apt, TRUE, FALSE, hkeydll, rclsid, riid, ppv);
}
/* everything except "Apartment", "Free" and "Both" */
else if (strcmpiW(threading_model, wszBoth))
@ -1915,29 +2066,7 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
debugstr_w(threading_model), debugstr_guid(rclsid));
if (apt->multi_threaded || !apt->main)
{
/* try to find an STA */
APARTMENT *host_apt = apartment_findfromtype(FALSE, TRUE);
if (!host_apt)
FIXME("create a host apartment for main-threaded object %s\n", debugstr_guid(rclsid));
if (host_apt)
{
struct host_object_params params;
HWND hwnd = apartment_getwindow(host_apt);
params.hkeydll = hkeydll;
params.clsid = *rclsid;
params.iid = *riid;
hr = CreateStreamOnHGlobal(NULL, TRUE, &params.stream);
if (FAILED(hr))
return hr;
hr = SendMessageW(hwnd, DM_HOSTOBJECT, 0, (LPARAM)&params);
if (SUCCEEDED(hr))
hr = CoUnmarshalInterface(params.stream, riid, ppv);
IStream_Release(params.stream);
return hr;
}
}
return apartment_hostobject_in_hostapt(apt, FALSE, TRUE, hkeydll, rclsid, riid, ppv);
}
if (COM_RegReadPath(hkeydll, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
@ -1982,6 +2111,7 @@ HRESULT WINAPI CoGetClassObject(
{
LPUNKNOWN regClassObject;
HRESULT hres = E_UNEXPECTED;
APARTMENT *apt;
TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
@ -1990,7 +2120,8 @@ HRESULT WINAPI CoGetClassObject(
*ppv = NULL;
if (!COM_CurrentApt())
apt = COM_CurrentApt();
if (!apt)
{
ERR("apartment not initialised\n");
return CO_E_NOTINITIALIZED;
@ -2005,7 +2136,8 @@ HRESULT WINAPI CoGetClassObject(
* First, try and see if we can't match the class ID with one of the
* registered classes.
*/
if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, &regClassObject))
if (S_OK == COM_GetRegisteredClassObject(apt, rclsid, dwClsContext,
&regClassObject))
{
/* Get the required interface from the retrieved pointer. */
hres = IUnknown_QueryInterface(regClassObject, iid, ppv);
@ -2034,13 +2166,16 @@ HRESULT WINAPI CoGetClassObject(
{
if (hres == REGDB_E_CLASSNOTREG)
ERR("class %s not registered\n", debugstr_guid(rclsid));
else
else if (hres == REGDB_E_KEYMISSING)
{
WARN("class %s not registered as in-proc server\n", debugstr_guid(rclsid));
hres = REGDB_E_CLASSNOTREG;
}
}
if (SUCCEEDED(hres))
{
hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
hres = get_inproc_class_object(apt, hkey, rclsid, iid, ppv);
RegCloseKey(hkey);
}
@ -2061,13 +2196,16 @@ HRESULT WINAPI CoGetClassObject(
{
if (hres == REGDB_E_CLASSNOTREG)
ERR("class %s not registered\n", debugstr_guid(rclsid));
else
else if (hres == REGDB_E_KEYMISSING)
{
WARN("class %s not registered in-proc handler\n", debugstr_guid(rclsid));
hres = REGDB_E_CLASSNOTREG;
}
}
if (SUCCEEDED(hres))
{
hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
hres = get_inproc_class_object(apt, hkey, rclsid, iid, ppv);
RegCloseKey(hkey);
}
@ -2388,20 +2526,6 @@ HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime )
return S_OK;
}
static void COM_RevokeAllClasses(void)
{
EnterCriticalSection( &csRegisteredClassList );
while (list_head(&RegisteredClassList))
{
RegisteredClass *curClass = LIST_ENTRY(list_head(&RegisteredClassList),
RegisteredClass, entry);
CoRevokeClassObject(curClass->dwCookie);
}
LeaveCriticalSection( &csRegisteredClassList );
}
/******************************************************************************
* CoLockObjectExternal [OLE32.@]
*

View file

@ -158,6 +158,8 @@ struct apartment
LONG remoting_started; /* has the RPC system been started for this apartment? (LOCK) */
struct list psclsids; /* list of registered PS CLSIDs (CS cs) */
struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
DWORD host_apt_tid; /* thread ID of apartment hosting objects of differing threading model (CS cs) */
HWND host_apt_hwnd; /* handle to apartment window of host apartment (CS cs) */
/* FIXME: OID's should be given out by RPCSS */
OID oidc; /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
@ -253,13 +255,13 @@ DWORD apartment_addref(struct apartment *apt);
DWORD apartment_release(struct apartment *apt);
HRESULT apartment_disconnectproxies(struct apartment *apt);
void apartment_disconnectobject(struct apartment *apt, void *object);
static inline HRESULT apartment_getoxid(struct apartment *apt, OXID *oxid)
static inline HRESULT apartment_getoxid(const struct apartment *apt, OXID *oxid)
{
*oxid = apt->oxid;
return S_OK;
}
HRESULT apartment_createwindowifneeded(struct apartment *apt);
HWND apartment_getwindow(struct apartment *apt);
HWND apartment_getwindow(const struct apartment *apt);
void apartment_joinmta(void);

View file

@ -126,8 +126,8 @@ void dictionary_insert(struct dictionary *d, const void *k, const void *v)
}
else
{
struct dictionary_entry *elem = (struct dictionary_entry *)
HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary_entry));
struct dictionary_entry *elem = HeapAlloc(GetProcessHeap(), 0,
sizeof(struct dictionary_entry));
if (!elem)
return;

View file

@ -189,7 +189,7 @@ enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
*
* Add an element to the enumeration.
*/
void *enumx_add_element(enumx_impl *enumx, void *data)
void *enumx_add_element(enumx_impl *enumx, const void *data)
{
struct list *element;

View file

@ -29,6 +29,6 @@ extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG);
extern HRESULT WINAPI enumx_Reset(enumx_impl *);
extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **);
extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG);
extern void *enumx_add_element(enumx_impl *, void *);
extern void *enumx_add_element(enumx_impl *, const void *);
#endif

View file

@ -465,8 +465,18 @@ static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable =
ISupportErrorInfoImpl_InterfaceSupportsErrorInfo
};
/***********************************************************************
* CreateErrorInfo (OLE32.@)
*
* Creates an object used to set details for an error info object.
*
* PARAMS
* pperrinfo [O]. Address where error info creation object will be stored.
*
* RETURNS
* Success: S_OK.
* Failure: HRESULT code.
*/
HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
{
@ -483,6 +493,21 @@ HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
/***********************************************************************
* GetErrorInfo (OLE32.@)
*
* Retrieves the error information object for the current thread.
*
* PARAMS
* dwReserved [I]. Reserved. Must be zero.
* pperrinfo [O]. Address where error information object will be stored on return.
*
* RETURNS
* Success: S_OK if an error information object was set for the current thread.
* S_FALSE if otherwise.
* Failure: E_INVALIDARG if dwReserved is not zero.
*
* NOTES
* This function causes the current error info object for the thread to be
* cleared if one was set beforehand.
*/
HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
{
@ -511,6 +536,16 @@ HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
/***********************************************************************
* SetErrorInfo (OLE32.@)
*
* Sets the error information object for the current thread.
*
* PARAMS
* dwReserved [I] Reserved. Must be zero.
* perrinfo [I] Error info object.
*
* RETURNS
* Success: S_OK.
* Failure: E_INVALIDARG if dwReserved is not zero.
*/
HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
{

View file

@ -1011,19 +1011,27 @@ FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** p
int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
{
static const WCHAR bSlash[] = {'\\',0};
WCHAR word[MAX_PATH];
int i=0,j,tabIndex=0;
LPOLESTR word;
int i=0,j,tabIndex=0, ret=0;
LPOLESTR *strgtable ;
int len=lstrlenW(str);
TRACE("%s, %p\n", debugstr_w(str), *stringTable);
strgtable =CoTaskMemAlloc(len*sizeof(LPOLESTR));
strgtable = CoTaskMemAlloc(len*sizeof(WCHAR));
if (strgtable==NULL)
return E_OUTOFMEMORY;
word = CoTaskMemAlloc((len + 1)*sizeof(WCHAR));
if (word==NULL)
{
ret = E_OUTOFMEMORY;
goto lend;
}
while(str[i]!=0){
if(str[i]==bSlash[0]){
@ -1031,7 +1039,10 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR));
if (strgtable[tabIndex]==NULL)
return E_OUTOFMEMORY;
{
ret = E_OUTOFMEMORY;
goto lend;
}
strcpyW(strgtable[tabIndex++],bSlash);
@ -1048,7 +1059,10 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
strgtable[tabIndex]=CoTaskMemAlloc(sizeof(WCHAR)*(j+1));
if (strgtable[tabIndex]==NULL)
return E_OUTOFMEMORY;
{
ret = E_OUTOFMEMORY;
goto lend;
}
strcpyW(strgtable[tabIndex++],word);
}
@ -1057,7 +1071,21 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
*stringTable=strgtable;
return tabIndex;
ret = tabIndex;
lend:
if (ret < 0)
{
for (i = 0; i < tabIndex; i++)
CoTaskMemFree(strgtable[i]);
CoTaskMemFree(strgtable);
}
if (word)
CoTaskMemFree(word);
return ret;
}
/******************************************************************************

View file

@ -96,7 +96,7 @@ static void StdGlobalInterfaceTable_Destroy(void* self)
/***
* A helper function to traverse the list and find the entry that matches the cookie.
* Returns NULL if not found
* Returns NULL if not found. Must be called inside git_section critical section.
*/
static StdGITEntry*
StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
@ -106,14 +106,10 @@ StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
TRACE("iface=%p, cookie=0x%x\n", iface, (UINT)cookie);
EnterCriticalSection(&git_section);
LIST_FOR_EACH_ENTRY(e, &self->list, StdGITEntry, entry) {
if (e->cookie == cookie) {
LeaveCriticalSection(&git_section);
if (e->cookie == cookie)
return e;
}
}
LeaveCriticalSection(&git_section);
TRACE("Entry not found\n");
return NULL;
@ -232,12 +228,19 @@ StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
HRESULT hr;
TRACE("iface=%p, dwCookie=0x%x\n", iface, (UINT)dwCookie);
EnterCriticalSection(&git_section);
entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
if (entry == NULL) {
TRACE("Entry not found\n");
LeaveCriticalSection(&git_section);
return E_INVALIDARG; /* not found */
}
list_remove(&entry->entry);
LeaveCriticalSection(&git_section);
/* Free the stream */
hr = CoReleaseMarshalData(entry->stream);
@ -248,11 +251,6 @@ StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
}
IStream_Release(entry->stream);
/* chop entry out of the list, and free the memory */
EnterCriticalSection(&git_section);
list_remove(&entry->entry);
LeaveCriticalSection(&git_section);
HeapFree(GetProcessHeap(), 0, entry);
return S_OK;
}
@ -264,36 +262,39 @@ StdGlobalInterfaceTable_GetInterfaceFromGlobal(
{
StdGITEntry* entry;
HRESULT hres;
LARGE_INTEGER move;
LPUNKNOWN lpUnk;
TRACE("dwCookie=0x%x, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
if (entry == NULL) return E_INVALIDARG;
IStream *stream;
if (!IsEqualIID(&entry->iid, riid)) {
WARN("entry->iid (%s) != riid\n", debugstr_guid(&entry->iid));
TRACE("dwCookie=0x%x, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
EnterCriticalSection(&git_section);
entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
if (entry == NULL) {
WARN("Entry for cookie 0x%x not found\n", dwCookie);
LeaveCriticalSection(&git_section);
return E_INVALIDARG;
}
TRACE("entry=%p\n", entry);
hres = IStream_Clone(entry->stream, &stream);
LeaveCriticalSection(&git_section);
if (hres) {
WARN("Failed to clone stream with error 0x%08x\n", hres);
return hres;
}
/* unmarshal the interface */
hres = CoUnmarshalInterface(entry->stream, riid, ppv);
/* rewind stream, in case it's used again */
move.u.LowPart = 0;
move.u.HighPart = 0;
IStream_Seek(entry->stream, move, STREAM_SEEK_SET, NULL);
hres = CoUnmarshalInterface(stream, riid, ppv);
IStream_Release(stream);
if (hres) {
WARN("Failed to unmarshal stream\n");
return hres;
}
/* addref it */
lpUnk = *ppv;
IUnknown_AddRef(lpUnk);
TRACE("ppv=%p\n", *ppv);
return S_OK;
}

View file

@ -39,7 +39,6 @@
#include "objbase.h"
#include "ole2.h"
#include "winerror.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/debug.h"
@ -234,6 +233,12 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
* Lock the buffer in position and copy the data.
*/
supportBuffer = GlobalLock(This->supportHandle);
if (!supportBuffer)
{
WARN("read from invalid hglobal %p\n", This->supportHandle);
*pcbRead = 0;
return S_OK;
}
memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
@ -294,6 +299,8 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
if (cb == 0)
goto out;
*pcbWritten = 0;
newSize.u.HighPart = 0;
newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
@ -315,6 +322,11 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
* Lock the buffer in position and copy the data.
*/
supportBuffer = GlobalLock(This->supportHandle);
if (!supportBuffer)
{
WARN("write to invalid hglobal %p\n", This->supportHandle);
return S_OK;
}
memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);

View file

@ -56,7 +56,7 @@ typedef struct {
DWORD SpyedAllocationsLeft; /* number of spyed allocations left */
BOOL SpyReleasePending; /* CoRevokeMallocSpy called with spyed allocations left*/
LPVOID * SpyedBlocks; /* root of the table */
int SpyedBlockTableLength; /* size of the table*/
DWORD SpyedBlockTableLength;/* size of the table*/
} _Malloc32;
/* this is the static object instance */
@ -73,7 +73,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 };
/* resize the old table */
static int SetSpyedBlockTableLength ( int NewLength )
static int SetSpyedBlockTableLength ( DWORD NewLength )
{
LPVOID *NewSpyedBlocks;
@ -103,7 +103,9 @@ static int AddMemoryLocation(LPVOID * pMem)
Current++;
if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
/* no more space in table, grow it */
DWORD old_length = Malloc32.SpyedBlockTableLength;
if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0;
Current = Malloc32.SpyedBlocks + old_length;
}
};
@ -114,7 +116,7 @@ static int AddMemoryLocation(LPVOID * pMem)
return 1;
}
static int RemoveMemoryLocation(LPVOID * pMem)
static int RemoveMemoryLocation(LPCVOID pMem)
{
LPVOID * Current;

View file

@ -283,6 +283,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
{
hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
nonlocal_mqis, iids, &qiresults);
IRemUnknown_Release(remunk);
if (FAILED(hr))
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
}
@ -297,7 +298,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
ULONG index = mapping[i];
HRESULT hrobj = qiresults[i].hResult;
if (hrobj == S_OK)
hrobj = unmarshal_object(&qiresults[i].std, This->parent,
hrobj = unmarshal_object(&qiresults[i].std, COM_CurrentApt(),
This->dest_context,
This->dest_context_data,
pMQIs[index].pIID, &This->oxid_info,
@ -375,22 +376,29 @@ static HRESULT WINAPI Proxy_MarshalInterface(
if (SUCCEEDED(hr))
{
STDOBJREF stdobjref = ifproxy->stdobjref;
ULONG cPublicRefs = ifproxy->refs;
ULONG cPublicRefsOld;
/* optimization - share out proxy's public references if possible
* instead of making new proxy do a roundtrip through the server */
do
stdobjref.cPublicRefs = 0;
if ((mshlflags != MSHLFLAGS_TABLEWEAK) &&
(mshlflags != MSHLFLAGS_TABLESTRONG))
{
ULONG cPublicRefsNew;
cPublicRefsOld = cPublicRefs;
stdobjref.cPublicRefs = cPublicRefs / 2;
cPublicRefsNew = cPublicRefs - stdobjref.cPublicRefs;
cPublicRefs = InterlockedCompareExchange(
(LONG *)&ifproxy->refs, cPublicRefsNew, cPublicRefsOld);
} while (cPublicRefs != cPublicRefsOld);
ULONG cPublicRefs = ifproxy->refs;
ULONG cPublicRefsOld;
/* optimization - share out proxy's public references if possible
* instead of making new proxy do a roundtrip through the server */
do
{
ULONG cPublicRefsNew;
cPublicRefsOld = cPublicRefs;
stdobjref.cPublicRefs = cPublicRefs / 2;
cPublicRefsNew = cPublicRefs - stdobjref.cPublicRefs;
cPublicRefs = InterlockedCompareExchange(
(LONG *)&ifproxy->refs, cPublicRefsNew, cPublicRefsOld);
} while (cPublicRefs != cPublicRefsOld);
}
if (!stdobjref.cPublicRefs)
/* normal and table-strong marshaling need at least one reference */
if (!stdobjref.cPublicRefs && (mshlflags != MSHLFLAGS_TABLEWEAK))
{
IRemUnknown *remunk;
hr = proxy_manager_get_remunknown(This, &remunk);
@ -399,11 +407,17 @@ static HRESULT WINAPI Proxy_MarshalInterface(
HRESULT hrref = S_OK;
REMINTERFACEREF rif;
rif.ipid = ifproxy->stdobjref.ipid;
rif.cPublicRefs = NORMALEXTREFS;
rif.cPublicRefs = (mshlflags == MSHLFLAGS_TABLESTRONG) ? 1 : NORMALEXTREFS;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
IRemUnknown_Release(remunk);
if (hr == S_OK && hrref == S_OK)
stdobjref.cPublicRefs = rif.cPublicRefs;
{
/* table-strong marshaling doesn't give the refs to the
* client that unmarshals the STDOBJREF */
if (mshlflags != MSHLFLAGS_TABLESTRONG)
stdobjref.cPublicRefs = rif.cPublicRefs;
}
else
ERR("IRemUnknown_RemAddRef returned with 0x%08x, hrref = 0x%08x\n", hr, hrref);
}
@ -455,6 +469,7 @@ static HRESULT WINAPI Proxy_MarshalInterface(
}
else
ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
IRemUnknown_Release(remunk);
}
}
@ -565,6 +580,7 @@ static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
rif.cPublicRefs = NORMALEXTREFS;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
IRemUnknown_Release(remunk);
if (hr == S_OK && hrref == S_OK)
InterlockedExchangeAdd((LONG *)&This->refs, NORMALEXTREFS);
else
@ -602,6 +618,7 @@ static HRESULT ifproxy_release_public_refs(struct ifproxy * This)
rif.cPublicRefs = public_refs;
rif.cPrivateRefs = 0;
hr = IRemUnknown_RemRelease(remunk, 1, &rif);
IRemUnknown_Release(remunk);
if (hr == S_OK)
InterlockedExchangeAdd((LONG *)&This->refs, -public_refs);
else if (hr == RPC_E_DISCONNECTED)
@ -947,16 +964,30 @@ static void proxy_manager_disconnect(struct proxy_manager * This)
static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnknown **remunk)
{
HRESULT hr = S_OK;
struct apartment *apt;
BOOL called_in_original_apt;
/* we don't want to try and unmarshal or use IRemUnknown if we don't want
* lifetime management */
if (This->sorflags & SORFP_NOLIFETIMEMGMT)
return S_FALSE;
apt = COM_CurrentApt();
if (!apt)
return CO_E_NOTINITIALIZED;
called_in_original_apt = This->parent && (This->parent->oxid == apt->oxid);
EnterCriticalSection(&This->cs);
if (This->remunk)
/* only return the cached object if called from the original apartment.
* in future, we might want to make the IRemUnknown proxy callable from any
* apartment to avoid these checks */
if (This->remunk && called_in_original_apt)
{
/* already created - return existing object */
*remunk = This->remunk;
IRemUnknown_AddRef(*remunk);
}
else if (!This->parent)
/* disconnected - we can't create IRemUnknown */
hr = S_FALSE;
@ -974,11 +1005,14 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
stdobjref.ipid = This->oxid_info.ipidRemUnknown;
/* do the unmarshal */
hr = unmarshal_object(&stdobjref, This->parent, This->dest_context,
hr = unmarshal_object(&stdobjref, COM_CurrentApt(), This->dest_context,
This->dest_context_data, &IID_IRemUnknown,
&This->oxid_info, (void**)&This->remunk);
if (hr == S_OK)
*remunk = This->remunk;
&This->oxid_info, (void**)remunk);
if (hr == S_OK && called_in_original_apt)
{
This->remunk = *remunk;
IRemUnknown_AddRef(This->remunk);
}
}
LeaveCriticalSection(&This->cs);

View file

@ -35,7 +35,6 @@
#include "winuser.h"
#include "objbase.h"
#include "ole2.h"
#include "ole2ver.h"
#include "rpc.h"
#include "winerror.h"
#include "winreg.h"

View file

@ -41,10 +41,8 @@
#include "winuser.h"
#include "winnls.h"
#include "winreg.h"
#include "commctrl.h"
#include "ole2.h"
#include "ole2ver.h"
#include "wownt32.h"
#include "wine/unicode.h"
#include "compobj_private.h"
@ -149,7 +147,7 @@ extern void OLEClipbrd_Initialize(void);
static void OLEDD_Initialize(void);
static DropTargetNode* OLEDD_FindDropTarget(
HWND hwndOfTarget);
static void OLEDD_FreeDropTarget(DropTargetNode*);
static void OLEDD_FreeDropTarget(DropTargetNode*, BOOL);
static LRESULT WINAPI OLEDD_DragTrackerWindowProc(
HWND hwnd,
UINT uMsg,
@ -355,7 +353,7 @@ HRESULT WINAPI RevokeDragDrop(
if (dropTargetInfo==NULL)
return DRAGDROP_E_NOTREGISTERED;
OLEDD_FreeDropTarget(dropTargetInfo);
OLEDD_FreeDropTarget(dropTargetInfo, TRUE);
return S_OK;
}
@ -1389,7 +1387,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar
OleMenuHookItem *pHookItem = NULL;
WORD fuFlags;
TRACE("%i, %04x, %08x\n", code, wParam, (unsigned)lParam );
TRACE("%i, %04lx, %08lx\n", code, wParam, lParam );
/* Check if we're being asked to process the message */
if ( HC_ACTION != code )
@ -1494,7 +1492,7 @@ static LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lPara
OleMenuHookItem *pHookItem = NULL;
WORD wCode;
TRACE("%i, %04x, %08x\n", code, wParam, (unsigned)lParam );
TRACE("%i, %04lx, %08lx\n", code, wParam, lParam );
/* Check if we're being asked to process a messages */
if ( HC_ACTION != code )
@ -1713,9 +1711,8 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
return FALSE;
}
if((lpMsg->message != WM_KEYDOWN &&
lpMsg->message != WM_KEYUP &&
lpMsg->message != WM_SYSKEYDOWN &&
lpMsg->message != WM_SYSKEYUP &&
lpMsg->message != WM_SYSCHAR &&
lpMsg->message != WM_CHAR)) return FALSE;
lpAccelTbl = HeapAlloc(GetProcessHeap(), 0, cAccelEntries * sizeof(ACCEL));
if (NULL == lpAccelTbl)
@ -1730,7 +1727,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
}
TRACE_(accel)("hAccel=%p, cAccelEntries=%d,"
"msg->hwnd=%p, msg->message=%04x, wParam=%08x, lParam=%08lx\n",
"msg->hwnd=%p, msg->message=%04x, wParam=%08lx, lParam=%08lx\n",
hAccel, cAccelEntries,
lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
for(i = 0; i < cAccelEntries; i++)
@ -1742,7 +1739,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
{
if(!(lpAccelTbl[i].fVirt & FALT) && !(lpAccelTbl[i].fVirt & FVIRTKEY))
{
TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", lpMsg->wParam & 0xff);
TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", LOWORD(lpMsg->wParam) & 0xff);
goto found;
}
}
@ -1751,7 +1748,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
if(lpAccelTbl[i].fVirt & FVIRTKEY)
{
INT mask = 0;
TRACE_(accel)("found accel for virt_key %04x (scan %04x)\n",
TRACE_(accel)("found accel for virt_key %04lx (scan %04x)\n",
lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff);
if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
@ -1765,7 +1762,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
{
if((lpAccelTbl[i].fVirt & FALT) && (lpMsg->lParam & 0x20000000))
{ /* ^^ ALT pressed */
TRACE_(accel)("found accel for Alt-%c\n", lpMsg->wParam & 0xff);
TRACE_(accel)("found accel for Alt-%c\n", LOWORD(lpMsg->wParam) & 0xff);
goto found;
}
}
@ -1897,10 +1894,10 @@ static void OLEDD_Initialize(void)
*
* Frees the drag and drop data structure
*/
static void OLEDD_FreeDropTarget(DropTargetNode *dropTargetInfo)
static void OLEDD_FreeDropTarget(DropTargetNode *dropTargetInfo, BOOL release_drop_target)
{
list_remove(&dropTargetInfo->entry);
IDropTarget_Release(dropTargetInfo->dropTarget);
if (release_drop_target) IDropTarget_Release(dropTargetInfo->dropTarget);
HeapFree(GetProcessHeap(), 0, dropTargetInfo);
}
@ -1916,9 +1913,8 @@ void OLEDD_UnInitialize(void)
*/
while (!list_empty(&targetListHead))
{
DropTargetNode* curNode;
curNode = LIST_ENTRY(list_head(&targetListHead), DropTargetNode, entry);
OLEDD_FreeDropTarget(curNode);
DropTargetNode* curNode = LIST_ENTRY(list_head(&targetListHead), DropTargetNode, entry);
OLEDD_FreeDropTarget(curNode, FALSE);
}
}
@ -2601,7 +2597,7 @@ BSTR WINAPI PropSysAllocString(LPCOLESTR str)
* string.
*/
stringBuffer = (WCHAR*)newBuffer;
stringBuffer[len] = L'\0';
stringBuffer[len] = '\0';
return (LPWSTR)stringBuffer;
}

View file

@ -35,12 +35,8 @@
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"
#include "winnls.h"
#include "commctrl.h"
#include "ole2.h"
#include "ole2ver.h"
#include "winerror.h"
#include "wownt32.h"
#include "wine/winbase16.h"
#include "wine/wingdi16.h"

View file

@ -32,7 +32,6 @@
#include "wine/debug.h"
#include "ole2.h"
#include "olestd.h"
#include "winreg.h"
WINE_DEFAULT_DEBUG_CHANNEL(ole);

View file

@ -31,11 +31,8 @@
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winnls.h"
#include "winreg.h"
#include "winuser.h"
#include "winver.h"
#include "wine/winbase16.h"

View file

@ -2,7 +2,6 @@
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
<importlibrary definition="ole32.spec.def" />
<include base="ole32">.</include>
<include base="ole32" root="intermediate">.</include>
<include base="ReactOS">include/reactos/wine</include>
<define name="__REACTOS__" />
<define name="__WINESRC__" />
@ -54,5 +53,6 @@
<file>usrmarshal.c</file>
<file>ole32res.rc</file>
<file>dcom.idl</file>
<include base="ole32" root="intermediate">.</include>
<file>ole32.spec</file>
</module>

View file

@ -58,6 +58,7 @@
@ stdcall CoRegisterMessageFilter(ptr ptr)
@ stdcall CoRegisterPSClsid(ptr ptr)
@ stub CoRegisterSurrogate
@ stub CoRegisterSurrogateEx
@ stdcall CoReleaseMarshalData(ptr)
@ stdcall CoReleaseServerProcess()
@ stdcall CoResumeClassObjects()

View file

@ -22,7 +22,6 @@
#include <stdio.h>
#include "windef.h"
#include "winerror.h"
#include "winbase.h"
#include "wingdi.h"
#include "winuser.h"

View file

@ -1,12 +0,0 @@
Index: rpc.c
===================================================================
--- rpc.c (revision 23782)
+++ rpc.c (working copy)
@@ -24,6 +24,7 @@
#include "wine/port.h"
#include <stdarg.h>
+#include <stdio.h>
#include <string.h>
#define COBJMACROS

View file

@ -53,7 +53,6 @@
#include "ole2.h"
#include "rpc.h"
#include "winerror.h"
#include "winreg.h"
#include "wtypes.h"
#include "compobj_private.h"

View file

@ -24,7 +24,6 @@
#include "wine/port.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define COBJMACROS

View file

@ -896,7 +896,7 @@ static HRESULT WINAPI ImplBIGBLOCKFILE_WriteAt(
if (bytes_left)
{
readPtr = (LPBYTE)readPtr + bytes_to_page;
readPtr = (const BYTE *)readPtr + bytes_to_page;
page_index ++;
offset_in_page = 0;
if (bytes_left > PAGE_SIZE)
@ -920,7 +920,7 @@ HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
}
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, const ULONG size, ULONG* bytesRead)
const void* buffer, ULONG size, ULONG* bytesRead)
{
if (This->fileBased)
return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);

View file

@ -1617,7 +1617,7 @@ end:
}
static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
DWORD propNum, DWORD propid, PROPVARIANT *var, DWORD *sectionOffset)
DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
{
HRESULT hr;
LARGE_INTEGER seek;
@ -1717,7 +1717,7 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
FILETIME temp;
StorageUtl_WriteULargeInteger((BYTE *)&temp, 0,
(ULARGE_INTEGER *)&var->u.filetime);
(const ULARGE_INTEGER *)&var->u.filetime);
hr = IStream_Write(This->stm, &temp, sizeof(FILETIME), &count);
bytesWritten = count;
break;
@ -1775,8 +1775,8 @@ static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value,
assert(value);
assert(extra);
assert(closure);
c->hr = PropertyStorage_WritePropertyToStream(This,
c->propNum++, (DWORD)key, (PROPVARIANT *)value, c->sectionOffset);
c->hr = PropertyStorage_WritePropertyToStream(This, c->propNum++,
(DWORD)key, value, c->sectionOffset);
return SUCCEEDED(c->hr);
}

View file

@ -36,7 +36,6 @@
#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/debug.h"

View file

@ -36,7 +36,6 @@
#define NONAMELESSSTRUCT
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "winerror.h"
#include "wine/winbase16.h"
@ -553,7 +552,7 @@ STORAGE_get_small_block(stream_access16 *str,int blocknr,BYTE *sblock) {
* STORAGE_put_small_block [INTERNAL]
*/
static BOOL
STORAGE_put_small_block(stream_access16 *str,int blocknr,BYTE *sblock) {
STORAGE_put_small_block(stream_access16 *str,int blocknr,const BYTE *sblock) {
BYTE block[BIGSIZE];
int bigblocknr;
struct storage_pps_entry root;
@ -655,7 +654,7 @@ STORAGE_get_pps_entry(stream_access16*str,int n,struct storage_pps_entry *pstde)
* STORAGE_put_pps_entry [Internal]
*/
static int
STORAGE_put_pps_entry(stream_access16*str,int n,struct storage_pps_entry *pstde) {
STORAGE_put_pps_entry(stream_access16*str,int n,const struct storage_pps_entry *pstde) {
int blocknr;
BYTE block[BIGSIZE];
struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3));

View file

@ -91,7 +91,7 @@ static StorageInternalImpl* StorageInternalImpl_Construct(StorageImpl* ancestorS
DWORD openFlags, ULONG rootTropertyIndex);
static void StorageImpl_Destroy(StorageBaseImpl* iface);
static BOOL StorageImpl_ReadBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer);
static BOOL StorageImpl_WriteBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer);
static BOOL StorageImpl_WriteBigBlock(StorageImpl* This, ULONG blockIndex, const void* buffer);
static void StorageImpl_SetNextBlockInChain(StorageImpl* This, ULONG blockIndex, ULONG nextBlock);
static HRESULT StorageImpl_LoadFileHeader(StorageImpl* This);
static void StorageImpl_SaveFileHeader(StorageImpl* This);
@ -279,7 +279,7 @@ static HRESULT StorageImpl_ReadAt(StorageImpl* This,
static HRESULT StorageImpl_WriteAt(StorageImpl* This,
ULARGE_INTEGER offset,
void* buffer,
const void* buffer,
const ULONG size,
ULONG* bytesWritten)
{
@ -753,6 +753,7 @@ static HRESULT WINAPI StorageBaseImpl_Stat(
grfStatFlag);
pstatstg->grfMode = This->openFlags;
pstatstg->grfStateBits = This->stateBits;
res = S_OK;
goto end;
@ -2352,8 +2353,9 @@ static HRESULT WINAPI StorageImpl_SetStateBits(
DWORD grfStateBits,/* [in] */
DWORD grfMask) /* [in] */
{
FIXME("not implemented!\n");
return E_NOTIMPL;
StorageImpl* const This = (StorageImpl*)iface;
This->base.stateBits = (This->base.stateBits & ~grfMask) | (grfStateBits & grfMask);
return S_OK;
}
/*
@ -3371,9 +3373,9 @@ BOOL StorageImpl_ReadProperty(
* Write the specified property into the property chain
*/
BOOL StorageImpl_WriteProperty(
StorageImpl* This,
ULONG index,
StgProperty* buffer)
StorageImpl* This,
ULONG index,
const StgProperty* buffer)
{
BYTE currentProperty[PROPSET_BLOCK_SIZE];
ULARGE_INTEGER offsetInPropSet;
@ -3490,9 +3492,9 @@ static BOOL StorageImpl_ReadDWordFromBigBlock(
}
static BOOL StorageImpl_WriteBigBlock(
StorageImpl* This,
ULONG blockIndex,
void* buffer)
StorageImpl* This,
ULONG blockIndex,
const void* buffer)
{
ULARGE_INTEGER ulOffset;
DWORD wrote;
@ -4223,16 +4225,13 @@ static StorageInternalImpl* StorageInternalImpl_Construct(
/*
* Allocate space for the new storage object
*/
newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageInternalImpl));
newStorage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StorageInternalImpl));
if (newStorage!=0)
{
memset(newStorage, 0, sizeof(StorageInternalImpl));
/*
* Initialize the stream list
*/
list_init(&newStorage->base.strmHead);
/*
@ -4338,9 +4337,9 @@ void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value)
}
void StorageUtl_CopyPropertyToSTATSTG(
STATSTG* destination,
StgProperty* source,
int statFlags)
STATSTG* destination,
const StgProperty* source,
int statFlags)
{
/*
* The copy of the string occurs only when the flag is not set
@ -4644,10 +4643,6 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
return STG_E_DOCFILECORRUPT;
}
/*
* Here, I'm casting away the constness on the buffer variable
* This is OK since we don't intend to modify that buffer.
*/
*bytesWritten = 0;
bufferWalker = (const BYTE*)buffer;
@ -4668,7 +4663,7 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
StorageImpl_WriteAt(This->parentStorage,
ulOffset,
(BYTE*)bufferWalker,
bufferWalker,
bytesToWrite,
&bytesWrittenAt);
@ -5683,6 +5678,10 @@ HRESULT WINAPI StgCreateDocfile(
if (reserved != 0)
return STG_E_INVALIDPARAMETER;
/* if no share mode given then DENY_NONE is the default */
if (STGM_SHARE_MODE(grfMode) == 0)
grfMode |= STGM_SHARE_DENY_NONE;
/*
* Validate the STGM flags
*/
@ -5699,14 +5698,6 @@ HRESULT WINAPI StgCreateDocfile(
goto end;
}
/* if no share mode given then DENY_NONE is the default */
if (STGM_SHARE_MODE(grfMode) == 0)
grfMode |= STGM_SHARE_DENY_NONE;
/* must have at least one access mode */
if (STGM_ACCESS_MODE(grfMode) == 0)
goto end;
/* in direct mode, can only use SHARE_EXCLUSIVE */
if (!(grfMode & STGM_TRANSACTED) && (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE))
goto end;
@ -6869,7 +6860,7 @@ static HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREA
*
*
*/
static void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD nBufferLength)
static void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, const BYTE *pBuffer, DWORD nBufferLength)
{
HRESULT hRes;
HANDLE hFile;
@ -7419,7 +7410,7 @@ static void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX,
* Might need to verify the data and return appropriate error message
*
*/
static void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD dwDataLength)
static void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, const BYTE *pData, DWORD dwDataLength)
{
HRESULT hRes;
IStream *pStream;

View file

@ -189,7 +189,7 @@ void BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
HRESULT BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, ULONG size, ULONG* bytesRead);
HRESULT BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
void* buffer, const ULONG size, ULONG* bytesRead);
const void* buffer, ULONG size, ULONG* bytesRead);
/*************************************************************************
* Ole Convert support
@ -245,6 +245,11 @@ struct StorageBaseImpl
* flags that this storage was opened or created with
*/
DWORD openFlags;
/*
* State bits appear to only be preserved while running. No in the stream
*/
DWORD stateBits;
};
/****************************************************************************
@ -306,14 +311,14 @@ struct StorageImpl
};
BOOL StorageImpl_ReadProperty(
StorageImpl* This,
ULONG index,
StgProperty* buffer);
StorageImpl* This,
ULONG index,
StgProperty* buffer);
BOOL StorageImpl_WriteProperty(
StorageImpl* This,
ULONG index,
StgProperty* buffer);
StorageImpl* This,
ULONG index,
const StgProperty* buffer);
BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
StorageImpl* This,
@ -418,9 +423,8 @@ void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
const ULARGE_INTEGER *value);
void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination,
StgProperty* source,
int statFlags);
void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination, const StgProperty* source,
int statFlags);
/****************************************************************************
* BlockChainStream definitions.

View file

@ -364,7 +364,7 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
{
/* FIXME: hack for IRemUnknown */
if (ipid->Data2 == 0xffff)
*stub_apt = apartment_findfromoxid(*(OXID *)ipid->Data4, TRUE);
*stub_apt = apartment_findfromoxid(*(const OXID *)ipid->Data4, TRUE);
else
*stub_apt = apartment_findfromtid(ipid->Data2);
if (!*stub_apt)