Use free Windows DDK and compile with latest MinGW releases.
[reactos.git] / reactos / drivers / fs / vfat / finfo.c
1 /* $Id: finfo.c,v 1.19 2002/09/07 15:12:03 chorns Exp $
2 *
3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS kernel
5 * FILE: services/fs/vfat/finfo.c
6 * PURPOSE: VFAT Filesystem
7 * PROGRAMMER: Jason Filby (jasonfilby@yahoo.com)
8 *
9 */
10
11 /* INCLUDES *****************************************************************/
12
13 #include <ddk/ntddk.h>
14 #include <wchar.h>
15
16 #define NDEBUG
17 #include <debug.h>
18
19 #include "vfat.h"
20
21 /* FUNCTIONS ****************************************************************/
22
23 static NTSTATUS
24 VfatGetStandardInformation(PVFATFCB FCB,
25 PDEVICE_OBJECT DeviceObject,
26 PFILE_STANDARD_INFORMATION StandardInfo,
27 PULONG BufferLength)
28 /*
29 * FUNCTION: Retrieve the standard file information
30 */
31 {
32 PDEVICE_EXTENSION DeviceExtension;
33
34 if (*BufferLength < sizeof(FILE_STANDARD_INFORMATION))
35 return STATUS_BUFFER_OVERFLOW;
36
37 DeviceExtension = DeviceObject->DeviceExtension;
38 /* PRECONDITION */
39 assert (DeviceExtension != NULL);
40 assert (DeviceExtension->FatInfo.BytesPerCluster != 0);
41 assert (StandardInfo != NULL);
42 assert (FCB != NULL);
43
44 RtlZeroMemory(StandardInfo,
45 sizeof(FILE_STANDARD_INFORMATION));
46
47 StandardInfo->AllocationSize = FCB->RFCB.AllocationSize;
48 StandardInfo->EndOfFile = FCB->RFCB.FileSize;
49 StandardInfo->NumberOfLinks = 0;
50 StandardInfo->DeletePending = FCB->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
51 StandardInfo->Directory = FCB->entry.Attrib & 0x10 ? TRUE : FALSE;
52
53 *BufferLength -= sizeof(FILE_STANDARD_INFORMATION);
54 return(STATUS_SUCCESS);
55 }
56
57 static NTSTATUS
58 VfatSetPositionInformation(PFILE_OBJECT FileObject,
59 PVFATFCB FCB,
60 PDEVICE_OBJECT DeviceObject,
61 PFILE_POSITION_INFORMATION PositionInfo)
62 {
63 DPRINT ("FsdSetPositionInformation()\n");
64
65 DPRINT ("PositionInfo %x\n", PositionInfo);
66 DPRINT ("Setting position %d\n", PositionInfo->CurrentByteOffset.u.LowPart);
67 memcpy (&FileObject->CurrentByteOffset, &PositionInfo->CurrentByteOffset,
68 sizeof (LARGE_INTEGER));
69
70 return (STATUS_SUCCESS);
71 }
72
73 static NTSTATUS
74 VfatGetPositionInformation(PFILE_OBJECT FileObject,
75 PVFATFCB FCB,
76 PDEVICE_OBJECT DeviceObject,
77 PFILE_POSITION_INFORMATION PositionInfo,
78 PULONG BufferLength)
79 {
80 DPRINT ("VfatGetPositionInformation()\n");
81
82 if (*BufferLength < sizeof(FILE_POSITION_INFORMATION))
83 return STATUS_BUFFER_OVERFLOW;
84
85 PositionInfo->CurrentByteOffset.QuadPart =
86 FileObject->CurrentByteOffset.QuadPart;
87
88 DPRINT("Getting position %I64x\n",
89 PositionInfo->CurrentByteOffset.QuadPart);
90
91 *BufferLength -= sizeof(FILE_POSITION_INFORMATION);
92 return(STATUS_SUCCESS);
93 }
94
95 static NTSTATUS
96 VfatGetBasicInformation(PFILE_OBJECT FileObject,
97 PVFATFCB FCB,
98 PDEVICE_OBJECT DeviceObject,
99 PFILE_BASIC_INFORMATION BasicInfo,
100 PULONG BufferLength)
101 {
102 DPRINT("VfatGetBasicInformation()\n");
103
104 if (*BufferLength < sizeof(FILE_BASIC_INFORMATION))
105 return STATUS_BUFFER_OVERFLOW;
106
107 FsdDosDateTimeToFileTime(FCB->entry.CreationDate,
108 FCB->entry.CreationTime,
109 &BasicInfo->CreationTime);
110 FsdDosDateTimeToFileTime(FCB->entry.AccessDate,
111 0,
112 &BasicInfo->LastAccessTime);
113 FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,
114 FCB->entry.UpdateTime,
115 &BasicInfo->LastWriteTime);
116 FsdDosDateTimeToFileTime(FCB->entry.UpdateDate,
117 FCB->entry.UpdateTime,
118 &BasicInfo->ChangeTime);
119
120 BasicInfo->FileAttributes = FCB->entry.Attrib;
121 DPRINT("Getting attributes %x\n", BasicInfo->FileAttributes);
122
123 *BufferLength -= sizeof(FILE_BASIC_INFORMATION);
124 return(STATUS_SUCCESS);
125 }
126
127
128 static NTSTATUS
129 VfatSetDispositionInformation(PFILE_OBJECT FileObject,
130 PVFATFCB FCB,
131 PDEVICE_OBJECT DeviceObject,
132 PFILE_DISPOSITION_INFORMATION DispositionInfo)
133 {
134 KIRQL oldIrql;
135 VFATFCB tmpFcb;
136 WCHAR star[2];
137 ULONG Index;
138 NTSTATUS Status = STATUS_SUCCESS;
139 int count;
140
141 PDEVICE_EXTENSION DeviceExt = DeviceObject->DeviceExtension;
142
143 DPRINT ("FsdSetDispositionInformation()\n");
144
145 assert (DeviceExt != NULL);
146 assert (DeviceExt->FatInfo.BytesPerCluster != 0);
147 assert (FCB != NULL);
148
149 if (!wcscmp(FCB->PathName, L"\\") || !wcscmp(FCB->ObjectName, L"..")
150 || !wcscmp(FCB->ObjectName, L"."))
151 {
152 // we cannot delete a '.', '..' or the root directory
153 return STATUS_ACCESS_DENIED;
154 }
155 if (DispositionInfo->DoDeleteFile)
156 {
157 KeAcquireSpinLock (&DeviceExt->FcbListLock, &oldIrql);
158 count = FCB->RefCount;
159 if (FCB->RefCount > 1)
160 Status = STATUS_ACCESS_DENIED;
161 else
162 {
163 FCB->Flags |= FCB_DELETE_PENDING;
164 FileObject->DeletePending = TRUE;
165 }
166 KeReleaseSpinLock(&DeviceExt->FcbListLock, oldIrql);
167 DPRINT("RefCount:%d\n", count);
168 if (NT_SUCCESS(Status) && vfatFCBIsDirectory(DeviceExt, FCB))
169 {
170 memset (&tmpFcb, 0, sizeof(VFATFCB));
171 tmpFcb.ObjectName = tmpFcb.PathName;
172 star[0] = L'*';
173 star[1] = 0;
174 // skip '.' and '..', start by 2
175 Index = 2;
176 Status = FindFile (DeviceExt, &tmpFcb, FCB, star, &Index, NULL);
177 if (NT_SUCCESS(Status))
178 {
179 DPRINT1("found: \'%S\'\n", tmpFcb.PathName);
180 Status = STATUS_DIRECTORY_NOT_EMPTY;
181 FCB->Flags &= ~FCB_DELETE_PENDING;
182 FileObject->DeletePending = FALSE;
183 }
184 else
185 {
186 Status = STATUS_SUCCESS;
187 }
188 }
189 }
190 else
191 FileObject->DeletePending = FALSE;
192 return Status;
193 }
194
195 static NTSTATUS
196 VfatGetNameInformation(PFILE_OBJECT FileObject,
197 PVFATFCB FCB,
198 PDEVICE_OBJECT DeviceObject,
199 PFILE_NAME_INFORMATION NameInfo,
200 PULONG BufferLength)
201 /*
202 * FUNCTION: Retrieve the file name information
203 */
204 {
205 ULONG NameLength;
206
207 assert (NameInfo != NULL);
208 assert (FCB != NULL);
209
210 NameLength = wcslen(FCB->PathName) * sizeof(WCHAR);
211 if (*BufferLength < sizeof(FILE_NAME_INFORMATION) + NameLength)
212 return STATUS_BUFFER_OVERFLOW;
213
214 NameInfo->FileNameLength = NameLength;
215 memcpy(NameInfo->FileName,
216 FCB->PathName,
217 NameLength + sizeof(WCHAR));
218
219 *BufferLength -=
220 (sizeof(FILE_NAME_INFORMATION) + NameLength + sizeof(WCHAR));
221
222 return STATUS_SUCCESS;
223 }
224
225 static NTSTATUS
226 VfatGetInternalInformation(PVFATFCB Fcb,
227 PFILE_INTERNAL_INFORMATION InternalInfo,
228 PULONG BufferLength)
229 {
230 assert (InternalInfo);
231 assert (Fcb);
232
233 if (*BufferLength < sizeof(FILE_INTERNAL_INFORMATION))
234 return STATUS_BUFFER_OVERFLOW;
235 // FIXME: get a real index, that can be used in a create operation
236 InternalInfo->IndexNumber.QuadPart = 0;
237 *BufferLength -= sizeof(FILE_INTERNAL_INFORMATION);
238 return STATUS_SUCCESS;
239 }
240
241
242 static NTSTATUS
243 VfatGetNetworkOpenInformation(PVFATFCB Fcb,
244 PFILE_NETWORK_OPEN_INFORMATION NetworkInfo,
245 PULONG BufferLength)
246 /*
247 * FUNCTION: Retrieve the file network open information
248 */
249 {
250 assert (NetworkInfo);
251 assert (Fcb);
252
253 if (*BufferLength < sizeof(FILE_NETWORK_OPEN_INFORMATION))
254 return(STATUS_BUFFER_OVERFLOW);
255
256 FsdDosDateTimeToFileTime(Fcb->entry.CreationDate,
257 Fcb->entry.CreationTime,
258 &NetworkInfo->CreationTime);
259 FsdDosDateTimeToFileTime(Fcb->entry.AccessDate,
260 0,
261 &NetworkInfo->LastAccessTime);
262 FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
263 Fcb->entry.UpdateTime,
264 &NetworkInfo->LastWriteTime);
265 FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
266 Fcb->entry.UpdateTime,
267 &NetworkInfo->ChangeTime);
268 NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
269 NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
270 NetworkInfo->FileAttributes = Fcb->entry.Attrib;
271
272 *BufferLength -= sizeof(FILE_NETWORK_OPEN_INFORMATION);
273 return STATUS_SUCCESS;
274 }
275
276
277 static NTSTATUS
278 VfatGetAllInformation(PFILE_OBJECT FileObject,
279 PVFATFCB Fcb,
280 PFILE_ALL_INFORMATION Info,
281 PULONG BufferLength)
282 /*
283 * FUNCTION: Retrieve the all file information
284 */
285 {
286 ULONG NameLength;
287
288 assert (Info);
289 assert (Fcb);
290
291 NameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
292 if (*BufferLength < sizeof(FILE_ALL_INFORMATION) + NameLength)
293 return(STATUS_BUFFER_OVERFLOW);
294
295 /* Basic Information */
296 FsdDosDateTimeToFileTime(Fcb->entry.CreationDate,
297 Fcb->entry.CreationTime,
298 &Info->BasicInformation.CreationTime);
299 FsdDosDateTimeToFileTime(Fcb->entry.AccessDate,
300 0,
301 &Info->BasicInformation.LastAccessTime);
302 FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
303 Fcb->entry.UpdateTime,
304 &Info->BasicInformation.LastWriteTime);
305 FsdDosDateTimeToFileTime(Fcb->entry.UpdateDate,
306 Fcb->entry.UpdateTime,
307 &Info->BasicInformation.ChangeTime);
308 Info->BasicInformation.FileAttributes = Fcb->entry.Attrib;
309
310 /* Standard Information */
311 Info->StandardInformation.AllocationSize = Fcb->RFCB.AllocationSize;
312 Info->StandardInformation.EndOfFile = Fcb->RFCB.FileSize;
313 Info->StandardInformation.NumberOfLinks = 0;
314 Info->StandardInformation.DeletePending = Fcb->Flags & FCB_DELETE_PENDING ? TRUE : FALSE;
315 Info->StandardInformation.Directory = Fcb->entry.Attrib & 0x10 ? TRUE : FALSE;
316
317 /* Internal Information */
318 /* FIXME: get a real index, that can be used in a create operation */
319 Info->InternalInformation.IndexNumber.QuadPart = 0;
320
321 /* EA Information */
322 Info->EaInformation.EaSize = 0;
323
324 /* Access Information */
325 /* The IO-Manager adds this information */
326
327 /* Position Information */
328 Info->PositionInformation.CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
329
330 /* Mode Information */
331 /* The IO-Manager adds this information */
332
333 /* Alignment Information */
334 /* The IO-Manager adds this information */
335
336 /* Name Information */
337 Info->NameInformation.FileNameLength = NameLength;
338 RtlCopyMemory(Info->NameInformation.FileName,
339 Fcb->PathName,
340 NameLength + sizeof(WCHAR));
341
342 *BufferLength -= (sizeof(FILE_ALL_INFORMATION) + NameLength + sizeof(WCHAR));
343
344 return STATUS_SUCCESS;
345 }
346
347 NTSTATUS
348 VfatSetAllocationSizeInformation(PFILE_OBJECT FileObject,
349 PVFATFCB Fcb,
350 PDEVICE_EXTENSION DeviceExt,
351 PLARGE_INTEGER AllocationSize)
352 {
353 ULONG OldSize;
354 ULONG Cluster;
355 ULONG Offset;
356 NTSTATUS Status;
357
358 ULONG ClusterSize = DeviceExt->FatInfo.BytesPerCluster;
359 ULONG NewSize = AllocationSize->u.LowPart;
360 ULONG NCluster;
361
362 DPRINT("VfatSetAllocationSizeInformation()\n");
363
364 OldSize = Fcb->entry.FileSize;
365 if (AllocationSize->u.HighPart > 0)
366 {
367 return STATUS_INVALID_PARAMETER;
368 }
369 if (OldSize == NewSize)
370 {
371 return(STATUS_SUCCESS);
372 }
373 Cluster = vfatDirEntryGetFirstCluster (DeviceExt, &Fcb->entry);
374
375 if (NewSize > Fcb->RFCB.AllocationSize.u.LowPart)
376 {
377 if (Cluster == 0)
378 {
379 Status = NextCluster (DeviceExt, Fcb, Cluster, &Cluster, TRUE);
380 if (!NT_SUCCESS(Status))
381 {
382 DPRINT1("NextCluster failed.\n");
383 return Status;
384 }
385 if (Cluster == 0xffffffff)
386 {
387 return STATUS_DISK_FULL;
388 }
389 Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
390 ROUND_DOWN(NewSize - 1, ClusterSize),
391 &NCluster, TRUE);
392 if (NCluster == 0xffffffff)
393 {
394 /* disk is full */
395 NCluster = Cluster;
396 while (Cluster != 0xffffffff)
397 {
398 NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
399 WriteCluster (DeviceExt, Cluster, 0);
400 Cluster = NCluster;
401 }
402 return STATUS_DISK_FULL;
403 }
404 Fcb->entry.FirstCluster = (Cluster & 0x0000FFFF);
405 Fcb->entry.FirstClusterHigh = (Cluster & 0xFFFF0000) >> 16;
406 }
407 else
408 {
409 Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
410 Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize,
411 &Cluster, FALSE);
412 /* Cluster points now to the last cluster within the chain */
413 Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
414 ROUND_DOWN(NewSize - 1, ClusterSize),
415 &NCluster, TRUE);
416 if (NCluster == 0xffffffff)
417 {
418 /* disk is full */
419 NCluster = Cluster;
420 NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
421 WriteCluster(DeviceExt, Cluster, 0xffffffff);
422 Cluster = NCluster;
423 while (Cluster != 0xffffffff)
424 {
425 NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
426 WriteCluster (DeviceExt, Cluster, 0);
427 Cluster = NCluster;
428 }
429 return STATUS_DISK_FULL;
430 }
431 }
432 }
433 else if (NewSize <= Fcb->RFCB.AllocationSize.u.LowPart - ClusterSize)
434 {
435 if (NewSize > 0)
436 {
437 Status = OffsetToCluster(DeviceExt, Fcb, Cluster,
438 ROUND_DOWN(NewSize - 1, ClusterSize),
439 &Cluster, FALSE);
440 }
441 NCluster = Cluster;
442 Status = NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
443 WriteCluster(DeviceExt, Cluster, 0xffffffff);
444 Cluster = NCluster;
445 while (Cluster != 0xffffffff)
446 {
447 NextCluster (DeviceExt, Fcb, Cluster, &NCluster, FALSE);
448 WriteCluster (DeviceExt, Cluster, 0);
449 Cluster = NCluster;
450 }
451 }
452 Fcb->entry.FileSize = NewSize;
453 if (NewSize > 0)
454 {
455 Fcb->RFCB.AllocationSize.QuadPart = ROUND_UP(NewSize - 1, ClusterSize);
456 }
457 else
458 {
459 Fcb->RFCB.AllocationSize.QuadPart = 0LL;
460 Fcb->entry.FirstCluster = 0;
461 Fcb->entry.FirstClusterHigh = 0;
462 }
463 Fcb->RFCB.FileSize.QuadPart = NewSize;
464 Fcb->RFCB.ValidDataLength.QuadPart = NewSize;
465
466 if (FileObject->SectionObjectPointer->SharedCacheMap != NULL)
467 {
468 CcSetFileSizes(FileObject, (PCC_FILE_SIZES)&Fcb->RFCB.AllocationSize);
469 }
470 /* Update the on-disk directory entry */
471 VfatUpdateEntry(DeviceExt, FileObject);
472 return STATUS_SUCCESS;
473 }
474
475 NTSTATUS VfatQueryInformation(PVFAT_IRP_CONTEXT IrpContext)
476 /*
477 * FUNCTION: Retrieve the specified file information
478 */
479 {
480 FILE_INFORMATION_CLASS FileInformationClass;
481 PVFATFCB FCB = NULL;
482
483 NTSTATUS RC = STATUS_SUCCESS;
484 PVOID SystemBuffer;
485 ULONG BufferLength;
486
487 /* PRECONDITION */
488 assert (IrpContext);
489
490 /* INITIALIZATION */
491 FileInformationClass = IrpContext->Stack->Parameters.QueryFile.FileInformationClass;
492 FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
493
494 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
495 BufferLength = IrpContext->Stack->Parameters.QueryFile.Length;
496
497 if (!(FCB->Flags & FCB_IS_PAGE_FILE))
498 {
499 if (!ExAcquireResourceSharedLite(&FCB->MainResource, IrpContext->Flags & IRPCONTEXT_CANWAIT))
500 {
501 return VfatQueueRequest (IrpContext);
502 }
503 }
504
505
506 switch (FileInformationClass)
507 {
508 case FileStandardInformation:
509 RC = VfatGetStandardInformation(FCB,
510 IrpContext->DeviceObject,
511 SystemBuffer,
512 &BufferLength);
513 break;
514 case FilePositionInformation:
515 RC = VfatGetPositionInformation(IrpContext->FileObject,
516 FCB,
517 IrpContext->DeviceObject,
518 SystemBuffer,
519 &BufferLength);
520 break;
521 case FileBasicInformation:
522 RC = VfatGetBasicInformation(IrpContext->FileObject,
523 FCB,
524 IrpContext->DeviceObject,
525 SystemBuffer,
526 &BufferLength);
527 break;
528 case FileNameInformation:
529 RC = VfatGetNameInformation(IrpContext->FileObject,
530 FCB,
531 IrpContext->DeviceObject,
532 SystemBuffer,
533 &BufferLength);
534 break;
535 case FileInternalInformation:
536 RC = VfatGetInternalInformation(FCB,
537 SystemBuffer,
538 &BufferLength);
539 break;
540 case FileNetworkOpenInformation:
541 RC = VfatGetNetworkOpenInformation(FCB,
542 SystemBuffer,
543 &BufferLength);
544 break;
545 case FileAllInformation:
546 RC = VfatGetAllInformation(IrpContext->FileObject,
547 FCB,
548 SystemBuffer,
549 &BufferLength);
550 break;
551
552 case FileAlternateNameInformation:
553 RC = STATUS_NOT_IMPLEMENTED;
554 break;
555 default:
556 RC = STATUS_NOT_SUPPORTED;
557 }
558
559 if (!(FCB->Flags & FCB_IS_PAGE_FILE))
560 {
561 ExReleaseResourceLite(&FCB->MainResource);
562 }
563 IrpContext->Irp->IoStatus.Status = RC;
564 if (NT_SUCCESS(RC))
565 IrpContext->Irp->IoStatus.Information =
566 IrpContext->Stack->Parameters.QueryFile.Length - BufferLength;
567 else
568 IrpContext->Irp->IoStatus.Information = 0;
569 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
570 VfatFreeIrpContext(IrpContext);
571
572 return RC;
573 }
574
575 NTSTATUS VfatSetInformation(PVFAT_IRP_CONTEXT IrpContext)
576 /*
577 * FUNCTION: Retrieve the specified file information
578 */
579 {
580 FILE_INFORMATION_CLASS FileInformationClass;
581 PVFATFCB FCB = NULL;
582 NTSTATUS RC = STATUS_SUCCESS;
583 PVOID SystemBuffer;
584 BOOL CanWait = IrpContext->Flags & IRPCONTEXT_CANWAIT;
585
586 /* PRECONDITION */
587 assert(IrpContext);
588
589 DPRINT("VfatSetInformation(IrpContext %x)\n", IrpContext);
590
591 /* INITIALIZATION */
592 FileInformationClass =
593 IrpContext->Stack->Parameters.SetFile.FileInformationClass;
594 FCB = ((PVFATCCB) IrpContext->FileObject->FsContext2)->pFcb;
595 SystemBuffer = IrpContext->Irp->AssociatedIrp.SystemBuffer;
596
597 DPRINT("FileInformationClass %d\n", FileInformationClass);
598 DPRINT("SystemBuffer %x\n", SystemBuffer);
599
600 if (FCB->Flags & FCB_IS_PAGE_FILE)
601 {
602 if (!ExAcquireResourceExclusiveLite(&FCB->PagingIoResource, CanWait))
603 {
604 return(VfatQueueRequest (IrpContext));
605 }
606 }
607 else
608 {
609 if (!ExAcquireResourceExclusiveLite(&FCB->MainResource, CanWait))
610 {
611 return(VfatQueueRequest (IrpContext));
612 }
613 }
614
615 switch (FileInformationClass)
616 {
617 case FilePositionInformation:
618 RC = VfatSetPositionInformation(IrpContext->FileObject,
619 FCB,
620 IrpContext->DeviceObject,
621 SystemBuffer);
622 break;
623 case FileDispositionInformation:
624 RC = VfatSetDispositionInformation(IrpContext->FileObject,
625 FCB,
626 IrpContext->DeviceObject,
627 SystemBuffer);
628 break;
629 case FileAllocationInformation:
630 case FileEndOfFileInformation:
631 RC = VfatSetAllocationSizeInformation(IrpContext->FileObject,
632 FCB,
633 IrpContext->DeviceExt,
634 (PLARGE_INTEGER)SystemBuffer);
635 break;
636 case FileBasicInformation:
637 case FileRenameInformation:
638 RC = STATUS_NOT_IMPLEMENTED;
639 break;
640 default:
641 RC = STATUS_NOT_SUPPORTED;
642 }
643
644 if (FCB->Flags & FCB_IS_PAGE_FILE)
645 {
646 ExReleaseResourceLite(&FCB->PagingIoResource);
647 }
648 else
649 {
650 ExReleaseResourceLite(&FCB->MainResource);
651 }
652
653 IrpContext->Irp->IoStatus.Status = RC;
654 IrpContext->Irp->IoStatus.Information = 0;
655 IoCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
656 VfatFreeIrpContext(IrpContext);
657
658 return RC;
659 }
660
661 /* EOF */