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