Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenirotp.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
1.7.6.1
|