Merge my current work done on the kd++ branch:
[reactos.git] / reactos / win32ss / user / 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 /*
20 * PROJECT: ReactOS user32.dll
21 * FILE: lib/user32/windows/input.c
22 * PURPOSE: Input
23 * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
24 * UPDATE HISTORY:
25 * 09-05-2001 CSH Created
26 */
27
28 /* INCLUDES ******************************************************************/
29
30 #include <user32.h>
31
32 #include <wine/debug.h>
33
34 WINE_DEFAULT_DEBUG_CHANNEL(user32);
35
36 #define ATOM_BUFFER_SIZE 256
37
38 /* INTERNAL FUNCTIONS ********************************************************/
39
40 HANDLE
41 FASTCALL
42 IntGetProp(HWND hWnd, ATOM Atom)
43 {
44 PLIST_ENTRY ListEntry, temp;
45 PPROPERTY Property;
46 PWND pWnd;
47 int i;
48
49 pWnd = ValidateHwnd(hWnd);
50 if (!pWnd) return NULL;
51
52 ListEntry = SharedPtrToUser(pWnd->PropListHead.Flink);
53 for (i = 0; i < pWnd->PropListItems; i++ )
54 {
55 Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry);
56 if (Property->Atom == Atom)
57 {
58 return(Property);
59 }
60 temp = ListEntry->Flink;
61 ListEntry = SharedPtrToUser(temp);
62 }
63 return NULL;
64 }
65
66
67 /* FUNCTIONS *****************************************************************/
68
69 /*
70 * @implemented
71 */
72 int WINAPI
73 EnumPropsA(HWND hWnd, PROPENUMPROCA lpEnumFunc)
74 {
75 PPROPLISTITEM pli, i;
76 NTSTATUS Status;
77 DWORD Count;
78 int ret = -1;
79
80 if(!lpEnumFunc)
81 {
82 SetLastError(ERROR_INVALID_PARAMETER);
83 return ret;
84 }
85
86 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
87 if(!NT_SUCCESS(Status))
88 {
89 if(Status == STATUS_INVALID_HANDLE)
90 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
91 else
92 SetLastError(RtlNtStatusToDosError(Status));
93 return ret;
94 }
95
96 if(Count > 0)
97 {
98 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
99 if (pli == NULL)
100 {
101 SetLastError(ERROR_OUTOFMEMORY);
102 return -1;
103 }
104
105 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
106 if(!NT_SUCCESS(Status))
107 {
108 RtlFreeHeap(GetProcessHeap(), 0, pli);
109 if(Status == STATUS_INVALID_HANDLE)
110 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
111 else
112 SetLastError(RtlNtStatusToDosError(Status));
113 return ret;
114 }
115
116 i = pli;
117 for(; Count > 0; Count--, i++)
118 {
119 char str[ATOM_BUFFER_SIZE];
120
121 if(!GlobalGetAtomNameA(i->Atom, str, ATOM_BUFFER_SIZE))
122 continue;
123
124 ret = lpEnumFunc(hWnd, str, i->Data);
125 if(!ret)
126 break;
127 }
128
129 RtlFreeHeap(GetProcessHeap(), 0, pli);
130 }
131
132 return ret;
133 }
134
135
136 /*
137 * @implemented
138 */
139 int WINAPI
140 EnumPropsExA(HWND hWnd, PROPENUMPROCEXA lpEnumFunc, LPARAM lParam)
141 {
142 PPROPLISTITEM pli, i;
143 NTSTATUS Status;
144 DWORD Count;
145 int ret = -1;
146
147 if(!lpEnumFunc)
148 {
149 SetLastError(ERROR_INVALID_PARAMETER);
150 return ret;
151 }
152
153 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
154 if(!NT_SUCCESS(Status))
155 {
156 if(Status == STATUS_INVALID_HANDLE)
157 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
158 else
159 SetLastError(RtlNtStatusToDosError(Status));
160 return ret;
161 }
162
163 if(Count > 0)
164 {
165 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
166 if (pli == NULL)
167 {
168 SetLastError(ERROR_OUTOFMEMORY);
169 return -1;
170 }
171
172 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
173 if(!NT_SUCCESS(Status))
174 {
175 RtlFreeHeap(GetProcessHeap(), 0, pli);
176 if(Status == STATUS_INVALID_HANDLE)
177 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
178 else
179 SetLastError(RtlNtStatusToDosError(Status));
180 return ret;
181 }
182
183 i = pli;
184 for(; Count > 0; Count--, i++)
185 {
186 char str[ATOM_BUFFER_SIZE];
187
188 if(!GlobalGetAtomNameA(i->Atom, str, ATOM_BUFFER_SIZE))
189 continue;
190
191 ret = lpEnumFunc(hWnd, str, i->Data, lParam);
192 if(!ret)
193 break;
194 }
195
196 RtlFreeHeap(GetProcessHeap(), 0, pli);
197 }
198
199 return ret;
200 }
201
202
203 /*
204 * @implemented
205 */
206 int WINAPI
207 EnumPropsExW(HWND hWnd, PROPENUMPROCEXW lpEnumFunc, LPARAM lParam)
208 {
209 PPROPLISTITEM pli, i;
210 NTSTATUS Status;
211 DWORD Count;
212 int ret = -1;
213
214 if(!lpEnumFunc)
215 {
216 SetLastError(ERROR_INVALID_PARAMETER);
217 return ret;
218 }
219
220 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
221 if(!NT_SUCCESS(Status))
222 {
223 if(Status == STATUS_INVALID_HANDLE)
224 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
225 else
226 SetLastError(RtlNtStatusToDosError(Status));
227 return ret;
228 }
229
230 if(Count > 0)
231 {
232 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
233 if (pli == NULL)
234 {
235 SetLastError(ERROR_OUTOFMEMORY);
236 return -1;
237 }
238
239 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
240 if(!NT_SUCCESS(Status))
241 {
242 RtlFreeHeap(GetProcessHeap(), 0, pli);
243 if(Status == STATUS_INVALID_HANDLE)
244 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
245 else
246 SetLastError(RtlNtStatusToDosError(Status));
247 return ret;
248 }
249
250 i = pli;
251 for(; Count > 0; Count--, i++)
252 {
253 WCHAR str[ATOM_BUFFER_SIZE];
254
255 if(!GlobalGetAtomNameW(i->Atom, str, ATOM_BUFFER_SIZE))
256 continue;
257
258 ret = lpEnumFunc(hWnd, str, i->Data, lParam);
259 if(!ret)
260 break;
261 }
262
263 RtlFreeHeap(GetProcessHeap(), 0, pli);
264 }
265
266 return ret;
267 }
268
269
270 /*
271 * @implemented
272 */
273 int WINAPI
274 EnumPropsW(HWND hWnd, PROPENUMPROCW lpEnumFunc)
275 {
276 PPROPLISTITEM pli, i;
277 NTSTATUS Status;
278 DWORD Count;
279 int ret = -1;
280
281 if(!lpEnumFunc)
282 {
283 SetLastError(ERROR_INVALID_PARAMETER);
284 return ret;
285 }
286
287 Status = NtUserBuildPropList(hWnd, NULL, 0, &Count);
288 if(!NT_SUCCESS(Status))
289 {
290 if(Status == STATUS_INVALID_HANDLE)
291 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
292 else
293 SetLastError(RtlNtStatusToDosError(Status));
294 return ret;
295 }
296
297 if(Count > 0)
298 {
299 pli = RtlAllocateHeap(GetProcessHeap(), 0, Count);
300 if (pli == NULL)
301 {
302 SetLastError(ERROR_OUTOFMEMORY);
303 return -1;
304 }
305
306 Status = NtUserBuildPropList(hWnd, (LPVOID)pli, Count, &Count);
307 if(!NT_SUCCESS(Status))
308 {
309 RtlFreeHeap(GetProcessHeap(), 0, pli);
310 if(Status == STATUS_INVALID_HANDLE)
311 SetLastError(ERROR_INVALID_WINDOW_HANDLE);
312 else
313 SetLastError(RtlNtStatusToDosError(Status));
314 return ret;
315 }
316
317 i = pli;
318 for(; Count > 0; Count--, i++)
319 {
320 WCHAR str[ATOM_BUFFER_SIZE];
321
322 if(!GlobalGetAtomNameW(i->Atom, str, ATOM_BUFFER_SIZE))
323 continue;
324
325 ret = lpEnumFunc(hWnd, str, i->Data);
326 if(!ret)
327 break;
328 }
329
330 RtlFreeHeap(GetProcessHeap(), 0, pli);
331 }
332
333 return ret;
334 }
335
336
337 /*
338 * @implemented
339 */
340 HANDLE WINAPI
341 GetPropA(HWND hWnd, LPCSTR lpString)
342 {
343 PWSTR lpWString;
344 UNICODE_STRING UString;
345 HANDLE Ret;
346 if (HIWORD(lpString))
347 {
348 RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
349 lpWString = UString.Buffer;
350 if (lpWString == NULL)
351 {
352 return(FALSE);
353 }
354 Ret = GetPropW(hWnd, lpWString);
355 RtlFreeUnicodeString(&UString);
356 }
357 else
358 {
359 Ret = GetPropW(hWnd, (LPWSTR)lpString);
360 }
361 return(Ret);
362 }
363
364
365 /*
366 * @implemented
367 */
368 HANDLE WINAPI
369 GetPropW(HWND hWnd, LPCWSTR lpString)
370 {
371 ATOM Atom;
372 HANDLE Data = NULL;
373 PPROPERTY Prop;
374 if (HIWORD(lpString))
375 {
376 Atom = GlobalFindAtomW(lpString);
377 }
378 else
379 {
380 Atom = LOWORD((DWORD_PTR)lpString);
381 }
382 Prop = IntGetProp(hWnd, Atom);
383 if (Prop != NULL) Data = Prop->Data;
384 return Data;
385 }
386
387
388 /*
389 * @implemented
390 */
391 HANDLE WINAPI
392 RemovePropA(HWND hWnd, LPCSTR lpString)
393 {
394 PWSTR lpWString;
395 UNICODE_STRING UString;
396 HANDLE Ret;
397
398 if (HIWORD(lpString))
399 {
400 RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
401 lpWString = UString.Buffer;
402 if (lpWString == NULL)
403 {
404 return(FALSE);
405 }
406 Ret = RemovePropW(hWnd, lpWString);
407 RtlFreeUnicodeString(&UString);
408 }
409 else
410 {
411 Ret = RemovePropW(hWnd, (LPCWSTR)lpString);
412 }
413 return(Ret);
414 }
415
416
417 /*
418 * @implemented
419 */
420 HANDLE WINAPI
421 RemovePropW(HWND hWnd,
422 LPCWSTR lpString)
423 {
424 ATOM Atom;
425 if (HIWORD(lpString))
426 {
427 Atom = GlobalFindAtomW(lpString);
428 }
429 else
430 {
431 Atom = LOWORD((DWORD_PTR)lpString);
432 }
433 return(NtUserRemoveProp(hWnd, Atom));
434 }
435
436
437 /*
438 * @implemented
439 */
440 BOOL WINAPI
441 SetPropA(HWND hWnd, LPCSTR lpString, HANDLE hData)
442 {
443 PWSTR lpWString;
444 UNICODE_STRING UString;
445 BOOL Ret;
446
447 if (HIWORD(lpString))
448 {
449 RtlCreateUnicodeStringFromAsciiz(&UString, (LPSTR)lpString);
450 lpWString = UString.Buffer;
451 if (lpWString == NULL)
452 {
453 return(FALSE);
454 }
455 Ret = SetPropW(hWnd, lpWString, hData);
456 RtlFreeUnicodeString(&UString);
457 }
458 else
459 {
460 Ret = SetPropW(hWnd, (LPWSTR)lpString, hData);
461 }
462 return(Ret);
463 }
464
465
466 /*
467 * @implemented
468 */
469 BOOL WINAPI
470 SetPropW(HWND hWnd, LPCWSTR lpString, HANDLE hData)
471 {
472 ATOM Atom;
473 if (HIWORD(lpString))
474 {
475 Atom = GlobalAddAtomW(lpString);
476 }
477 else
478 {
479 Atom = LOWORD((DWORD_PTR)lpString);
480 }
481
482 return(NtUserSetProp(hWnd, Atom, hData));
483 }