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.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%08lx\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 %ld\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("%ld\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("%ld %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);
- }
|