4 * Copyright 2007 Robert Shearman
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
30 #include "wine/list.h"
31 #include "wine/debug.h"
33 WINE_DEFAULT_DEBUG_CHANNEL(rpcss);
35 /* define the structure of the running object table elements */
39 InterfaceData *object; /* marshaled running object*/
40 InterfaceData *moniker; /* marshaled moniker that identifies this object */
41 MonikerComparisonData *moniker_data; /* moniker comparison data that identifies this object */
42 DWORD cookie; /* cookie identifying this object */
43 FILETIME last_modified;
46 static struct list RunningObjectTable = LIST_INIT(RunningObjectTable);
48 static CRITICAL_SECTION csRunningObjectTable;
49 static CRITICAL_SECTION_DEBUG critsect_debug =
51 0, 0, &csRunningObjectTable,
52 { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
53 0, 0, { (DWORD_PTR)(__FILE__ ": csRunningObjectTable") }
55 static CRITICAL_SECTION csRunningObjectTable = { &critsect_debug, -1, 0, 0, 0, 0 };
57 static LONG last_cookie = 1;
59 static inline void rot_entry_delete(struct rot_entry *rot_entry)
61 HeapFree(GetProcessHeap(), 0, rot_entry->object);
62 HeapFree(GetProcessHeap(), 0, rot_entry->moniker);
63 HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data);
64 HeapFree(GetProcessHeap(), 0, rot_entry);
69 const MonikerComparisonData *data,
70 const InterfaceData *obj,
71 const InterfaceData *mk,
76 struct rot_entry *rot_entry;
77 const struct rot_entry *existing_rot_entry;
80 if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
82 WINE_ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
86 rot_entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rot_entry));
90 rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData]));
91 if (!rot_entry->object)
93 rot_entry_delete(rot_entry);
96 rot_entry->object->ulCntData = obj->ulCntData;
97 memcpy(&rot_entry->object->abData, obj->abData, obj->ulCntData);
99 rot_entry->last_modified = *time;
101 rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData]));
102 if (!rot_entry->moniker)
104 rot_entry_delete(rot_entry);
105 return E_OUTOFMEMORY;
107 rot_entry->moniker->ulCntData = mk->ulCntData;
108 memcpy(&rot_entry->moniker->abData, mk->abData, mk->ulCntData);
110 rot_entry->moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData]));
111 if (!rot_entry->moniker_data)
113 rot_entry_delete(rot_entry);
114 return E_OUTOFMEMORY;
116 rot_entry->moniker_data->ulCntData = data->ulCntData;
117 memcpy(&rot_entry->moniker_data->abData, data->abData, data->ulCntData);
119 EnterCriticalSection(&csRunningObjectTable);
123 LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, const struct rot_entry, entry)
125 if ((existing_rot_entry->moniker_data->ulCntData == data->ulCntData) &&
126 !memcmp(&data->abData, &existing_rot_entry->moniker_data->abData, data->ulCntData))
128 hr = MK_S_MONIKERALREADYREGISTERED;
129 WINE_TRACE("moniker already registered with cookie %d\n", existing_rot_entry->cookie);
136 list_add_tail(&RunningObjectTable, &rot_entry->entry);
137 /* gives a registration identifier to the registered object*/
138 *cookie = rot_entry->cookie = InterlockedIncrement(&last_cookie);
142 rot_entry_delete(rot_entry);
143 *cookie = existing_rot_entry->cookie;
147 LeaveCriticalSection(&csRunningObjectTable);
158 struct rot_entry *rot_entry;
160 WINE_TRACE("%d\n", cookie);
162 EnterCriticalSection(&csRunningObjectTable);
163 LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
165 if (rot_entry->cookie == cookie)
169 list_remove(&rot_entry->entry);
170 LeaveCriticalSection(&csRunningObjectTable);
172 *obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData]));
173 *mk = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData]));
176 (*obj)->ulCntData = rot_entry->object->ulCntData;
177 memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
178 (*mk)->ulCntData = rot_entry->moniker->ulCntData;
179 memcpy((*mk)->abData, rot_entry->moniker->abData, (*mk)->ulCntData);
183 MIDL_user_free(*obj);
188 rot_entry_delete(rot_entry);
192 LeaveCriticalSection(&csRunningObjectTable);
197 HRESULT IrotIsRunning(
199 const MonikerComparisonData *data)
201 const struct rot_entry *rot_entry;
202 HRESULT hr = S_FALSE;
206 EnterCriticalSection(&csRunningObjectTable);
208 LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
210 if ((rot_entry->moniker_data->ulCntData == data->ulCntData) &&
211 !memcmp(&data->abData, &rot_entry->moniker_data->abData, data->ulCntData))
217 LeaveCriticalSection(&csRunningObjectTable);
222 HRESULT IrotGetObject(
224 const MonikerComparisonData *moniker_data,
228 const struct rot_entry *rot_entry;
230 WINE_TRACE("%p\n", moniker_data);
232 EnterCriticalSection(&csRunningObjectTable);
234 LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
237 if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
238 !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
240 *obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData]));
243 (*obj)->ulCntData = rot_entry->object->ulCntData;
244 memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
246 *cookie = rot_entry->cookie;
251 LeaveCriticalSection(&csRunningObjectTable);
257 LeaveCriticalSection(&csRunningObjectTable);
259 return MK_E_UNAVAILABLE;
262 HRESULT IrotNoteChangeTime(
265 const FILETIME *last_modified_time)
267 struct rot_entry *rot_entry;
269 WINE_TRACE("%d %p\n", cookie, last_modified_time);
271 EnterCriticalSection(&csRunningObjectTable);
272 LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
274 if (rot_entry->cookie == cookie)
276 rot_entry->last_modified = *last_modified_time;
277 LeaveCriticalSection(&csRunningObjectTable);
281 LeaveCriticalSection(&csRunningObjectTable);
286 HRESULT IrotGetTimeOfLastChange(
288 const MonikerComparisonData *moniker_data,
291 const struct rot_entry *rot_entry;
292 HRESULT hr = MK_E_UNAVAILABLE;
294 WINE_TRACE("%p\n", moniker_data);
296 EnterCriticalSection(&csRunningObjectTable);
297 LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
299 if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
300 !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
302 *time = rot_entry->last_modified;
307 LeaveCriticalSection(&csRunningObjectTable);
312 HRESULT IrotEnumRunning(
314 PInterfaceList *list)
316 const struct rot_entry *rot_entry;
318 ULONG moniker_count = 0;
323 EnterCriticalSection(&csRunningObjectTable);
325 LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
328 *list = MIDL_user_allocate(FIELD_OFFSET(InterfaceList, interfaces[moniker_count]));
331 (*list)->size = moniker_count;
332 LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
334 (*list)->interfaces[i] = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData]));
335 if (!(*list)->interfaces[i])
338 for (i = 0; i < end; i++)
339 MIDL_user_free((*list)->interfaces[i]);
340 MIDL_user_free(*list);
344 (*list)->interfaces[i]->ulCntData = rot_entry->moniker->ulCntData;
345 memcpy((*list)->interfaces[i]->abData, rot_entry->moniker->abData, rot_entry->moniker->ulCntData);
352 LeaveCriticalSection(&csRunningObjectTable);
357 void * __RPC_USER MIDL_user_allocate(size_t size)
359 return HeapAlloc(GetProcessHeap(), 0, size);
362 void __RPC_USER MIDL_user_free(void * p)
364 HeapFree(GetProcessHeap(), 0, p);