Fixed FCB management functions.
[reactos.git] / reactos / drivers / fs / cdfs / finfo.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2002 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 /* $Id: finfo.c,v 1.2 2002/05/01 13:15:42 ekohl Exp $
20 *
21 * COPYRIGHT: See COPYING in the top level directory
22 * PROJECT: ReactOS kernel
23 * FILE: services/fs/cdfs/dirctl.c
24 * PURPOSE: CDROM (ISO 9660) filesystem driver
25 * PROGRAMMER: Art Yerkes
26 * Eric Kohl
27 * UPDATE HISTORY:
28 */
29
30 /* INCLUDES *****************************************************************/
31
32 #include <ddk/ntddk.h>
33
34 #define NDEBUG
35 #include <debug.h>
36
37 #include "cdfs.h"
38
39
40 /* FUNCTIONS ****************************************************************/
41
42 static NTSTATUS
43 CdfsGetStandardInformation(PFCB Fcb,
44 PDEVICE_OBJECT DeviceObject,
45 PFILE_STANDARD_INFORMATION StandardInfo,
46 PULONG BufferLength)
47 /*
48 * FUNCTION: Retrieve the standard file information
49 */
50 {
51 DPRINT("CdfsGetStandardInformation() called\n");
52
53 if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
54 return STATUS_BUFFER_OVERFLOW;
55
56 /* PRECONDITION */
57 assert(StandardInfo != NULL);
58 assert(Fcb != NULL);
59
60 RtlZeroMemory(StandardInfo,
61 sizeof(FILE_STANDARD_INFORMATION));
62
63 StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
64 StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
65 StandardInfo->NumberOfLinks = 0;
66 StandardInfo->DeletePending = FALSE;
67 StandardInfo->Directory = Fcb->Entry.FileFlags & 0x02 ? TRUE : FALSE;
68
69 *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
70 return(STATUS_SUCCESS);
71 }
72
73
74 static NTSTATUS
75 CdfsGetPositionInformation(PFILE_OBJECT FileObject,
76 PFILE_POSITION_INFORMATION PositionInfo,
77 PULONG BufferLength)
78 {
79 DPRINT("CdfsGetPositionInformation() called\n");
80
81 if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
82 return STATUS_BUFFER_OVERFLOW;
83
84 PositionInfo->CurrentByteOffset.QuadPart =
85 FileObject->CurrentByteOffset.QuadPart;
86
87 DPRINT("Getting position %I64x\n",
88 PositionInfo->CurrentByteOffset.QuadPart);
89
90 *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
91 return(STATUS_SUCCESS);
92 }
93
94
95 static NTSTATUS
96 CdfsGetBasicInformation(PFILE_OBJECT FileObject,
97 PFCB Fcb,
98 PDEVICE_OBJECT DeviceObject,
99 PFILE_BASIC_INFORMATION BasicInfo,
100 PULONG BufferLength)
101 {
102 DPRINT("CdfsGetBasicInformation() called\n");
103
104 if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
105 return STATUS_BUFFER_OVERFLOW;
106
107 CdfsDateTimeToFileTime(Fcb,
108 &BasicInfo->CreationTime);
109 CdfsDateTimeToFileTime(Fcb,
110 &BasicInfo->LastAccessTime);
111 CdfsDateTimeToFileTime(Fcb,
112 &BasicInfo->LastWriteTime);
113 CdfsDateTimeToFileTime(Fcb,
114 &BasicInfo->ChangeTime);
115
116 CdfsFileFlagsToAttributes(Fcb,
117 &BasicInfo->FileAttributes);
118
119 *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
120
121 return(STATUS_SUCCESS);
122 }
123
124
125 static NTSTATUS
126 CdfsGetNameInformation(PFILE_OBJECT FileObject,
127 PFCB Fcb,
128 PDEVICE_OBJECT DeviceObject,
129 PFILE_NAME_INFORMATION NameInfo,
130 PULONG BufferLength)
131 /*
132 * FUNCTION: Retrieve the file name information
133 */
134 {
135 ULONG NameLength;
136
137 DPRINT("CdfsGetNameInformation() called\n");
138
139 assert(NameInfo != NULL);
140 assert(Fcb != NULL);
141
142 NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
143 if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
144 return STATUS_BUFFER_OVERFLOW;
145
146 NameInfo->FileNameLength = NameLength;
147 memcpy(NameInfo->FileName,
148 Fcb->PathName,
149 NameLength + sizeof(WCHAR));
150
151 *BufferLength -=
152 (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
153
154 return STATUS_SUCCESS;
155 }
156
157
158 static NTSTATUS
159 CdfsGetInternalInformation(PFCB Fcb,
160 PFILE_INTERNAL_INFORMATION InternalInfo,
161 PULONG BufferLength)
162 {
163 DPRINT("CdfsGetInternalInformation() called\n");
164
165 assert(InternalInfo);
166 assert(Fcb);
167
168 if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
169 return(STATUS_BUFFER_OVERFLOW);
170
171 /* FIXME: get a real index, that can be used in a create operation */
172 InternalInfo->IndexNumber.QuadPart = 0;
173
174 *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
175
176 return(STATUS_SUCCESS);
177 }
178
179
180 NTSTATUS STDCALL
181 CdfsQueryInformation(PDEVICE_OBJECT DeviceObject,
182 PIRP Irp)
183 /*
184 * FUNCTION: Retrieve the specified file information
185 */
186 {
187 FILE_INFORMATION_CLASS FileInformationClass;
188 PIO_STACK_LOCATION Stack;
189 PFILE_OBJECT FileObject;
190 PFCB Fcb;
191 PVOID SystemBuffer;
192 ULONG BufferLength;
193
194 NTSTATUS Status = STATUS_SUCCESS;
195
196 DPRINT("CdfsQueryInformation() called\n");
197
198 Stack = IoGetCurrentIrpStackLocation(Irp);
199 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
200 FileObject = Stack->FileObject;
201 Fcb = FileObject->FsContext;
202
203 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
204 BufferLength = Stack->Parameters.QueryFile.Length;
205
206 switch (FileInformationClass)
207 {
208 case FileStandardInformation:
209 Status = CdfsGetStandardInformation(Fcb,
210 DeviceObject,
211 SystemBuffer,
212 &BufferLength);
213 break;
214
215 case FilePositionInformation:
216 Status = CdfsGetPositionInformation(FileObject,
217 SystemBuffer,
218 &BufferLength);
219 break;
220
221 case FileBasicInformation:
222 Status = CdfsGetBasicInformation(FileObject,
223 Fcb,
224 DeviceObject,
225 SystemBuffer,
226 &BufferLength);
227 break;
228
229 case FileNameInformation:
230 Status = CdfsGetNameInformation(FileObject,
231 Fcb,
232 DeviceObject,
233 SystemBuffer,
234 &BufferLength);
235 break;
236
237 case FileInternalInformation:
238 Status = CdfsGetInternalInformation(Fcb,
239 SystemBuffer,
240 &BufferLength);
241 break;
242
243 case FileAlternateNameInformation:
244 case FileAllInformation:
245 Status = STATUS_NOT_IMPLEMENTED;
246 break;
247
248 default:
249 DPRINT("Unimplemented information class %u\n", FileInformationClass);
250 Status = STATUS_NOT_SUPPORTED;
251 }
252
253 Irp->IoStatus.Status = Status;
254 if (NT_SUCCESS(Status))
255 Irp->IoStatus.Information =
256 Stack->Parameters.QueryFile.Length - BufferLength;
257 else
258 Irp->IoStatus.Information = 0;
259
260 IoCompleteRequest(Irp, IO_NO_INCREMENT);
261
262 return(Status);
263 }
264
265 /* EOF */