Something went wrong. Try again.
Reactos
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380/* * Running Object Table * * Copyright 2007 Robert Shearman * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
#include <stdarg.h>#include <string.h>
#include "winerror.h"#include "windef.h"#include "winbase.h"
#include "irot_s.h"
#include "wine/list.h"#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(rpcss);
/* define the structure of the running object table elements */struct rot_entry{ struct list entry; InterfaceData *object; /* marshaled running object*/ InterfaceData *moniker; /* marshaled moniker that identifies this object */ MonikerComparisonData *moniker_data; /* moniker comparison data that identifies this object */ DWORD cookie; /* cookie identifying this object */ FILETIME last_modified; LONG refs;};
static struct list RunningObjectTable = LIST_INIT(RunningObjectTable);
static CRITICAL_SECTION csRunningObjectTable;static CRITICAL_SECTION_DEBUG critsect_debug ={ 0, 0, &csRunningObjectTable, { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList }, 0, 0, { (DWORD_PTR)(__FILE__ ": csRunningObjectTable") }};static CRITICAL_SECTION csRunningObjectTable = { &critsect_debug, -1, 0, 0, 0, 0 };
static LONG last_cookie = 1;
static inline void rot_entry_release(struct rot_entry *rot_entry){ if (!InterlockedDecrement(&rot_entry->refs)) { HeapFree(GetProcessHeap(), 0, rot_entry->object); HeapFree(GetProcessHeap(), 0, rot_entry->moniker); HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data); HeapFree(GetProcessHeap(), 0, rot_entry); }}
HRESULT __cdecl IrotRegister( IrotHandle h, const MonikerComparisonData *data, const InterfaceData *obj, const InterfaceData *mk, const FILETIME *time, DWORD grfFlags, IrotCookie *cookie, IrotContextHandle *ctxt_handle){ struct rot_entry *rot_entry; struct rot_entry *existing_rot_entry; HRESULT hr;
if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT)) { WINE_ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT)); return E_INVALIDARG; }
rot_entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rot_entry)); if (!rot_entry) return E_OUTOFMEMORY;
rot_entry->refs = 1; rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData])); if (!rot_entry->object) { rot_entry_release(rot_entry); return E_OUTOFMEMORY; } rot_entry->object->ulCntData = obj->ulCntData; memcpy(&rot_entry->object->abData, obj->abData, obj->ulCntData);
rot_entry->last_modified = *time;
rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData])); if (!rot_entry->moniker) { rot_entry_release(rot_entry); return E_OUTOFMEMORY; } rot_entry->moniker->ulCntData = mk->ulCntData; memcpy(&rot_entry->moniker->abData, mk->abData, mk->ulCntData);
rot_entry->moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData])); if (!rot_entry->moniker_data) { rot_entry_release(rot_entry); return E_OUTOFMEMORY; } rot_entry->moniker_data->ulCntData = data->ulCntData; memcpy(&rot_entry->moniker_data->abData, data->abData, data->ulCntData);
EnterCriticalSection(&csRunningObjectTable);
hr = S_OK;
LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, struct rot_entry, entry) { if ((existing_rot_entry->moniker_data->ulCntData == data->ulCntData) && !memcmp(&data->abData, &existing_rot_entry->moniker_data->abData, data->ulCntData)) { hr = MK_S_MONIKERALREADYREGISTERED; WINE_TRACE("moniker already registered with cookie %d\n", existing_rot_entry->cookie); break; } }
list_add_tail(&RunningObjectTable, &rot_entry->entry);
LeaveCriticalSection(&csRunningObjectTable);
/* gives a registration identifier to the registered object*/ *cookie = rot_entry->cookie = InterlockedIncrement(&last_cookie); *ctxt_handle = rot_entry;
return hr;}
HRESULT __cdecl IrotRevoke( IrotHandle h, IrotCookie cookie, IrotContextHandle *ctxt_handle, PInterfaceData *obj, PInterfaceData *mk){ struct rot_entry *rot_entry;
WINE_TRACE("%d\n", cookie);
EnterCriticalSection(&csRunningObjectTable); LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry) { if (rot_entry->cookie == cookie) { HRESULT hr = S_OK;
list_remove(&rot_entry->entry); LeaveCriticalSection(&csRunningObjectTable);
*obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData])); *mk = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData])); if (*obj && *mk) { (*obj)->ulCntData = rot_entry->object->ulCntData; memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData); (*mk)->ulCntData = rot_entry->moniker->ulCntData; memcpy((*mk)->abData, rot_entry->moniker->abData, (*mk)->ulCntData); } else { MIDL_user_free(*obj); MIDL_user_free(*mk); hr = E_OUTOFMEMORY; }
rot_entry_release(rot_entry); *ctxt_handle = NULL; return hr; } } LeaveCriticalSection(&csRunningObjectTable);
return E_INVALIDARG;}
HRESULT __cdecl IrotIsRunning( IrotHandle h, const MonikerComparisonData *data){ const struct rot_entry *rot_entry; HRESULT hr = S_FALSE;
WINE_TRACE("\n");
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry) { if ((rot_entry->moniker_data->ulCntData == data->ulCntData) && !memcmp(&data->abData, &rot_entry->moniker_data->abData, data->ulCntData)) { hr = S_OK; break; } } LeaveCriticalSection(&csRunningObjectTable);
return hr;}
HRESULT __cdecl IrotGetObject( IrotHandle h, const MonikerComparisonData *moniker_data, PInterfaceData *obj, IrotCookie *cookie){ const struct rot_entry *rot_entry;
WINE_TRACE("%p\n", moniker_data);
*cookie = 0;
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry) { HRESULT hr = S_OK; if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) && !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData)) { *obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData])); if (*obj) { (*obj)->ulCntData = rot_entry->object->ulCntData; memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
*cookie = rot_entry->cookie; } else hr = E_OUTOFMEMORY;
LeaveCriticalSection(&csRunningObjectTable);
return hr; } }
LeaveCriticalSection(&csRunningObjectTable);
return MK_E_UNAVAILABLE;}
HRESULT __cdecl IrotNoteChangeTime( IrotHandle h, IrotCookie cookie, const FILETIME *last_modified_time){ struct rot_entry *rot_entry;
WINE_TRACE("%d %p\n", cookie, last_modified_time);
EnterCriticalSection(&csRunningObjectTable); LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry) { if (rot_entry->cookie == cookie) { rot_entry->last_modified = *last_modified_time; LeaveCriticalSection(&csRunningObjectTable); return S_OK; } } LeaveCriticalSection(&csRunningObjectTable);
return E_INVALIDARG;}
HRESULT __cdecl IrotGetTimeOfLastChange( IrotHandle h, const MonikerComparisonData *moniker_data, FILETIME *time){ const struct rot_entry *rot_entry; HRESULT hr = MK_E_UNAVAILABLE;
WINE_TRACE("%p\n", moniker_data);
memset(time, 0, sizeof(*time));
EnterCriticalSection(&csRunningObjectTable); LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry) { if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) && !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData)) { *time = rot_entry->last_modified; hr = S_OK; break; } } LeaveCriticalSection(&csRunningObjectTable);
return hr;}
HRESULT __cdecl IrotEnumRunning( IrotHandle h, PInterfaceList *list){ const struct rot_entry *rot_entry; HRESULT hr = S_OK; ULONG moniker_count = 0; ULONG i = 0;
WINE_TRACE("\n");
EnterCriticalSection(&csRunningObjectTable);
LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry ) moniker_count++;
*list = MIDL_user_allocate(FIELD_OFFSET(InterfaceList, interfaces[moniker_count])); if (*list) { (*list)->size = moniker_count; LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry ) { (*list)->interfaces[i] = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData])); if (!(*list)->interfaces[i]) { ULONG end = i - 1; for (i = 0; i < end; i++) MIDL_user_free((*list)->interfaces[i]); MIDL_user_free(*list); hr = E_OUTOFMEMORY; break; } (*list)->interfaces[i]->ulCntData = rot_entry->moniker->ulCntData; memcpy((*list)->interfaces[i]->abData, rot_entry->moniker->abData, rot_entry->moniker->ulCntData); i++; } } else hr = E_OUTOFMEMORY;
LeaveCriticalSection(&csRunningObjectTable);
return hr;}
void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle){ struct rot_entry *rot_entry = ctxt_handle; EnterCriticalSection(&csRunningObjectTable); list_remove(&rot_entry->entry); LeaveCriticalSection(&csRunningObjectTable); rot_entry_release(rot_entry);}
void * __RPC_USER MIDL_user_allocate(SIZE_T size){ return HeapAlloc(GetProcessHeap(), 0, size);}
void __RPC_USER MIDL_user_free(void * p){ HeapFree(GetProcessHeap(), 0, p);}