Implement A->W call for GetNamedSecurityInfo.
[wine] / dlls / msi / handle.c
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include <stdarg.h>
22
23 #include "windef.h"
24 #include "winbase.h"
25 #include "winreg.h"
26 #include "shlwapi.h"
27 #include "wine/debug.h"
28 #include "msi.h"
29 #include "msiquery.h"
30 #include "msipriv.h"
31
32 WINE_DEFAULT_DEBUG_CHANNEL(msi);
33
34 static CRITICAL_SECTION MSI_handle_cs;
35 static CRITICAL_SECTION_DEBUG MSI_handle_cs_debug =
36 {
37     0, 0, &MSI_handle_cs,
38     { &MSI_handle_cs_debug.ProcessLocksList, 
39       &MSI_handle_cs_debug.ProcessLocksList },
40       0, 0, { 0, (DWORD)(__FILE__ ": MSI_handle_cs") }
41 };
42 static CRITICAL_SECTION MSI_handle_cs = { &MSI_handle_cs_debug, -1, 0, 0, 0, 0 };
43
44 MSIOBJECTHDR *msihandletable[MSIMAXHANDLES];
45
46 MSIHANDLE alloc_msihandle( MSIOBJECTHDR *obj )
47 {
48     MSIHANDLE ret = 0;
49     UINT i;
50
51     EnterCriticalSection( &MSI_handle_cs );
52
53     /* find a slot */
54     for(i=0; i<MSIMAXHANDLES; i++)
55         if( !msihandletable[i] )
56             break;
57     if( (i>=MSIMAXHANDLES) || msihandletable[i] )
58         goto out;
59
60     msiobj_addref( obj );
61     msihandletable[i] = obj;
62     ret = (MSIHANDLE) (i+1);
63 out:
64     TRACE("%p -> %ld\n", obj, ret );
65
66     LeaveCriticalSection( &MSI_handle_cs );
67     return ret;
68 }
69
70 void *msihandle2msiinfo(MSIHANDLE handle, UINT type)
71 {
72     MSIOBJECTHDR *ret = NULL;
73
74     EnterCriticalSection( &MSI_handle_cs );
75     handle--;
76     if( handle<0 )
77         goto out;
78     if( handle>=MSIMAXHANDLES )
79         goto out;
80     if( !msihandletable[handle] )
81         goto out;
82     if( msihandletable[handle]->magic != MSIHANDLE_MAGIC )
83         goto out;
84     if( type && (msihandletable[handle]->type != type) )
85         goto out;
86     ret = msihandletable[handle];
87     msiobj_addref( ret );
88     
89 out:
90     LeaveCriticalSection( &MSI_handle_cs );
91
92     return (void*) ret;
93 }
94
95 MSIHANDLE msiobj_findhandle( MSIOBJECTHDR *hdr )
96 {
97     MSIHANDLE ret = 0;
98     UINT i;
99
100     TRACE("%p\n", hdr);
101
102     EnterCriticalSection( &MSI_handle_cs );
103     for(i=0; (i<MSIMAXHANDLES) && !ret; i++)
104         if( msihandletable[i] == hdr )
105             ret = i+1;
106     LeaveCriticalSection( &MSI_handle_cs );
107
108     TRACE("%p -> %ld\n", hdr, ret);
109
110     msiobj_addref( hdr );
111     return ret;
112 }
113
114 void *alloc_msiobject(UINT type, UINT size, msihandledestructor destroy )
115 {
116     MSIOBJECTHDR *info;
117
118     info = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, size );
119     if( info )
120     {
121         info->magic = MSIHANDLE_MAGIC;
122         info->type = type;
123         info->refcount = 1;
124         info->destructor = destroy;
125     }
126
127     return info;
128 }
129
130 void msiobj_addref( MSIOBJECTHDR *info )
131 {
132     TRACE("%p\n", info);
133
134     if( !info )
135         return;
136
137     if( info->magic != MSIHANDLE_MAGIC )
138     {
139         ERR("Invalid handle!\n");
140         return;
141     }
142
143     info->refcount++;
144 }
145
146 int msiobj_release( MSIOBJECTHDR *info )
147 {
148     int ret;
149
150     TRACE("%p\n",info);
151
152     if( !info )
153         return -1;
154
155     if( info->magic != MSIHANDLE_MAGIC )
156     {
157         ERR("Invalid handle!\n");
158         return -1;
159     }
160
161     ret = info->refcount--;
162     if (info->refcount == 0)
163     {
164     if( info->destructor )
165             info->destructor( info );
166     HeapFree( GetProcessHeap(), 0, info );
167         TRACE("object %p destroyed\n", info);
168     }
169
170     return ret;
171 }
172
173 UINT WINAPI MsiCloseHandle(MSIHANDLE handle)
174 {
175     MSIOBJECTHDR *info;
176     UINT ret = ERROR_INVALID_HANDLE;
177
178     TRACE("%lx\n",handle);
179
180     EnterCriticalSection( &MSI_handle_cs );
181
182     info = msihandle2msiinfo(handle, 0);
183     if( !info )
184         goto out;
185
186     if( info->magic != MSIHANDLE_MAGIC )
187     {
188         ERR("Invalid handle!\n");
189         goto out;
190     }
191
192     msiobj_release( info );
193     msihandletable[handle-1] = NULL;
194     ret = ERROR_SUCCESS;
195
196     TRACE("handle %lx Destroyed\n", handle);
197 out:
198     LeaveCriticalSection( &MSI_handle_cs );
199     if( info )
200         msiobj_release( info );
201
202     return ret;
203 }
204
205 UINT WINAPI MsiCloseAllHandles(void)
206 {
207     UINT i;
208
209     TRACE("\n");
210
211     for(i=0; i<MSIMAXHANDLES; i++)
212         MsiCloseHandle( i+1 );
213
214     return 0;
215 }