Check for failed allocations. Spotted by Martin Bealby.
[reactos.git] / reactos / lib / user32 / windows / prop.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id$
20 *
21 * PROJECT: ReactOS user32.dll
22 * FILE: lib/user32/windows/input.c
23 * PURPOSE: Input
24 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * UPDATE HISTORY:
26 * 09-05-2001 CSH Created
27 */
28
29 /* INCLUDES ******************************************************************/
30
31 #include <user32.h>
32
33 typedef struct _PROPLISTITEM
34 {
35 ATOM Atom;
36 HANDLE Data;
37 } PROPLISTITEM, *PPROPLISTITEM;
38
39 #define ATOM_BUFFER_SIZE 256
40
41 /* FUNCTIONS *****************************************************************/
42
43 /*
44 * @implemented
45 */
46 int STDCALL
47 EnumPropsA(HWND hWnd, PROPENUMPROCA lpEnumFunc)
48 {
49 PPROPLISTITEM pli, i;
50 NTSTATUS Status;
51 DWORD Count;
52 int ret = -1;
53
54 if(!lpEnumFunc)
55 {
56 SetLastError(ERROR_INVALID_PARAMETER);
57 return ret;
58 }
59
60 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
61 if(!NT_SUCCESS(Status))
62 {
63 if(Status == STATUS_INVALID_HANDLE)
64 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
65 else
66 SetLastError(RtlNtStatusToDosError(Status));
67 return ret;
68 }
69
70 if(Count > 0)
71 {
72 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
73 if (pli == NULL)
74 {
75 SetLastError(ERROR_OUTOFMEMORY);
76 return -1;
77 }
78
79 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
80 if(!NT_SUCCESS(Status))
81 {
82 RtlFreeHeap(GetProcessHeap(), 0, pli);
83 if(Status == STATUS_INVALID_HANDLE)
84 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
85 else
86 SetLastError(RtlNtStatusToDosError(Status));
87 return ret;
88 }
89
90 i = pli;
91 for(; Count > 0; Count--, i++)
92 {
93 char str[ATOM_BUFFER_SIZE];
94
95 if(!GlobalGetAtomNameA(i->Atom, str, ATOM_BUFFER_SIZE))
96 continue;
97
98 ret = lpEnumFunc(hWnd, str, i->Data);
99 if(!ret)
100 break;
101 }
102
103 RtlFreeHeap(GetProcessHeap(), 0, pli);
104 }
105
106 return ret;
107 }
108
109
110 /*
111 * @implemented
112 */
113 int STDCALL
114 EnumPropsExA(HWND hWnd, PROPENUMPROCEXA lpEnumFunc, LPARAM lParam)
115 {
116 PPROPLISTITEM pli, i;
117 NTSTATUS Status;
118 DWORD Count;
119 int ret = -1;
120
121 if(!lpEnumFunc)
122 {
123 SetLastError(ERROR_INVALID_PARAMETER);
124 return ret;
125 }
126
127 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
128 if(!NT_SUCCESS(Status))
129 {
130 if(Status == STATUS_INVALID_HANDLE)
131 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
132 else
133 SetLastError(RtlNtStatusToDosError(Status));
134 return ret;
135 }
136
137 if(Count > 0)
138 {
139 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
140 if (pli == NULL)
141 {
142 SetLastError(ERROR_OUTOFMEMORY);
143 return -1;
144 }
145
146 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
147 if(!NT_SUCCESS(Status))
148 {
149 RtlFreeHeap(GetProcessHeap(), 0, pli);
150 if(Status == STATUS_INVALID_HANDLE)
151 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
152 else
153 SetLastError(RtlNtStatusToDosError(Status));
154 return ret;
155 }
156
157 i = pli;
158 for(; Count > 0; Count--, i++)
159 {
160 char str[ATOM_BUFFER_SIZE];
161
162 if(!GlobalGetAtomNameA(i->Atom, str, ATOM_BUFFER_SIZE))
163 continue;
164
165 ret = lpEnumFunc(hWnd, str, i->Data, lParam);
166 if(!ret)
167 break;
168 }
169
170 RtlFreeHeap(GetProcessHeap(), 0, pli);
171 }
172
173 return ret;
174 }
175
176
177 /*
178 * @implemented
179 */
180 int STDCALL
181 EnumPropsExW(HWND hWnd, PROPENUMPROCEXW lpEnumFunc, LPARAM lParam)
182 {
183 PPROPLISTITEM pli, i;
184 NTSTATUS Status;
185 DWORD Count;
186 int ret = -1;
187
188 if(!lpEnumFunc)
189 {
190 SetLastError(ERROR_INVALID_PARAMETER);
191 return ret;
192 }
193
194 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
195 if(!NT_SUCCESS(Status))
196 {
197 if(Status == STATUS_INVALID_HANDLE)
198 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
199 else
200 SetLastError(RtlNtStatusToDosError(Status));
201 return ret;
202 }
203
204 if(Count > 0)
205 {
206 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
207 if (pli == NULL)
208 {
209 SetLastError(ERROR_OUTOFMEMORY);
210 return -1;
211 }
212
213 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
214 if(!NT_SUCCESS(Status))
215 {
216 RtlFreeHeap(GetProcessHeap(), 0, pli);
217 if(Status == STATUS_INVALID_HANDLE)
218 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
219 else
220 SetLastError(RtlNtStatusToDosError(Status));
221 return ret;
222 }
223
224 i = pli;
225 for(; Count > 0; Count--, i++)
226 {
227 WCHAR str[ATOM_BUFFER_SIZE];
228
229 if(!GlobalGetAtomNameW(i->Atom, str, ATOM_BUFFER_SIZE))
230 continue;
231
232 ret = lpEnumFunc(hWnd, str, i->Data, lParam);
233 if(!ret)
234 break;
235 }
236
237 RtlFreeHeap(GetProcessHeap(), 0, pli);
238 }
239
240 return ret;
241 }
242
243
244 /*
245 * @implemented
246 */
247 int STDCALL
248 EnumPropsW(HWND hWnd, PROPENUMPROCW lpEnumFunc)
249 {
250 PPROPLISTITEM pli, i;
251 NTSTATUS Status;
252 DWORD Count;
253 int ret = -1;
254
255 if(!lpEnumFunc)
256 {
257 SetLastError(ERROR_INVALID_PARAMETER);
258 return ret;
259 }
260
261 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
262 if(!NT_SUCCESS(Status))
263 {
264 if(Status == STATUS_INVALID_HANDLE)
265 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
266 else
267 SetLastError(RtlNtStatusToDosError(Status));
268 return ret;
269 }
270
271 if(Count > 0)
272 {
273 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
274 if (pli == NULL)
275 {
276 SetLastError(ERROR_OUTOFMEMORY);
277 return -1;
278 }
279
280 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
281 if(!NT_SUCCESS(Status))
282 {
283 RtlFreeHeap(GetProcessHeap(), 0, pli);
284 if(Status == STATUS_INVALID_HANDLE)
285 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
286 else
287 SetLastError(RtlNtStatusToDosError(Status));
288 return ret;
289 }
290
291 i = pli;
292 for(; Count > 0; Count--, i++)
293 {
294 WCHAR str[ATOM_BUFFER_SIZE];
295
296 if(!GlobalGetAtomNameW(i->Atom, str, ATOM_BUFFER_SIZE))
297 continue;
298
299 ret = lpEnumFunc(hWnd, str, i->Data);
300 if(!ret)
301 break;
302 }
303
304 RtlFreeHeap(GetProcessHeap(), 0, pli);
305 }
306
307 return ret;
308 }
309
310
311 /*
312 * @implemented
313 */
314 HANDLE STDCALL
315 GetPropA(HWND hWnd, LPCSTR lpString)
316 {
317 PWSTR lpWString;
318 UNICODE_STRING UString;
319 HANDLE Ret;
320 if (HIWORD(lpString))
321 {
322 RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
323 lpWString = UString.Buffer;
324 if (lpWString == NULL)
325 {
326 return(FALSE);
327 }
328 Ret = GetPropW(hWnd, lpWString);
329 RtlFreeUnicodeString(&UString);
330 }
331 else
332 {
333 Ret = GetPropW(hWnd, (LPWSTR)lpString);
334 }
335 return(Ret);
336 }
337
338
339 /*
340 * @implemented
341 */
342 HANDLE STDCALL
343 GetPropW(HWND hWnd, LPCWSTR lpString)
344 {
345 ATOM Atom;
346 if (HIWORD(lpString))
347 {
348 Atom = GlobalFindAtomW(lpString);
349 }
350 else
351 {
352 Atom = LOWORD((DWORD)lpString);
353 }
354 return(NtUserGetProp(hWnd, Atom));
355 }
356
357
358 /*
359 * @implemented
360 */
361 HANDLE STDCALL
362 RemovePropA(HWND hWnd, LPCSTR lpString)
363 {
364 PWSTR lpWString;
365 UNICODE_STRING UString;
366 HANDLE Ret;
367
368 if (HIWORD(lpString))
369 {
370 RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
371 lpWString = UString.Buffer;
372 if (lpWString == NULL)
373 {
374 return(FALSE);
375 }
376 Ret = RemovePropW(hWnd, lpWString);
377 RtlFreeUnicodeString(&UString);
378 }
379 else
380 {
381 Ret = RemovePropW(hWnd, (LPCWSTR)lpString);
382 }
383 return(Ret);
384 }
385
386
387 /*
388 * @implemented
389 */
390 HANDLE STDCALL
391 RemovePropW(HWND hWnd,
392 LPCWSTR lpString)
393 {
394 ATOM Atom;
395 if (HIWORD(lpString))
396 {
397 Atom = GlobalFindAtomW(lpString);
398 }
399 else
400 {
401 Atom = LOWORD((DWORD)lpString);
402 }
403 return(NtUserRemoveProp(hWnd, Atom));
404 }
405
406
407 /*
408 * @implemented
409 */
410 BOOL STDCALL
411 SetPropA(HWND hWnd, LPCSTR lpString, HANDLE hData)
412 {
413 PWSTR lpWString;
414 UNICODE_STRING UString;
415 BOOL Ret;
416
417 if (HIWORD(lpString))
418 {
419 RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
420 lpWString = UString.Buffer;
421 if (lpWString == NULL)
422 {
423 return(FALSE);
424 }
425 Ret = SetPropW(hWnd, lpWString, hData);
426 RtlFreeUnicodeString(&UString);
427 }
428 else
429 {
430 Ret = SetPropW(hWnd, (LPWSTR)lpString, hData);
431 }
432 return(Ret);
433 }
434
435
436 /*
437 * @implemented
438 */
439 BOOL STDCALL
440 SetPropW(HWND hWnd, LPCWSTR lpString, HANDLE hData)
441 {
442 ATOM Atom;
443 if (HIWORD(lpString))
444 {
445 Atom = GlobalAddAtomW(lpString);
446 }
447 else
448 {
449 Atom = LOWORD((DWORD)lpString);
450 }
451
452 return(NtUserSetProp(hWnd, Atom, hData));
453 }