INT21_GetFreeDiskSpace(): The drive parameter is found in the DL
[wine] / dlls / user / property.c
1 /*
2  * Window properties
3  *
4  * Copyright 1995, 1996, 2001 Alexandre Julliard
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 #include <string.h>
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "wownt32.h"
28 #include "wine/winuser16.h"
29 #include "wine/server.h"
30 #include "win.h"
31
32 /* size of buffer needed to store an atom string */
33 #define ATOM_BUFFER_SIZE 256
34
35
36 /***********************************************************************
37  *              get_properties
38  *
39  * Retrieve the list of properties of a given window.
40  * Returned buffer must be freed by caller.
41  */
42 static property_data_t *get_properties( HWND hwnd, int *count )
43 {
44     property_data_t *data;
45     int total = 32;
46
47     while (total)
48     {
49         int res = 0;
50         if (!(data = HeapAlloc( GetProcessHeap(), 0, total * sizeof(*data) ))) break;
51         *count = 0;
52         SERVER_START_REQ( get_window_properties )
53         {
54             req->window = hwnd;
55             wine_server_add_data( req, data, total * sizeof(*data) );
56             if (!wine_server_call( req )) res = reply->total;
57         }
58         SERVER_END_REQ;
59         if (res && res <= total)
60         {
61             *count = res;
62             return data;
63         }
64         HeapFree( GetProcessHeap(), 0, data );
65         total = res;  /* restart with larger buffer */
66     }
67     return NULL;
68 }
69
70
71 /***********************************************************************
72  *              EnumPropsA_relay
73  *
74  * relay to call the EnumProps callback function from EnumPropsEx
75  */
76 static BOOL CALLBACK EnumPropsA_relay( HWND hwnd, LPCSTR str, HANDLE handle, ULONG_PTR lparam )
77 {
78     PROPENUMPROCA func = (PROPENUMPROCA)lparam;
79     return func( hwnd, str, handle );
80 }
81
82
83 /***********************************************************************
84  *              EnumPropsW_relay
85  *
86  * relay to call the EnumProps callback function from EnumPropsEx
87  */
88 static BOOL CALLBACK EnumPropsW_relay( HWND hwnd, LPCWSTR str, HANDLE handle, ULONG_PTR lparam )
89 {
90     PROPENUMPROCW func = (PROPENUMPROCW)lparam;
91     return func( hwnd, str, handle );
92 }
93
94
95 /***********************************************************************
96  *              EnumPropsA   (USER32.@)
97  */
98 INT WINAPI EnumPropsA( HWND hwnd, PROPENUMPROCA func )
99 {
100     return EnumPropsExA( hwnd, EnumPropsA_relay, (LPARAM)func );
101 }
102
103
104 /***********************************************************************
105  *              EnumPropsW   (USER32.@)
106  */
107 INT WINAPI EnumPropsW( HWND hwnd, PROPENUMPROCW func )
108 {
109     return EnumPropsExW( hwnd, EnumPropsW_relay, (LPARAM)func );
110 }
111
112
113 /***********************************************************************
114  *              GetPropA   (USER32.@)
115  */
116 HANDLE WINAPI GetPropA( HWND hwnd, LPCSTR str )
117 {
118     ATOM atom;
119     HANDLE ret = 0;
120
121     if (!HIWORD(str)) atom = LOWORD(str);
122     else if (!(atom = GlobalFindAtomA( str ))) return 0;
123
124     SERVER_START_REQ( get_window_property )
125     {
126         req->window = hwnd;
127         req->atom = atom;
128         if (!wine_server_call_err( req )) ret = reply->handle;
129     }
130     SERVER_END_REQ;
131     return ret;
132 }
133
134
135 /***********************************************************************
136  *              GetPropW   (USER32.@)
137  */
138 HANDLE WINAPI GetPropW( HWND hwnd, LPCWSTR str )
139 {
140     ATOM atom;
141     HANDLE ret = 0;
142
143     if (!HIWORD(str)) atom = LOWORD(str);
144     else if (!(atom = GlobalFindAtomW( str ))) return 0;
145
146     SERVER_START_REQ( get_window_property )
147     {
148         req->window = hwnd;
149         req->atom = atom;
150         if (!wine_server_call_err( req )) ret = reply->handle;
151     }
152     SERVER_END_REQ;
153     return ret;
154 }
155
156
157 /***********************************************************************
158  *              SetPropA   (USER32.@)
159  */
160 BOOL WINAPI SetPropA( HWND hwnd, LPCSTR str, HANDLE handle )
161 {
162     ATOM atom;
163     BOOL ret;
164
165     if (!HIWORD(str)) atom = LOWORD(str);
166     else if (!(atom = GlobalAddAtomA( str ))) return FALSE;
167
168     SERVER_START_REQ( set_window_property )
169     {
170         req->window = hwnd;
171         req->atom   = atom;
172         req->string = (HIWORD(str) != 0);
173         req->handle = handle;
174         ret = !wine_server_call_err( req );
175     }
176     SERVER_END_REQ;
177
178     if (HIWORD(str)) GlobalDeleteAtom( atom );
179     return ret;
180 }
181
182
183 /***********************************************************************
184  *              SetPropW   (USER32.@)
185  */
186 BOOL WINAPI SetPropW( HWND hwnd, LPCWSTR str, HANDLE handle )
187 {
188     ATOM atom;
189     BOOL ret;
190
191     if (!HIWORD(str)) atom = LOWORD(str);
192     else if (!(atom = GlobalAddAtomW( str ))) return FALSE;
193
194     SERVER_START_REQ( set_window_property )
195     {
196         req->window = hwnd;
197         req->atom   = atom;
198         req->string = (HIWORD(str) != 0);
199         req->handle = handle;
200         ret = !wine_server_call_err( req );
201     }
202     SERVER_END_REQ;
203
204     if (HIWORD(str)) GlobalDeleteAtom( atom );
205     return ret;
206 }
207
208
209 /***********************************************************************
210  *              RemovePropA   (USER32.@)
211  */
212 HANDLE WINAPI RemovePropA( HWND hwnd, LPCSTR str )
213 {
214     ATOM atom;
215     HANDLE ret = 0;
216
217     if (!HIWORD(str)) return RemovePropW( hwnd, MAKEINTATOMW(LOWORD(str)) );
218
219     if ((atom = GlobalAddAtomA( str )))
220     {
221         ret = RemovePropW( hwnd, MAKEINTATOMW(atom) );
222         GlobalDeleteAtom( atom );
223     }
224     return ret;
225 }
226
227
228 /***********************************************************************
229  *              RemovePropW   (USER32.@)
230  */
231 HANDLE WINAPI RemovePropW( HWND hwnd, LPCWSTR str )
232 {
233     ATOM atom;
234     HANDLE ret = 0;
235
236     if (!HIWORD(str)) atom = LOWORD(str);
237     else if (!(atom = GlobalAddAtomW( str ))) return 0;
238
239     SERVER_START_REQ( remove_window_property )
240     {
241         req->window = hwnd;
242         req->atom   = atom;
243         if (!wine_server_call_err( req )) ret = reply->handle;
244     }
245     SERVER_END_REQ;
246
247     if (HIWORD(str)) GlobalDeleteAtom( atom );
248     return ret;
249 }
250
251
252 /***********************************************************************
253  *              EnumPropsExA   (USER32.@)
254  */
255 INT WINAPI EnumPropsExA(HWND hwnd, PROPENUMPROCEXA func, LPARAM lParam)
256 {
257     int ret = -1, i, count;
258     property_data_t *list = get_properties( hwnd, &count );
259
260     if (list)
261     {
262         for (i = 0; i < count; i++)
263         {
264             char string[ATOM_BUFFER_SIZE];
265             if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
266             if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
267         }
268         HeapFree( GetProcessHeap(), 0, list );
269     }
270     return ret;
271 }
272
273
274 /***********************************************************************
275  *              EnumPropsExW   (USER32.@)
276  */
277 INT WINAPI EnumPropsExW(HWND hwnd, PROPENUMPROCEXW func, LPARAM lParam)
278 {
279     int ret = -1, i, count;
280     property_data_t *list = get_properties( hwnd, &count );
281
282     if (list)
283     {
284         for (i = 0; i < count; i++)
285         {
286             WCHAR string[ATOM_BUFFER_SIZE];
287             if (!GlobalGetAtomNameW( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
288             if (!(ret = func( hwnd, string, list[i].handle, lParam ))) break;
289         }
290         HeapFree( GetProcessHeap(), 0, list );
291     }
292     return ret;
293 }
294
295
296 /***********************************************************************
297  *              EnumProps   (USER.27)
298  */
299 INT16 WINAPI EnumProps16( HWND16 hwnd, PROPENUMPROC16 func )
300 {
301     int ret = -1, i, count;
302     property_data_t *list = get_properties( HWND_32(hwnd), &count );
303
304     if (list)
305     {
306         char string[ATOM_BUFFER_SIZE];
307         SEGPTR segptr = MapLS( string );
308         WORD args[4];
309         DWORD result;
310
311         for (i = 0; i < count; i++)
312         {
313             if (list[i].string)  /* it was a string originally */
314             {
315                 if (!GlobalGetAtomNameA( list[i].atom, string, ATOM_BUFFER_SIZE )) continue;
316                 args[3] = hwnd;
317                 args[2] = SELECTOROF(segptr);
318                 args[1] = OFFSETOF(segptr);
319                 args[0] = LOWORD(list[i].handle);
320             }
321             else
322             {
323                 args[3] = hwnd;
324                 args[2] = 0;
325                 args[1] = list[i].atom;
326                 args[0] = LOWORD(list[i].handle);
327             }
328             WOWCallback16Ex( (DWORD)func, WCB16_PASCAL, sizeof(args), args, &result );
329             if (!(ret = LOWORD(result))) break;
330         }
331         UnMapLS( segptr );
332         HeapFree( GetProcessHeap(), 0, list );
333     }
334     return ret;
335 }