+ntoskrnl/ob/ntobj.c
[reactos.git] / 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  * PROGRAMMER:    David Welch (welch@cwcom.net)
8  * UPDATE HISTORY:
9  *               10/06/98: Created
10  */
11
12 /* INCLUDES *****************************************************************/
13
14 #include <ddk/ntddk.h>
15 #include <internal/ob.h>
16 #include <internal/id.h>
17
18 #define NDEBUG
19 #include <internal/debug.h>
20
21 /* FUNCTIONS ************************************************************/
22
23 #ifndef LIBCAPTIVE
24
25 NTSTATUS
26 STDCALL
27 NtSetInformationObject (
28         IN      HANDLE  ObjectHandle,
29         IN      CINT    ObjectInformationClass,
30         IN      PVOID   ObjectInformation,
31         IN      ULONG   Length
32         )
33 {
34         UNIMPLEMENTED;
35 }
36
37 #endif /* LIBCAPTIVE */
38
39 NTSTATUS
40 internalNameBuilder
41 (
42 POBJECT_HEADER  ObjectHeader,
43 PUNICODE_STRING string)
44 /* So, what's the purpose of this function?
45    It will take any OBJECT_HEADER and traverse the Parent structure up to the root
46    and form the name, i.e. this will only work on objects where the Parent/Name fields
47    have any meaning (not files) */
48 {
49         NTSTATUS status;
50         if (ObjectHeader->Parent)
51         {
52                 status = internalNameBuilder(BODY_TO_HEADER(ObjectHeader->Parent),string);
53                 if (status != STATUS_SUCCESS)
54                 {
55                         return status;
56                 }
57         }
58         if (ObjectHeader->Name.Buffer)
59         {
60                 status = RtlAppendUnicodeToString(string, L"\\");
61                 if (status != STATUS_SUCCESS) return status;
62                 return RtlAppendUnicodeStringToString(string, &ObjectHeader->Name);
63         }
64         return STATUS_SUCCESS;
65 }
66
67 #ifndef LIBCAPTIVE
68
69 NTSTATUS
70 STDCALL
71 NtQueryObject (
72         IN      HANDLE  ObjectHandle,
73         IN      CINT    ObjectInformationClass,
74         OUT     PVOID   ObjectInformation,
75         IN      ULONG   Length,
76         OUT     PULONG  ResultLength
77         )
78 /*Very, very, very new implementation. Test it!
79
80   Probably we should add meaning to QueryName in POBJECT_TYPE, no matter if we know
81   the correct parameters or not. For FILE_OBJECTs, it would probably look like the code
82   for ObjectNameInformation below. You give it a POBJECT and a PUNICODE_STRING, and it
83   returns the full path in the PUNICODE_STRING
84
85   If we don't do it this way, we should anyway add switches and separate functions to handle
86   the different object types*/
87 {
88   POBJECT_NAME_INFORMATION nameinfo;
89   POBJECT_TYPE_INFORMATION typeinfo;
90   PFILE_NAME_INFORMATION filenameinfo;
91   PVOID         Object;
92   NTSTATUS      Status;  
93   POBJECT_HEADER        ObjectHeader;
94   PFILE_OBJECT    fileob;
95   
96   Status = ObReferenceObjectByHandle(ObjectHandle,
97                                      0,
98                                      NULL,
99                                      KernelMode,
100                                      &Object,
101                                      NULL);
102   if (Status != STATUS_SUCCESS)
103     {
104       return Status;
105     }
106   
107   ObjectHeader = BODY_TO_HEADER(Object);
108   
109   switch (ObjectInformationClass)
110     {
111     case ObjectNameInformation:
112       if (Length!=sizeof(OBJECT_NAME_INFORMATION)) return STATUS_INVALID_BUFFER_SIZE;
113       nameinfo = (POBJECT_NAME_INFORMATION)ObjectInformation;
114       (*ResultLength)=Length;           
115       
116       if (ObjectHeader->Type==InternalFileType)  // FIXME: Temporary QueryName implementation, or at least separate functions
117         {
118           fileob = (PFILE_OBJECT) Object;
119           Status = internalNameBuilder(BODY_TO_HEADER(fileob->DeviceObject->Vpb->RealDevice), &nameinfo->Name);
120           
121           if (Status != STATUS_SUCCESS)
122             {
123               ObDereferenceObject(Object);
124               return Status;
125             }
126           filenameinfo = ExAllocatePool(NonPagedPool,MAX_PATH*sizeof(WCHAR)+sizeof(ULONG));
127           IoQueryFileInformation(fileob,FileNameInformation,MAX_PATH*sizeof(WCHAR)+sizeof(ULONG), filenameinfo,NULL);
128           
129           Status = RtlAppendUnicodeToString(&(nameinfo->Name), filenameinfo->FileName);
130           
131           ExFreePool( filenameinfo);
132           ObDereferenceObject(Object);
133           return Status;
134         }
135       else
136         if (ObjectHeader->Name.Buffer) // If it's got a name there, we can probably just make the full path through Name and Parent
137           {
138             Status = internalNameBuilder(ObjectHeader, &nameinfo->Name);
139             ObDereferenceObject(Object);
140             return Status;
141           }
142       ObDereferenceObject(Object);
143       return STATUS_NOT_IMPLEMENTED;
144     case ObjectTypeInformation:
145       typeinfo = (POBJECT_TYPE_INFORMATION)ObjectInformation;
146       if (Length!=sizeof(OBJECT_TYPE_INFORMATION)) return STATUS_INVALID_BUFFER_SIZE;
147       
148       // FIXME: Is this supposed to only be the header's Name field?
149       // Can somebody check/verify this?
150       RtlCopyUnicodeString(&typeinfo->Name,&ObjectHeader->Name);
151       
152       if (Status != STATUS_SUCCESS)
153         {
154           ObDereferenceObject(Object);
155           return Status;
156         }
157       
158       RtlCopyUnicodeString(&typeinfo->Type,&ObjectHeader->ObjectType->TypeName);
159       //This should be info from the object header, not the object type, right?                 
160       typeinfo->TotalHandles = ObjectHeader-> HandleCount; 
161       typeinfo->ReferenceCount = ObjectHeader -> RefCount;
162       
163       ObDereferenceObject(Object);
164       return Status;
165     default:
166       ObDereferenceObject(Object);
167       return STATUS_NOT_IMPLEMENTED;
168     }
169 }
170
171 VOID STDCALL
172 ObMakeTemporaryObject (PVOID    ObjectBody)
173 {
174   POBJECT_HEADER        ObjectHeader;
175   
176   ObjectHeader = BODY_TO_HEADER(ObjectBody);
177   ObjectHeader->Permanent = FALSE;
178 }
179
180
181 /**********************************************************************
182  * NAME                                                 EXPORTED
183  *      NtMakeTemporaryObject
184  *      
185  * DESCRIPTION
186  *
187  * ARGUMENTS
188  *
189  * RETURN VALUE
190  *
191  * REVISIONS
192  */
193 NTSTATUS
194 STDCALL
195 NtMakeTemporaryObject (
196         HANDLE  Handle
197         )
198 {
199         PVOID           Object;
200         NTSTATUS        Status;  
201         POBJECT_HEADER  ObjectHeader;
202    
203         Status = ObReferenceObjectByHandle(
204                         Handle,
205                         0,
206                         NULL,
207                         KernelMode,
208                         & Object,
209                         NULL
210                         );
211         if (Status != STATUS_SUCCESS)
212         {
213                 return Status;
214         }
215
216         ObjectHeader = BODY_TO_HEADER(Object);
217         ObjectHeader->Permanent = FALSE;
218    
219         ObDereferenceObject(Object);
220    
221         return STATUS_SUCCESS;
222 }
223
224 #endif /* LIBCAPTIVE */
225
226 /* EOF */