9b03ba45448c0198f66d5af0dc735c9fafc9b077
[reactos.git] / reactos / win32ss / user / ntuser / prop.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * PURPOSE: Window properties
5 * FILE: subsys/win32k/ntuser/prop.c
6 * PROGRAMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 */
8
9 #include <win32k.h>
10 DBG_DEFAULT_CHANNEL(UserProp);
11
12 /* STATIC FUNCTIONS **********************************************************/
13
14 PPROPERTY FASTCALL
15 IntGetProp(PWND Window, ATOM Atom)
16 {
17 PLIST_ENTRY ListEntry;
18 PPROPERTY Property;
19
20 ListEntry = Window->PropListHead.Flink;
21 while (ListEntry != &Window->PropListHead)
22 {
23 Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry);
24 if (!Property) break;
25 if (Property->Atom == Atom)
26 {
27 return(Property);
28 }
29 ListEntry = ListEntry->Flink;
30 }
31 return(NULL);
32 }
33
34 HANDLE
35 FASTCALL
36 UserGetProp(PWND pWnd, ATOM Atom)
37 {
38 PPROPERTY Prop;
39 Prop = IntGetProp(pWnd, Atom);
40 return Prop ? Prop->Data : NULL;
41 }
42
43 BOOL FASTCALL
44 IntRemoveProp(PWND Window, ATOM Atom)
45 {
46 PPROPERTY Prop;
47 Prop = IntGetProp(Window, Atom);
48
49 if (Prop == NULL)
50 {
51 return FALSE;
52 }
53 RemoveEntryList(&Prop->PropListEntry);
54 UserHeapFree(Prop);
55 Window->PropListItems--;
56 return TRUE;
57 }
58
59 BOOL FASTCALL
60 IntSetProp(PWND pWnd, ATOM Atom, HANDLE Data)
61 {
62 PPROPERTY Prop;
63
64 Prop = IntGetProp(pWnd, Atom);
65
66 if (Prop == NULL)
67 {
68 Prop = UserHeapAlloc(sizeof(PROPERTY));
69 if (Prop == NULL)
70 {
71 return FALSE;
72 }
73 Prop->Atom = Atom;
74 InsertTailList(&pWnd->PropListHead, &Prop->PropListEntry);
75 pWnd->PropListItems++;
76 }
77
78 Prop->Data = Data;
79 return TRUE;
80 }
81
82 /* FUNCTIONS *****************************************************************/
83
84 NTSTATUS APIENTRY
85 NtUserBuildPropList(HWND hWnd,
86 LPVOID Buffer,
87 DWORD BufferSize,
88 DWORD *Count)
89 {
90 PWND Window;
91 PPROPERTY Property;
92 PLIST_ENTRY ListEntry;
93 PROPLISTITEM listitem, *li;
94 NTSTATUS Status;
95 DWORD Cnt = 0;
96 DECLARE_RETURN(NTSTATUS);
97
98 TRACE("Enter NtUserBuildPropList\n");
99 UserEnterShared();
100
101 if (!(Window = UserGetWindowObject(hWnd)))
102 {
103 RETURN( STATUS_INVALID_HANDLE);
104 }
105
106 if(Buffer)
107 {
108 if(!BufferSize || (BufferSize % sizeof(PROPLISTITEM) != 0))
109 {
110 RETURN( STATUS_INVALID_PARAMETER);
111 }
112
113 /* Copy list */
114 li = (PROPLISTITEM *)Buffer;
115 ListEntry = Window->PropListHead.Flink;
116 while((BufferSize >= sizeof(PROPLISTITEM)) && (ListEntry != &Window->PropListHead))
117 {
118 Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry);
119 listitem.Atom = Property->Atom;
120 listitem.Data = Property->Data;
121
122 Status = MmCopyToCaller(li, &listitem, sizeof(PROPLISTITEM));
123 if(!NT_SUCCESS(Status))
124 {
125 RETURN( Status);
126 }
127
128 BufferSize -= sizeof(PROPLISTITEM);
129 Cnt++;
130 li++;
131 ListEntry = ListEntry->Flink;
132 }
133
134 }
135 else
136 {
137 Cnt = Window->PropListItems * sizeof(PROPLISTITEM);
138 }
139
140 if(Count)
141 {
142 Status = MmCopyToCaller(Count, &Cnt, sizeof(DWORD));
143 if(!NT_SUCCESS(Status))
144 {
145 RETURN( Status);
146 }
147 }
148
149 RETURN( STATUS_SUCCESS);
150
151 CLEANUP:
152 TRACE("Leave NtUserBuildPropList, ret=%i\n",_ret_);
153 UserLeave();
154 END_CLEANUP;
155 }
156
157 HANDLE APIENTRY
158 NtUserRemoveProp(HWND hWnd, ATOM Atom)
159 {
160 PWND Window;
161 PPROPERTY Prop;
162 HANDLE Data;
163 DECLARE_RETURN(HANDLE);
164
165 TRACE("Enter NtUserRemoveProp\n");
166 UserEnterExclusive();
167
168 if (!(Window = UserGetWindowObject(hWnd)))
169 {
170 RETURN( NULL);
171 }
172
173 Prop = IntGetProp(Window, Atom);
174
175 if (Prop == NULL)
176 {
177 RETURN(NULL);
178 }
179 Data = Prop->Data;
180 RemoveEntryList(&Prop->PropListEntry);
181 UserHeapFree(Prop);
182 Window->PropListItems--;
183
184 RETURN(Data);
185
186 CLEANUP:
187 TRACE("Leave NtUserRemoveProp, ret=%p\n", _ret_);
188 UserLeave();
189 END_CLEANUP;
190 }
191
192 BOOL APIENTRY
193 NtUserSetProp(HWND hWnd, ATOM Atom, HANDLE Data)
194 {
195 PWND Window;
196 DECLARE_RETURN(BOOL);
197
198 TRACE("Enter NtUserSetProp\n");
199 UserEnterExclusive();
200
201 if (!(Window = UserGetWindowObject(hWnd)))
202 {
203 RETURN( FALSE);
204 }
205
206 RETURN( IntSetProp(Window, Atom, Data));
207
208 CLEANUP:
209 TRACE("Leave NtUserSetProp, ret=%i\n",_ret_);
210 UserLeave();
211 END_CLEANUP;
212 }
213
214 /* EOF */