ReactOS  0.4.12-dev-432-g3463b2d
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 
28 static
29 PCHAR
30 WINAPI
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 
44 static
45 PWCHAR
46 WINAPI
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 
60 static
61 const char *
62 WINAPI
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 
95 BOOL
96 WINAPI
98  IN PUNICODE_STRING DirectoryName,
99  IN PUNICODE_STRING SymbolicLinkName,
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  }
120  RtlAppendUnicodeStringToString (& Path, SymbolicLinkName);
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 
168 BOOL
169 WINAPI
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;
183  ULONG ReturnLength = 0;
184  ULONG EntryCount = 0;
185 
186  /* For expanding symbolic links */
187  WCHAR TargetName [2 * MAX_PATH];
188  UNICODE_STRING TargetObjectName = {
189  sizeof TargetName,
190  sizeof TargetName,
191  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  */
210  & DirectoryHandle,
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,
237  & ReturnLength
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 
332 int 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))
374  ? EXIT_FAILURE
375  : EXIT_SUCCESS;
376 }
377 
378 
379 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:35
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:39
static int argc
Definition: ServiceArgs.c:12
static PWCHAR WINAPI RawAszUsz(PCHAR szA, PWCHAR szW)
Definition: objdir.c:47
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
#define STATUS_NO_MORE_ENTRIES
Definition: ntstatus.h:193
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
__wchar_t WCHAR
Definition: xmlstorage.h:180
NTSTATUS NTAPI NtOpenDirectoryObject(OUT PHANDLE DirectoryHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: obdir.c:359
char CHAR
Definition: xmlstorage.h:175
LONG NTSTATUS
Definition: precomp.h:26
static HANDLE DirectoryHandle
Definition: ObType.c:48
uint16_t * PWCHAR
Definition: typedefs.h:54
#define argv
Definition: mplay32.c:18
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:456
#define WCHAR
Definition: msvc.h:43
#define STATUS_INVALID_HANDLE
Definition: ntstatus.h:231
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define sprintf(buf, format,...)
Definition: sprintf.c:55
#define EXIT_SUCCESS
Definition: rdjpgcom.c:55
struct _OBJECT_DIRECTORY_INFORMATION * POBJECT_DIRECTORY_INFORMATION
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
#define a
Definition: ke_i.h:78
smooth NULL
Definition: ftsmooth.c:416
BOOL WINAPI ExpandSymbolicLink(IN PUNICODE_STRING DirectoryName, IN PUNICODE_STRING SymbolicLinkName, IN OUT PUNICODE_STRING TargetObjectName)
Definition: objdir.c:97
struct _OBJECT_ATTRIBUTES OBJECT_ATTRIBUTES
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
unsigned int BOOL
Definition: ntddk_ex.h:94
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:24
#define MAX_PATH
Definition: compat.h:26
#define EXIT_FAILURE
Definition: jerror.c:33
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3393
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1087
BOOL WINAPI ListDirectory(IN PUNICODE_STRING DirectoryNameW, IN BOOL Recurse)
Definition: objdir.c:170
unsigned char BYTE
Definition: mem.h:68
WCHAR TargetName[256]
Definition: arping.c:27
#define STATUS_MORE_ENTRIES
Definition: udferr_usr.h:124
#define WINAPI
Definition: msvc.h:20
Status
Definition: gdiplustypes.h:24
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
static const char *WINAPI StatusToName(NTSTATUS Status)
Definition: objdir.c:63
PRTL_UNICODE_STRING_BUFFER Path
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
PVOID SecurityDescriptor
Definition: umtypes.h:187
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
static PCHAR WINAPI RawUszAsz(PWCHAR szU, PCHAR szA)
Definition: objdir.c:31
_CRTIMP wchar_t *__cdecl wcscat(_Inout_updates_z_(_String_length_(_Dest)+_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
PVOID SecurityQualityOfService
Definition: umtypes.h:188
#define OUT
Definition: typedefs.h:39
PUNICODE_STRING ObjectName
Definition: umtypes.h:185
HANDLE RootDirectory
Definition: umtypes.h:184
unsigned int ULONG
Definition: retypes.h:1
FILE * stderr
#define SYMBOLIC_LINK_QUERY
Definition: nt_native.h:1265
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#define DIRECTORY_QUERY
Definition: nt_native.h:1254
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define STATUS_OBJECT_PATH_SYNTAX_BAD
Definition: ntstatus.h:281
#define memset(x, y, z)
Definition: compat.h:39
#define CHAR(Char)
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
UNICODE_STRING TypeName
Definition: obtypes.h:279
#define printf
Definition: config.h:203
int main(int argc, char *argv[])
Definition: objdir.c:332