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

handle.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 doxygen 1.7.6.1

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