~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Wine Cross Reference
wine/programs/rpcss/irotp.c

Version: ~ [ wine-1.1.33 ] ~ [ wine-1.1.32 ] ~ [ wine-1.1.31 ] ~ [ wine-1.1.30 ] ~ [ wine-1.1.29 ] ~ [ wine-1.1.28 ] ~ [ wine-1.1.27 ] ~ [ wine-1.1.26 ] ~ [ wine-1.1.25 ] ~ [ wine-1.1.24 ] ~ [ wine-1.1.23 ] ~ [ wine-1.1.22 ] ~ [ wine-1.1.21 ] ~ [ wine-1.1.20 ] ~ [ wine-1.1.19 ] ~ [ wine-1.1.18 ] ~ [ wine-1.1.17 ] ~ [ wine-1.1.16 ] ~ [ wine-1.1.15 ] ~ [ wine-1.1.14 ] ~ [ wine-1.1.13 ] ~ [ wine-1.1.12 ] ~ [ wine-1.1.11 ] ~ [ wine-1.1.10 ] ~ [ wine-1.1.9 ] ~ [ wine-1.1.8 ] ~ [ wine-1.1.7 ] ~ [ wine-1.0.1 ] ~ [ wine-1.1.6 ] ~ [ wine-1.1.5 ] ~ [ wine-1.1.4 ] ~ [ wine-1.1.3 ] ~ [ wine-1.1.2 ] ~ [ wine-1.1.1 ] ~ [ wine-1.1.0 ] ~ [ wine-1.0 ] ~

  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.h"
 29 
 30 #include "wine/list.h"
 31 #include "wine/debug.h"
 32 
 33 WINE_DEFAULT_DEBUG_CHANNEL(rpcss);
 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 */
 43     FILETIME           last_modified;
 44     LONG               refs;
 45 };
 46 
 47 static struct list RunningObjectTable = LIST_INIT(RunningObjectTable);
 48 
 49 static CRITICAL_SECTION csRunningObjectTable;
 50 static CRITICAL_SECTION_DEBUG critsect_debug =
 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 
 71 HRESULT IrotRegister(
 72     IrotHandle h,
 73     const MonikerComparisonData *data,
 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         {
134             hr = MK_S_MONIKERALREADYREGISTERED;
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 
151 HRESULT IrotRevoke(
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 
198 HRESULT IrotIsRunning(
199     IrotHandle h,
200     const MonikerComparisonData *data)
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 
223 HRESULT IrotGetObject(
224     IrotHandle h,
225     const MonikerComparisonData *moniker_data,
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 
265 HRESULT IrotNoteChangeTime(
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 
289 HRESULT IrotGetTimeOfLastChange(
290     IrotHandle h,
291     const MonikerComparisonData *moniker_data,
292     FILETIME *time)
293 {
294     const struct rot_entry *rot_entry;
295     HRESULT hr = MK_E_UNAVAILABLE;
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 
317 HRESULT IrotEnumRunning(
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 
362 void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle)
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 
371 void * __RPC_USER MIDL_user_allocate(SIZE_T size)
372 {
373     return HeapAlloc(GetProcessHeap(), 0, size);
374 }
375 
376 void __RPC_USER MIDL_user_free(void * p)
377 {
378     HeapFree(GetProcessHeap(), 0, p);
379 }
380 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.