ReactOS  0.4.12-dev-43-g63b00d8
irotp.c
Go to the documentation of this file.
1 /*
2  * Running Object Table
3  *
4  * Copyright 2007 Robert Shearman
5  *
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.
10  *
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.
15  *
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
19  */
20 
21 #include <stdarg.h>
22 #include <string.h>
23 
24 #include "winerror.h"
25 #include "windef.h"
26 #include "winbase.h"
27 
28 #include "irot_s.h"
29 
30 #include "wine/list.h"
31 #include "wine/debug.h"
32 
34 
35 /* define the structure of the running object table elements */
36 struct rot_entry
37 {
38  struct list entry;
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 */
45 };
46 
47 static struct list RunningObjectTable = LIST_INIT(RunningObjectTable);
48 
51 {
52  0, 0, &csRunningObjectTable,
53  { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
54  0, 0, { (DWORD_PTR)(__FILE__ ": csRunningObjectTable") }
55 };
56 static CRITICAL_SECTION csRunningObjectTable = { &critsect_debug, -1, 0, 0, 0, 0 };
57 
58 static LONG last_cookie = 1;
59 
60 static inline void rot_entry_release(struct rot_entry *rot_entry)
61 {
62  if (!InterlockedDecrement(&rot_entry->refs))
63  {
64  HeapFree(GetProcessHeap(), 0, rot_entry->object);
65  HeapFree(GetProcessHeap(), 0, rot_entry->moniker);
66  HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data);
67  HeapFree(GetProcessHeap(), 0, rot_entry);
68  }
69 }
70 
72  IrotHandle h,
74  const InterfaceData *obj,
75  const InterfaceData *mk,
76  const FILETIME *time,
77  DWORD grfFlags,
78  IrotCookie *cookie,
79  IrotContextHandle *ctxt_handle)
80 {
81  struct rot_entry *rot_entry;
82  struct rot_entry *existing_rot_entry;
83  HRESULT hr;
84 
85  if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
86  {
87  WINE_ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
88  return E_INVALIDARG;
89  }
90 
91  rot_entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rot_entry));
92  if (!rot_entry)
93  return E_OUTOFMEMORY;
94 
95  rot_entry->refs = 1;
96  rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData]));
97  if (!rot_entry->object)
98  {
99  rot_entry_release(rot_entry);
100  return E_OUTOFMEMORY;
101  }
102  rot_entry->object->ulCntData = obj->ulCntData;
103  memcpy(&rot_entry->object->abData, obj->abData, obj->ulCntData);
104 
105  rot_entry->last_modified = *time;
106 
107  rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData]));
108  if (!rot_entry->moniker)
109  {
110  rot_entry_release(rot_entry);
111  return E_OUTOFMEMORY;
112  }
113  rot_entry->moniker->ulCntData = mk->ulCntData;
114  memcpy(&rot_entry->moniker->abData, mk->abData, mk->ulCntData);
115 
116  rot_entry->moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData]));
117  if (!rot_entry->moniker_data)
118  {
119  rot_entry_release(rot_entry);
120  return E_OUTOFMEMORY;
121  }
122  rot_entry->moniker_data->ulCntData = data->ulCntData;
123  memcpy(&rot_entry->moniker_data->abData, data->abData, data->ulCntData);
124 
125  EnterCriticalSection(&csRunningObjectTable);
126 
127  hr = S_OK;
128 
129  LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, struct rot_entry, entry)
130  {
131  if ((existing_rot_entry->moniker_data->ulCntData == data->ulCntData) &&
132  !memcmp(&data->abData, &existing_rot_entry->moniker_data->abData, data->ulCntData))
133  {
135  WINE_TRACE("moniker already registered with cookie %d\n", existing_rot_entry->cookie);
136  break;
137  }
138  }
139 
140  list_add_tail(&RunningObjectTable, &rot_entry->entry);
141 
142  LeaveCriticalSection(&csRunningObjectTable);
143 
144  /* gives a registration identifier to the registered object*/
145  *cookie = rot_entry->cookie = InterlockedIncrement(&last_cookie);
146  *ctxt_handle = rot_entry;
147 
148  return hr;
149 }
150 
152  IrotHandle h,
153  IrotCookie cookie,
154  IrotContextHandle *ctxt_handle,
155  PInterfaceData *obj,
156  PInterfaceData *mk)
157 {
158  struct rot_entry *rot_entry;
159 
160  WINE_TRACE("%d\n", cookie);
161 
162  EnterCriticalSection(&csRunningObjectTable);
163  LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
164  {
165  if (rot_entry->cookie == cookie)
166  {
167  HRESULT hr = S_OK;
168 
169  list_remove(&rot_entry->entry);
170  LeaveCriticalSection(&csRunningObjectTable);
171 
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]));
174  if (*obj && *mk)
175  {
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);
180  }
181  else
182  {
183  MIDL_user_free(*obj);
184  MIDL_user_free(*mk);
185  hr = E_OUTOFMEMORY;
186  }
187 
188  rot_entry_release(rot_entry);
189  *ctxt_handle = NULL;
190  return hr;
191  }
192  }
193  LeaveCriticalSection(&csRunningObjectTable);
194 
195  return E_INVALIDARG;
196 }
197 
199  IrotHandle h,
201 {
202  const struct rot_entry *rot_entry;
203  HRESULT hr = S_FALSE;
204 
205  WINE_TRACE("\n");
206 
207  EnterCriticalSection(&csRunningObjectTable);
208 
209  LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
210  {
211  if ((rot_entry->moniker_data->ulCntData == data->ulCntData) &&
212  !memcmp(&data->abData, &rot_entry->moniker_data->abData, data->ulCntData))
213  {
214  hr = S_OK;
215  break;
216  }
217  }
218  LeaveCriticalSection(&csRunningObjectTable);
219 
220  return hr;
221 }
222 
224  IrotHandle h,
226  PInterfaceData *obj,
227  IrotCookie *cookie)
228 {
229  const struct rot_entry *rot_entry;
230 
231  WINE_TRACE("%p\n", moniker_data);
232 
233  *cookie = 0;
234 
235  EnterCriticalSection(&csRunningObjectTable);
236 
237  LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
238  {
239  HRESULT hr = S_OK;
240  if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
241  !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
242  {
243  *obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData]));
244  if (*obj)
245  {
246  (*obj)->ulCntData = rot_entry->object->ulCntData;
247  memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
248 
249  *cookie = rot_entry->cookie;
250  }
251  else
252  hr = E_OUTOFMEMORY;
253 
254  LeaveCriticalSection(&csRunningObjectTable);
255 
256  return hr;
257  }
258  }
259 
260  LeaveCriticalSection(&csRunningObjectTable);
261 
262  return MK_E_UNAVAILABLE;
263 }
264 
266  IrotHandle h,
267  IrotCookie cookie,
268  const FILETIME *last_modified_time)
269 {
270  struct rot_entry *rot_entry;
271 
272  WINE_TRACE("%d %p\n", cookie, last_modified_time);
273 
274  EnterCriticalSection(&csRunningObjectTable);
275  LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
276  {
277  if (rot_entry->cookie == cookie)
278  {
279  rot_entry->last_modified = *last_modified_time;
280  LeaveCriticalSection(&csRunningObjectTable);
281  return S_OK;
282  }
283  }
284  LeaveCriticalSection(&csRunningObjectTable);
285 
286  return E_INVALIDARG;
287 }
288 
290  IrotHandle h,
292  FILETIME *time)
293 {
294  const struct rot_entry *rot_entry;
296 
297  WINE_TRACE("%p\n", moniker_data);
298 
299  memset(time, 0, sizeof(*time));
300 
301  EnterCriticalSection(&csRunningObjectTable);
302  LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
303  {
304  if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
305  !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
306  {
307  *time = rot_entry->last_modified;
308  hr = S_OK;
309  break;
310  }
311  }
312  LeaveCriticalSection(&csRunningObjectTable);
313 
314  return hr;
315 }
316 
318  IrotHandle h,
319  PInterfaceList *list)
320 {
321  const struct rot_entry *rot_entry;
322  HRESULT hr = S_OK;
323  ULONG moniker_count = 0;
324  ULONG i = 0;
325 
326  WINE_TRACE("\n");
327 
328  EnterCriticalSection(&csRunningObjectTable);
329 
330  LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
331  moniker_count++;
332 
333  *list = MIDL_user_allocate(FIELD_OFFSET(InterfaceList, interfaces[moniker_count]));
334  if (*list)
335  {
336  (*list)->size = moniker_count;
337  LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
338  {
339  (*list)->interfaces[i] = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData]));
340  if (!(*list)->interfaces[i])
341  {
342  ULONG end = i - 1;
343  for (i = 0; i < end; i++)
344  MIDL_user_free((*list)->interfaces[i]);
345  MIDL_user_free(*list);
346  hr = E_OUTOFMEMORY;
347  break;
348  }
349  (*list)->interfaces[i]->ulCntData = rot_entry->moniker->ulCntData;
350  memcpy((*list)->interfaces[i]->abData, rot_entry->moniker->abData, rot_entry->moniker->ulCntData);
351  i++;
352  }
353  }
354  else
355  hr = E_OUTOFMEMORY;
356 
357  LeaveCriticalSection(&csRunningObjectTable);
358 
359  return hr;
360 }
361 
363 {
364  struct rot_entry *rot_entry = ctxt_handle;
365  EnterCriticalSection(&csRunningObjectTable);
366  list_remove(&rot_entry->entry);
367  LeaveCriticalSection(&csRunningObjectTable);
368  rot_entry_release(rot_entry);
369 }
370 
372 {
373  return HeapAlloc(GetProcessHeap(), 0, size);
374 }
375 
377 {
378  HeapFree(GetProcessHeap(), 0, p);
379 }
HRESULT __cdecl IrotNoteChangeTime(IrotHandle h, IrotCookie cookie, const FILETIME *last_modified_time)
Definition: irotp.c:265
static LONG last_cookie
Definition: irotp.c:58
MonikerComparisonData * moniker_data
Definition: irotp.c:41
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
#define DWORD_PTR
Definition: treelist.c:76
#define __cdecl
Definition: accygwin.h:79
IrotContextHandle ctxt_handle
Definition: moniker.c:69
WINE_DEFAULT_DEBUG_CHANNEL(rpcss)
_In_ PUSBD_INTERFACE_LIST_ENTRY InterfaceList
Definition: usbdlib.h:168
void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle)
Definition: irotp.c:362
#define WINE_TRACE
Definition: debug.h:353
static void rot_entry_release(struct rot_entry *rot_entry)
Definition: irotp.c:60
GLuint GLuint end
Definition: gl.h:1545
__u16 time
Definition: mkdosfs.c:366
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
__WINE_SERVER_LIST_INLINE void list_add_tail(struct list *list, struct list *elem)
Definition: list.h:102
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
GLenum GLclampf GLint i
Definition: glfuncs.h:14
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
long LONG
Definition: pedump.c:60
static CRITICAL_SECTION_DEBUG critsect_debug
Definition: irotp.c:50
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
#define WINE_ERR
Definition: debug.h:370
smooth NULL
Definition: ftsmooth.c:416
HRESULT __cdecl IrotEnumRunning(IrotHandle h, PInterfaceList *list)
Definition: irotp.c:317
#define __RPC_USER
Definition: rpc.h:65
Definition: irotp.c:36
__WINE_SERVER_LIST_INLINE void list_remove(struct list *elem)
Definition: list.h:108
IROT_ENDPOINT struct tagMonikerComparisonData MonikerComparisonData
HRESULT __cdecl IrotRevoke(IrotHandle h, IrotCookie cookie, IrotContextHandle *ctxt_handle, PInterfaceData *obj, PInterfaceData *mk)
Definition: irotp.c:151
GLsizeiptr size
Definition: glext.h:5919
#define GetProcessHeap()
Definition: compat.h:395
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
HRESULT __cdecl IrotGetObject(IrotHandle h, const MonikerComparisonData *moniker_data, PInterfaceData *obj, IrotCookie *cookie)
Definition: irotp.c:223
#define LIST_INIT(head)
Definition: queue.h:197
LONG HRESULT
Definition: typedefs.h:77
static struct list RunningObjectTable
Definition: irotp.c:47
unsigned long DWORD
Definition: ntddk_ex.h:95
HRESULT __cdecl IrotRegister(IrotHandle h, const MonikerComparisonData *data, const InterfaceData *obj, const InterfaceData *mk, const FILETIME *time, DWORD grfFlags, IrotCookie *cookie, IrotContextHandle *ctxt_handle)
Definition: irotp.c:71
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
InterfaceData * moniker
Definition: irotp.c:40
#define InterlockedDecrement
Definition: armddk.h:52
LONG refs
Definition: irotp.c:44
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
Definition: _list.h:228
#define MK_S_MONIKERALREADYREGISTERED
Definition: winerror.h:2777
LIST_ENTRY ProcessLocksList
Definition: winbase.h:848
ULONG_PTR SIZE_T
Definition: typedefs.h:78
#define S_OK
Definition: intsafe.h:59
#define InterlockedIncrement
Definition: armddk.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:254
DWORD cookie
Definition: irotp.c:42
HRESULT __cdecl IrotGetTimeOfLastChange(IrotHandle h, const MonikerComparisonData *moniker_data, FILETIME *time)
Definition: irotp.c:289
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
#define MK_E_UNAVAILABLE
Definition: winerror.h:2784
unsigned int ULONG
Definition: retypes.h:1
IN PVOID IN PVOID InterfaceData
Definition: pci.h:359
void *__RPC_USER MIDL_user_allocate(SIZE_T size)
Definition: irotp.c:371
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
GLfloat GLfloat p
Definition: glext.h:8902
struct list entry
Definition: irotp.c:38
void __RPC_USER MIDL_user_free(void *p)
Definition: irotp.c:376
#define memset(x, y, z)
Definition: compat.h:39
FILETIME last_modified
Definition: irotp.c:43
static CRITICAL_SECTION csRunningObjectTable
Definition: irotp.c:49
InterfaceData * object
Definition: irotp.c:39
#define HeapFree(x, y, z)
Definition: compat.h:394
HRESULT __cdecl IrotIsRunning(IrotHandle h, const MonikerComparisonData *data)
Definition: irotp.c:198