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

Wine Cross Reference
wine/dlls/msi/handle.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  * Implementation of the Microsoft Installer (msi.dll)
  3  *
  4  * Copyright 2002-2004 Mike McCormack for CodeWeavers
  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 #define COBJMACROS
 22 
 23 #include <stdarg.h>
 24 
 25 #include "windef.h"
 26 #include "winbase.h"
 27 #include "winreg.h"
 28 #include "shlwapi.h"
 29 #include "wine/debug.h"
 30 #include "msi.h"
 31 #include "msiquery.h"
 32 #include "msipriv.h"
 33 
 34 WINE_DEFAULT_DEBUG_CHANNEL(msi);
 35 
 36 static CRITICAL_SECTION MSI_handle_cs;
 37 static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =
 38 {
 39     0, 0, &MSI_handle_cs,
 40     { &MSI_handle_cs_debug.ProcessLocksList, 
 41       &MSI_handle_cs_debug.ProcessLocksList },
 42       0, 0, { (DWORD_PTR)(__FILE__ ": MSI_handle_cs") }
 43 };
 44 static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
 45 
 46 static CRITICAL_SECTION MSI_object_cs;
 47 static CRITICAL_SECTION_DEBUG MSI_object_cs_debug =
 48 {
 49     0, 0, &MSI_object_cs,
 50     { &MSI_object_cs_debug.ProcessLocksList, 
 51       &MSI_object_cs_debug.ProcessLocksList },
 52       0, 0, { (DWORD_PTR)(__FILE__ ": MSI_object_cs") }
 53 };
 54 static CRITICAL_SECTION MSI_object_cs = { &MSI_object_cs_debug, -1, 0, 0, 0, 0 };
 55 
 56 typedef struct msi_handle_info_t
 57 {
 58     BOOL remote;
 59     union {
 60         MSIOBJECTHDR *obj;
 61         IUnknown *unk;
 62     } u;
 63     DWORD dwThreadId;
 64 } msi_handle_info;
 65 
 66 static msi_handle_info *msihandletable = NULL;
 67 static unsigned int msihandletable_size = 0;
 68 
 69 void msi_free_handle_table(void)
 70 {
 71     msi_free( msihandletable );
 72     msihandletable = NULL;
 73     msihandletable_size = 0;
 74 }
 75 
 76 static MSIHANDLE alloc_handle_table_entry(void)
 77 {
 78     UINT i;
 79 
 80     /* find a slot */
 81     for(i=0; i<msihandletable_size; i++)
 82         if( !msihandletable[i].u.obj && !msihandletable[i].u.unk )
 83             break;
 84     if( i==msihandletable_size )
 85     {
 86         msi_handle_info *p;
 87         int newsize;
 88         if (msihandletable_size == 0)
 89         {
 90             newsize = 256;
 91             p = msi_alloc_zero(newsize*sizeof(msi_handle_info));
 92         }
 93         else
 94         {
 95             newsize = msihandletable_size * 2;
 96             p = msi_realloc_zero(msihandletable,
 97                             newsize*sizeof(msi_handle_info));
 98         }
 99         if (!p)
100             return 0;
101         msihandletable = p;
102         msihandletable_size = newsize;
103     }
104     return i + 1;
105 }
106 
107 MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
108 {
109     msi_handle_info *entry;
110     MSIHANDLE ret;
111 
112     EnterCriticalSection( &MSI_handle_cs );
113 
114     ret = alloc_handle_table_entry();
115     if (ret)
116     {
117         entry = &msihandletable[ ret - 1 ];
118         msiobj_addref( obj );
119         entry->u.obj = obj;
120         entry->dwThreadId = GetCurrentThreadId();
121         entry->remote = FALSE;
122     }
123 
124     LeaveCriticalSection( &MSI_handle_cs );
125 
126     TRACE("%p -> %d\n", obj, ret );
127 
128     return ret;
129 }
130 
131 MSIHANDLE alloc_msi_remote_handle( IUnknown *unk )
132 {
133     msi_handle_info *entry;
134     MSIHANDLE ret;
135 
136     EnterCriticalSection( &MSI_handle_cs );
137 
138     ret = alloc_handle_table_entry();
139     if (ret)
140     {
141         entry = &msihandletable[ ret - 1 ];
142         IUnknown_AddRef( unk );
143         entry->u.unk = unk;
144         entry->dwThreadId = GetCurrentThreadId();
145         entry->remote = TRUE;
146     }
147 
148     LeaveCriticalSection( &MSI_handle_cs );
149 
150     TRACE("%p -> %d\n", unk, ret);
151 
152     return ret;
153 }
154 
155 void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
156 {
157     MSIOBJECTHDR *ret = NULL;
158 
159     EnterCriticalSection( &MSI_handle_cs );
160     handle--;
161     if( handle >= msihandletable_size )
162         goto out;
163     if( msihandletable[handle].remote)
164         goto out;
165     if( !msihandletable[handle].u.obj )
166         goto out;
167     if( msihandletable[handle].u.obj->magic != MSIHANDLE_MAGIC )
168         goto out;
169     if( type && (msihandletable[handle].u.obj->type != type) )
170         goto out;
171     ret = msihandletable[handle].u.obj;
172     msiobj_addref( ret );
173 
174 out:
175     LeaveCriticalSection( &MSI_handle_cs );
176 
177     return ret;
178 }
179 
180 IUnknown *msi_get_remote( MSIHANDLE handle )
181 {
182     IUnknown *unk = NULL;
183 
184     EnterCriticalSection( &MSI_handle_cs );
185     handle--;
186     if( handle>=msihandletable_size )
187         goto out;
188     if( !msihandletable[handle].remote)
189         goto out;
190     unk = msihandletable[handle].u.unk;
191     if( unk )
192         IUnknown_AddRef( unk );
193 
194 out:
195     LeaveCriticalSection( &MSI_handle_cs );
196 
197     return unk;
198 }
199 
200 void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
201 {
202     MSIOBJECTHDR *info;
203 
204     info = msi_alloc_zero( size );
205     if( info )
206     {
207         info->magic = MSIHANDLE_MAGIC;
208         info->type = type;
209         info->refcount = 1;
210         info->destructor = destroy;
211     }
212 
213     return info;
214 }
215 
216 void msiobj_addref( MSIOBJECTHDR *info )
217 {
218     if( !info )
219         return;
220 
221     if( info->magic != MSIHANDLE_MAGIC )
222     {
223         ERR("Invalid handle!\n");
224         return;
225     }
226 
227     InterlockedIncrement(&info->refcount);
228 }
229 
230 void msiobj_lock( MSIOBJECTHDR *info )
231 {
232     EnterCriticalSection( &MSI_object_cs );
233 }
234 
235 void msiobj_unlock( MSIOBJECTHDR *info )
236 {
237     LeaveCriticalSection( &MSI_object_cs );
238 }
239 
240 int msiobj_release( MSIOBJECTHDR *info )
241 {
242     int ret;
243 
244     if( !info )
245         return -1;
246 
247     if( info->magic != MSIHANDLE_MAGIC )
248     {
249         ERR("Invalid handle!\n");
250         return -1;
251     }
252 
253     ret = InterlockedDecrement( &info->refcount );
254     if( ret==0 )
255     {
256         if( info->destructor )
257             info->destructor( info );
258         msi_free( info );
259         TRACE("object %p destroyed\n", info);
260     }
261 
262     return ret;
263 }
264 
265 /***********************************************************
266  *   MsiCloseHandle   [MSI.@]
267  */
268 UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
269 {
270     MSIOBJECTHDR *info = NULL;
271     UINT ret = ERROR_INVALID_HANDLE;
272 
273     TRACE("%x\n",handle);
274 
275     if (!handle)
276         return ERROR_SUCCESS;
277 
278     EnterCriticalSection( &MSI_handle_cs );
279 
280     handle--;
281     if (handle >= msihandletable_size)
282         goto out;
283 
284     if (msihandletable[handle].remote)
285     {
286         IUnknown_Release( msihandletable[handle].u.unk );
287     }
288     else
289     {
290         info = msihandletable[handle].u.obj;
291         if( !info )
292             goto out;
293 
294         if( info->magic != MSIHANDLE_MAGIC )
295         {
296             ERR("Invalid handle!\n");
297             goto out;
298         }
299     }
300 
301     msihandletable[handle].u.obj = NULL;
302     msihandletable[handle].remote = 0;
303     msihandletable[handle].dwThreadId = 0;
304 
305     ret = ERROR_SUCCESS;
306 
307     TRACE("handle %x destroyed\n", handle+1);
308 out:
309     LeaveCriticalSection( &MSI_handle_cs );
310     if( info )
311         msiobj_release( info );
312 
313     return ret;
314 }
315 
316 /***********************************************************
317  *   MsiCloseAllHandles   [MSI.@]
318  *
319  *  Closes all handles owned by the current thread
320  *
321  *  RETURNS:
322  *   The number of handles closed
323  */
324 UINT WINAPI MsiCloseAllHandles(void)
325 {
326     UINT i, n=0;
327 
328     TRACE("\n");
329 
330     EnterCriticalSection( &MSI_handle_cs );
331     for(i=0; i<msihandletable_size; i++)
332     {
333         if(msihandletable[i].dwThreadId == GetCurrentThreadId())
334         {
335             LeaveCriticalSection( &MSI_handle_cs );
336             MsiCloseHandle( i+1 );
337             EnterCriticalSection( &MSI_handle_cs );
338             n++;
339         }
340     }
341     LeaveCriticalSection( &MSI_handle_cs );
342 
343     return n;
344 }
345 

~ [ 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.