mirror of
https://github.com/reactos/reactos.git
synced 2024-12-31 19:42:51 +00:00
Autosyncing with Wine HEAD
svn path=/trunk/; revision=27912
This commit is contained in:
parent
e2d4cbc97d
commit
a0b832df14
30 changed files with 548 additions and 345 deletions
|
@ -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"
|
||||
|
|
|
@ -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(¶ms->clsid), debugstr_guid(¶ms->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, ¶ms.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)¶ms))
|
||||
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)¶ms);
|
||||
}
|
||||
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, ¶ms.stream);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
hr = SendMessageW(hwnd, DM_HOSTOBJECT, 0, (LPARAM)¶ms);
|
||||
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, ¶ms.stream);
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
hr = SendMessageW(hwnd, DM_HOSTOBJECT, 0, (LPARAM)¶ms);
|
||||
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, ®ClassObject))
|
||||
if (S_OK == COM_GetRegisteredClassObject(apt, rclsid, dwClsContext,
|
||||
®ClassObject))
|
||||
{
|
||||
/* 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.@]
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "wine/debug.h"
|
||||
#include "ole2.h"
|
||||
#include "olestd.h"
|
||||
#include "winreg.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(ole);
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
@ stdcall CoRegisterMessageFilter(ptr ptr)
|
||||
@ stdcall CoRegisterPSClsid(ptr ptr)
|
||||
@ stub CoRegisterSurrogate
|
||||
@ stub CoRegisterSurrogateEx
|
||||
@ stdcall CoReleaseMarshalData(ptr)
|
||||
@ stdcall CoReleaseServerProcess()
|
||||
@ stdcall CoResumeClassObjects()
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "windef.h"
|
||||
#include "winerror.h"
|
||||
#include "winbase.h"
|
||||
#include "wingdi.h"
|
||||
#include "winuser.h"
|
||||
|
|
|
@ -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
|
|
@ -53,7 +53,6 @@
|
|||
#include "ole2.h"
|
||||
#include "rpc.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "wtypes.h"
|
||||
|
||||
#include "compobj_private.h"
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include "wine/port.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define COBJMACROS
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
#include "windef.h"
|
||||
#include "winbase.h"
|
||||
#include "winerror.h"
|
||||
#include "winreg.h"
|
||||
#include "winternl.h"
|
||||
#include "wine/debug.h"
|
||||
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue