update for HEAD-2003091401
[reactos.git] / drivers / fs / ntfs / 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$
20  *
21  * COPYRIGHT:        See COPYING in the top level directory
22  * PROJECT:          ReactOS kernel
23  * FILE:             services/fs/ntfs/dirctl.c
24  * PURPOSE:          NTFS filesystem driver
25  * PROGRAMMER:       Eric Kohl
26  */
27
28 /* INCLUDES *****************************************************************/
29
30 #include <ddk/ntddk.h>
31
32 //#define NDEBUG
33 #include <debug.h>
34
35 #include "ntfs.h"
36
37
38 /* FUNCTIONS ****************************************************************/
39
40 static NTSTATUS
41 NtfsGetStandardInformation(PFCB Fcb,
42                            PDEVICE_OBJECT DeviceObject,
43                            PFILE_STANDARD_INFORMATION StandardInfo,
44                            PULONG BufferLength)
45 /*
46  * FUNCTION: Retrieve the standard file information
47  */
48 {
49   DPRINT("NtfsGetStandardInformation() called\n");
50
51   if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
52     return(STATUS_BUFFER_OVERFLOW);
53
54   /* PRECONDITION */
55   assert(StandardInfo != NULL);
56   assert(Fcb != NULL);
57
58   RtlZeroMemory(StandardInfo,
59                 sizeof(FILE_STANDARD_INFORMATION));
60
61   StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
62   StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
63   StandardInfo->NumberOfLinks = 0;
64   StandardInfo->DeletePending = FALSE;
65   StandardInfo->Directory = NtfsFCBIsDirectory(Fcb);
66
67   *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
68   return(STATUS_SUCCESS);
69 }
70
71
72 static NTSTATUS
73 NtfsGetPositionInformation(PFILE_OBJECT FileObject,
74                            PFILE_POSITION_INFORMATION PositionInfo,
75                            PULONG BufferLength)
76 {
77   DPRINT("NtfsGetPositionInformation() called\n");
78
79   if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
80     return(STATUS_BUFFER_OVERFLOW);
81
82   PositionInfo->CurrentByteOffset.QuadPart = 
83     0;
84 //    FileObject->CurrentByteOffset.QuadPart;
85
86   DPRINT("Getting position %I64x\n",
87          PositionInfo->CurrentByteOffset.QuadPart);
88
89   *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
90   return(STATUS_SUCCESS);
91 }
92
93
94 static NTSTATUS
95 NtfsGetBasicInformation(PFILE_OBJECT FileObject,
96                         PFCB Fcb,
97                         PDEVICE_OBJECT DeviceObject,
98                         PFILE_BASIC_INFORMATION BasicInfo,
99                         PULONG BufferLength)
100 {
101   DPRINT("NtfsGetBasicInformation() called\n");
102
103   if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
104     return(STATUS_BUFFER_OVERFLOW);
105
106 #if 0
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 #endif
119
120   *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
121
122   return(STATUS_SUCCESS);
123 }
124
125
126 static NTSTATUS
127 NtfsGetNameInformation(PFILE_OBJECT FileObject,
128                        PFCB Fcb,
129                        PDEVICE_OBJECT DeviceObject,
130                        PFILE_NAME_INFORMATION NameInfo,
131                        PULONG BufferLength)
132 /*
133  * FUNCTION: Retrieve the file name information
134  */
135 {
136   ULONG NameLength;
137
138   DPRINT("NtfsGetNameInformation() called\n");
139
140   assert(NameInfo != NULL);
141   assert(Fcb != NULL);
142
143   NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
144 //  NameLength = 2;
145   if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
146     return(STATUS_BUFFER_OVERFLOW);
147
148   NameInfo->FileNameLength = NameLength;
149   memcpy(NameInfo->FileName,
150          Fcb->PathName,
151          NameLength + sizeof(WCHAR));
152 //  wcscpy(NameInfo->FileName, L"\\");
153
154   *BufferLength -=
155     (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
156
157   return(STATUS_SUCCESS);
158 }
159
160
161 static NTSTATUS
162 NtfsGetInternalInformation(PFCB Fcb,
163                            PFILE_INTERNAL_INFORMATION InternalInfo,
164                            PULONG BufferLength)
165 {
166   DPRINT("NtfsGetInternalInformation() called\n");
167
168   assert(InternalInfo);
169   assert(Fcb);
170
171   if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
172     return(STATUS_BUFFER_OVERFLOW);
173
174   /* FIXME: get a real index, that can be used in a create operation */
175   InternalInfo->IndexNumber.QuadPart = 0;
176
177   *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
178
179   return(STATUS_SUCCESS);
180 }
181
182
183 NTSTATUS STDCALL
184 NtfsQueryInformation(PDEVICE_OBJECT DeviceObject,
185                      PIRP Irp)
186 /*
187  * FUNCTION: Retrieve the specified file information
188  */
189 {
190   FILE_INFORMATION_CLASS FileInformationClass;
191   PIO_STACK_LOCATION Stack;
192   PFILE_OBJECT FileObject;
193   PFCB Fcb;
194   PVOID SystemBuffer;
195   ULONG BufferLength;
196
197   NTSTATUS Status = STATUS_SUCCESS;
198
199   DPRINT("NtfsQueryInformation() called\n");
200
201   Stack = IoGetCurrentIrpStackLocation(Irp);
202   FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
203   FileObject = Stack->FileObject;
204   Fcb = FileObject->FsContext;
205
206   SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
207   BufferLength = Stack->Parameters.QueryFile.Length;
208
209   switch (FileInformationClass)
210     {
211       case FileStandardInformation:
212         Status = NtfsGetStandardInformation(Fcb,
213                                             DeviceObject,
214                                             SystemBuffer,
215                                             &BufferLength);
216         break;
217
218       case FilePositionInformation:
219         Status = NtfsGetPositionInformation(FileObject,
220                                             SystemBuffer,
221                                             &BufferLength);
222         break;
223
224       case FileBasicInformation:
225         Status = NtfsGetBasicInformation(FileObject,
226                                          Fcb,
227                                          DeviceObject,
228                                          SystemBuffer,
229                                          &BufferLength);
230         break;
231
232       case FileNameInformation:
233         Status = NtfsGetNameInformation(FileObject,
234                                         Fcb,
235                                         DeviceObject,
236                                         SystemBuffer,
237                                         &BufferLength);
238         break;
239
240       case FileInternalInformation:
241         Status = NtfsGetInternalInformation(Fcb,
242                                             SystemBuffer,
243                                             &BufferLength);
244         break;
245
246       case FileAlternateNameInformation:
247       case FileAllInformation:
248         Status = STATUS_NOT_IMPLEMENTED;
249         break;
250
251       default:
252         DPRINT("Unimplemented information class %u\n", FileInformationClass);
253         Status = STATUS_NOT_SUPPORTED;
254     }
255
256   Irp->IoStatus.Status = Status;
257   if (NT_SUCCESS(Status))
258     Irp->IoStatus.Information =
259       Stack->Parameters.QueryFile.Length - BufferLength;
260   else
261     Irp->IoStatus.Information = 0;
262
263   IoCompleteRequest(Irp, IO_NO_INCREMENT);
264
265   return(Status);
266 }
267
268 /* EOF */