Changed drive assignment.
[reactos.git] / posix / lib / psxdll / dirent / readdir.c
1 /* $Id: readdir.c,v 1.2 2002/02/20 09:17:56 hyperion Exp $
2 */
3 /*
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>
9 * UPDATE HISTORY:
10 * 27/01/2002: Created
11 * 13/02/2002: KJK::Hyperion: modified to use file descriptors
12 */
13
14 #include <sys/types.h>
15 #include <fcntl.h>
16 #include <stdlib.h>
17 #include <stddef.h>
18 #include <dirent.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>
24
25 struct dirent *readdir(DIR *dirp)
26 {
27 struct _Wdirent *lpwdReturn;
28 struct __internal_DIR *pidData;
29 ANSI_STRING strFileName;
30 UNICODE_STRING wstrFileName;
31 NTSTATUS nErrCode;
32
33 /* call Unicode function */
34 lpwdReturn = _Wreaddir(dirp);
35
36 /* failure */
37 if(lpwdReturn == 0)
38 return (0);
39
40 /* get the internal data object */
41 pidData = ((struct __internal_DIR *)dirp);
42
43 /* create NT Unicode string from the Unicode dirent's buffer */
44 RtlInitUnicodeString(&wstrFileName, pidData->ent.de_unicode.d_name);
45
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;
50
51 /* convert the filename to ANSI */
52 nErrCode = RtlUnicodeStringToAnsiString(&strFileName, &wstrFileName, FALSE);
53
54 /* failure */
55 if(!NT_SUCCESS(nErrCode))
56 {
57 errno = __status_to_errno(nErrCode);
58 return (0);
59 }
60
61 /* make the ANSI dirent filename point to the ANSI buffer */
62 pidData->ent.de_ansi.d_name = strFileName.Buffer;
63
64 /* null-terminate the ANSI name */
65 pidData->ent.de_ansi.d_name[strFileName.Length] = 0;
66
67 /* success */
68 return (&(pidData->ent.de_ansi));
69 }
70
71 int readdir_r(DIR *dirp, struct dirent *entry, struct dirent **result)
72 {
73 errno = ENOSYS;
74 return (0);
75 }
76
77 struct _Wdirent *_Wreaddir(DIR *dirp)
78 {
79 HANDLE hFile;
80 HANDLE hDir;
81 OBJECT_ATTRIBUTES oaFileAttribs;
82 UNICODE_STRING wstrFileName;
83 FILE_INTERNAL_INFORMATION fiiInfo;
84 IO_STATUS_BLOCK isbStatus;
85 NTSTATUS nErrCode;
86 struct __internal_DIR *pidData;
87
88 /* check the "magic" signature */
89 if(!__safeobj_validate(dirp, __IDIR_MAGIC))
90 {
91 errno = EINVAL;
92 return (0);
93 }
94
95 /* get internal data */
96 pidData = (struct __internal_DIR *)dirp;
97
98 /* get handle */
99 hDir = (HANDLE)fcntl(pidData->fildes, F_GETFH);
100
101 /* failure */
102 if(((int)hDir) == -1)
103 return (0);
104
105 /* read next directory entry */
106 nErrCode = NtQueryDirectoryFile
107 (
108 hDir,
109 NULL,
110 NULL,
111 NULL,
112 &isbStatus,
113 (PVOID)&pidData->info,
114 sizeof(pidData->info) + sizeof(WCHAR) * (MAX_PATH - 1),
115 FileDirectoryInformation,
116 TRUE,
117 NULL,
118 FALSE
119 );
120
121 /* failure or EOF */
122 if(!NT_SUCCESS(nErrCode))
123 {
124 if(nErrCode == (NTSTATUS)STATUS_NO_MORE_FILES)
125 return (0);
126 else
127 {
128 ERR("NtQueryDirectoryFile() failed with status 0x%08X", nErrCode);
129 errno = __status_to_errno(nErrCode);
130 return (0);
131 }
132 }
133
134 /* null-terminate the filename, just in case */
135 pidData->info.FileName[pidData->info.FileNameLength / sizeof(WCHAR)] = 0;
136
137 INFO("this entry: %ls", pidData->info.FileName);
138
139 #if 0
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];
145
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;
152
153 /* open the file */
154 nErrCode = NtOpenFile
155 (
156 &hFile,
157 FILE_READ_ATTRIBUTES,
158 &oaFileAttribs,
159 &isbStatus,
160 0,
161 FILE_SYNCHRONOUS_IO_NONALERT
162 );
163
164 /* failure */
165 if(!NT_SUCCESS(nErrCode))
166 {
167 ERR("NtOpenFile() failed with status %#X", nErrCode);
168 errno = __status_to_errno(nErrCode);
169 return (0);
170 }
171
172 /* get the internal information for the file */
173 nErrCode = NtQueryInformationFile
174 (
175 hFile,
176 &isbStatus,
177 &fiiInfo,
178 sizeof(FILE_INTERNAL_INFORMATION),
179 FileInternalInformation
180 );
181
182 /* close the handle (not needed anymore) */
183 NtClose(hFile);
184
185 /* failure */
186 if(!NT_SUCCESS(nErrCode))
187 {
188 ERR("NtQueryInformationFile() failed with status %#X", nErrCode);
189 errno = __status_to_errno(nErrCode);
190 return (0);
191 }
192
193 /* return file inode */
194 pidData->ent.de_unicode.d_ino = (ino_t)fiiInfo.IndexNumber.QuadPart;
195 #endif
196
197 FIXME("file inodes currently hardcoded to 0");
198 pidData->ent.de_unicode.d_ino = 0;
199
200 /* return file name */
201 pidData->ent.de_unicode.d_name = &pidData->info.FileName[0];
202
203 /* success */
204 return &(pidData->ent.de_unicode);
205 }
206
207 int _Wreaddir_r(DIR *dirp, struct _Wdirent *entry, struct _Wdirent **result)
208 {
209 errno = ENOSYS;
210 return (0);
211 }
212
213 /* EOF */
214