1 /* $Id: readdir.c,v 1.2 2002/02/20 09:17:56 hyperion 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
);
140 /* file inodes are not returned by NtQueryDirectoryFile, we have to open every file */
141 /* set file's object attributes */
142 wstrFileName
.Length
= pidData
->info
.FileNameLength
;
143 wstrFileName
.MaximumLength
= sizeof(WCHAR
) * MAX_PATH
;
144 wstrFileName
.Buffer
= &pidData
->info
.FileName
[0];
146 oaFileAttribs
.Length
= sizeof(OBJECT_ATTRIBUTES
);
147 oaFileAttribs
.RootDirectory
= pidData
->dirhandle
;
148 oaFileAttribs
.ObjectName
= &wstrFileName
;
149 oaFileAttribs
.Attributes
= 0;
150 oaFileAttribs
.SecurityDescriptor
= NULL
;
151 oaFileAttribs
.SecurityQualityOfService
= NULL
;
154 nErrCode
= NtOpenFile
157 FILE_READ_ATTRIBUTES
,
161 FILE_SYNCHRONOUS_IO_NONALERT
165 if(!NT_SUCCESS(nErrCode
))
167 ERR("NtOpenFile() failed with status %#X", nErrCode
);
168 errno
= __status_to_errno(nErrCode
);
172 /* get the internal information for the file */
173 nErrCode
= NtQueryInformationFile
178 sizeof(FILE_INTERNAL_INFORMATION
),
179 FileInternalInformation
182 /* close the handle (not needed anymore) */
186 if(!NT_SUCCESS(nErrCode
))
188 ERR("NtQueryInformationFile() failed with status %#X", nErrCode
);
189 errno
= __status_to_errno(nErrCode
);
193 /* return file inode */
194 pidData
->ent
.de_unicode
.d_ino
= (ino_t
)fiiInfo
.IndexNumber
.QuadPart
;
197 FIXME("file inodes currently hardcoded to 0");
198 pidData
->ent
.de_unicode
.d_ino
= 0;
200 /* return file name */
201 pidData
->ent
.de_unicode
.d_name
= &pidData
->info
.FileName
[0];
204 return &(pidData
->ent
.de_unicode
);
207 int _Wreaddir_r(DIR *dirp
, struct _Wdirent
*entry
, struct _Wdirent
**result
)