- Update address of Free Software Foundation.
[reactos.git] / reactos / subsystems / win32 / win32k / ntuser / prop.c
1 /*
2 * ReactOS W32 Subsystem
3 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 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 along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS kernel
22 * PURPOSE: Window properties
23 * FILE: subsys/win32k/ntuser/prop.c
24 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
25 * REVISION HISTORY:
26 * 06-06-2001 CSH Created
27 */
28 /* INCLUDES ******************************************************************/
29
30 #include <w32k.h>
31
32 #define NDEBUG
33 #include <debug.h>
34
35 /* STATIC FUNCTIONS **********************************************************/
36
37 PPROPERTY FASTCALL
38 IntGetProp(PWINDOW_OBJECT Window, ATOM Atom)
39 {
40 PLIST_ENTRY ListEntry;
41 PPROPERTY Property;
42
43 ListEntry = Window->Wnd->PropListHead.Flink;
44 while (ListEntry != &Window->Wnd->PropListHead)
45 {
46 Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry);
47 if (Property->Atom == Atom)
48 {
49 return(Property);
50 }
51 ListEntry = ListEntry->Flink;
52 }
53 return(NULL);
54 }
55
56 BOOL FASTCALL
57 IntRemoveProp(PWINDOW_OBJECT Window, ATOM Atom)
58 {
59 PPROPERTY Prop;
60 HANDLE Data;
61 Prop = IntGetProp(Window, Atom);
62
63 if (Prop == NULL)
64 {
65 return FALSE;
66 }
67 Data = Prop->Data;
68 RemoveEntryList(&Prop->PropListEntry);
69 UserHeapFree(Prop);
70 Window->Wnd->PropListItems--;
71 return TRUE;
72 }
73
74 BOOL FASTCALL
75 IntSetProp(PWINDOW_OBJECT pWnd, ATOM Atom, HANDLE Data)
76 {
77 PPROPERTY Prop;
78
79 Prop = IntGetProp(pWnd, Atom);
80
81 if (Prop == NULL)
82 {
83 Prop = UserHeapAlloc(sizeof(PROPERTY));
84 if (Prop == NULL)
85 {
86 return FALSE;
87 }
88 Prop->Atom = Atom;
89 InsertTailList(&pWnd->Wnd->PropListHead, &Prop->PropListEntry);
90 pWnd->Wnd->PropListItems++;
91 }
92
93 Prop->Data = Data;
94 return TRUE;
95 }
96
97 /* FUNCTIONS *****************************************************************/
98
99 NTSTATUS APIENTRY
100 NtUserBuildPropList(HWND hWnd,
101 LPVOID Buffer,
102 DWORD BufferSize,
103 DWORD *Count)
104 {
105 PWINDOW_OBJECT Window;
106 PPROPERTY Property;
107 PLIST_ENTRY ListEntry;
108 PROPLISTITEM listitem, *li;
109 NTSTATUS Status;
110 DWORD Cnt = 0;
111 DECLARE_RETURN(NTSTATUS);
112
113 DPRINT("Enter NtUserBuildPropList\n");
114 UserEnterShared();
115
116 if (!(Window = UserGetWindowObject(hWnd)))
117 {
118 RETURN( STATUS_INVALID_HANDLE);
119 }
120
121 if(Buffer)
122 {
123 if(!BufferSize || (BufferSize % sizeof(PROPLISTITEM) != 0))
124 {
125 RETURN( STATUS_INVALID_PARAMETER);
126 }
127
128 /* copy list */
129 li = (PROPLISTITEM *)Buffer;
130 ListEntry = Window->Wnd->PropListHead.Flink;
131 while((BufferSize >= sizeof(PROPLISTITEM)) && (ListEntry != &Window->Wnd->PropListHead))
132 {
133 Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry);
134 listitem.Atom = Property->Atom;
135 listitem.Data = Property->Data;
136
137 Status = MmCopyToCaller(li, &listitem, sizeof(PROPLISTITEM));
138 if(!NT_SUCCESS(Status))
139 {
140 RETURN( Status);
141 }
142
143 BufferSize -= sizeof(PROPLISTITEM);
144 Cnt++;
145 li++;
146 ListEntry = ListEntry->Flink;
147 }
148
149 }
150 else
151 {
152 Cnt = Window->Wnd->PropListItems * sizeof(PROPLISTITEM);
153 }
154
155 if(Count)
156 {
157 Status = MmCopyToCaller(Count, &Cnt, sizeof(DWORD));
158 if(!NT_SUCCESS(Status))
159 {
160 RETURN( Status);
161 }
162 }
163
164 RETURN( STATUS_SUCCESS);
165
166 CLEANUP:
167 DPRINT("Leave NtUserBuildPropList, ret=%i\n",_ret_);
168 UserLeave();
169 END_CLEANUP;
170 }
171
172 HANDLE APIENTRY
173 NtUserRemoveProp(HWND hWnd, ATOM Atom)
174 {
175 PWINDOW_OBJECT Window;
176 PPROPERTY Prop;
177 HANDLE Data;
178 DECLARE_RETURN(HANDLE);
179
180 DPRINT("Enter NtUserRemoveProp\n");
181 UserEnterExclusive();
182
183 if (!(Window = UserGetWindowObject(hWnd)))
184 {
185 RETURN( NULL);
186 }
187
188 Prop = IntGetProp(Window, Atom);
189
190 if (Prop == NULL)
191 {
192 RETURN(NULL);
193 }
194 Data = Prop->Data;
195 RemoveEntryList(&Prop->PropListEntry);
196 UserHeapFree(Prop);
197 Window->Wnd->PropListItems--;
198
199 RETURN(Data);
200
201 CLEANUP:
202 DPRINT("Leave NtUserRemoveProp, ret=%i\n",_ret_);
203 UserLeave();
204 END_CLEANUP;
205 }
206
207 BOOL APIENTRY
208 NtUserSetProp(HWND hWnd, ATOM Atom, HANDLE Data)
209 {
210 PWINDOW_OBJECT Window;
211 DECLARE_RETURN(BOOL);
212
213 DPRINT("Enter NtUserSetProp\n");
214 UserEnterExclusive();
215
216 if (!(Window = UserGetWindowObject(hWnd)))
217 {
218 RETURN( FALSE);
219 }
220
221 RETURN( IntSetProp(Window, Atom, Data));
222
223 CLEANUP:
224 DPRINT("Leave NtUserSetProp, ret=%i\n",_ret_);
225 UserLeave();
226 END_CLEANUP;
227 }
228
229 /* EOF */