[WIN32K]
[reactos.git] / reactos / subsystems / win32 / win32k / 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->Atom == Atom)
25 {
26 return(Property);
27 }
28 ListEntry = ListEntry->Flink;
29 }
30 return(NULL);
31 }
32
33 BOOL FASTCALL
34 IntRemoveProp(PWND Window, ATOM Atom)
35 {
36 PPROPERTY Prop;
37 Prop = IntGetProp(Window, Atom);
38
39 if (Prop == NULL)
40 {
41 return FALSE;
42 }
43 RemoveEntryList(&Prop->PropListEntry);
44 UserHeapFree(Prop);
45 Window->PropListItems--;
46 return TRUE;
47 }
48
49 BOOL FASTCALL
50 IntSetProp(PWND pWnd, ATOM Atom, HANDLE Data)
51 {
52 PPROPERTY Prop;
53
54 Prop = IntGetProp(pWnd, Atom);
55
56 if (Prop == NULL)
57 {
58 Prop = UserHeapAlloc(sizeof(PROPERTY));
59 if (Prop == NULL)
60 {
61 return FALSE;
62 }
63 Prop->Atom = Atom;
64 InsertTailList(&pWnd->PropListHead, &Prop->PropListEntry);
65 pWnd->PropListItems++;
66 }
67
68 Prop->Data = Data;
69 return TRUE;
70 }
71
72 /* FUNCTIONS *****************************************************************/
73
74 NTSTATUS APIENTRY
75 NtUserBuildPropList(HWND hWnd,
76 LPVOID Buffer,
77 DWORD BufferSize,
78 DWORD *Count)
79 {
80 PWND Window;
81 PPROPERTY Property;
82 PLIST_ENTRY ListEntry;
83 PROPLISTITEM listitem, *li;
84 NTSTATUS Status;
85 DWORD Cnt = 0;
86 DECLARE_RETURN(NTSTATUS);
87
88 TRACE("Enter NtUserBuildPropList\n");
89 UserEnterShared();
90
91 if (!(Window = UserGetWindowObject(hWnd)))
92 {
93 RETURN( STATUS_INVALID_HANDLE);
94 }
95
96 if(Buffer)
97 {
98 if(!BufferSize || (BufferSize % sizeof(PROPLISTITEM) != 0))
99 {
100 RETURN( STATUS_INVALID_PARAMETER);
101 }
102
103 /* Copy list */
104 li = (PROPLISTITEM *)Buffer;
105 ListEntry = Window->PropListHead.Flink;
106 while((BufferSize >= sizeof(PROPLISTITEM)) && (ListEntry != &Window->PropListHead))
107 {
108 Property = CONTAINING_RECORD(ListEntry, PROPERTY, PropListEntry);
109 listitem.Atom = Property->Atom;
110 listitem.Data = Property->Data;
111
112 Status = MmCopyToCaller(li, &listitem, sizeof(PROPLISTITEM));
113 if(!NT_SUCCESS(Status))
114 {
115 RETURN( Status);
116 }
117
118 BufferSize -= sizeof(PROPLISTITEM);
119 Cnt++;
120 li++;
121 ListEntry = ListEntry->Flink;
122 }
123
124 }
125 else
126 {
127 Cnt = Window->PropListItems * sizeof(PROPLISTITEM);
128 }
129
130 if(Count)
131 {
132 Status = MmCopyToCaller(Count, &Cnt, sizeof(DWORD));
133 if(!NT_SUCCESS(Status))
134 {
135 RETURN( Status);
136 }
137 }
138
139 RETURN( STATUS_SUCCESS);
140
141 CLEANUP:
142 TRACE("Leave NtUserBuildPropList, ret=%i\n",_ret_);
143 UserLeave();
144 END_CLEANUP;
145 }
146
147 HANDLE APIENTRY
148 NtUserRemoveProp(HWND hWnd, ATOM Atom)
149 {
150 PWND Window;
151 PPROPERTY Prop;
152 HANDLE Data;
153 DECLARE_RETURN(HANDLE);
154
155 TRACE("Enter NtUserRemoveProp\n");
156 UserEnterExclusive();
157
158 if (!(Window = UserGetWindowObject(hWnd)))
159 {
160 RETURN( NULL);
161 }
162
163 Prop = IntGetProp(Window, Atom);
164
165 if (Prop == NULL)
166 {
167 RETURN(NULL);
168 }
169 Data = Prop->Data;
170 RemoveEntryList(&Prop->PropListEntry);
171 UserHeapFree(Prop);
172 Window->PropListItems--;
173
174 RETURN(Data);
175
176 CLEANUP:
177 TRACE("Leave NtUserRemoveProp, ret=%i\n",_ret_);
178 UserLeave();
179 END_CLEANUP;
180 }
181
182 BOOL APIENTRY
183 NtUserSetProp(HWND hWnd, ATOM Atom, HANDLE Data)
184 {
185 PWND Window;
186 DECLARE_RETURN(BOOL);
187
188 TRACE("Enter NtUserSetProp\n");
189 UserEnterExclusive();
190
191 if (!(Window = UserGetWindowObject(hWnd)))
192 {
193 RETURN( FALSE);
194 }
195
196 RETURN( IntSetProp(Window, Atom, Data));
197
198 CLEANUP:
199 TRACE("Leave NtUserSetProp, ret=%i\n",_ret_);
200 UserLeave();
201 END_CLEANUP;
202 }
203
204 /* EOF */