ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

irotp.c
Go to the documentation of this file.
00001 /*
00002  *       Running Object Table
00003  *
00004  *      Copyright 2007  Robert Shearman
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Lesser General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2.1 of the License, or (at your option) any later version.
00010  *
00011  * This library is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014  * Lesser General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public
00017  * License along with this library; if not, write to the Free Software
00018  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00019  */
00020 
00021 #include <stdarg.h>
00022 #include <string.h>
00023 
00024 #include "winerror.h"
00025 #include "windef.h"
00026 #include "winbase.h"
00027 
00028 #include "irot_s.h"
00029 
00030 #include "wine/list.h"
00031 #include "wine/debug.h"
00032 
00033 WINE_DEFAULT_DEBUG_CHANNEL(rpcss);
00034 
00035 /* define the structure of the running object table elements */
00036 struct rot_entry
00037 {
00038     struct list        entry;
00039     InterfaceData *object; /* marshaled running object*/
00040     InterfaceData *moniker; /* marshaled moniker that identifies this object */
00041     MonikerComparisonData *moniker_data; /* moniker comparison data that identifies this object */
00042     DWORD              cookie; /* cookie identifying this object */
00043     FILETIME           last_modified;
00044     LONG               refs;
00045 };
00046 
00047 static struct list RunningObjectTable = LIST_INIT(RunningObjectTable);
00048 
00049 static CRITICAL_SECTION csRunningObjectTable;
00050 static CRITICAL_SECTION_DEBUG critsect_debug =
00051 {
00052     0, 0, &csRunningObjectTable,
00053     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
00054       0, 0, { (DWORD_PTR)(__FILE__ ": csRunningObjectTable") }
00055 };
00056 static CRITICAL_SECTION csRunningObjectTable = { &critsect_debug, -1, 0, 0, 0, 0 };
00057 
00058 static LONG last_cookie = 1;
00059 
00060 static inline void rot_entry_release(struct rot_entry *rot_entry)
00061 {
00062     if (!InterlockedDecrement(&rot_entry->refs))
00063     {
00064         HeapFree(GetProcessHeap(), 0, rot_entry->object);
00065         HeapFree(GetProcessHeap(), 0, rot_entry->moniker);
00066         HeapFree(GetProcessHeap(), 0, rot_entry->moniker_data);
00067         HeapFree(GetProcessHeap(), 0, rot_entry);
00068     }
00069 }
00070 
00071 HRESULT IrotRegister(
00072     IrotHandle h,
00073     const MonikerComparisonData *data,
00074     const InterfaceData *obj,
00075     const InterfaceData *mk,
00076     const FILETIME *time,
00077     DWORD grfFlags,
00078     IrotCookie *cookie,
00079     IrotContextHandle *ctxt_handle)
00080 {
00081     struct rot_entry *rot_entry;
00082     struct rot_entry *existing_rot_entry;
00083     HRESULT hr;
00084 
00085     if (grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT))
00086     {
00087         WINE_ERR("Invalid grfFlags: 0x%08x\n", grfFlags & ~(ROTFLAGS_REGISTRATIONKEEPSALIVE|ROTFLAGS_ALLOWANYCLIENT));
00088         return E_INVALIDARG;
00089     }
00090 
00091     rot_entry = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*rot_entry));
00092     if (!rot_entry)
00093         return E_OUTOFMEMORY;
00094 
00095     rot_entry->refs = 1;
00096     rot_entry->object = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[obj->ulCntData]));
00097     if (!rot_entry->object)
00098     {
00099         rot_entry_release(rot_entry);
00100         return E_OUTOFMEMORY;
00101     }
00102     rot_entry->object->ulCntData = obj->ulCntData;
00103     memcpy(&rot_entry->object->abData, obj->abData, obj->ulCntData);
00104 
00105     rot_entry->last_modified = *time;
00106 
00107     rot_entry->moniker = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(InterfaceData, abData[mk->ulCntData]));
00108     if (!rot_entry->moniker)
00109     {
00110         rot_entry_release(rot_entry);
00111         return E_OUTOFMEMORY;
00112     }
00113     rot_entry->moniker->ulCntData = mk->ulCntData;
00114     memcpy(&rot_entry->moniker->abData, mk->abData, mk->ulCntData);
00115 
00116     rot_entry->moniker_data = HeapAlloc(GetProcessHeap(), 0, FIELD_OFFSET(MonikerComparisonData, abData[data->ulCntData]));
00117     if (!rot_entry->moniker_data)
00118     {
00119         rot_entry_release(rot_entry);
00120         return E_OUTOFMEMORY;
00121     }
00122     rot_entry->moniker_data->ulCntData = data->ulCntData;
00123     memcpy(&rot_entry->moniker_data->abData, data->abData, data->ulCntData);
00124 
00125     EnterCriticalSection(&csRunningObjectTable);
00126 
00127     hr = S_OK;
00128 
00129     LIST_FOR_EACH_ENTRY(existing_rot_entry, &RunningObjectTable, struct rot_entry, entry)
00130     {
00131         if ((existing_rot_entry->moniker_data->ulCntData == data->ulCntData) &&
00132             !memcmp(&data->abData, &existing_rot_entry->moniker_data->abData, data->ulCntData))
00133         {
00134             hr = MK_S_MONIKERALREADYREGISTERED;
00135             WINE_TRACE("moniker already registered with cookie %d\n", existing_rot_entry->cookie);
00136             break;
00137         }
00138     }
00139 
00140     list_add_tail(&RunningObjectTable, &rot_entry->entry);
00141 
00142     LeaveCriticalSection(&csRunningObjectTable);
00143 
00144     /* gives a registration identifier to the registered object*/
00145     *cookie = rot_entry->cookie = InterlockedIncrement(&last_cookie);
00146     *ctxt_handle = rot_entry;
00147 
00148     return hr;
00149 }
00150 
00151 HRESULT IrotRevoke(
00152     IrotHandle h,
00153     IrotCookie cookie,
00154     IrotContextHandle *ctxt_handle,
00155     PInterfaceData *obj,
00156     PInterfaceData *mk)
00157 {
00158     struct rot_entry *rot_entry;
00159 
00160     WINE_TRACE("%d\n", cookie);
00161 
00162     EnterCriticalSection(&csRunningObjectTable);
00163     LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
00164     {
00165         if (rot_entry->cookie == cookie)
00166         {
00167             HRESULT hr = S_OK;
00168 
00169             list_remove(&rot_entry->entry);
00170             LeaveCriticalSection(&csRunningObjectTable);
00171 
00172             *obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData]));
00173             *mk = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData]));
00174             if (*obj && *mk)
00175             {
00176                 (*obj)->ulCntData = rot_entry->object->ulCntData;
00177                 memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
00178                 (*mk)->ulCntData = rot_entry->moniker->ulCntData;
00179                 memcpy((*mk)->abData, rot_entry->moniker->abData, (*mk)->ulCntData);
00180             }
00181             else
00182             {
00183                 MIDL_user_free(*obj);
00184                 MIDL_user_free(*mk);
00185                 hr = E_OUTOFMEMORY;
00186             }
00187 
00188             rot_entry_release(rot_entry);
00189             *ctxt_handle = NULL;
00190             return hr;
00191         }
00192     }
00193     LeaveCriticalSection(&csRunningObjectTable);
00194 
00195     return E_INVALIDARG;
00196 }
00197 
00198 HRESULT IrotIsRunning(
00199     IrotHandle h,
00200     const MonikerComparisonData *data)
00201 {
00202     const struct rot_entry *rot_entry;
00203     HRESULT hr = S_FALSE;
00204 
00205     WINE_TRACE("\n");
00206 
00207     EnterCriticalSection(&csRunningObjectTable);
00208 
00209     LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
00210     {
00211         if ((rot_entry->moniker_data->ulCntData == data->ulCntData) &&
00212             !memcmp(&data->abData, &rot_entry->moniker_data->abData, data->ulCntData))
00213         {
00214             hr = S_OK;
00215             break;
00216         }
00217     }
00218     LeaveCriticalSection(&csRunningObjectTable);
00219 
00220     return hr;
00221 }
00222 
00223 HRESULT IrotGetObject(
00224     IrotHandle h,
00225     const MonikerComparisonData *moniker_data,
00226     PInterfaceData *obj,
00227     IrotCookie *cookie)
00228 {
00229     const struct rot_entry *rot_entry;
00230 
00231     WINE_TRACE("%p\n", moniker_data);
00232 
00233     *cookie = 0;
00234 
00235     EnterCriticalSection(&csRunningObjectTable);
00236 
00237     LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
00238     {
00239         HRESULT hr = S_OK;
00240         if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
00241             !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
00242         {
00243             *obj = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->object->ulCntData]));
00244             if (*obj)
00245             {
00246                 (*obj)->ulCntData = rot_entry->object->ulCntData;
00247                 memcpy((*obj)->abData, rot_entry->object->abData, (*obj)->ulCntData);
00248 
00249                 *cookie = rot_entry->cookie;
00250             }
00251             else
00252                 hr = E_OUTOFMEMORY;
00253 
00254             LeaveCriticalSection(&csRunningObjectTable);
00255 
00256             return hr;
00257         }
00258     }
00259 
00260     LeaveCriticalSection(&csRunningObjectTable);
00261 
00262     return MK_E_UNAVAILABLE;
00263 }
00264 
00265 HRESULT IrotNoteChangeTime(
00266     IrotHandle h,
00267     IrotCookie cookie,
00268     const FILETIME *last_modified_time)
00269 {
00270     struct rot_entry *rot_entry;
00271 
00272     WINE_TRACE("%d %p\n", cookie, last_modified_time);
00273 
00274     EnterCriticalSection(&csRunningObjectTable);
00275     LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, struct rot_entry, entry)
00276     {
00277         if (rot_entry->cookie == cookie)
00278         {
00279             rot_entry->last_modified = *last_modified_time;
00280             LeaveCriticalSection(&csRunningObjectTable);
00281             return S_OK;
00282         }
00283     }
00284     LeaveCriticalSection(&csRunningObjectTable);
00285 
00286     return E_INVALIDARG;
00287 }
00288 
00289 HRESULT IrotGetTimeOfLastChange(
00290     IrotHandle h,
00291     const MonikerComparisonData *moniker_data,
00292     FILETIME *time)
00293 {
00294     const struct rot_entry *rot_entry;
00295     HRESULT hr = MK_E_UNAVAILABLE;
00296 
00297     WINE_TRACE("%p\n", moniker_data);
00298 
00299     memset(time, 0, sizeof(*time));
00300 
00301     EnterCriticalSection(&csRunningObjectTable);
00302     LIST_FOR_EACH_ENTRY(rot_entry, &RunningObjectTable, const struct rot_entry, entry)
00303     {
00304         if ((rot_entry->moniker_data->ulCntData == moniker_data->ulCntData) &&
00305             !memcmp(&moniker_data->abData, &rot_entry->moniker_data->abData, moniker_data->ulCntData))
00306         {
00307             *time = rot_entry->last_modified;
00308             hr = S_OK;
00309             break;
00310         }
00311     }
00312     LeaveCriticalSection(&csRunningObjectTable);
00313 
00314     return hr;
00315 }
00316 
00317 HRESULT IrotEnumRunning(
00318     IrotHandle h,
00319     PInterfaceList *list)
00320 {
00321     const struct rot_entry *rot_entry;
00322     HRESULT hr = S_OK;
00323     ULONG moniker_count = 0;
00324     ULONG i = 0;
00325 
00326     WINE_TRACE("\n");
00327 
00328     EnterCriticalSection(&csRunningObjectTable);
00329 
00330     LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
00331         moniker_count++;
00332 
00333     *list = MIDL_user_allocate(FIELD_OFFSET(InterfaceList, interfaces[moniker_count]));
00334     if (*list)
00335     {
00336         (*list)->size = moniker_count;
00337         LIST_FOR_EACH_ENTRY( rot_entry, &RunningObjectTable, const struct rot_entry, entry )
00338         {
00339             (*list)->interfaces[i] = MIDL_user_allocate(FIELD_OFFSET(InterfaceData, abData[rot_entry->moniker->ulCntData]));
00340             if (!(*list)->interfaces[i])
00341             {
00342                 ULONG end = i - 1;
00343                 for (i = 0; i < end; i++)
00344                     MIDL_user_free((*list)->interfaces[i]);
00345                 MIDL_user_free(*list);
00346                 hr = E_OUTOFMEMORY;
00347                 break;
00348             }
00349             (*list)->interfaces[i]->ulCntData = rot_entry->moniker->ulCntData;
00350             memcpy((*list)->interfaces[i]->abData, rot_entry->moniker->abData, rot_entry->moniker->ulCntData);
00351             i++;
00352         }
00353     }
00354     else
00355         hr = E_OUTOFMEMORY;
00356 
00357     LeaveCriticalSection(&csRunningObjectTable);
00358 
00359     return hr;
00360 }
00361 
00362 void __RPC_USER IrotContextHandle_rundown(IrotContextHandle ctxt_handle)
00363 {
00364     struct rot_entry *rot_entry = ctxt_handle;
00365     EnterCriticalSection(&csRunningObjectTable);
00366     list_remove(&rot_entry->entry);
00367     LeaveCriticalSection(&csRunningObjectTable);
00368     rot_entry_release(rot_entry);
00369 }
00370 
00371 void * __RPC_USER MIDL_user_allocate(SIZE_T size)
00372 {
00373     return HeapAlloc(GetProcessHeap(), 0, size);
00374 }
00375 
00376 void __RPC_USER MIDL_user_free(void * p)
00377 {
00378     HeapFree(GetProcessHeap(), 0, p);
00379 }

Generated on Sun May 27 2012 04:17:54 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.