- Implemented InterlockedBitTestAndReset, InterlockedBitTestAndSet, InterlockedExchan...
[reactos.git] / reactos / ntoskrnl / ob / ntobj.c
1 /* $Id$
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: ntoskrnl/ob/ntobj.c
6 * PURPOSE: User mode interface to object manager
7 *
8 * PROGRAMMERS: David Welch (welch@cwcom.net)
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ntoskrnl.h>
14 #define NDEBUG
15 #include <internal/debug.h>
16
17
18 /* FUNCTIONS ************************************************************/
19
20 /**********************************************************************
21 * NAME EXPORTED
22 * NtSetInformationObject
23 *
24 * DESCRIPTION
25 *
26 * ARGUMENTS
27 *
28 * RETURN VALUE
29 *
30 * REVISIONS
31 */
32 NTSTATUS STDCALL
33 NtSetInformationObject (IN HANDLE ObjectHandle,
34 IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
35 IN PVOID ObjectInformation,
36 IN ULONG Length)
37 {
38 PVOID Object;
39 NTSTATUS Status;
40
41 PAGED_CODE();
42
43 if (ObjectInformationClass != ObjectHandleInformation)
44 return STATUS_INVALID_INFO_CLASS;
45
46 if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
47 return STATUS_INFO_LENGTH_MISMATCH;
48
49 Status = ObReferenceObjectByHandle (ObjectHandle,
50 0,
51 NULL,
52 (KPROCESSOR_MODE)KeGetPreviousMode (),
53 &Object,
54 NULL);
55 if (!NT_SUCCESS (Status))
56 {
57 return Status;
58 }
59
60 Status = ObpSetHandleAttributes (ObjectHandle,
61 (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation);
62
63 ObDereferenceObject (Object);
64
65 return Status;
66 }
67
68
69 /**********************************************************************
70 * NAME EXPORTED
71 * NtQueryObject
72 *
73 * DESCRIPTION
74 *
75 * ARGUMENTS
76 *
77 * RETURN VALUE
78 *
79 * REVISIONS
80 */
81 NTSTATUS STDCALL
82 NtQueryObject (IN HANDLE ObjectHandle,
83 IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
84 OUT PVOID ObjectInformation,
85 IN ULONG Length,
86 OUT PULONG ResultLength OPTIONAL)
87 {
88 OBJECT_HANDLE_INFORMATION HandleInfo;
89 POBJECT_HEADER ObjectHeader;
90 ULONG InfoLength;
91 PVOID Object;
92 NTSTATUS Status;
93
94 PAGED_CODE();
95
96 Status = ObReferenceObjectByHandle (ObjectHandle,
97 0,
98 NULL,
99 (KPROCESSOR_MODE)KeGetPreviousMode(),
100 &Object,
101 &HandleInfo);
102 if (!NT_SUCCESS (Status))
103 {
104 return Status;
105 }
106
107 ObjectHeader = BODY_TO_HEADER(Object);
108
109 switch (ObjectInformationClass)
110 {
111 case ObjectBasicInformation:
112 InfoLength = sizeof(OBJECT_BASIC_INFORMATION);
113 if (Length != sizeof(OBJECT_BASIC_INFORMATION))
114 {
115 Status = STATUS_INFO_LENGTH_MISMATCH;
116 }
117 else
118 {
119 POBJECT_BASIC_INFORMATION BasicInfo;
120
121 BasicInfo = (POBJECT_BASIC_INFORMATION)ObjectInformation;
122 BasicInfo->Attributes = HandleInfo.HandleAttributes;
123 BasicInfo->GrantedAccess = HandleInfo.GrantedAccess;
124 BasicInfo->HandleCount = ObjectHeader->HandleCount;
125 BasicInfo->PointerCount = ObjectHeader->PointerCount;
126 BasicInfo->PagedPoolUsage = 0; /* FIXME*/
127 BasicInfo->NonPagedPoolUsage = 0; /* FIXME*/
128 BasicInfo->NameInformationLength = 0; /* FIXME*/
129 BasicInfo->TypeInformationLength = 0; /* FIXME*/
130 BasicInfo->SecurityDescriptorLength = 0; /* FIXME*/
131 if (ObjectHeader->Type == ObSymbolicLinkType)
132 {
133 BasicInfo->CreateTime.QuadPart =
134 ((PSYMLINK_OBJECT)Object)->CreateTime.QuadPart;
135 }
136 else
137 {
138 BasicInfo->CreateTime.QuadPart = (ULONGLONG)0;
139 }
140 Status = STATUS_SUCCESS;
141 }
142 break;
143
144 case ObjectNameInformation:
145 Status = ObQueryNameString (Object,
146 (POBJECT_NAME_INFORMATION)ObjectInformation,
147 Length,
148 &InfoLength);
149 break;
150
151 case ObjectTypeInformation:
152 #if 0
153 // InfoLength =
154 if (Length != sizeof(OBJECT_TYPE_INFORMATION))
155 {
156 Status = STATUS_INVALID_BUFFER_SIZE;
157 }
158 else
159 {
160 POBJECT_TYPE_INFORMATION TypeInfo;
161
162 TypeInfo = (POBJECT_TYPE_INFORMATION)ObjectInformation;
163 // FIXME: Is this supposed to only be the header's Name field?
164 // Can somebody check/verify this?
165 RtlCopyUnicodeString(&typeinfo->Name,&ObjectHeader->Name);
166
167 if (Status != STATUS_SUCCESS)
168 {
169 break;
170 }
171
172 RtlCopyUnicodeString(&typeinfo->Type,&ObjectHeader->Type->TypeName);
173 //This should be info from the object header, not the object type, right?
174 typeinfo->TotalHandles = ObjectHeader-> HandleCount;
175 typeinfo->ReferenceCount = ObjectHeader -> PointerCount;
176 }
177 #endif
178 Status = STATUS_NOT_IMPLEMENTED;
179 break;
180
181 case ObjectAllTypesInformation:
182 Status = STATUS_NOT_IMPLEMENTED;
183 break;
184
185 case ObjectHandleInformation:
186 InfoLength = sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION);
187 if (Length != sizeof (OBJECT_HANDLE_ATTRIBUTE_INFORMATION))
188 {
189 Status = STATUS_INFO_LENGTH_MISMATCH;
190 }
191 else
192 {
193 Status = ObpQueryHandleAttributes (ObjectHandle,
194 (POBJECT_HANDLE_ATTRIBUTE_INFORMATION)ObjectInformation);
195 }
196 break;
197
198 default:
199 Status = STATUS_INVALID_INFO_CLASS;
200 break;
201 }
202
203 ObDereferenceObject (Object);
204
205 if (ResultLength != NULL)
206 *ResultLength = InfoLength;
207
208 return Status;
209 }
210
211
212 /**********************************************************************
213 * NAME PRIVATE
214 * ObpSetPermanentObject/2
215 *
216 * DESCRIPTION
217 * Fast general purpose routine to set an object's permanent
218 * attribute, given a pointer to the object's body.
219 */
220 VOID FASTCALL
221 ObpSetPermanentObject (IN PVOID ObjectBody, IN BOOLEAN Permanent)
222 {
223 POBJECT_HEADER ObjectHeader;
224
225 ObjectHeader = BODY_TO_HEADER(ObjectBody);
226 ASSERT (ObjectHeader->PointerCount > 0);
227 if (Permanent)
228 {
229 ObjectHeader->Flags |= OB_FLAG_PERMANENT;
230 }
231 else
232 {
233 ObjectHeader->Flags &= ~OB_FLAG_PERMANENT;
234 if (ObjectHeader->HandleCount == 0 && HEADER_TO_OBJECT_NAME(ObjectHeader)->Directory)
235 {
236 /* Remove the object from the namespace */
237 ObpRemoveEntryDirectory(ObjectHeader);
238 }
239 }
240 }
241
242 /**********************************************************************
243 * NAME EXPORTED
244 * ObMakeTemporaryObject/1
245 *
246 * DESCRIPTION
247 *
248 * ARGUMENTS
249 *
250 * RETURN VALUE
251 *
252 * REVISIONS
253 *
254 * @implemented
255 */
256 VOID STDCALL
257 ObMakeTemporaryObject(IN PVOID ObjectBody)
258 {
259 ObpSetPermanentObject (ObjectBody, FALSE);
260 }
261
262
263 /**********************************************************************
264 * NAME EXPORTED
265 * NtMakeTemporaryObject
266 *
267 * DESCRIPTION
268 *
269 * ARGUMENTS
270 *
271 * RETURN VALUE
272 *
273 * REVISIONS
274 */
275 NTSTATUS STDCALL
276 NtMakeTemporaryObject(IN HANDLE ObjectHandle)
277 {
278 PVOID ObjectBody;
279 NTSTATUS Status;
280
281 PAGED_CODE();
282
283 Status = ObReferenceObjectByHandle(ObjectHandle,
284 0,
285 NULL,
286 (KPROCESSOR_MODE)KeGetPreviousMode(),
287 &ObjectBody,
288 NULL);
289 if (Status != STATUS_SUCCESS)
290 {
291 return Status;
292 }
293
294 ObpSetPermanentObject (ObjectBody, FALSE);
295
296 ObDereferenceObject(ObjectBody);
297
298 return STATUS_SUCCESS;
299 }
300
301
302 /**********************************************************************
303 * NAME EXPORTED
304 * NtMakePermanentObject/1
305 *
306 * DESCRIPTION
307 *
308 * ARGUMENTS
309 *
310 * RETURN VALUE
311 *
312 * REVISIONS
313 *
314 * @implemented
315 */
316 NTSTATUS STDCALL
317 NtMakePermanentObject(IN HANDLE ObjectHandle)
318 {
319 PVOID ObjectBody;
320 NTSTATUS Status;
321
322 PAGED_CODE();
323
324 Status = ObReferenceObjectByHandle(ObjectHandle,
325 0,
326 NULL,
327 (KPROCESSOR_MODE)KeGetPreviousMode(),
328 &ObjectBody,
329 NULL);
330 if (Status != STATUS_SUCCESS)
331 {
332 return Status;
333 }
334
335 ObpSetPermanentObject (ObjectBody, TRUE);
336
337 ObDereferenceObject(ObjectBody);
338
339 return STATUS_SUCCESS;
340 }
341
342 /* EOF */