ReactOS 0.4.17-dev-1190-g4c812f4
finfo.c
Go to the documentation of this file.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 * COPYRIGHT: See COPYING in the top level directory
20 * PROJECT: ReactOS kernel
21 * FILE: drivers/filesystem/ntfs/dirctl.c
22 * PURPOSE: NTFS filesystem driver
23 * PROGRAMMERS: Eric Kohl
24 * Hervé Poussineau (hpoussin@reactos.org)
25 * Pierre Schweitzer (pierre@reactos.org)
26 */
27
28/* INCLUDES *****************************************************************/
29
30#include "ntfs.h"
31
32#define NDEBUG
33#include <debug.h>
34
35/* Longest name a $FILE_NAME can hold, in characters */
36#define NTFS_MAX_NAME_LENGTH 255
37
38/* FUNCTIONS ****************************************************************/
39
40/*
41 * FUNCTION: Retrieve the standard file information
42 */
43static
47 PFILE_STANDARD_INFORMATION StandardInfo,
49{
51
52 DPRINT("NtfsGetStandardInformation(%p, %p, %p, %p)\n", Fcb, DeviceObject, StandardInfo, BufferLength);
53
56
57 /* PRECONDITION */
58 ASSERT(StandardInfo != NULL);
59 ASSERT(Fcb != NULL);
60
61 RtlZeroMemory(StandardInfo,
63
64 StandardInfo->AllocationSize = Fcb->RFCB.AllocationSize;
65 StandardInfo->EndOfFile = Fcb->RFCB.FileSize;
66 StandardInfo->NumberOfLinks = Fcb->LinkCount;
68 StandardInfo->Directory = NtfsFCBIsDirectory(Fcb);
69
71
72 return STATUS_SUCCESS;
73}
74
75
76static
79 PFILE_POSITION_INFORMATION PositionInfo,
81{
82 DPRINT1("NtfsGetPositionInformation(%p, %p, %p)\n", FileObject, PositionInfo, BufferLength);
83
86
87 PositionInfo->CurrentByteOffset.QuadPart = FileObject->CurrentByteOffset.QuadPart;
88
89 DPRINT("Getting position %I64x\n",
90 PositionInfo->CurrentByteOffset.QuadPart);
91
93
94 return STATUS_SUCCESS;
95}
96
97
98static
103 PFILE_BASIC_INFORMATION BasicInfo,
105{
107
108 DPRINT("NtfsGetBasicInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, BasicInfo, BufferLength);
109
112
113 RtlZeroMemory(BasicInfo, sizeof(FILE_BASIC_INFORMATION));
114
115 BasicInfo->CreationTime.QuadPart = FileName->CreationTime;
116 BasicInfo->LastAccessTime.QuadPart = FileName->LastAccessTime;
117 BasicInfo->LastWriteTime.QuadPart = FileName->LastWriteTime;
118 BasicInfo->ChangeTime.QuadPart = FileName->ChangeTime;
119
120 NtfsFileFlagsToAttributes(FileName->FileAttributes, &BasicInfo->FileAttributes);
121
123
124 return STATUS_SUCCESS;
125}
126
127static
130 PFILE_ATTRIBUTE_TAG_INFORMATION AttributeTagInfo,
132{
134
135 DPRINT("NtfsGetAttributeTagInformation(%p, %p, %p)\n", Fcb, AttributeTagInfo, BufferLength);
136
139
140 RtlZeroMemory(AttributeTagInfo, sizeof(FILE_ATTRIBUTE_TAG_INFORMATION));
141
142 NtfsFileFlagsToAttributes(FileName->FileAttributes, &AttributeTagInfo->FileAttributes);
143
144 /* FIXME: Read the tag from $REPARSE_POINT for a reparse point */
145 AttributeTagInfo->ReparseTag = 0;
146
148
149 return STATUS_SUCCESS;
150}
151
152
153static
158{
160
161 DPRINT("NtfsGetEaInformation(%p, %p, %p)\n", Fcb, EaInfo, BufferLength);
162
163 if (*BufferLength < sizeof(FILE_EA_INFORMATION))
165
166 /* We do not support extended attributes yet, so there are none */
167 EaInfo->EaSize = 0;
168
170
171 return STATUS_SUCCESS;
172}
173
174
175/*
176 * FUNCTION: Retrieve the file name information
177 */
178static
183 PFILE_NAME_INFORMATION NameInfo,
185{
187
190
191 DPRINT("NtfsGetNameInformation(%p, %p, %p, %p, %p)\n", FileObject, Fcb, DeviceObject, NameInfo, BufferLength);
192
193 ASSERT(NameInfo != NULL);
194 ASSERT(Fcb != NULL);
195
196 /* If buffer can't hold at least the file name length, bail out */
199
200 /* Save file name length, and as much file len, as buffer length allows */
201 NameInfo->FileNameLength = wcslen(Fcb->PathName) * sizeof(WCHAR);
202
203 /* Calculate amount of bytes to copy not to overflow the buffer */
204 BytesToCopy = min(NameInfo->FileNameLength,
206
207 /* Fill in the bytes */
209
210 /* Check if we could write more but are not able to */
211 if (*BufferLength < NameInfo->FileNameLength + (ULONG)FIELD_OFFSET(FILE_NAME_INFORMATION, FileName[0]))
212 {
213 /* Return number of bytes written */
216 }
217
218 /* We filled up as many bytes, as needed */
220
221 return STATUS_SUCCESS;
222}
223
224
225static
228 PFILE_INTERNAL_INFORMATION InternalInfo,
230{
231 DPRINT1("NtfsGetInternalInformation(%p, %p, %p)\n", Fcb, InternalInfo, BufferLength);
232
233 ASSERT(InternalInfo);
234 ASSERT(Fcb);
235
238
239 InternalInfo->IndexNumber.QuadPart = Fcb->MFTIndex;
240
242
243 return STATUS_SUCCESS;
244}
245
246static
249 PDEVICE_EXTENSION DeviceExt,
252{
254
255 DPRINT("NtfsGetNetworkOpenInformation(%p, %p, %p, %p)\n", Fcb, DeviceExt, NetworkInfo, BufferLength);
256
259
260 NetworkInfo->CreationTime.QuadPart = FileName->CreationTime;
261 NetworkInfo->LastAccessTime.QuadPart = FileName->LastAccessTime;
262 NetworkInfo->LastWriteTime.QuadPart = FileName->LastWriteTime;
263 NetworkInfo->ChangeTime.QuadPart = FileName->ChangeTime;
264
265 NetworkInfo->EndOfFile = Fcb->RFCB.FileSize;
266 NetworkInfo->AllocationSize = Fcb->RFCB.AllocationSize;
267
268 NtfsFileFlagsToAttributes(FileName->FileAttributes, &NetworkInfo->FileAttributes);
269
271 return STATUS_SUCCESS;
272}
273
274static
277 PDEVICE_EXTENSION DeviceExt,
278 PFILE_STREAM_INFORMATION StreamInfo,
280{
281 ULONG CurrentSize;
283 PNTFS_ATTR_RECORD Attribute;
284 NTSTATUS Status, BrowseStatus;
285 PFILE_RECORD_HEADER FileRecord;
286 PFILE_STREAM_INFORMATION CurrentInfo = StreamInfo, Previous = NULL;
287
290
291 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
292 if (FileRecord == NULL)
293 {
294 DPRINT1("Not enough memory!\n");
296 }
297
298 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
299 if (!NT_SUCCESS(Status))
300 {
301 DPRINT1("Can't find record!\n");
302 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
303 return Status;
304 }
305
306 BrowseStatus = FindFirstAttribute(&Context, DeviceExt, FileRecord, FALSE, &Attribute);
307 while (NT_SUCCESS(BrowseStatus))
308 {
309 if (Attribute->Type == AttributeData)
310 {
311 CurrentSize = FIELD_OFFSET(FILE_STREAM_INFORMATION, StreamName) + Attribute->NameLength * sizeof(WCHAR) + wcslen(L"::$DATA") * sizeof(WCHAR);
312
313 if (CurrentSize > *BufferLength)
314 {
316 break;
317 }
318
319 CurrentInfo->NextEntryOffset = 0;
320 CurrentInfo->StreamNameLength = (Attribute->NameLength + wcslen(L"::$DATA")) * sizeof(WCHAR);
321 CurrentInfo->StreamSize.QuadPart = AttributeDataLength(Attribute);
323 CurrentInfo->StreamName[0] = L':';
324 RtlMoveMemory(&CurrentInfo->StreamName[1], (PWCHAR)((ULONG_PTR)Attribute + Attribute->NameOffset), CurrentInfo->StreamNameLength);
325 RtlMoveMemory(&CurrentInfo->StreamName[Attribute->NameLength + 1], L":$DATA", sizeof(L":$DATA") - sizeof(UNICODE_NULL));
326
327 if (Previous != NULL)
328 {
329 Previous->NextEntryOffset = (ULONG_PTR)CurrentInfo - (ULONG_PTR)Previous;
330 }
331 Previous = CurrentInfo;
332 CurrentInfo = (PFILE_STREAM_INFORMATION)((ULONG_PTR)CurrentInfo + CurrentSize);
333 *BufferLength -= CurrentSize;
334 }
335
336 BrowseStatus = FindNextAttribute(&Context, &Attribute);
337 }
338
340 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
341 return Status;
342}
343
344// Convert enum value to friendly name
345const PCSTR
347{
348 const PCSTR fileInfoClassNames[] = { "???????",
349 "FileDirectoryInformation",
350 "FileFullDirectoryInformation",
351 "FileBothDirectoryInformation",
352 "FileBasicInformation",
353 "FileStandardInformation",
354 "FileInternalInformation",
355 "FileEaInformation",
356 "FileAccessInformation",
357 "FileNameInformation",
358 "FileRenameInformation",
359 "FileLinkInformation",
360 "FileNamesInformation",
361 "FileDispositionInformation",
362 "FilePositionInformation",
363 "FileFullEaInformation",
364 "FileModeInformation",
365 "FileAlignmentInformation",
366 "FileAllInformation",
367 "FileAllocationInformation",
368 "FileEndOfFileInformation",
369 "FileAlternateNameInformation",
370 "FileStreamInformation",
371 "FilePipeInformation",
372 "FilePipeLocalInformation",
373 "FilePipeRemoteInformation",
374 "FileMailslotQueryInformation",
375 "FileMailslotSetInformation",
376 "FileCompressionInformation",
377 "FileObjectIdInformation",
378 "FileCompletionInformation",
379 "FileMoveClusterInformation",
380 "FileQuotaInformation",
381 "FileReparsePointInformation",
382 "FileNetworkOpenInformation",
383 "FileAttributeTagInformation",
384 "FileTrackingInformation",
385 "FileIdBothDirectoryInformation",
386 "FileIdFullDirectoryInformation",
387 "FileValidDataLengthInformation",
388 "FileShortNameInformation",
389 "FileIoCompletionNotificationInformation",
390 "FileIoStatusBlockRangeInformation",
391 "FileIoPriorityHintInformation",
392 "FileSfioReserveInformation",
393 "FileSfioVolumeInformation",
394 "FileHardLinkInformation",
395 "FileProcessIdsUsingFileInformation",
396 "FileNormalizedNameInformation",
397 "FileNetworkPhysicalNameInformation",
398 "FileIdGlobalTxDirectoryInformation",
399 "FileIsRemoteDeviceInformation",
400 "FileAttributeCacheInformation",
401 "FileNumaNodeInformation",
402 "FileStandardLinkInformation",
403 "FileRemoteProtocolInformation",
404 "FileReplaceCompletionInformation",
405 "FileMaximumInformation",
406 "FileDirectoryInformation",
407 "FileFullDirectoryInformation",
408 "FileBothDirectoryInformation",
409 "FileBasicInformation",
410 "FileStandardInformation",
411 "FileInternalInformation",
412 "FileEaInformation",
413 "FileAccessInformation",
414 "FileNameInformation",
415 "FileRenameInformation",
416 "FileLinkInformation",
417 "FileNamesInformation",
418 "FileDispositionInformation",
419 "FilePositionInformation",
420 "FileFullEaInformation",
421 "FileModeInformation",
422 "FileAlignmentInformation",
423 "FileAllInformation",
424 "FileAllocationInformation",
425 "FileEndOfFileInformation",
426 "FileAlternateNameInformation",
427 "FileStreamInformation",
428 "FilePipeInformation",
429 "FilePipeLocalInformation",
430 "FilePipeRemoteInformation",
431 "FileMailslotQueryInformation",
432 "FileMailslotSetInformation",
433 "FileCompressionInformation",
434 "FileObjectIdInformation",
435 "FileCompletionInformation",
436 "FileMoveClusterInformation",
437 "FileQuotaInformation",
438 "FileReparsePointInformation",
439 "FileNetworkOpenInformation",
440 "FileAttributeTagInformation",
441 "FileTrackingInformation",
442 "FileIdBothDirectoryInformation",
443 "FileIdFullDirectoryInformation",
444 "FileValidDataLengthInformation",
445 "FileShortNameInformation",
446 "FileIoCompletionNotificationInformation",
447 "FileIoStatusBlockRangeInformation",
448 "FileIoPriorityHintInformation",
449 "FileSfioReserveInformation",
450 "FileSfioVolumeInformation",
451 "FileHardLinkInformation",
452 "FileProcessIdsUsingFileInformation",
453 "FileNormalizedNameInformation",
454 "FileNetworkPhysicalNameInformation",
455 "FileIdGlobalTxDirectoryInformation",
456 "FileIsRemoteDeviceInformation",
457 "FileAttributeCacheInformation",
458 "FileNumaNodeInformation",
459 "FileStandardLinkInformation",
460 "FileRemoteProtocolInformation",
461 "FileReplaceCompletionInformation",
462 "FileMaximumInformation" };
463 return fileInfoClassNames[infoClass];
464}
465
466/*
467 * FUNCTION: Retrieve the specified file information
468 */
471{
476 PVOID SystemBuffer;
478 PIRP Irp;
481
482 DPRINT("NtfsQueryInformation(%p)\n", IrpContext);
483
484 Irp = IrpContext->Irp;
485 Stack = IrpContext->Stack;
486 DeviceObject = IrpContext->DeviceObject;
487 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
488 FileObject = IrpContext->FileObject;
489 Fcb = FileObject->FsContext;
490
491 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
492 BufferLength = Stack->Parameters.QueryFile.Length;
493
496 {
497 return NtfsMarkIrpContextForQueue(IrpContext);
498 }
499
500 switch (FileInformationClass)
501 {
505 SystemBuffer,
506 &BufferLength);
507 break;
508
511 SystemBuffer,
512 &BufferLength);
513 break;
514
517 SystemBuffer,
518 &BufferLength);
519 break;
520
523 Fcb,
525 SystemBuffer,
526 &BufferLength);
527 break;
528
531 Fcb,
533 SystemBuffer,
534 &BufferLength);
535 break;
536
539 SystemBuffer,
540 &BufferLength);
541 break;
542
545 DeviceObject->DeviceExtension,
546 SystemBuffer,
547 &BufferLength);
548 break;
549
552 DeviceObject->DeviceExtension,
553 SystemBuffer,
554 &BufferLength);
555 break;
556
559 SystemBuffer,
560 &BufferLength);
561 break;
562
565 DPRINT1("Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
567 break;
568
569 default:
570 DPRINT1("Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
572 }
573
575
576 if (NT_SUCCESS(Status))
577 Irp->IoStatus.Information =
578 Stack->Parameters.QueryFile.Length - BufferLength;
579 else
580 Irp->IoStatus.Information = 0;
581
582 return Status;
583}
584
627 PDEVICE_EXTENSION DeviceExt,
628 ULONG IrpFlags,
629 BOOLEAN CaseSensitive,
631{
632 LARGE_INTEGER CurrentFileSize;
633 PFILE_RECORD_HEADER FileRecord;
634 PNTFS_ATTR_CONTEXT DataContext;
635 ULONG AttributeOffset;
637 PFILENAME_ATTRIBUTE FileNameAttribute;
638
639
640 // Allocate non-paged memory for the file record
641 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
642 if (FileRecord == NULL)
643 {
644 DPRINT1("Couldn't allocate memory for file record!");
646 }
647
648 // read the file record
649 DPRINT("Reading file record...\n");
650 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
651 if (!NT_SUCCESS(Status))
652 {
653 // We couldn't get the file's record. Free the memory and return the error
654 DPRINT1("Can't find record for %wS!\n", Fcb->ObjectName);
655 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
656 return Status;
657 }
658
659 DPRINT("Found record for %wS\n", Fcb->ObjectName);
660
661 CurrentFileSize.QuadPart = NtfsGetFileSize(DeviceExt, FileRecord, L"", 0, NULL);
662
663 // Are we trying to decrease the file size?
664 if (NewFileSize->QuadPart < CurrentFileSize.QuadPart)
665 {
666 // Is the file mapped?
667 if (!MmCanFileBeTruncated(FileObject->SectionObjectPointer,
669 {
670 DPRINT1("Couldn't decrease file size!\n");
671 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
673 }
674 }
675
676 // Find the attribute with the data stream for our file
677 DPRINT("Finding Data Attribute...\n");
678 Status = FindAttribute(DeviceExt,
679 FileRecord,
681 Fcb->Stream,
682 wcslen(Fcb->Stream),
683 &DataContext,
684 &AttributeOffset);
685
686 // Did we fail to find the attribute?
687 if (!NT_SUCCESS(Status))
688 {
689 DPRINT1("No '%S' data stream associated with file!\n", Fcb->Stream);
690 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
691 return Status;
692 }
693
694 // Get the size of the data attribute
695 CurrentFileSize.QuadPart = AttributeDataLength(DataContext->pRecord);
696
697 // Are we enlarging the attribute?
698 if (NewFileSize->QuadPart > CurrentFileSize.QuadPart)
699 {
700 // is increasing the stream size not allowed?
701 if ((Fcb->Flags & FCB_IS_VOLUME) ||
702 (IrpFlags & IRP_PAGING_IO))
703 {
704 // TODO - just fail for now
705 ReleaseAttributeContext(DataContext);
706 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
708 }
709 }
710
711 // set the attribute data length
712 Status = SetAttributeDataLength(FileObject, Fcb, DataContext, AttributeOffset, FileRecord, NewFileSize);
713 if (!NT_SUCCESS(Status))
714 {
715 ReleaseAttributeContext(DataContext);
716 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
717 return Status;
718 }
719
720 // now we need to update this file's size in every directory index entry that references it
721 // TODO: expand to work with every filename / hardlink stored in the file record.
722 FileNameAttribute = GetBestFileNameFromRecord(Fcb->Vcb, FileRecord);
723 if (FileNameAttribute == NULL)
724 {
725 DPRINT1("Unable to find FileName attribute associated with file!\n");
726 ReleaseAttributeContext(DataContext);
727 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
729 }
730
732 FileRecord,
733 Fcb->MFTIndex,
735 CaseSensitive);
736
737 ReleaseAttributeContext(DataContext);
738 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
739
740 return Status;
741}
742
743/* Sets the allocation of a file. Below the data, the file is cut down to it as on Windows. */
744static
746NTAPI
750 _In_ PDEVICE_EXTENSION DeviceExt,
751 _In_ ULONG IrpFlags,
752 _In_ BOOLEAN CaseSensitive,
754{
756
757 if ((Fcb->Flags & FCB_IS_VOLUME) || NtfsFCBIsDirectory(Fcb) || AllocationSize->QuadPart < 0)
759
760 if (AllocationSize->QuadPart < Fcb->RFCB.FileSize.QuadPart)
761 {
762 Status = NtfsSetEndOfFile(Fcb, FileObject, DeviceExt, IrpFlags, CaseSensitive, AllocationSize);
763 if (!NT_SUCCESS(Status))
764 return Status;
765 }
766
769 CaseSensitive,
770 ROUND_UP(AllocationSize->QuadPart, DeviceExt->NtfsInfo.BytesPerCluster));
771}
772
828static
832 BOOLEAN CaseSensitive,
833 PFILE_BASIC_INFORMATION BasicInfo)
834{
835 PFILE_RECORD_HEADER FileRecord;
836 PSTANDARD_INFORMATION StdInfo;
838
839 DPRINT("NtfsSetBasicInformation(%p, %p, %p)\n", DeviceExt, Fcb, BasicInfo);
840
841 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
842 if (FileRecord == NULL)
843 {
844 DPRINT1("Not enough memory!\n");
846 }
847
848 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
849 if (!NT_SUCCESS(Status))
850 {
851 DPRINT1("Can't find record for %wS!\n", Fcb->ObjectName);
852 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
853 return Status;
854 }
855
856 StdInfo = GetStandardInformationFromRecord(DeviceExt, FileRecord);
857 if (StdInfo == NULL)
858 {
859 DPRINT1("No $STANDARD_INFORMATION for %wS!\n", Fcb->ObjectName);
860 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
862 }
863
864 if (BasicInfo->CreationTime.QuadPart > 0)
865 StdInfo->CreationTime = BasicInfo->CreationTime.QuadPart;
866
867 if (BasicInfo->LastAccessTime.QuadPart > 0)
868 StdInfo->LastAccessTime = BasicInfo->LastAccessTime.QuadPart;
869
870 if (BasicInfo->LastWriteTime.QuadPart > 0)
871 StdInfo->LastWriteTime = BasicInfo->LastWriteTime.QuadPart;
872
873 if (BasicInfo->ChangeTime.QuadPart > 0)
874 StdInfo->ChangeTime = BasicInfo->ChangeTime.QuadPart;
875
876 if (BasicInfo->FileAttributes != 0)
877 {
878 ULONG Attributes = BasicInfo->FileAttributes;
879
880 /* Whether this is a directory isn't the caller's to say */
882
883 /* NORMAL only means anything on its own */
886
887 StdInfo->FileAttribute = Attributes;
888 }
889
890 /* Everything else NTFS keeps a second and third copy of goes out through the one funnel,
891 * which also writes the file record back. */
893 FileRecord,
894 Fcb->MFTIndex,
897 CaseSensitive);
898 if (!NT_SUCCESS(Status))
899 {
900 DPRINT1("Failed to refresh the duplicated information for %wS (Status %lx)\n",
902 }
903
904 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
905
906 return Status;
907}
908
939static
944 BOOLEAN CaseSensitive,
945 PFILE_DISPOSITION_INFORMATION DispositionInfo)
946{
947 DPRINT("NtfsSetDispositionInformation(%p, %p, %p, %s, %p)\n",
948 DeviceExt, Fcb, FileObject, CaseSensitive ? "TRUE" : "FALSE", DispositionInfo);
949
950 if (!DispositionInfo->DeleteFile)
951 {
952 Fcb->Flags &= ~FCB_DELETE_PENDING;
953 FileObject->DeletePending = FALSE;
954 return STATUS_SUCCESS;
955 }
956
958 {
959 DPRINT1("NTFS write-support is EXPERIMENTAL and is disabled by default!\n");
961 }
962
963 /* The volume root has no parent index to be removed from */
964 if (NtfsFCBIsRoot(Fcb))
966
969
971 {
974
975 /* A lookup treats an unreadable sub-node as a miss, which here would
976 * delete a directory that still has children. This check fails instead. */
978 ExAcquireResourceSharedLite(&DeviceExt->IndexResource, TRUE);
980 ExReleaseResourceLite(&DeviceExt->IndexResource);
982
983 if (!NT_SUCCESS(Status))
984 return Status;
985
986 if (!Empty)
988 }
989
990 /* Deleting a mapped file would free its record out from under the section */
991 if (!MmFlushImageSection(&Fcb->SectionObjectPointers, MmFlushForDelete))
993
995 FileObject->DeletePending = TRUE;
996
997 return STATUS_SUCCESS;
998}
999
1005static
1006BOOLEAN
1009{
1010 USHORT i;
1011
1012 if (Name->Length == 0 ||
1013 Name->Length > NTFS_MAX_NAME_LENGTH * sizeof(WCHAR) ||
1014 (Name->Length % sizeof(WCHAR)) != 0)
1015 {
1016 return FALSE;
1017 }
1018
1019 if ((Name->Length == sizeof(WCHAR) && Name->Buffer[0] == L'.') ||
1020 (Name->Length == 2 * sizeof(WCHAR) && Name->Buffer[0] == L'.' && Name->Buffer[1] == L'.'))
1021 {
1022 return FALSE;
1023 }
1024
1025 for (i = 0; i < Name->Length / sizeof(WCHAR); i++)
1026 {
1027 WCHAR Char = Name->Buffer[i];
1028
1029 if (Char < 0x20 || wcschr(L"\\/:*?\"<>|", Char) != NULL)
1030 return FALSE;
1031 }
1032
1033 return TRUE;
1034}
1035
1046static
1049 _In_ PDEVICE_EXTENSION DeviceExt,
1050 _Inout_ PFILE_RECORD_HEADER FileRecord,
1053{
1054 ULONG RecordSize = DeviceExt->NtfsInfo.BytesPerFileRecord;
1055 ULONG HeaderLength = FIELD_OFFSET(NTFS_ATTR_RECORD, Resident.Reserved) + sizeof(UCHAR);
1057 PFILE_RECORD_HEADER NewRecord;
1059 PNTFS_ATTR_RECORD Dest;
1060 ULONG SourceOffset = FileRecord->AttributeOffset;
1061 ULONG DestOffset = FileRecord->AttributeOffset;
1062 BOOLEAN Inserted = FALSE;
1064
1065 NewRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
1066 if (NewRecord == NULL)
1068
1069 RtlZeroMemory(NewRecord, RecordSize);
1070 RtlCopyMemory(NewRecord, FileRecord, FileRecord->AttributeOffset);
1071
1072 for (;;)
1073 {
1074 BOOLEAN AtEnd;
1075
1077 AtEnd = (SourceOffset + sizeof(ULONG) > RecordSize || Source->Type == AttributeEnd);
1078
1079 /* The new name goes ahead of the first attribute that sorts after it */
1080 if (!Inserted && (AtEnd || Source->Type > AttributeFileName))
1081 {
1082 if (DestOffset + NewLength + 2 * sizeof(ULONG) > RecordSize)
1083 {
1085 break;
1086 }
1087
1088 Dest = (PNTFS_ATTR_RECORD)((ULONG_PTR)NewRecord + DestOffset);
1089 Dest->Type = AttributeFileName;
1090 Dest->Length = NewLength;
1091 Dest->Instance = NewRecord->NextAttributeNumber++;
1092 Dest->Resident.ValueLength = ValueLength;
1093 Dest->Resident.ValueOffset = (USHORT)HeaderLength;
1094 Dest->Resident.Flags = RA_INDEXED;
1095 RtlCopyMemory((PUCHAR)Dest + HeaderLength, Value, ValueLength);
1096
1097 DestOffset += NewLength;
1098 Inserted = TRUE;
1099 }
1100
1101 if (AtEnd)
1102 break;
1103
1104 if (Source->Length == 0 || SourceOffset + Source->Length > RecordSize)
1105 {
1107 break;
1108 }
1109
1110 if (Source->Type != AttributeFileName)
1111 {
1112 if (DestOffset + Source->Length + 2 * sizeof(ULONG) > RecordSize)
1113 {
1115 break;
1116 }
1117
1118 RtlCopyMemory((PUCHAR)NewRecord + DestOffset, Source, Source->Length);
1119 DestOffset += Source->Length;
1120 }
1121
1122 SourceOffset += Source->Length;
1123 }
1124
1125 if (NT_SUCCESS(Status))
1126 {
1127 SetFileRecordEnd(NewRecord, (PNTFS_ATTR_RECORD)((ULONG_PTR)NewRecord + DestOffset), FILE_RECORD_END);
1128 RtlCopyMemory(FileRecord, NewRecord, RecordSize);
1129 }
1130
1131 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, NewRecord);
1132 return Status;
1133}
1134
1141static
1142VOID
1144 _In_ PDEVICE_EXTENSION DeviceExt,
1146 _In_ PCWSTR NewPath)
1147{
1148 WCHAR OldPath[MAX_PATH];
1149 WCHAR Rebuilt[MAX_PATH];
1150 SIZE_T OldLength;
1152 KIRQL OldIrql;
1153
1154 wcscpy(OldPath, Fcb->PathName);
1155 OldLength = wcslen(OldPath);
1156
1157 KeAcquireSpinLock(&DeviceExt->FcbListLock, &OldIrql);
1158
1159 for (Entry = DeviceExt->FcbListHead.Flink; Entry != &DeviceExt->FcbListHead; Entry = Entry->Flink)
1160 {
1162
1163 if (_wcsnicmp(Other->PathName, OldPath, OldLength) != 0 ||
1164 (Other->PathName[OldLength] != UNICODE_NULL && Other->PathName[OldLength] != L'\\'))
1165 {
1166 continue;
1167 }
1168
1169 /* NtfsCheckRenamePaths() already made sure this fits */
1170 wcscpy(Rebuilt, NewPath);
1171 wcscat(Rebuilt, Other->PathName + OldLength);
1172 wcscpy(Other->PathName, Rebuilt);
1173 Other->ObjectName = wcsrchr(Other->PathName, L'\\');
1174 }
1175
1176 KeReleaseSpinLock(&DeviceExt->FcbListLock, OldIrql);
1177}
1178
1184static
1187 _In_ PDEVICE_EXTENSION DeviceExt,
1189 _In_ PCWSTR NewPath)
1190{
1191 SIZE_T OldLength = wcslen(Fcb->PathName);
1192 SIZE_T NewLength = wcslen(NewPath);
1195 KIRQL OldIrql;
1196
1197 KeAcquireSpinLock(&DeviceExt->FcbListLock, &OldIrql);
1198
1199 for (Entry = DeviceExt->FcbListHead.Flink; Entry != &DeviceExt->FcbListHead; Entry = Entry->Flink)
1200 {
1202
1203 if (_wcsnicmp(Other->PathName, Fcb->PathName, OldLength) == 0 &&
1204 (Other->PathName[OldLength] == UNICODE_NULL || Other->PathName[OldLength] == L'\\') &&
1205 wcslen(Other->PathName) - OldLength + NewLength >= MAX_PATH)
1206 {
1208 break;
1209 }
1210 }
1211
1212 KeReleaseSpinLock(&DeviceExt->FcbListLock, OldIrql);
1213 return Status;
1214}
1215
1222static
1223VOID
1225 _In_ PDEVICE_EXTENSION DeviceExt,
1226 _In_ PFILE_RECORD_HEADER FileRecord,
1227 _In_ ULONGLONG FileReference,
1229 _In_ BOOLEAN CaseSensitive)
1230{
1231 PNTFS_ATTR_RECORD Attribute;
1232 ULONG Offset = FileRecord->AttributeOffset;
1233
1234 while (Count != 0 && Offset + sizeof(ULONG) <= DeviceExt->NtfsInfo.BytesPerFileRecord)
1235 {
1236 Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + Offset);
1237 if (Attribute->Type == AttributeEnd || Attribute->Length == 0)
1238 break;
1239
1240 if (Attribute->Type == AttributeFileName && !Attribute->IsNonResident)
1241 {
1242 PFILENAME_ATTRIBUTE Name = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1243
1245 Name->DirectoryFileReferenceNumber & NTFS_MFT_MASK,
1246 FileReference,
1247 Name,
1248 CaseSensitive)))
1249 {
1250 DPRINT1("Couldn't restore '%.*S' in directory %I64u\n",
1251 Name->NameLength, Name->Name, Name->DirectoryFileReferenceNumber & NTFS_MFT_MASK);
1252 }
1253
1254 Count--;
1255 }
1256
1257 Offset += Attribute->Length;
1258 }
1259}
1260
1270static
1274 _In_opt_ PFILE_OBJECT TargetFileObject,
1275 _In_ PFILE_RENAME_INFORMATION RenameInfo,
1278 _Out_writes_z_(MAX_PATH) PWSTR NewPath,
1279 _Out_ PULONGLONG TargetDirMft)
1280{
1281 PCWSTR TargetDirPath;
1282 SIZE_T TargetDirLength;
1283 SIZE_T NameLength;
1284
1285 if (TargetFileObject != NULL)
1286 {
1287 PNTFS_FCB TargetFcb = TargetFileObject->FsContext;
1288
1289 *NewName = TargetFileObject->FileName;
1290 *TargetDirMft = TargetFcb->MFTIndex;
1291 TargetDirPath = TargetFcb->PathName;
1292 TargetDirLength = NtfsFCBIsRoot(TargetFcb) ? 0 : wcslen(TargetFcb->PathName);
1293 }
1294 else
1295 {
1297 RenameInfo->FileNameLength > BufferLength - FIELD_OFFSET(FILE_RENAME_INFORMATION, FileName) ||
1298 RenameInfo->FileNameLength > MAXUSHORT)
1299 {
1301 }
1302
1303 NewName->Buffer = RenameInfo->FileName;
1304 NewName->Length = (USHORT)RenameInfo->FileNameLength;
1306
1307 *TargetDirMft = 0;
1308 TargetDirPath = Fcb->PathName;
1309 TargetDirLength = Fcb->ObjectName - Fcb->PathName;
1310 }
1311
1314
1315 NameLength = NewName->Length / sizeof(WCHAR);
1316 if (TargetDirLength + 1 + NameLength >= MAX_PATH)
1317 return STATUS_NAME_TOO_LONG;
1318
1319 /* A directory can't become its own descendant */
1321 {
1322 SIZE_T OldLength = wcslen(Fcb->PathName);
1323
1324 if (TargetDirLength >= OldLength &&
1325 _wcsnicmp(TargetDirPath, Fcb->PathName, OldLength) == 0 &&
1326 (TargetDirLength == OldLength || TargetDirPath[OldLength] == L'\\'))
1327 {
1329 }
1330 }
1331
1332 RtlCopyMemory(NewPath, TargetDirPath, TargetDirLength * sizeof(WCHAR));
1333 NewPath[TargetDirLength] = L'\\';
1334 RtlCopyMemory(NewPath + TargetDirLength + 1, NewName->Buffer, NewName->Length);
1335 NewPath[TargetDirLength + 1 + NameLength] = UNICODE_NULL;
1336
1337 return STATUS_SUCCESS;
1338}
1339
1347static
1350 _In_ PDEVICE_EXTENSION DeviceExt,
1351 _In_ PFILE_RECORD_HEADER FileRecord,
1353 _Out_ PULONGLONG ParentMft)
1354{
1355 PNTFS_ATTR_RECORD Attribute;
1356 ULONG Offset = FileRecord->AttributeOffset;
1357 BOOLEAN SeenName = FALSE;
1358
1359 *LongName = NULL;
1360 *ParentMft = 0;
1361
1362 while (Offset + sizeof(ULONG) <= DeviceExt->NtfsInfo.BytesPerFileRecord)
1363 {
1364 Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + Offset);
1365 if (Attribute->Type == AttributeEnd || Attribute->Length == 0)
1366 break;
1367
1368 if (Attribute->Type == AttributeFileName && !Attribute->IsNonResident)
1369 {
1370 PFILENAME_ATTRIBUTE Name = (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset);
1371 ULONGLONG Parent = Name->DirectoryFileReferenceNumber & NTFS_MFT_MASK;
1372
1373 if (SeenName && Parent != *ParentMft)
1375
1376 SeenName = TRUE;
1377 *ParentMft = Parent;
1378
1379 if (Name->NameType != NTFS_FILE_NAME_DOS)
1380 {
1381 if (*LongName != NULL)
1383
1384 *LongName = Name;
1385 }
1386 }
1387
1388 Offset += Attribute->Length;
1389 }
1390
1391 if (*LongName == NULL)
1393
1394 return STATUS_SUCCESS;
1395}
1396
1406static
1409 _In_ PDEVICE_EXTENSION DeviceExt,
1411 _In_ ULONGLONG TargetDirMft,
1413 _In_z_ PCWSTR NewPath,
1414 _In_ BOOLEAN ReplaceIfExists,
1415 _In_ BOOLEAN CaseSensitive,
1416 _Out_ PFILE_RECORD_HEADER Scratch)
1417{
1418 PNTFS_FCB ExistingFcb;
1419 ULONGLONG ExistingMft;
1420 ULONG FirstEntry = 0;
1422
1423 Status = NtfsFindMftRecord(DeviceExt, TargetDirMft, NewName, &FirstEntry, FALSE, CaseSensitive, &ExistingMft);
1425 return STATUS_SUCCESS;
1426
1427 if (!NT_SUCCESS(Status))
1428 return Status;
1429
1430 /* A case-only rename finds the file itself */
1431 if (ExistingMft == Fcb->MFTIndex)
1432 return STATUS_SUCCESS;
1433
1434 if (!ReplaceIfExists)
1436
1437 Status = ReadFileRecord(DeviceExt, ExistingMft, Scratch);
1438 if (!NT_SUCCESS(Status))
1439 return Status;
1440
1441 if (Scratch->Flags & FRH_DIRECTORY)
1442 return STATUS_ACCESS_DENIED;
1443
1444 /* A cached FCB means it's open or still mapped */
1445 ExistingFcb = NtfsGrabFCBFromTable(DeviceExt, NewPath);
1446 if (ExistingFcb != NULL)
1447 {
1448 NtfsReleaseFCB(DeviceExt, ExistingFcb);
1449 return STATUS_ACCESS_DENIED;
1450 }
1451
1452 return NtfsDeleteFileRecord(DeviceExt, ExistingMft, CaseSensitive);
1453}
1454
1464static
1467 _In_ PDEVICE_EXTENSION DeviceExt,
1468 _In_ PFILENAME_ATTRIBUTE OldName,
1469 _In_ ULONGLONG TargetDirMft,
1471 _In_ BOOLEAN CaseSensitive,
1472 _Out_ PFILE_RECORD_HEADER Scratch,
1473 _Outptr_ PFILENAME_ATTRIBUTE *NewValue,
1474 _Out_ PULONG NewValueLength)
1475{
1477 ULONG Length;
1479
1480 *NewValue = NULL;
1481 *NewValueLength = 0;
1482
1483 /* The parent reference needs the directory's sequence number */
1484 Status = ReadFileRecord(DeviceExt, TargetDirMft, Scratch);
1485 if (!NT_SUCCESS(Status))
1486 return Status;
1487
1490 if (Value == NULL)
1492
1494 Value->DirectoryFileReferenceNumber = TargetDirMft | ((ULONGLONG)Scratch->SequenceNumber << 48);
1495 Value->NameLength = (UCHAR)(NewName->Length / sizeof(WCHAR));
1497
1498 if (CaseSensitive)
1499 Value->NameType = NTFS_FILE_NAME_POSIX;
1502 else
1503 Value->NameType = NTFS_FILE_NAME_WIN32;
1504
1505 *NewValue = Value;
1506 *NewValueLength = Length;
1507 return STATUS_SUCCESS;
1508}
1509
1516static
1519 _In_ PDEVICE_EXTENSION DeviceExt,
1520 _In_ PFILE_RECORD_HEADER FileRecord,
1521 _In_ ULONGLONG ParentMft,
1522 _In_ BOOLEAN CaseSensitive,
1524{
1525 PNTFS_ATTR_RECORD Attribute;
1526 ULONG Offset = FileRecord->AttributeOffset;
1528
1529 *Removed = 0;
1530
1531 while (Offset + sizeof(ULONG) <= DeviceExt->NtfsInfo.BytesPerFileRecord)
1532 {
1533 Attribute = (PNTFS_ATTR_RECORD)((ULONG_PTR)FileRecord + Offset);
1534 if (Attribute->Type == AttributeEnd || Attribute->Length == 0)
1535 break;
1536
1537 if (Attribute->Type == AttributeFileName && !Attribute->IsNonResident)
1538 {
1540 ParentMft,
1541 (PFILENAME_ATTRIBUTE)((ULONG_PTR)Attribute + Attribute->Resident.ValueOffset),
1542 CaseSensitive);
1543 if (!NT_SUCCESS(Status))
1544 break;
1545
1546 (*Removed)++;
1547 }
1548
1549 Offset += Attribute->Length;
1550 }
1551
1552 return Status;
1553}
1554
1567static
1570 _In_ PDEVICE_EXTENSION DeviceExt,
1572 _Inout_ PFILE_RECORD_HEADER FileRecord,
1573 _In_ PFILE_RECORD_HEADER Original,
1574 _In_ ULONGLONG OldParentMft,
1575 _In_ ULONGLONG TargetDirMft,
1576 _In_ PFILENAME_ATTRIBUTE NewValue,
1577 _In_ ULONG NewValueLength,
1578 _In_ BOOLEAN CaseSensitive)
1579{
1580 ULONGLONG FileReference = Fcb->MFTIndex | ((ULONGLONG)FileRecord->SequenceNumber << 48);
1581 BOOLEAN RecordChanged = FALSE;
1582 ULONG Removed;
1584
1585 /* Take the old names out of the index first, so a case-only rename in the
1586 * same directory doesn't collide with itself */
1587 Status = NtfsUnlinkFileNames(DeviceExt, Original, OldParentMft, CaseSensitive, &Removed);
1588
1589 if (NT_SUCCESS(Status))
1590 Status = NtfsSetFileNameAttribute(DeviceExt, FileRecord, NewValue, NewValueLength);
1591
1592 if (NT_SUCCESS(Status))
1593 {
1594 RecordChanged = TRUE;
1595 Status = UpdateFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
1596 }
1597
1598 if (NT_SUCCESS(Status))
1599 Status = NtfsAddFilenameToDirectory(DeviceExt, TargetDirMft, FileReference, NewValue, CaseSensitive);
1600
1601 if (!NT_SUCCESS(Status))
1602 {
1603 /* Put the old record back, then the names that were taken out */
1604 if (RecordChanged)
1605 UpdateFileRecord(DeviceExt, Fcb->MFTIndex, Original);
1606
1607 NtfsRelinkFileNames(DeviceExt, Original, FileReference, Removed, CaseSensitive);
1608 }
1609
1610 return Status;
1611}
1612
1649static
1652 _In_ PDEVICE_EXTENSION DeviceExt,
1654 _In_opt_ PFILE_OBJECT TargetFileObject,
1655 _In_ BOOLEAN ReplaceIfExists,
1656 _In_ BOOLEAN CaseSensitive,
1657 _In_ PFILE_RENAME_INFORMATION RenameInfo,
1659{
1661 WCHAR NewPath[MAX_PATH];
1662 ULONGLONG TargetDirMft;
1663 ULONGLONG OldParentMft;
1664 PFILE_RECORD_HEADER FileRecord = NULL;
1665 PFILE_RECORD_HEADER Original = NULL;
1666 PFILENAME_ATTRIBUTE OldName;
1667 PFILENAME_ATTRIBUTE NewValue = NULL;
1668 ULONG NewValueLength;
1670
1672 return STATUS_ACCESS_DENIED;
1673
1676
1677 /* Renaming an alternate stream is a different operation */
1678 if (Fcb->Stream[0] != UNICODE_NULL)
1680
1681 Status = NtfsBuildRenamePath(Fcb, TargetFileObject, RenameInfo, BufferLength, &NewName, NewPath, &TargetDirMft);
1682 if (!NT_SUCCESS(Status))
1683 return Status;
1684
1685 Status = NtfsCheckRenamePaths(DeviceExt, Fcb, NewPath);
1686 if (!NT_SUCCESS(Status))
1687 return Status;
1688
1689 FileRecord = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
1690 Original = ExAllocateFromNPagedLookasideList(&DeviceExt->FileRecLookasideList);
1691 if (FileRecord == NULL || Original == NULL)
1692 {
1694 goto Quit;
1695 }
1696
1697 Status = ReadFileRecord(DeviceExt, Fcb->MFTIndex, FileRecord);
1698 if (!NT_SUCCESS(Status))
1699 goto Quit;
1700
1701 Status = NtfsFindLongFileName(DeviceExt, FileRecord, &OldName, &OldParentMft);
1702 if (!NT_SUCCESS(Status))
1703 goto Quit;
1704
1705 if (TargetFileObject == NULL)
1706 TargetDirMft = OldParentMft;
1707
1708 /* Original is scratch space until it holds the backup below */
1709 Status = NtfsClearRenameTarget(DeviceExt, Fcb, TargetDirMft, &NewName, NewPath, ReplaceIfExists, CaseSensitive, Original);
1710 if (!NT_SUCCESS(Status))
1711 goto Quit;
1712
1713 Status = NtfsBuildRenamedFileName(DeviceExt, OldName, TargetDirMft, &NewName, CaseSensitive, Original, &NewValue, &NewValueLength);
1714 if (!NT_SUCCESS(Status))
1715 goto Quit;
1716
1717 RtlCopyMemory(Original, FileRecord, DeviceExt->NtfsInfo.BytesPerFileRecord);
1718
1719 Status = NtfsCommitRename(DeviceExt,
1720 Fcb,
1721 FileRecord,
1722 Original,
1723 OldParentMft,
1724 TargetDirMft,
1725 NewValue,
1726 NewValueLength,
1727 CaseSensitive);
1728 if (!NT_SUCCESS(Status))
1729 goto Quit;
1730
1731 NtfsRenameFcbs(DeviceExt, Fcb, NewPath);
1732
1733 RtlCopyMemory(&Fcb->Entry, NewValue, FIELD_OFFSET(FILENAME_ATTRIBUTE, NameLength));
1734 Fcb->Entry.NameType = NewValue->NameType;
1735
1736Quit:
1737 if (NewValue != NULL)
1738 ExFreePoolWithTag(NewValue, TAG_NTFS);
1739 if (Original != NULL)
1740 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, Original);
1741 if (FileRecord != NULL)
1742 ExFreeToNPagedLookasideList(&DeviceExt->FileRecLookasideList, FileRecord);
1743
1744 return Status;
1745}
1746
1749{
1752 PDEVICE_EXTENSION DeviceExt;
1754 PNTFS_FCB Fcb;
1755 PVOID SystemBuffer;
1757 PIRP Irp;
1760
1761 DPRINT("NtfsSetInformation(%p)\n", IrpContext);
1762
1763 Irp = IrpContext->Irp;
1764 Stack = IrpContext->Stack;
1765 DeviceObject = IrpContext->DeviceObject;
1766 DeviceExt = DeviceObject->DeviceExtension;
1767 FileInformationClass = Stack->Parameters.QueryFile.FileInformationClass;
1768 FileObject = IrpContext->FileObject;
1769 Fcb = FileObject->FsContext;
1770
1771 SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
1772 BufferLength = Stack->Parameters.QueryFile.Length;
1773
1774 /* A rename changes two directories and the FCB table, which creates rely
1775 * on under DirResource. Take it first, the same order create does. */
1777 !ExAcquireResourceExclusiveLite(&DeviceExt->DirResource,
1778 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1779 {
1780 return NtfsMarkIrpContextForQueue(IrpContext);
1781 }
1782
1783 /* Every class below rewrites the file record from a copy it reads, so
1784 * two of them at once on the same file would lose one update */
1786 BooleanFlagOn(IrpContext->Flags, IRPCONTEXT_CANWAIT)))
1787 {
1789 ExReleaseResourceLite(&DeviceExt->DirResource);
1790
1791 return NtfsMarkIrpContextForQueue(IrpContext);
1792 }
1793
1794 switch (FileInformationClass)
1795 {
1796 PFILE_END_OF_FILE_INFORMATION EndOfFileInfo;
1797
1800 {
1802 break;
1803 }
1804
1805 /* A directory's record carries its index, which a create in it
1806 * could be changing; IndexResource keeps the two apart */
1808 ExAcquireResourceExclusiveLite(&DeviceExt->IndexResource, TRUE);
1809 Status = NtfsSetBasicInformation(DeviceExt,
1810 Fcb,
1812 (PFILE_BASIC_INFORMATION)SystemBuffer);
1813 ExReleaseResourceLite(&DeviceExt->IndexResource);
1815 break;
1816
1819 {
1821 break;
1822 }
1823
1825 FileObject,
1826 DeviceExt,
1827 Irp->Flags,
1829 &((PFILE_ALLOCATION_INFORMATION)SystemBuffer)->AllocationSize);
1830 break;
1831
1833 EndOfFileInfo = (PFILE_END_OF_FILE_INFORMATION)SystemBuffer;
1835 FileObject,
1836 DeviceExt,
1837 Irp->Flags,
1839 &EndOfFileInfo->EndOfFile);
1840 break;
1841
1844 {
1846 break;
1847 }
1848
1850 Fcb,
1851 FileObject,
1853 (PFILE_DISPOSITION_INFORMATION)SystemBuffer);
1854 break;
1855
1858 {
1860 break;
1861 }
1862
1863 Status = NtfsSetRenameInformation(DeviceExt,
1864 Fcb,
1865 Stack->Parameters.SetFile.FileObject,
1866 Stack->Parameters.SetFile.ReplaceIfExists,
1868 (PFILE_RENAME_INFORMATION)SystemBuffer,
1869 BufferLength);
1870 break;
1871
1872 // TODO: all other information classes
1873
1874 default:
1875 DPRINT1("FIXME: Unimplemented information class: %s\n", GetInfoClassName(FileInformationClass));
1877 }
1878
1880
1882 ExReleaseResourceLite(&DeviceExt->DirResource);
1883
1884 if (NT_SUCCESS(Status))
1885 Irp->IoStatus.Information =
1886 Stack->Parameters.QueryFile.Length - BufferLength;
1887 else
1888 Irp->IoStatus.Information = 0;
1889
1890 return Status;
1891}
1892/* EOF */
static USHORT USHORT * NewLength
#define ALIGN_UP_BY(size, align)
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 ACPI_BUFFER *RetPathPtr ACPI_OBJECT_HANDLER void *Data ACPI_OBJECT_HANDLER void **Data ACPI_STRING ACPI_OBJECT_LIST ACPI_BUFFER *ReturnObjectBuffer ACPI_DEVICE_INFO **ReturnBuffer ACPI_HANDLE Parent
Definition: acpixf.h:732
unsigned char BOOLEAN
Definition: actypes.h:127
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
struct NTFS_ATTR_RECORD * PNTFS_ATTR_RECORD
#define NTFS_FILE_NAME_DOS
Definition: ntfs.h:65
#define NTFS_FILE_NAME_WIN32
Definition: ntfs.h:64
#define NTFS_MFT_MASK
Definition: ntfs.h:76
#define NTFS_FILE_NAME_POSIX
Definition: ntfs.h:63
#define NTFS_FILE_NAME_WIN32_AND_DOS
Definition: ntfs.h:66
static BOOLEAN NtfsFindMftRecord(_In_ PNTFS_VOLUME_INFO Volume, _In_ ULONGLONG MFTIndex, _In_ PCSTR FileName, _Out_ PULONGLONG OutMFTIndex, _Out_ PULONG FileAttributes)
Definition: ntfs.c:675
_In_ PFCB Fcb
Definition: cdprocs.h:159
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
@ Resident
Definition: data.h:23
LPWSTR Name
Definition: desk.c:124
_In_ ULONG Attributes
Definition: dispmprt.h:1077
_In_ ULONG AllocationSize
Definition: dispmprt.h:712
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define wcschr
Definition: compat.h:17
#define wcsrchr
Definition: compat.h:16
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2988
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
#define L(x)
Definition: resources.c:13
@ Empty
Definition: npfs.h:126
PSTANDARD_INFORMATION GetStandardInformationFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:1970
NTSTATUS FindFirstAttribute(PFIND_ATTR_CONTXT Context, PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, BOOLEAN OnlyResident, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1413
VOID FindCloseAttribute(PFIND_ATTR_CONTXT Context)
Definition: attrib.c:1495
NTSTATUS FindNextAttribute(PFIND_ATTR_CONTXT Context, PNTFS_ATTR_RECORD *Attribute)
Definition: attrib.c:1461
PFILENAME_ATTRIBUTE GetBestFileNameFromRecord(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord)
Definition: attrib.c:2015
VOID NtfsFileFlagsToAttributes(ULONG NtfsAttributes, PULONG FileAttributes)
Definition: misc.c:105
PNTFS_GLOBAL_DATA NtfsGlobalData
Definition: ntfs.c:36
FORCEINLINE NTSTATUS NtfsMarkIrpContextForQueue(PNTFS_IRP_CONTEXT IrpContext)
Definition: ntfs.h:652
struct FILENAME_ATTRIBUTE * PFILENAME_ATTRIBUTE
#define NTFS_FILENAME_UPDATE_SIZES
Definition: ntfs.h:1332
#define NTFS_FILENAME_UPDATE_ATTRS
Definition: ntfs.h:1334
#define FRH_DIRECTORY
Definition: ntfs.h:299
#define NTFS_FILE_TYPE_READ_ONLY
Definition: ntfs.h:249
#define NTFS_FILE_TYPE_DIRECTORY
Definition: ntfs.h:259
#define IRPCONTEXT_CANWAIT
Definition: ntfs.h:505
#define NTFS_FILENAME_UPDATE_TIMES
Definition: ntfs.h:1333
#define FILE_RECORD_END
Definition: ntfs.h:209
@ AttributeEnd
Definition: ntfs.h:204
@ AttributeFileName
Definition: ntfs.h:190
@ AttributeData
Definition: ntfs.h:195
#define TAG_NTFS
Definition: ntfs.h:12
#define FCB_IS_VOLUME_STREAM
Definition: ntfs.h:584
#define ATTR_RECORD_ALIGNMENT
Definition: ntfs.h:351
#define FCB_IS_VOLUME
Definition: ntfs.h:585
#define RA_INDEXED
Definition: ntfs.h:266
#define ULONG_PTR
Definition: config.h:101
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExAcquireResourceSharedLite(res, wait)
Definition: env_spec_w32.h:621
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define FCB_DELETE_PENDING
Definition: ext2fs.h:888
#define BooleanFlagOn(F, SF)
Definition: ext2fs.h:183
@ Removed
Definition: fbtusb.h:86
_Must_inspect_result_ _In_ PFILE_OBJECT _In_opt_ HANDLE _In_ ULONG FileNameLength
Definition: fltkernel.h:1129
@ FilePositionInformation
Definition: from_kernel.h:75
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileAllInformation
Definition: from_kernel.h:79
@ FileInternalInformation
Definition: from_kernel.h:67
@ FileAttributeTagInformation
Definition: from_kernel.h:96
@ FileEaInformation
Definition: from_kernel.h:68
@ FileAlternateNameInformation
Definition: from_kernel.h:82
@ FileNameInformation
Definition: from_kernel.h:70
@ FileAllocationInformation
Definition: from_kernel.h:80
@ FileNetworkOpenInformation
Definition: from_kernel.h:95
@ FileStreamInformation
Definition: from_kernel.h:83
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
struct _FILE_NETWORK_OPEN_INFORMATION FILE_NETWORK_OPEN_INFORMATION
enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS
Definition: directory.c:44
struct _FILE_INTERNAL_INFORMATION FILE_INTERNAL_INFORMATION
_In_ ULONGLONG _In_ PUNICODE_STRING _In_ PUNICODE_STRING LongName
Definition: fsrtlfuncs.h:338
_In_ PLIST_ENTRY _In_ PSTRING _In_ USHORT _In_opt_ PSTRING StreamName
Definition: fsrtlfuncs.h:741
Status
Definition: gdiplustypes.h:24
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
_In_ PIRP Irp
Definition: kse.h:79
_In_ PIRP _In_ PIO_COMPLETION_ROUTINE _In_ PVOID Context
Definition: kse.h:81
NTSTATUS ReadFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG index, PFILE_RECORD_HEADER file)
Definition: mft.c:1936
NTSTATUS UpdateFileRecord(PDEVICE_EXTENSION Vcb, ULONGLONG MftIndex, PFILE_RECORD_HEADER FileRecord)
Definition: mft.c:2391
NTSTATUS NtfsUpdateDuplicatedInformation(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER FileRecord, ULONGLONG MFTIndex, ULONG Flags, BOOLEAN CaseSensitive)
Definition: mft.c:1995
VOID ReleaseAttributeContext(PNTFS_ATTR_CONTEXT Context)
Definition: mft.c:104
NTSTATUS NtfsIsDirectoryEmpty(_In_ PDEVICE_EXTENSION Vcb, _In_ ULONGLONG MftIndex, _Out_ PBOOLEAN Empty)
Definition: mft.c:4554
NTSTATUS NtfsRemoveFilenameFromDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
Definition: mft.c:3297
NTSTATUS NtfsDeleteFileRecord(PDEVICE_EXTENSION DeviceExt, ULONGLONG MftIndex, BOOLEAN CaseSensitive)
Definition: mft.c:3470
ULONGLONG AttributeDataLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:259
NTSTATUS FindAttribute(PDEVICE_EXTENSION Vcb, PFILE_RECORD_HEADER MftRecord, ULONG Type, PCWSTR Name, ULONG NameLength, PNTFS_ATTR_CONTEXT *AttrCtx, PULONG Offset)
Definition: mft.c:131
VOID SetFileRecordEnd(PFILE_RECORD_HEADER FileRecord, PNTFS_ATTR_RECORD AttrEnd, ULONG EndMarker)
Definition: mft.c:706
NTSTATUS NtfsAddFilenameToDirectory(PDEVICE_EXTENSION DeviceExt, ULONGLONG DirectoryMftIndex, ULONGLONG FileReferenceNumber, PFILENAME_ATTRIBUTE FilenameAttribute, BOOLEAN CaseSensitive)
Definition: mft.c:3049
NTSTATUS NtfsResizeAllocation(_In_ PNTFS_FCB Fcb, _In_ PFILE_OBJECT FileObject, _In_ BOOLEAN CaseSensitive, _In_ ULONGLONG AllocationSize)
Definition: mft.c:924
ULONGLONG AttributeAllocatedLength(PNTFS_ATTR_RECORD AttrRecord)
Definition: mft.c:249
NTSTATUS SetAttributeDataLength(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PNTFS_ATTR_CONTEXT AttrContext, ULONG AttrOffset, PFILE_RECORD_HEADER FileRecord, PLARGE_INTEGER DataSize)
Definition: mft.c:615
#define ASSERT(a)
Definition: mode.c:44
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
#define FILE_STANDARD_INFORMATION
Definition: disk.h:54
#define FILE_BASIC_INFORMATION
Definition: disk.h:53
#define min(a, b)
Definition: monoChain.cc:55
_In_ UINT _In_ UINT BytesToCopy
Definition: ndis.h:3168
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
#define _Out_writes_z_(s)
Definition: no_sal2.h:180
#define _Inout_
Definition: no_sal2.h:162
#define _In_z_
Definition: no_sal2.h:164
#define _Outptr_
Definition: no_sal2.h:262
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
int Count
Definition: noreturn.cpp:7
struct _FILE_POSITION_INFORMATION FILE_POSITION_INFORMATION
struct _FILE_END_OF_FILE_INFORMATION * PFILE_END_OF_FILE_INFORMATION
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
__GNU_EXTENSION typedef unsigned __int64 * PULONGLONG
Definition: ntbasedef.h:395
#define UNICODE_NULL
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:329
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
static OUT PIO_STATUS_BLOCK OUT PVOID IN ULONG IN FILE_INFORMATION_CLASS FileInformationClass
Definition: pipe.c:100
ULONGLONG NtfsGetFileSize(PDEVICE_EXTENSION DeviceExt, PFILE_RECORD_HEADER FileRecord, PCWSTR Stream, ULONG StreamLength, PULONGLONG AllocatedSize)
Definition: dirctl.c:38
BOOLEAN NtfsFCBIsDirectory(PNTFS_FCB Fcb)
Definition: fcb.c:144
PNTFS_FCB NtfsGrabFCBFromTable(PNTFS_VCB Vcb, PCWSTR FileName)
Definition: fcb.c:291
BOOLEAN NtfsFCBIsRoot(PNTFS_FCB Fcb)
Definition: fcb.c:185
VOID NtfsReleaseFCB(PNTFS_VCB Vcb, PNTFS_FCB Fcb)
Definition: fcb.c:209
static NTSTATUS NtfsGetAttributeTagInformation(PNTFS_FCB Fcb, PFILE_ATTRIBUTE_TAG_INFORMATION AttributeTagInfo, PULONG BufferLength)
Definition: finfo.c:129
static VOID NtfsRelinkFileNames(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG FileReference, _In_ ULONG Count, _In_ BOOLEAN CaseSensitive)
Definition: finfo.c:1224
static NTSTATUS NtfsBuildRenamedFileName(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILENAME_ATTRIBUTE OldName, _In_ ULONGLONG TargetDirMft, _In_ PUNICODE_STRING NewName, _In_ BOOLEAN CaseSensitive, _Out_ PFILE_RECORD_HEADER Scratch, _Outptr_ PFILENAME_ATTRIBUTE *NewValue, _Out_ PULONG NewValueLength)
Definition: finfo.c:1466
static NTSTATUS NtfsGetNameInformation(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_NAME_INFORMATION NameInfo, PULONG BufferLength)
Definition: finfo.c:180
static BOOLEAN NtfsIsValidFileName(_In_ PCUNICODE_STRING Name)
Definition: finfo.c:1007
static NTSTATUS NtfsGetStreamInformation(PNTFS_FCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_STREAM_INFORMATION StreamInfo, PULONG BufferLength)
Definition: finfo.c:276
static VOID NtfsRenameFcbs(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ PCWSTR NewPath)
Definition: finfo.c:1143
static NTSTATUS NtfsSetBasicInformation(PDEVICE_EXTENSION DeviceExt, PNTFS_FCB Fcb, BOOLEAN CaseSensitive, PFILE_BASIC_INFORMATION BasicInfo)
Definition: finfo.c:830
NTSTATUS NtfsSetEndOfFile(PNTFS_FCB Fcb, PFILE_OBJECT FileObject, PDEVICE_EXTENSION DeviceExt, ULONG IrpFlags, BOOLEAN CaseSensitive, PLARGE_INTEGER NewFileSize)
Definition: finfo.c:625
static NTSTATUS NTAPI NtfsSetAllocationInformation(_In_ PNTFS_FCB Fcb, _In_ PFILE_OBJECT FileObject, _In_ PDEVICE_EXTENSION DeviceExt, _In_ ULONG IrpFlags, _In_ BOOLEAN CaseSensitive, _In_ PLARGE_INTEGER AllocationSize)
Definition: finfo.c:747
NTSTATUS NtfsQueryInformation(PNTFS_IRP_CONTEXT IrpContext)
Definition: finfo.c:470
static NTSTATUS NtfsGetPositionInformation(PFILE_OBJECT FileObject, PFILE_POSITION_INFORMATION PositionInfo, PULONG BufferLength)
Definition: finfo.c:78
static NTSTATUS NtfsCommitRename(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _Inout_ PFILE_RECORD_HEADER FileRecord, _In_ PFILE_RECORD_HEADER Original, _In_ ULONGLONG OldParentMft, _In_ ULONGLONG TargetDirMft, _In_ PFILENAME_ATTRIBUTE NewValue, _In_ ULONG NewValueLength, _In_ BOOLEAN CaseSensitive)
Definition: finfo.c:1569
static NTSTATUS NtfsSetRenameInformation(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_opt_ PFILE_OBJECT TargetFileObject, _In_ BOOLEAN ReplaceIfExists, _In_ BOOLEAN CaseSensitive, _In_ PFILE_RENAME_INFORMATION RenameInfo, _In_ ULONG BufferLength)
Definition: finfo.c:1651
static NTSTATUS NtfsFindLongFileName(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _Outptr_ PFILENAME_ATTRIBUTE *LongName, _Out_ PULONGLONG ParentMft)
Definition: finfo.c:1349
static NTSTATUS NtfsUnlinkFileNames(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PFILE_RECORD_HEADER FileRecord, _In_ ULONGLONG ParentMft, _In_ BOOLEAN CaseSensitive, _Out_ PULONG Removed)
Definition: finfo.c:1518
const PCSTR GetInfoClassName(FILE_INFORMATION_CLASS infoClass)
Definition: finfo.c:346
static NTSTATUS NtfsBuildRenamePath(_In_ PNTFS_FCB Fcb, _In_opt_ PFILE_OBJECT TargetFileObject, _In_ PFILE_RENAME_INFORMATION RenameInfo, _In_ ULONG BufferLength, _Out_ PUNICODE_STRING NewName, _Out_writes_z_(MAX_PATH) PWSTR NewPath, _Out_ PULONGLONG TargetDirMft)
Definition: finfo.c:1272
static NTSTATUS NtfsCheckRenamePaths(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ PCWSTR NewPath)
Definition: finfo.c:1186
static NTSTATUS NtfsClearRenameTarget(_In_ PDEVICE_EXTENSION DeviceExt, _In_ PNTFS_FCB Fcb, _In_ ULONGLONG TargetDirMft, _In_ PUNICODE_STRING NewName, _In_z_ PCWSTR NewPath, _In_ BOOLEAN ReplaceIfExists, _In_ BOOLEAN CaseSensitive, _Out_ PFILE_RECORD_HEADER Scratch)
Definition: finfo.c:1408
static NTSTATUS NtfsGetStandardInformation(PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_STANDARD_INFORMATION StandardInfo, PULONG BufferLength)
Definition: finfo.c:45
static NTSTATUS NtfsGetNetworkOpenInformation(PNTFS_FCB Fcb, PDEVICE_EXTENSION DeviceExt, PFILE_NETWORK_OPEN_INFORMATION NetworkInfo, PULONG BufferLength)
Definition: finfo.c:248
static NTSTATUS NtfsGetInternalInformation(PNTFS_FCB Fcb, PFILE_INTERNAL_INFORMATION InternalInfo, PULONG BufferLength)
Definition: finfo.c:227
NTSTATUS NtfsSetInformation(PNTFS_IRP_CONTEXT IrpContext)
Definition: finfo.c:1748
static NTSTATUS NtfsSetFileNameAttribute(_In_ PDEVICE_EXTENSION DeviceExt, _Inout_ PFILE_RECORD_HEADER FileRecord, _In_ PFILENAME_ATTRIBUTE Value, _In_ ULONG ValueLength)
Definition: finfo.c:1048
static NTSTATUS NtfsGetBasicInformation(PFILE_OBJECT FileObject, PNTFS_FCB Fcb, PDEVICE_OBJECT DeviceObject, PFILE_BASIC_INFORMATION BasicInfo, PULONG BufferLength)
Definition: finfo.c:100
static NTSTATUS NtfsSetDispositionInformation(PDEVICE_EXTENSION DeviceExt, PNTFS_FCB Fcb, PFILE_OBJECT FileObject, BOOLEAN CaseSensitive, PFILE_DISPOSITION_INFORMATION DispositionInfo)
Definition: finfo.c:941
#define NTFS_MAX_NAME_LENGTH
Definition: finfo.c:36
static NTSTATUS NtfsGetEaInformation(PNTFS_FCB Fcb, PFILE_EA_INFORMATION EaInfo, PULONG BufferLength)
Definition: finfo.c:155
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
#define STATUS_USER_MAPPED_FILE
Definition: ntstatus.h:833
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
short WCHAR
Definition: pedump.c:58
unsigned short USHORT
Definition: pedump.c:61
BOOLEAN NTAPI RtlIsNameLegalDOS8Dot3(_In_ PUNICODE_STRING Name, _Inout_opt_ POEM_STRING OemName, _Inout_opt_ PBOOLEAN NameContainsSpaces)
@ Other
Definition: video.h:273
wcscat
wcscpy
BOOLEAN NTAPI MmCanFileBeTruncated(_In_ PSECTION_OBJECT_POINTERS SectionObjectPointer, _In_opt_ PLARGE_INTEGER NewFileSize)
Definition: section.c:4312
Entry
Definition: section.c:5216
BOOLEAN NTAPI MmFlushImageSection(IN PSECTION_OBJECT_POINTERS SectionObjectPointer, IN MMFLUSH_TYPE FlushType)
Definition: section.c:4413
#define FileStandardInformation
Definition: propsheet.cpp:61
#define STATUS_CANNOT_DELETE
Definition: shellext.h:71
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:73
UCHAR NameType
Definition: ntfs.h:409
ULONG FileAttributes
Definition: ntfs.h:398
struct NTFS_ATTR_RECORD::@170::@172 Resident
ULONG Length
Definition: ntfs.h:135
USHORT NameOffset
Definition: ntfs.h:138
USHORT Instance
Definition: ntfs.h:140
UCHAR NameLength
Definition: ntfs.h:137
UCHAR IsNonResident
Definition: ntfs.h:136
ULONG Type
Definition: ntfs.h:134
BOOLEAN EnableWriteSupport
Definition: ntfs.h:182
PFILE_OBJECT FileObject
Definition: ntfs.h:564
ULONG Flags
Definition: ntfs.h:556
PIO_STACK_LOCATION Stack
Definition: ntfs.h:557
PDEVICE_OBJECT DeviceObject
Definition: ntfs.h:563
ULONGLONG LastAccessTime
Definition: ntfs.h:364
ULONGLONG ChangeTime
Definition: ntfs.h:363
ULONGLONG LastWriteTime
Definition: ntfs.h:362
ULONG FileAttribute
Definition: ntfs.h:365
ULONGLONG CreationTime
Definition: ntfs.h:361
Definition: cdstruc.h:902
ULONG Flags
Definition: ntfs.h:618
PVCB Vcb
Definition: cdstruc.h:933
FSRTL_COMMON_FCB_HEADER RFCB
Definition: ntfs.h:593
ULONGLONG MFTIndex
Definition: ntfs.h:622
WCHAR Stream[MAX_PATH]
Definition: ntfs.h:602
SECTION_OBJECT_POINTERS SectionObjectPointers
Definition: ntfs.h:597
WCHAR * ObjectName
Definition: ntfs.h:603
WCHAR PathName[MAX_PATH]
Definition: ntfs.h:604
USHORT LinkCount
Definition: ntfs.h:623
FILENAME_ATTRIBUTE Entry
Definition: ntfs.h:625
ERESOURCE MainResource
Definition: ntfs.h:607
PFILE_OBJECT FileObject
Definition: ntfs.h:599
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:944
LARGE_INTEGER CreationTime
Definition: nt_native.h:942
LARGE_INTEGER ChangeTime
Definition: nt_native.h:945
LARGE_INTEGER LastAccessTime
Definition: nt_native.h:943
LARGE_INTEGER CurrentByteOffset
Definition: nt_native.h:958
USHORT NextAttributeNumber
Definition: ntfs.h:291
USHORT AttributeOffset
Definition: ntfs.h:286
LARGE_INTEGER AllocationSize
Definition: propsheet.cpp:54
LARGE_INTEGER StreamSize
Definition: winternl.h:1700
LARGE_INTEGER StreamAllocationSize
Definition: winternl.h:1701
LARGE_INTEGER AllocationSize
Definition: env_spec_w32.h:755
Definition: typedefs.h:120
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
unsigned char UCHAR
Definition: typedefs.h:53
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
#define NTAPI
Definition: typedefs.h:36
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint64_t ULONGLONG
Definition: typedefs.h:67
const char * PCSTR
Definition: typedefs.h:52
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_DIRECTORY_NOT_EMPTY
Definition: udferr_usr.h:167
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_OBJECT_PATH_NOT_FOUND
Definition: udferr_usr.h:151
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_OBJECT_NAME_COLLISION
Definition: udferr_usr.h:150
#define STATUS_INFO_LENGTH_MISMATCH
Definition: udferr_usr.h:133
#define STATUS_FILE_CORRUPT_ERROR
Definition: udferr_usr.h:168
#define STATUS_OBJECT_NAME_INVALID
Definition: udferr_usr.h:148
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
LONGLONG QuadPart
Definition: typedefs.h:114
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2061
_In_ WDFREQUEST _In_ WDFFILEOBJECT FileObject
Definition: wdfdevice.h:550
_Must_inspect_result_ _In_ WDFDEVICE _In_ DEVICE_REGISTRY_PROPERTY _In_ ULONG BufferLength
Definition: wdfdevice.h:3777
_Must_inspect_result_ _In_ WDFMEMORY _In_ size_t SourceOffset
Definition: wdfmemory.h:320
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_In_ WDFREQUEST _In_ PIO_STACK_LOCATION Stack
Definition: wdfrequest.h:639
struct _FILE_ATTRIBUTE_TAG_INFORMATION FILE_ATTRIBUTE_TAG_INFORMATION
struct _FILE_STREAM_INFORMATION * PFILE_STREAM_INFORMATION
struct _FILE_EA_INFORMATION FILE_EA_INFORMATION
#define IRP_PAGING_IO
* PFILE_OBJECT
Definition: iotypes.h:1998
#define SL_CASE_SENSITIVE
Definition: iotypes.h:1820
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778
_In_opt_ PLARGE_INTEGER NewFileSize
Definition: mmfuncs.h:608
_In_ PUNICODE_STRING NewName
Definition: zwfuncs.h:1203