1 /* $Id: readdir.c,v 1.7 2002/10/29 04:45:28 rex Exp $
4 * COPYRIGHT: See COPYING in the top level directory
5 * PROJECT: ReactOS POSIX+ Subsystem
6 * FILE: subsys/psx/lib/psxdll/dirent/readdir.c
7 * PURPOSE: Read directory
8 * PROGRAMMER: KJK::Hyperion <noog@libero.it>
11 * 13/02/2002: KJK::Hyperion: modified to use file descriptors
14 #include <sys/types.h>
19 #include <psx/dirent.h>
20 #include <psx/debug.h>
21 #include <psx/errno.h>
22 #include <psx/safeobj.h>
23 #include <ddk/ntddk.h>
25 struct dirent
*readdir(DIR *dirp
)
27 struct _Wdirent
*lpwdReturn
;
28 struct __internal_DIR
*pidData
;
29 ANSI_STRING strFileName
;
30 UNICODE_STRING wstrFileName
;
33 /* call Unicode function */
34 lpwdReturn
= _Wreaddir(dirp
);
40 /* get the internal data object */
41 pidData
= ((struct __internal_DIR
*)dirp
);
43 /* create NT Unicode string from the Unicode dirent's buffer */
44 RtlInitUnicodeString(&wstrFileName
, pidData
->ent
.de_unicode
.d_name
);
46 /* HACK: make the ANSI string point to the same buffer where the Unicode string is stored */
47 strFileName
.Buffer
= (PCSZ
)&pidData
->info
.FileName
[0];
48 strFileName
.Length
= 0;
49 strFileName
.MaximumLength
= MAX_PATH
;
51 /* convert the filename to ANSI */
52 nErrCode
= RtlUnicodeStringToAnsiString(&strFileName
, &wstrFileName
, FALSE
);
55 if(!NT_SUCCESS(nErrCode
))
57 errno
= __status_to_errno(nErrCode
);
61 /* make the ANSI dirent filename point to the ANSI buffer */
62 pidData
->ent
.de_ansi
.d_name
= strFileName
.Buffer
;
64 /* null-terminate the ANSI name */
65 pidData
->ent
.de_ansi
.d_name
[strFileName
.Length
] = 0;
68 return (&(pidData
->ent
.de_ansi
));
71 int readdir_r(DIR *dirp
, struct dirent
*entry
, struct dirent
**result
)
77 struct _Wdirent
*_Wreaddir(DIR *dirp
)
81 OBJECT_ATTRIBUTES oaFileAttribs
;
82 UNICODE_STRING wstrFileName
;
83 FILE_INTERNAL_INFORMATION fiiInfo
;
84 IO_STATUS_BLOCK isbStatus
;
86 struct __internal_DIR
*pidData
;
88 /* check the "magic" signature */
89 if(!__safeobj_validate(dirp
, __IDIR_MAGIC
))
95 /* get internal data */
96 pidData
= (struct __internal_DIR
*)dirp
;
99 hDir
= (HANDLE
)fcntl(pidData
->fildes
, F_GETFH
);
102 if(((int)hDir
) == -1)
105 /* read next directory entry */
106 nErrCode
= NtQueryDirectoryFile
113 (PVOID
)&pidData
->info
,
114 sizeof(pidData
->info
) + sizeof(WCHAR
) * (MAX_PATH
- 1),
115 FileDirectoryInformation
,
122 if(!NT_SUCCESS(nErrCode
))
124 if(nErrCode
== (NTSTATUS
)STATUS_NO_MORE_FILES
)
128 ERR("NtQueryDirectoryFile() failed with status 0x%08X", nErrCode
);
129 errno
= __status_to_errno(nErrCode
);
134 /* null-terminate the filename, just in case */
135 pidData
->info
.FileName
[pidData
->info
.FileNameLength
/ sizeof(WCHAR
)] = 0;
137 INFO("this entry: %ls", pidData
->info
.FileName
);
139 /* file inodes are not returned by NtQueryDirectoryFile, we have to open every file */
140 /* set file's object attributes */
141 wstrFileName
.Length
= pidData
->info
.FileNameLength
;
142 wstrFileName
.MaximumLength
= sizeof(WCHAR
) * MAX_PATH
;
143 wstrFileName
.Buffer
= &pidData
->info
.FileName
[0];
145 oaFileAttribs
.Length
= sizeof(OBJECT_ATTRIBUTES
);
146 oaFileAttribs
.RootDirectory
= hDir
;
147 oaFileAttribs
.ObjectName
= &wstrFileName
;
148 oaFileAttribs
.Attributes
= 0;
149 oaFileAttribs
.SecurityDescriptor
= NULL
;
150 oaFileAttribs
.SecurityQualityOfService
= NULL
;
153 nErrCode
= NtOpenFile
156 FILE_READ_ATTRIBUTES
| SYNCHRONIZE
,
160 FILE_SYNCHRONOUS_IO_NONALERT
164 if(!NT_SUCCESS(nErrCode
))
166 ERR("NtOpenFile() failed with status %#X", nErrCode
);
167 errno
= __status_to_errno(nErrCode
);
171 /* get the internal information for the file */
172 nErrCode
= NtQueryInformationFile
177 sizeof(FILE_INTERNAL_INFORMATION
),
178 FileInternalInformation
181 /* close the handle (not needed anymore) */
185 if(!NT_SUCCESS(nErrCode
))
187 ERR("NtQueryInformationFile() failed with status %#X", nErrCode
);
188 errno
= __status_to_errno(nErrCode
);
192 /* return file inode */
193 pidData
->ent
.de_unicode
.d_ino
= (ino_t
)fiiInfo
.IndexNumber
.QuadPart
;
195 /* return file name */
196 pidData
->ent
.de_unicode
.d_name
= &pidData
->info
.FileName
[0];
199 return &(pidData
->ent
.de_unicode
);
202 int _Wreaddir_r(DIR *dirp
, struct _Wdirent
*entry
, struct _Wdirent
**result
)