Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenhandle.c
Go to the documentation of this file.
00001 /* 00002 * Implementation of the Microsoft Installer (msi.dll) 00003 * 00004 * Copyright 2002-2004 Mike McCormack for CodeWeavers 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 #define COBJMACROS 00022 00023 #include <stdarg.h> 00024 00025 #include "windef.h" 00026 #include "winbase.h" 00027 #include "winreg.h" 00028 #include "shlwapi.h" 00029 #include "wine/debug.h" 00030 #include "msi.h" 00031 #include "msiquery.h" 00032 #include "msipriv.h" 00033 00034 WINE_DEFAULT_DEBUG_CHANNEL(msi); 00035 00036 static CRITICAL_SECTION MSI_handle_cs; 00037 static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug = 00038 { 00039 0, 0, &MSI_handle_cs, 00040 { &MSI_handle_cs_debug.ProcessLocksList, 00041 &MSI_handle_cs_debug.ProcessLocksList }, 00042 0, 0, { (DWORD_PTR)(__FILE__ ": MSI_handle_cs") } 00043 }; 00044 static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 }; 00045 00046 static CRITICAL_SECTION MSI_object_cs; 00047 static CRITICAL_SECTION_DEBUG MSI_object_cs_debug = 00048 { 00049 0, 0, &MSI_object_cs, 00050 { &MSI_object_cs_debug.ProcessLocksList, 00051 &MSI_object_cs_debug.ProcessLocksList }, 00052 0, 0, { (DWORD_PTR)(__FILE__ ": MSI_object_cs") } 00053 }; 00054 static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 }; 00055 00056 typedef struct msi_handle_info_t 00057 { 00058 BOOL remote; 00059 union { 00060 MSIOBJECTHDR *obj; 00061 IUnknown *unk; 00062 } u; 00063 DWORD dwThreadId; 00064 } msi_handle_info; 00065 00066 static msi_handle_info *msihandletable = NULL; 00067 static unsigned int msihandletable_size = 0; 00068 00069 void msi_free_handle_table(void) 00070 { 00071 msi_free( msihandletable ); 00072 msihandletable = NULL; 00073 msihandletable_size = 0; 00074 DeleteCriticalSection(&MSI_handle_cs); 00075 DeleteCriticalSection(&MSI_object_cs); 00076 } 00077 00078 static MSIHANDLE alloc_handle_table_entry(void) 00079 { 00080 UINT i; 00081 00082 /* find a slot */ 00083 for(i=0; i<msihandletable_size; i++) 00084 if( !msihandletable[i].u.obj && !msihandletable[i].u.unk ) 00085 break; 00086 if( i==msihandletable_size ) 00087 { 00088 msi_handle_info *p; 00089 int newsize; 00090 if (msihandletable_size == 0) 00091 { 00092 newsize = 256; 00093 p = msi_alloc_zero(newsize*sizeof(msi_handle_info)); 00094 } 00095 else 00096 { 00097 newsize = msihandletable_size * 2; 00098 p = msi_realloc_zero(msihandletable, 00099 newsize*sizeof(msi_handle_info)); 00100 } 00101 if (!p) 00102 return 0; 00103 msihandletable = p; 00104 msihandletable_size = newsize; 00105 } 00106 return i + 1; 00107 } 00108 00109 MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj ) 00110 { 00111 msi_handle_info *entry; 00112 MSIHANDLE ret; 00113 00114 EnterCriticalSection( &MSI_handle_cs ); 00115 00116 ret = alloc_handle_table_entry(); 00117 if (ret) 00118 { 00119 entry = &msihandletable[ ret - 1 ]; 00120 msiobj_addref( obj ); 00121 entry->u.obj = obj; 00122 entry->dwThreadId = GetCurrentThreadId(); 00123 entry->remote = FALSE; 00124 } 00125 00126 LeaveCriticalSection( &MSI_handle_cs ); 00127 00128 TRACE("%p -> %d\n", obj, ret ); 00129 00130 return ret; 00131 } 00132 00133 MSIHANDLE alloc_msi_remote_handle( IUnknown *unk ) 00134 { 00135 msi_handle_info *entry; 00136 MSIHANDLE ret; 00137 00138 EnterCriticalSection( &MSI_handle_cs ); 00139 00140 ret = alloc_handle_table_entry(); 00141 if (ret) 00142 { 00143 entry = &msihandletable[ ret - 1 ]; 00144 IUnknown_AddRef( unk ); 00145 entry->u.unk = unk; 00146 entry->dwThreadId = GetCurrentThreadId(); 00147 entry->remote = TRUE; 00148 } 00149 00150 LeaveCriticalSection( &MSI_handle_cs ); 00151 00152 TRACE("%p -> %d\n", unk, ret); 00153 00154 return ret; 00155 } 00156 00157 void *msihandle2msiinfo(MSIHANDLE handle, UINT type) 00158 { 00159 MSIOBJECTHDR *ret = NULL; 00160 00161 EnterCriticalSection( &MSI_handle_cs ); 00162 handle--; 00163 if( handle >= msihandletable_size ) 00164 goto out; 00165 if( msihandletable[handle].remote) 00166 goto out; 00167 if( !msihandletable[handle].u.obj ) 00168 goto out; 00169 if( msihandletable[handle].u.obj->magic != MSIHANDLE_MAGIC ) 00170 goto out; 00171 if( type && (msihandletable[handle].u.obj->type != type) ) 00172 goto out; 00173 ret = msihandletable[handle].u.obj; 00174 msiobj_addref( ret ); 00175 00176 out: 00177 LeaveCriticalSection( &MSI_handle_cs ); 00178 00179 return ret; 00180 } 00181 00182 IUnknown *msi_get_remote( MSIHANDLE handle ) 00183 { 00184 IUnknown *unk = NULL; 00185 00186 EnterCriticalSection( &MSI_handle_cs ); 00187 handle--; 00188 if( handle>=msihandletable_size ) 00189 goto out; 00190 if( !msihandletable[handle].remote) 00191 goto out; 00192 unk = msihandletable[handle].u.unk; 00193 if( unk ) 00194 IUnknown_AddRef( unk ); 00195 00196 out: 00197 LeaveCriticalSection( &MSI_handle_cs ); 00198 00199 return unk; 00200 } 00201 00202 void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy ) 00203 { 00204 MSIOBJECTHDR *info; 00205 00206 info = msi_alloc_zero( size ); 00207 if( info ) 00208 { 00209 info->magic = MSIHANDLE_MAGIC; 00210 info->type = type; 00211 info->refcount = 1; 00212 info->destructor = destroy; 00213 } 00214 00215 return info; 00216 } 00217 00218 void msiobj_addref( MSIOBJECTHDR *info ) 00219 { 00220 if( !info ) 00221 return; 00222 00223 if( info->magic != MSIHANDLE_MAGIC ) 00224 { 00225 ERR("Invalid handle!\n"); 00226 return; 00227 } 00228 00229 InterlockedIncrement(&info->refcount); 00230 } 00231 00232 void msiobj_lock( MSIOBJECTHDR *info ) 00233 { 00234 EnterCriticalSection( &MSI_object_cs ); 00235 } 00236 00237 void msiobj_unlock( MSIOBJECTHDR *info ) 00238 { 00239 LeaveCriticalSection( &MSI_object_cs ); 00240 } 00241 00242 int msiobj_release( MSIOBJECTHDR *info ) 00243 { 00244 int ret; 00245 00246 if( !info ) 00247 return -1; 00248 00249 if( info->magic != MSIHANDLE_MAGIC ) 00250 { 00251 ERR("Invalid handle!\n"); 00252 return -1; 00253 } 00254 00255 ret = InterlockedDecrement( &info->refcount ); 00256 if( ret==0 ) 00257 { 00258 if( info->destructor ) 00259 info->destructor( info ); 00260 msi_free( info ); 00261 TRACE("object %p destroyed\n", info); 00262 } 00263 00264 return ret; 00265 } 00266 00267 /*********************************************************** 00268 * MsiCloseHandle [MSI.@] 00269 */ 00270 UINT WINAPI MsiCloseHandle(MSIHANDLE handle) 00271 { 00272 MSIOBJECTHDR *info = NULL; 00273 UINT ret = ERROR_INVALID_HANDLE; 00274 00275 TRACE("%x\n",handle); 00276 00277 if (!handle) 00278 return ERROR_SUCCESS; 00279 00280 EnterCriticalSection( &MSI_handle_cs ); 00281 00282 handle--; 00283 if (handle >= msihandletable_size) 00284 goto out; 00285 00286 if (msihandletable[handle].remote) 00287 { 00288 IUnknown_Release( msihandletable[handle].u.unk ); 00289 } 00290 else 00291 { 00292 info = msihandletable[handle].u.obj; 00293 if( !info ) 00294 goto out; 00295 00296 if( info->magic != MSIHANDLE_MAGIC ) 00297 { 00298 ERR("Invalid handle!\n"); 00299 goto out; 00300 } 00301 } 00302 00303 msihandletable[handle].u.obj = NULL; 00304 msihandletable[handle].remote = 0; 00305 msihandletable[handle].dwThreadId = 0; 00306 00307 ret = ERROR_SUCCESS; 00308 00309 TRACE("handle %x destroyed\n", handle+1); 00310 out: 00311 LeaveCriticalSection( &MSI_handle_cs ); 00312 if( info ) 00313 msiobj_release( info ); 00314 00315 return ret; 00316 } 00317 00318 /*********************************************************** 00319 * MsiCloseAllHandles [MSI.@] 00320 * 00321 * Closes all handles owned by the current thread 00322 * 00323 * RETURNS: 00324 * The number of handles closed 00325 */ 00326 UINT WINAPI MsiCloseAllHandles(void) 00327 { 00328 UINT i, n=0; 00329 00330 TRACE("\n"); 00331 00332 EnterCriticalSection( &MSI_handle_cs ); 00333 for(i=0; i<msihandletable_size; i++) 00334 { 00335 if(msihandletable[i].dwThreadId == GetCurrentThreadId()) 00336 { 00337 LeaveCriticalSection( &MSI_handle_cs ); 00338 MsiCloseHandle( i+1 ); 00339 EnterCriticalSection( &MSI_handle_cs ); 00340 n++; 00341 } 00342 } 00343 LeaveCriticalSection( &MSI_handle_cs ); 00344 00345 return n; 00346 } Generated on Mon May 28 2012 04:24:06 for ReactOS by
1.7.6.1
|