Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / libcaptive / ob / object.c
1 /* $Id$
2  * reactos support for object handling for reactos of libcaptive
3  * Copyright (C) 2002 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include "reactos/ddk/obfuncs.h"        /* self */
23 #include <glib/gmessages.h>
24 #include "reactos/ddk/status.h"
25 #include "reactos/ddk/exfuncs.h"        /* for ExFreePool() */
26 #include "captive/unicode.h"    /* for captive_validate_UnicodeString() */
27
28
29 /* reactos/ntoskrnl/ob/object.c: */
30 extern POBJECT_HEADER BODY_TO_HEADER(PVOID body);
31
32 /* reactos/ntoskrnl/ob/ntobj.c: */
33 NTSTATUS internalNameBuilder(POBJECT_HEADER ObjectHeader,PUNICODE_STRING string);
34
35
36 /**
37  * ObQueryNameString:
38  * @Object: Object to identify the name from.
39  * %NULL value is forbidden.
40  * @ObjectNameInfo: Target structure to be filled with the @Object name.
41  * %NULL value is permitted.
42  * @Length: Length of @ObjectNameInfo allocated memory block.
43  * sizeof(*@ObjectNameInfo) is required by libcaptive.
44  * @ReturnLength: Returns the length of the unicode name string including the final 0-terminator in bytes.
45  * %NULL value is forbidden.
46  *
47  * Function detects the name of a given object @Object. The returned name
48  * string will start with backslash (absolute pathname) and it will be zero terminated.
49  *
50  * You can detect the name string length by passing %NULL for @ObjectNameInfo
51  * and %0 for @Length together. The requested string length will be returned by @ReturnLength.
52  * In such case the function return code will be %STATUS_INFO_LENGTH_MISMATCH.
53  *
54  * Returns: The unicode string name of @Object. Return code is %STATUS_SUCCESS.
55  * The only valid return code in the case of passed %NULL @ObjectNameInfo is %STATUS_INFO_LENGTH_MISMATCH.
56  */
57 NTSTATUS ObQueryNameString(IN PVOID Object,OUT POBJECT_NAME_INFORMATION ObjectNameInfo,IN ULONG Length,OUT PULONG ReturnLength)
58 {
59 OBJECT_HEADER *ObjectHeader;
60 NTSTATUS r;
61 UNICODE_STRING UnicodeString;
62
63         g_return_val_if_fail(Object!=NULL,STATUS_INVALID_PARAMETER);
64         /* 'ObjectNameInfo' may be NULL */
65         g_return_val_if_fail(ReturnLength!=NULL,STATUS_INVALID_PARAMETER);
66
67         if (ObjectNameInfo) {
68                 g_return_val_if_fail(Length!=sizeof(*ObjectNameInfo),STATUS_INFO_LENGTH_MISMATCH);
69                 g_assert(sizeof(*ObjectNameInfo)==sizeof(UnicodeString)/* ==ObjectNameInfo->Name */);
70                 }
71         else
72                 g_return_val_if_fail(Length==0,STATUS_INFO_LENGTH_MISMATCH);
73
74         ObjectHeader=BODY_TO_HEADER(Object);
75
76         UnicodeString.Buffer=NULL;
77         UnicodeString.MaximumLength=0;
78
79         do {
80                 if (UnicodeString.Buffer)
81                         ExFreePool(UnicodeString.Buffer);
82                 UnicodeString.MaximumLength=MAX(0x100,UnicodeString.MaximumLength*2);
83                 UnicodeString.Buffer=ExAllocatePool(PagedPool,UnicodeString.MaximumLength);
84                 g_return_val_if_fail(UnicodeString.Buffer!=NULL,STATUS_NO_MEMORY);
85
86                 UnicodeString.Length=0;
87                 r=internalNameBuilder(ObjectHeader,&UnicodeString);
88                 } while (r==STATUS_BUFFER_TOO_SMALL);
89
90         if (!NT_SUCCESS(r)) {
91                 ExFreePool(UnicodeString.Buffer);
92                 return r;
93                 }
94         g_assert(captive_validate_UnicodeString(&UnicodeString));       /* ensure 0-termination */
95         *ReturnLength=UnicodeString.Length+sizeof(*UnicodeString.Buffer);
96
97         if (!ObjectNameInfo) {
98                 ExFreePool(UnicodeString.Buffer);
99                 /* Valid detection of the object name string length */
100                 return STATUS_INFO_LENGTH_MISMATCH;
101                 }
102
103         ObjectNameInfo->Name=UnicodeString;
104         return STATUS_SUCCESS;
105 }