ReactOS 0.4.15-dev-7842-g558ab78
objdir.c
Go to the documentation of this file.
1/*
2 * DESCRIPTION: Object Manager Simple Explorer
3 * PROGRAMMER: David Welch
4 * REVISIONS
5 * 2000-04-30 (ea)
6 * Added directory enumeration.
7 * (tested under nt4sp4/x86)
8 * 2000-08-11 (ea)
9 * Added symbolic link expansion.
10 * (tested under nt4sp4/x86)
11 * 2001-05-01 (ea)
12 * Fixed entries counter. Added more
13 * error codes check. Removed wprintf,
14 * because it does not work in .17.
15 * 2001-05-02 (ea)
16 * Added -r option.
17 */
18
19#define WIN32_NO_STATUS
20#include <windows.h>
21#include <stdlib.h>
22#include <ntndk.h>
23#include <stdio.h>
24
25#define MAX_DIR_ENTRY 256
26
27
28static
32 PWCHAR szU,
33 PCHAR szA
34 )
35{
36 register PCHAR a = szA;
37
38 while (*szU) {*szA++ = (CHAR) (0x00ff & * szU++);}
39 *szA = '\0';
40 return a;
41}
42
43
44static
48 PCHAR szA,
49 PWCHAR szW
50 )
51{
52 register PWCHAR w = szW;
53
54 while (*szA) {*szW++ = (WCHAR) *szA++;}
55 *szW = L'\0';
56 return w;
57}
58
59
60static
61const char *
64{
65 static char RawValue [16];
66
67 switch (Status)
68 {
70 return "STATUS_BUFFER_TOO_SMALL";
72 return "STATUS_INVALID_PARAMETER";
74 return "STATUS_OBJECT_NAME_INVALID";
76 return "STATUS_OBJECT_NAME_NOT_FOUND";
78 return "STATUS_PATH_SYNTAX_BAD";
80 return "STATUS_NO_MORE_ENTRIES";
82 return "STATUS_MORE_ENTRIES";
84 return "STATUS_ACCESS_DENIED";
86 return "STATUS_UNSUCCESSFUL";
88 return "STATUS_INVALID_HANDLE";
89 }
90 sprintf (RawValue, "0x%08lx", Status);
91 return (const char *) RawValue;
92}
93
94
95BOOL
98 IN PUNICODE_STRING DirectoryName,
100 IN OUT PUNICODE_STRING TargetObjectName
101 )
102{
104 HANDLE hSymbolicLink;
107 WCHAR PathBuffer [MAX_PATH];
108 ULONG DataWritten = 0;
109
110
111 Path.Buffer = PathBuffer;
112 Path.Length = 0;
113 Path.MaximumLength = sizeof PathBuffer;
114
115 RtlCopyUnicodeString (& Path, DirectoryName);
116 if (L'\\' != Path.Buffer [(Path.Length / sizeof Path.Buffer[0]) - 1])
117 {
119 }
121
122 oa.Length = sizeof (OBJECT_ATTRIBUTES);
123 oa.ObjectName = & Path;
124 oa.Attributes = 0; /* OBJ_CASE_INSENSITIVE; */
125 oa.RootDirectory = NULL;
128
130 & hSymbolicLink,
131 SYMBOLIC_LINK_QUERY, /* 0x20001 */
132 & oa
133 );
134
135 if (!NT_SUCCESS(Status))
136 {
137 printf (
138 "Failed to open SymbolicLink object (Status: %s)\n",
140 );
141 return FALSE;
142 }
143 TargetObjectName->Length = TargetObjectName->MaximumLength;
144 memset (
145 TargetObjectName->Buffer,
146 0,
147 TargetObjectName->MaximumLength
148 );
150 hSymbolicLink,
151 TargetObjectName,
152 & DataWritten
153 );
154 if (!NT_SUCCESS(Status))
155 {
156 printf (
157 "Failed to query SymbolicLink object (Status: %s)\n",
159 );
160 NtClose (hSymbolicLink);
161 return FALSE;
162 }
163 NtClose (hSymbolicLink);
164 return TRUE;
165}
166
167
168BOOL
169WINAPI
171 IN PUNICODE_STRING DirectoryNameW,
172 IN BOOL Recurse
173 )
174{
175 CHAR DirectoryNameA [MAX_PATH];
179 BYTE DirectoryEntry [512];
180 POBJECT_DIRECTORY_INFORMATION pDirectoryEntry = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
181 POBJECT_DIRECTORY_INFORMATION pDirectoryEntries = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
182 ULONG Context = 0;
184 ULONG EntryCount = 0;
185
186 /* For expanding symbolic links */
188 UNICODE_STRING TargetObjectName = {
189 sizeof TargetName,
190 sizeof TargetName,
192 };
193
194 /* Convert to ANSI the directory's name */
195 RawUszAsz (DirectoryNameW->Buffer, DirectoryNameA);
196 /*
197 * Prepare parameters for next call.
198 */
201 DirectoryNameW,
202 0,
203 NULL,
204 NULL
205 );
206 /*
207 * Try opening the directory.
208 */
213 );
214 if (!NT_SUCCESS(Status))
215 {
216 printf (
217 "Failed to open directory object \"%s\" (Status: %s)\n",
218 DirectoryNameA,
220 );
221 return (FALSE);
222 }
223 printf ("\n Directory of %s\n\n", DirectoryNameA);
224
225 for(;;)
226 {
227 /*
228 * Enumerate each item in the directory.
229 */
232 pDirectoryEntries,
233 sizeof DirectoryEntry,
234 FALSE,/* ReturnSingleEntry */
235 FALSE, /* RestartScan */
236 & Context,
238 );
240 {
241 printf (
242 "Failed to query directory object (Status: %s)\n",
244 );
246 return (FALSE);
247 }
249 {
250 break;
251 }
252 pDirectoryEntry = pDirectoryEntries;
253 while (EntryCount < Context)
254 {
255 CHAR ObjectNameA [MAX_PATH];
256 CHAR TypeNameA [MAX_PATH];
257 CHAR TargetNameA [MAX_PATH];
258
259 if (0 == wcscmp (L"SymbolicLink", pDirectoryEntry->TypeName.Buffer))
260 {
261 if (TRUE == ExpandSymbolicLink (
262 DirectoryNameW,
263 & pDirectoryEntry->Name,
264 & TargetObjectName
265 )
266 )
267 {
268
269 printf (
270 "%-16s %s -> %s\n",
271 RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA),
272 RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA),
273 RawUszAsz (TargetObjectName.Buffer, TargetNameA)
274 );
275 }
276 else
277 {
278 printf (
279 "%-16s %s -> (error!)\n",
280 RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA),
281 RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA)
282 );
283 }
284 }
285 else
286 {
287 printf (
288 "%-16s %s\n",
289 RawUszAsz (pDirectoryEntry->TypeName.Buffer, TypeNameA),
290 RawUszAsz (pDirectoryEntry->Name.Buffer, ObjectNameA)
291 );
292 }
293 ++ pDirectoryEntry;
294 ++ EntryCount;
295 }
296 };
297 printf ("\n\t%lu object(s)\n", EntryCount);
298 /*
299 * Free any resource.
300 */
302 /*
303 * Recurse into, if required so.
304 */
305 if (FALSE != Recurse)
306 {
307 pDirectoryEntry = (POBJECT_DIRECTORY_INFORMATION) DirectoryEntry;
308 while (0 != pDirectoryEntry->TypeName.Length)
309 {
310 if (0 == wcscmp (L"Directory", pDirectoryEntry->TypeName.Buffer))
311 {
312 WCHAR CurrentName [MAX_PATH];
314
315 CurrentName [0] = L'\0';
316 wcscpy (CurrentName, DirectoryNameW->Buffer);
317 if (wcslen (CurrentName) > 1)
318 {
319 wcscat (CurrentName, L"\\");
320 }
321 wcscat (CurrentName, pDirectoryEntry->Name.Buffer);
322 RtlInitUnicodeString (& CurrentDirectory, CurrentName);
323 ListDirectory (& CurrentDirectory, Recurse);
324 }
325 ++ pDirectoryEntry;
326 }
327 }
328 return (TRUE);
329}
330
331
332int main(int argc, char* argv[])
333{
334 WCHAR DirectoryNameW [MAX_PATH];
335 UNICODE_STRING DirectoryName;
336 BOOL Recurse = FALSE;
337
338 /*
339 * Check user arguments.
340 */
341 switch (argc)
342 {
343 case 2:
344 RawAszUsz (argv[1], DirectoryNameW);
345 break;
346 case 3:
347 if (strcmp (argv[1], "-r"))
348 {
349 fprintf (
350 stderr,
351 "%s: unknown option '%s'.\n",
352 argv [0], argv[1]
353 );
354 return EXIT_FAILURE;
355 }
356 RawAszUsz (argv[2], DirectoryNameW);
357 Recurse = TRUE;
358 break;
359 default:
360 fprintf (
361 stderr,
362 "\nUsage: %s [-r] directory\n\n"
363 " -r recurse\n"
364 " directory a directory name in the system namespace\n\n",
365 argv [0]
366 );
367 return EXIT_FAILURE;
368 }
369 /*
370 * List the directory.
371 */
372 RtlInitUnicodeString (& DirectoryName, DirectoryNameW);
373 return (FALSE == ListDirectory (& DirectoryName, Recurse))
375 : EXIT_SUCCESS;
376}
377
378
379/* EOF */
static HANDLE DirectoryHandle
Definition: ObType.c:48
PRTL_UNICODE_STRING_BUFFER Path
static int argc
Definition: ServiceArgs.c:12
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
LONG NTSTATUS
Definition: precomp.h:26
#define CHAR(Char)
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:34
int main()
Definition: test.c:6
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
unsigned int BOOL
Definition: ntddk_ex.h:94
#define printf
Definition: freeldr.h:93
Status
Definition: gdiplustypes.h:25
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define EXIT_FAILURE
Definition: jerror.c:33
#define a
Definition: ke_i.h:78
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define argv
Definition: mplay32.c:18
struct _OBJECT_DIRECTORY_INFORMATION * POBJECT_DIRECTORY_INFORMATION
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:245
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:295
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:205
#define L(x)
Definition: ntvdm.h:50
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:393
NTSTATUS NTAPI NtQueryDirectoryObject(IN HANDLE DirectoryHandle, OUT PVOID Buffer, IN ULONG BufferLength, IN BOOLEAN ReturnSingleEntry, IN BOOLEAN RestartScan, IN OUT PULONG Context, OUT PULONG ReturnLength OPTIONAL)
Definition: obdir.c:490
static PCHAR WINAPI RawUszAsz(PWCHAR szU, PCHAR szA)
Definition: objdir.c:31
static PWCHAR WINAPI RawAszUsz(PCHAR szA, PWCHAR szW)
Definition: objdir.c:47
BOOL WINAPI ExpandSymbolicLink(IN PUNICODE_STRING DirectoryName, IN PUNICODE_STRING SymbolicLinkName, IN OUT PUNICODE_STRING TargetObjectName)
Definition: objdir.c:97
static const char *WINAPI StatusToName(NTSTATUS Status)
Definition: objdir.c:63
BOOL WINAPI ListDirectory(IN PUNICODE_STRING DirectoryNameW, IN BOOL Recurse)
Definition: objdir.c:170
static PCWSTR TargetName
Definition: ping.c:67
#define EXIT_SUCCESS
Definition: rdjpgcom.c:55
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
#define memset(x, y, z)
Definition: compat.h:39
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
HANDLE RootDirectory
Definition: umtypes.h:184
PVOID SecurityQualityOfService
Definition: umtypes.h:188
PUNICODE_STRING ObjectName
Definition: umtypes.h:185
PVOID SecurityDescriptor
Definition: umtypes.h:187
UNICODE_STRING TypeName
Definition: obtypes.h:279
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _OBJECT_ATTRIBUTES OBJECT_ATTRIBUTES
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3739
#define WINAPI
Definition: msvc.h:6
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193