ReactOS 0.4.16-dev-2-g02a6913
filesup.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Setup Library
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: File support functions.
5 * COPYRIGHT: Casper S. Hornstrup (chorns@users.sourceforge.net)
6 * Copyright 2017-2018 Hermes Belusca-Maito
7 */
8
9/* INCLUDES *****************************************************************/
10
11#include "precomp.h"
12#include "filesup.h"
13
14#define NDEBUG
15#include <debug.h>
16
17
18// ACHTUNG! HAXX FIXME!!
19#define _SEH2_TRY
20#define _SEH2_LEAVE goto __SEH2_FINALLY__label;
21#define _SEH2_FINALLY __SEH2_FINALLY__label:
22#define _SEH2_END
23
24
25/* FUNCTIONS ****************************************************************/
26
27static
30 _In_ PCUNICODE_STRING DirectoryName)
31{
33 UNICODE_STRING PathName = *DirectoryName;
37
38 /* Remove the trailing separator if needed */
39 if (PathName.Length >= 2 * sizeof(WCHAR) &&
40 PathName.Buffer[PathName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
41 {
42 PathName.Length -= sizeof(WCHAR);
43 }
44
46 &PathName,
48 NULL,
49 NULL);
50
55 NULL,
60 NULL,
61 0);
62 if (NT_SUCCESS(Status))
64
65 return Status;
66}
67
80 _In_ PCWSTR PathName)
81{
83 UNICODE_STRING PathNameU;
85 PCWCH Ptr, End;
86
87 RtlInitUnicodeString(&PathNameU, PathName);
88 Buffer = PathNameU.Buffer;
89 End = Buffer + (PathNameU.Length / sizeof(WCHAR));
90
91 /* Find the deepest existing sub-directory: start from the
92 * end and go back, verifying each sub-directory in turn */
93 for (Ptr = End; Ptr > Buffer;)
94 {
95 BOOLEAN bExists;
96
97 /* If we are on a separator, truncate at the next character.
98 * The trailing separator is kept for the existence check. */
99 if ((Ptr < End) && (*Ptr == OBJ_NAME_PATH_SEPARATOR))
100 PathNameU.Length = (ULONG_PTR)(Ptr+1) - (ULONG_PTR)Buffer;
101
102 /* Check if the sub-directory exists and stop
103 * if so: this is the deepest existing one */
104 DPRINT("PathName: %wZ\n", &PathNameU);
105 bExists = DoesPathExist_UStr(NULL, &PathNameU, TRUE);
106 if (bExists)
107 break;
108
109 /* Skip back any consecutive path separators */
110 while ((Ptr > Buffer) && (*Ptr == OBJ_NAME_PATH_SEPARATOR))
111 --Ptr;
112 /* Go to the beginning of the path component, stop at the separator */
113 while ((Ptr > Buffer) && (*Ptr != OBJ_NAME_PATH_SEPARATOR))
114 --Ptr;
115 }
116
117 /* Skip any consecutive path separators */
118 while ((Ptr < End) && (*Ptr == OBJ_NAME_PATH_SEPARATOR))
119 ++Ptr;
120
121 /* Create all the remaining sub-directories */
122 for (; Ptr < End; ++Ptr)
123 {
124 /* Go to the end of the current path component, stop at
125 * the separator or terminating NUL and truncate it */
126 while ((Ptr < End) && (*Ptr != OBJ_NAME_PATH_SEPARATOR))
127 ++Ptr;
128 PathNameU.Length = (ULONG_PTR)Ptr - (ULONG_PTR)Buffer;
129
130 DPRINT("Create: %wZ\n", &PathNameU);
132 if (!NT_SUCCESS(Status))
133 break;
134 }
135
136 DPRINT("Done.\n");
137 return Status;
138}
139
143 IN BOOLEAN ForceDelete) // ForceDelete can be used to delete read-only files
144{
146 UNICODE_STRING NtPathU;
150 FILE_DISPOSITION_INFORMATION FileDispInfo;
151 BOOLEAN RetryOnce = FALSE;
152
153 /* Open the directory name that was passed in */
156 &NtPathU,
158 NULL,
159 NULL);
160
161Retry: // We go back there once if RetryOnce == TRUE
164 (RetryOnce ? FILE_WRITE_ATTRIBUTES : 0),
169 if (!NT_SUCCESS(Status))
170 {
171 DPRINT1("NtOpenFile failed with Status 0x%08lx\n", Status);
172 return Status;
173 }
174
175 if (RetryOnce)
176 {
178
184 if (!NT_SUCCESS(Status))
185 {
186 DPRINT1("NtQueryInformationFile failed with Status 0x%08lx\n", Status);
188 return Status;
189 }
190
191 FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
198 if (!NT_SUCCESS(Status))
199 {
200 DPRINT1("NtSetInformationFile failed with Status 0x%08lx\n", Status);
201 return Status;
202 }
203 }
204
205 /* Ask for the file to be deleted */
206 FileDispInfo.DeleteFile = TRUE;
209 &FileDispInfo,
213
214 if (!NT_SUCCESS(Status))
215 DPRINT1("Deletion of file '%S' failed, Status 0x%08lx\n", FileName, Status);
216
217 // FIXME: Check the precise value of Status!
218 if (!NT_SUCCESS(Status) && ForceDelete && !RetryOnce)
219 {
220 /* Retry once */
221 RetryOnce = TRUE;
222 goto Retry;
223 }
224
225 /* Return result to the caller */
226 return Status;
227}
228
231 IN PCWSTR SourceFileName,
232 IN PCWSTR DestinationFileName,
233 IN BOOLEAN FailIfExists)
234{
238 HANDLE FileHandleSource;
239 HANDLE FileHandleDest;
241 FILE_STANDARD_INFORMATION FileStandard;
242 FILE_BASIC_INFORMATION FileBasic;
244 HANDLE SourceFileSection;
245 PVOID SourceFileMap = NULL;
246 SIZE_T SourceSectionSize = 0;
248
249 RtlInitUnicodeString(&FileName, SourceFileName);
251 &FileName,
253 NULL,
254 NULL);
255
256 Status = NtOpenFile(&FileHandleSource,
262 if (!NT_SUCCESS(Status))
263 {
264 DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
265 goto done;
266 }
267
268 Status = NtQueryInformationFile(FileHandleSource,
270 &FileStandard,
273 if (!NT_SUCCESS(Status))
274 {
275 DPRINT1("NtQueryInformationFile failed: %x\n", Status);
276 goto closesrc;
277 }
278
279 Status = NtQueryInformationFile(FileHandleSource,
281 &FileBasic,
284 if (!NT_SUCCESS(Status))
285 {
286 DPRINT1("NtQueryInformationFile failed: %x\n", Status);
287 goto closesrc;
288 }
289
290 Status = NtCreateSection(&SourceFileSection,
292 NULL,
293 NULL,
296 FileHandleSource);
297 if (!NT_SUCCESS(Status))
298 {
299 DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
300 goto closesrc;
301 }
302
303 Status = NtMapViewOfSection(SourceFileSection,
305 &SourceFileMap,
306 0,
307 0,
308 NULL,
309 &SourceSectionSize,
310 ViewUnmap,
311 0,
313 if (!NT_SUCCESS(Status))
314 {
315 DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
316 goto closesrcsec;
317 }
318
319 RtlInitUnicodeString(&FileName, DestinationFileName);
321 &FileName,
323 NULL,
324 NULL);
325
326 Status = NtCreateFile(&FileHandleDest,
330 NULL,
331 FileBasic.FileAttributes, // FILE_ATTRIBUTE_NORMAL,
332 0,
333 FailIfExists ? FILE_CREATE : FILE_OVERWRITE_IF,
337 NULL,
338 0);
339 if (!NT_SUCCESS(Status))
340 {
341 /*
342 * Open may have failed because the file to overwrite
343 * is in readonly mode.
344 */
346 {
347 FILE_BASIC_INFORMATION FileBasicInfo;
348
349 /* Reattempt to open it with limited access */
350 Status = NtCreateFile(&FileHandleDest,
354 NULL,
356 0,
357 FILE_OPEN,
361 NULL,
362 0);
363 /* Fail for real if we cannot open it that way */
364 if (!NT_SUCCESS(Status))
365 {
366 DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
367 goto unmapsrcsec;
368 }
369
370 /* Zero our basic info, just to set attributes */
371 RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
372 /* Reset attributes to normal, no read-only */
374 /*
375 * We basically don't care about whether it succeed:
376 * if it didn't, later open will fail.
377 */
378 NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasicInfo,
379 sizeof(FileBasicInfo), FileBasicInformation);
380
381 /* Close file */
382 NtClose(FileHandleDest);
383
384 /* And re-attempt overwrite */
385 Status = NtCreateFile(&FileHandleDest,
389 NULL,
391 0,
396 NULL,
397 0);
398 }
399
400 /* We failed */
401 if (!NT_SUCCESS(Status))
402 {
403 DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
404 goto unmapsrcsec;
405 }
406 }
407
408 RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
410 ByteOffset.QuadPart = 0ULL;
411 Status = NtWriteFile(FileHandleDest,
412 NULL,
413 NULL,
414 NULL,
416 SourceFileMap,
418 &ByteOffset,
419 NULL);
420 if (!NT_SUCCESS(Status))
421 {
422 DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n",
424 goto closedest;
425 }
426
427 /* Copy file date/time from source file */
428 Status = NtSetInformationFile(FileHandleDest,
430 &FileBasic,
433 if (!NT_SUCCESS(Status))
434 {
435 DPRINT1("NtSetInformationFile failed: %x\n", Status);
436 goto closedest;
437 }
438
439 /* Shorten the file back to its real size after completing the write */
440 Status = NtSetInformationFile(FileHandleDest,
442 &FileStandard.EndOfFile,
445 if (!NT_SUCCESS(Status))
446 {
447 DPRINT1("NtSetInformationFile failed: %x\n", Status);
448 }
449
450closedest:
451 NtClose(FileHandleDest);
452
453unmapsrcsec:
454 NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);
455
456closesrcsec:
457 NtClose(SourceFileSection);
458
459closesrc:
460 NtClose(FileHandleSource);
461
462done:
463 return Status;
464}
465
466/*
467 * Synchronized with its kernel32 counterpart, but we don't manage reparse points here.
468 */
471 IN PCWSTR ExistingFileName,
472 IN PCWSTR NewFileName,
473 IN ULONG Flags)
474{
478 PFILE_RENAME_INFORMATION RenameInfo;
479 UNICODE_STRING NewPathU, ExistingPathU;
481 BOOLEAN ReplaceIfExists;
482
483 RtlInitUnicodeString(&ExistingPathU, ExistingFileName);
484 RtlInitUnicodeString(&NewPathU, NewFileName);
485
487 {
488 ReplaceIfExists = !!(Flags & MOVEFILE_REPLACE_EXISTING);
489
490 /* Unless we manage a proper opening, we'll attempt to reopen without reparse support */
492 &ExistingPathU,
494 NULL,
495 NULL);
496 /* Attempt to open source file */
503 if (!NT_SUCCESS(Status))
504 {
506 {
508 }
509 }
510
511 /* At that point, we MUST have a source handle */
513
514 /* Allocate renaming buffer and fill it */
515 RenameInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(FILE_RENAME_INFORMATION));
516 if (RenameInfo == NULL)
517 {
520 }
521
522 RtlCopyMemory(&RenameInfo->FileName, NewPathU.Buffer, NewPathU.Length);
523 RenameInfo->ReplaceIfExists = ReplaceIfExists;
524 RenameInfo->RootDirectory = NULL;
525 RenameInfo->FileNameLength = NewPathU.Length;
526
527 /* Attempt to rename the file */
530 RenameInfo,
531 NewPathU.Length + sizeof(FILE_RENAME_INFORMATION),
533 RtlFreeHeap(RtlGetProcessHeap(), 0, RenameInfo);
534 if (NT_SUCCESS(Status))
535 {
536 /* If it succeeded, all fine, quit */
538 }
539 /*
540 * If we failed for any other reason than not the same device, fail.
541 * If we failed because of different devices, only allow renaming
542 * if user allowed copy.
543 */
545 {
546 /* ReactOS hack! To be removed once all FSD have proper renaming support
547 * Just leave status to error and leave
548 */
550 {
551 DPRINT1("Forcing copy, renaming not supported by FSD\n");
552 }
553 else
554 {
556 }
557 }
558
559 /* Close the source file */
562
563 /* Perform the file copy */
564 Status = SetupCopyFile(ExistingFileName,
565 NewFileName,
566 !ReplaceIfExists);
567
568 /* If it succeeded, delete the source file */
569 if (NT_SUCCESS(Status))
570 {
571 /* Force-delete files even if read-only */
572 SetupDeleteFile(ExistingFileName, TRUE);
573 }
574 }
576 {
577 if (SourceHandle)
579 }
580 _SEH2_END;
581
582 return Status;
583}
584
587 IN OUT PWSTR PathBuffer,
588 IN SIZE_T cchPathSize,
589 IN ULONG NumberOfPathComponents,
590 IN va_list PathComponentsList)
591{
593 SIZE_T cchPathLen;
595
596 if (cchPathSize < 1)
597 return STATUS_SUCCESS;
598
599 while (NumberOfPathComponents--)
600 {
601 PathComponent = va_arg(PathComponentsList, PCWSTR);
602 if (!PathComponent)
603 continue;
604
605 cchPathLen = min(cchPathSize, wcslen(PathBuffer));
606 if (cchPathLen >= cchPathSize)
608
610 cchPathLen > 0 && PathBuffer[cchPathLen-1] != OBJ_NAME_PATH_SEPARATOR)
611 {
612 /* PathComponent does not start with '\' and PathBuffer does not end with '\' */
613 Status = RtlStringCchCatW(PathBuffer, cchPathSize, L"\\");
614 if (!NT_SUCCESS(Status))
615 return Status;
616 }
617 else if (PathComponent[0] == OBJ_NAME_PATH_SEPARATOR &&
618 cchPathLen > 0 && PathBuffer[cchPathLen-1] == OBJ_NAME_PATH_SEPARATOR)
619 {
620 /* PathComponent starts with '\' and PathBuffer ends with '\' */
622 ++PathComponent; // Skip any backslash
623 }
624 Status = RtlStringCchCatW(PathBuffer, cchPathSize, PathComponent);
625 if (!NT_SUCCESS(Status))
626 return Status;
627 }
628
629 return Status;
630}
631
634 OUT PWSTR PathBuffer,
635 IN SIZE_T cchPathSize,
636 IN ULONG NumberOfPathComponents,
637 IN va_list PathComponentsList)
638{
639 if (cchPathSize < 1)
640 return STATUS_SUCCESS;
641
642 *PathBuffer = UNICODE_NULL;
643 return ConcatPathsV(PathBuffer, cchPathSize,
644 NumberOfPathComponents,
645 PathComponentsList);
646}
647
650 IN OUT PWSTR PathBuffer,
651 IN SIZE_T cchPathSize,
652 IN ULONG NumberOfPathComponents,
653 IN /* PCWSTR */ ...)
654{
656 va_list PathComponentsList;
657
658 if (cchPathSize < 1)
659 return STATUS_SUCCESS;
660
661 va_start(PathComponentsList, NumberOfPathComponents);
662 Status = ConcatPathsV(PathBuffer, cchPathSize,
663 NumberOfPathComponents,
664 PathComponentsList);
665 va_end(PathComponentsList);
666
667 return Status;
668}
669
672 OUT PWSTR PathBuffer,
673 IN SIZE_T cchPathSize,
674 IN ULONG NumberOfPathComponents,
675 IN /* PCWSTR */ ...)
676{
678 va_list PathComponentsList;
679
680 if (cchPathSize < 1)
681 return STATUS_SUCCESS;
682
683 *PathBuffer = UNICODE_NULL;
684
685 va_start(PathComponentsList, NumberOfPathComponents);
686 Status = CombinePathsV(PathBuffer, cchPathSize,
687 NumberOfPathComponents,
688 PathComponentsList);
689 va_end(PathComponentsList);
690
691 return Status;
692}
693
697 _In_ PCUNICODE_STRING PathName,
699{
704
706 (PUNICODE_STRING)PathName,
709 NULL);
710
713 : FILE_GENERIC_READ, // Contains SYNCHRONIZE
720 if (NT_SUCCESS(Status))
721 {
723 }
724 else
725 {
726 DPRINT("Failed to open %s '%wZ', Status 0x%08lx\n",
727 IsDirectory ? "directory" : "file",
728 PathName, Status);
729 }
730
731 return NT_SUCCESS(Status);
732}
733
737 _In_ PCWSTR PathName,
739{
740 UNICODE_STRING PathNameU;
741 RtlInitUnicodeString(&PathNameU, PathName);
742 return DoesPathExist_UStr(RootDirectory, &PathNameU, IsDirectory);
743}
744
745// FIXME: DEPRECATED! HACKish function that needs to be deprecated!
748 IN PCWSTR PathName OPTIONAL,
750{
753 return DoesFileExist(NULL, FullName);
754}
755
756/*
757 * The format of NtPath should be:
758 * \Device\HarddiskXXX\PartitionYYY[\path] ,
759 * where XXX and YYY respectively represent the hard disk and partition numbers,
760 * and [\path] represent an optional path (separated by '\\').
761 *
762 * If a NT path of such a form is correctly parsed, the function returns respectively:
763 * - in pDiskNumber: the hard disk number XXX,
764 * - in pPartNumber: the partition number YYY,
765 * - in PathComponent: pointer value (inside NtPath) to the beginning of \path.
766 *
767 * NOTE: The function does not accept leading whitespace.
768 */
771 IN PCWSTR NtPath,
772 OUT PULONG pDiskNumber,
773 OUT PULONG pPartNumber,
775{
776 ULONG DiskNumber, PartNumber;
777 PCWSTR Path;
778
779 *pDiskNumber = 0;
780 *pPartNumber = 0;
782
783 Path = NtPath;
784
785 if (_wcsnicmp(Path, L"\\Device\\Harddisk", 16) != 0)
786 {
787 /* The NT path doesn't start with the prefix string, thus it cannot be a hard disk device path */
788 DPRINT1("'%S' : Not a possible hard disk device.\n", NtPath);
789 return FALSE;
790 }
791
792 Path += 16;
793
794 /* A number must be present now */
795 if (!iswdigit(*Path))
796 {
797 DPRINT1("'%S' : expected a number! Not a regular hard disk device.\n", Path);
798 return FALSE;
799 }
800 DiskNumber = wcstoul(Path, (PWSTR*)&Path, 10);
801
802 /* Either NULL termination, or a path separator must be present now */
804 {
805 DPRINT1("'%S' : expected a path separator!\n", Path);
806 return FALSE;
807 }
808
809 if (!*Path)
810 {
811 DPRINT1("The path only specified a hard disk (and nothing else, like a partition...), so we stop there.\n");
812 goto Quit;
813 }
814
815 /* Here, *Path == L'\\' */
816
817 if (_wcsnicmp(Path, L"\\Partition", 10) != 0)
818 {
819 /* Actually, \Partition is optional so, if we don't have it, we still return success. Or should we? */
820 DPRINT1("'%S' : unexpected format!\n", NtPath);
821 goto Quit;
822 }
823
824 Path += 10;
825
826 /* A number must be present now */
827 if (!iswdigit(*Path))
828 {
829 /* If we don't have a number it means this part of path is actually not a partition specifier, so we shouldn't fail either. Or should we? */
830 DPRINT1("'%S' : expected a number!\n", Path);
831 goto Quit;
832 }
833 PartNumber = wcstoul(Path, (PWSTR*)&Path, 10);
834
835 /* Either NULL termination, or a path separator must be present now */
837 {
838 /* We shouldn't fail here because it just means this part of path is actually not a partition specifier. Or should we? */
839 DPRINT1("'%S' : expected a path separator!\n", Path);
840 goto Quit;
841 }
842
843 /* OK, here we really have a partition specifier: return its number */
844 *pPartNumber = PartNumber;
845
846Quit:
847 /* Return the disk number */
848 *pDiskNumber = DiskNumber;
849
850 /* Return the path component also, if the user wants it */
852
853 return TRUE;
854}
855
888 _In_ PCWSTR PathNameToFile,
891 _Out_ PHANDLE SectionHandle,
893 _In_ BOOLEAN ReadWriteAccess)
894{
899 HANDLE LocalFileHandle;
900
901 /* Open the file */
902 RtlInitUnicodeString(&FileName, PathNameToFile);
904 &FileName,
907 NULL);
908
909 if (FileHandle) *FileHandle = NULL;
910 Status = NtOpenFile(&LocalFileHandle,
911 FILE_GENERIC_READ | // Contains SYNCHRONIZE
912 (ReadWriteAccess ? FILE_GENERIC_WRITE : 0),
917 if (!NT_SUCCESS(Status))
918 {
919 DPRINT1("Failed to open file '%wZ' (Status 0x%08lx)\n", &FileName, Status);
920 return Status;
921 }
922
923 if (FileSize)
924 {
925 /* Query the file size */
927 Status = NtQueryInformationFile(LocalFileHandle,
929 &FileInfo,
930 sizeof(FileInfo),
932 if (!NT_SUCCESS(Status))
933 {
934 DPRINT("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status);
935 goto Quit;
936 }
937
938 if (FileInfo.EndOfFile.HighPart != 0)
939 DPRINT1("WARNING!! The file '%wZ' is too large!\n", &FileName);
940
941 *FileSize = FileInfo.EndOfFile.LowPart;
942 DPRINT("File size: %lu\n", *FileSize);
943 }
944
945 /* Map the whole file into memory */
946 Status = MapFile(LocalFileHandle,
947 SectionHandle,
949 ReadWriteAccess);
950 if (!NT_SUCCESS(Status))
951 {
952 DPRINT1("Failed to map file '%wZ' (Status 0x%08lx)\n", &FileName, Status);
953 goto Quit;
954 }
955
956Quit:
957 /* If we succeeded, return the opened file handle if needed.
958 * If we failed or the caller does not need the handle, close it now. */
960 *FileHandle = LocalFileHandle;
961 else
962 NtClose(LocalFileHandle);
963
964 return Status;
965}
966
990 _Out_ PHANDLE SectionHandle,
992 _In_ BOOLEAN ReadWriteAccess)
993{
997 PVOID ViewBase;
998
999 SectionPageProtection = (ReadWriteAccess ? PAGE_READWRITE : PAGE_READONLY);
1000
1001 /* Create the section */
1002 *SectionHandle = NULL;
1003 Status = NtCreateSection(SectionHandle,
1006 (ReadWriteAccess ? SECTION_MAP_WRITE : 0),
1007 NULL,
1008 NULL,
1010 SEC_COMMIT /* | SEC_IMAGE (_NO_EXECUTE) */,
1011 FileHandle);
1012 if (!NT_SUCCESS(Status))
1013 {
1014 DPRINT1("Failed to create a memory section for file 0x%p (Status 0x%08lx)\n",
1016 return Status;
1017 }
1018
1019 /* Map the section */
1020 ViewSize = 0;
1021 ViewBase = NULL;
1022 Status = NtMapViewOfSection(*SectionHandle,
1024 &ViewBase,
1025 0, 0,
1026 NULL,
1027 &ViewSize,
1028 ViewShare,
1029 0,
1031 if (!NT_SUCCESS(Status))
1032 {
1033 DPRINT1("Failed to map a view for file 0x%p (Status 0x%08lx)\n",
1035 NtClose(*SectionHandle);
1036 *SectionHandle = NULL;
1037 return Status;
1038 }
1039
1040 *BaseAddress = ViewBase;
1041 return STATUS_SUCCESS;
1042}
1043
1057BOOLEAN
1059 _In_ HANDLE SectionHandle,
1061{
1064
1066 if (!NT_SUCCESS(Status))
1067 {
1068 DPRINT1("NtUnmapViewOfSection(0x%p) failed (Status 0x%08lx)\n",
1070 Success = FALSE;
1071 }
1072 Status = NtClose(SectionHandle);
1073 if (!NT_SUCCESS(Status))
1074 {
1075 DPRINT1("NtClose(0x%p) failed (Status 0x%08lx)\n",
1076 SectionHandle, Status);
1077 Success = FALSE;
1078 }
1079
1080 return Success;
1081}
1082
1083/* EOF */
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3481
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3074
NTSTATUS NTAPI NtMapViewOfSection(IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress, IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize, IN OUT PLARGE_INTEGER SectionOffset OPTIONAL, IN OUT PSIZE_T ViewSize, IN SECTION_INHERIT InheritDisposition, IN ULONG AllocationType, IN ULONG Protect)
Definition: section.c:3255
static HANDLE DirectoryHandle
Definition: ObType.c:48
unsigned char BOOLEAN
PRTL_UNICODE_STRING_BUFFER Path
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#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 ARRAYSIZE(array)
Definition: filtermapper.c:47
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
#define ULONG_PTR
Definition: config.h:101
@ Success
Definition: eventcreate.c:712
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:731
struct _FileName FileName
Definition: fatprocs.h:896
BOOLEAN DoesPathExist(_In_opt_ HANDLE RootDirectory, _In_ PCWSTR PathName, _In_ BOOLEAN IsDirectory)
Definition: filesup.c:735
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:671
NTSTATUS MapFile(_In_ HANDLE FileHandle, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
Maps an opened file in memory.
Definition: filesup.c:988
static NTSTATUS SetupCreateSingleDirectory(_In_ PCUNICODE_STRING DirectoryName)
Definition: filesup.c:29
BOOLEAN DoesFileExist_2(IN PCWSTR PathName OPTIONAL, IN PCWSTR FileName)
Definition: filesup.c:747
BOOLEAN NtPathToDiskPartComponents(IN PCWSTR NtPath, OUT PULONG pDiskNumber, OUT PULONG pPartNumber, OUT PCWSTR *PathComponent OPTIONAL)
Definition: filesup.c:770
NTSTATUS OpenAndMapFile(_In_opt_ HANDLE RootDirectory, _In_ PCWSTR PathNameToFile, _Out_opt_ PHANDLE FileHandle, _Out_opt_ PULONG FileSize, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
Opens and maps a file in memory.
Definition: filesup.c:886
NTSTATUS ConcatPathsV(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:586
NTSTATUS CombinePathsV(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:633
NTSTATUS SetupMoveFile(IN PCWSTR ExistingFileName, IN PCWSTR NewFileName, IN ULONG Flags)
Definition: filesup.c:470
#define _SEH2_FINALLY
Definition: filesup.c:21
NTSTATUS SetupCreateDirectory(_In_ PCWSTR PathName)
Create a new directory, specified by the given path. Any intermediate non-existing directory is creat...
Definition: filesup.c:79
NTSTATUS ConcatPaths(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:649
#define _SEH2_END
Definition: filesup.c:22
BOOLEAN UnMapFile(_In_ HANDLE SectionHandle, _In_ PVOID BaseAddress)
Unmaps a mapped file by section.
Definition: filesup.c:1058
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:230
#define _SEH2_TRY
Definition: filesup.c:19
NTSTATUS SetupDeleteFile(IN PCWSTR FileName, IN BOOLEAN ForceDelete)
Definition: filesup.c:141
#define _SEH2_LEAVE
Definition: filesup.c:20
BOOLEAN DoesPathExist_UStr(_In_opt_ HANDLE RootDirectory, _In_ PCUNICODE_STRING PathName, _In_ BOOLEAN IsDirectory)
Definition: filesup.c:695
#define MOVEFILE_WRITE_THROUGH
Definition: filesup.h:30
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:83
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileRenameInformation
Definition: from_kernel.h:71
@ FileBasicInformation
Definition: from_kernel.h:65
@ FileDispositionInformation
Definition: from_kernel.h:74
#define FILE_OPEN
Definition: from_kernel.h:54
#define FILE_CREATE
Definition: from_kernel.h:55
#define FILE_OVERWRITE_IF
Definition: from_kernel.h:58
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define FILE_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
Status
Definition: gdiplustypes.h:25
#define iswdigit(_c)
Definition: ctype.h:667
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define ASSERT(a)
Definition: mode.c:44
#define ULL(a, b)
Definition: format_msg.c:27
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
#define min(a, b)
Definition: monoChain.cc:55
#define _Out_opt_
Definition: ms_sal.h:346
#define _Out_
Definition: ms_sal.h:345
#define _In_
Definition: ms_sal.h:308
#define _In_opt_
Definition: ms_sal.h:309
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_opt_ PLARGE_INTEGER _In_ ULONG SectionPageProtection
Definition: mmfuncs.h:363
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID _In_ ULONG_PTR _In_ SIZE_T _Inout_opt_ PLARGE_INTEGER _Inout_ PSIZE_T ViewSize
Definition: mmfuncs.h:408
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
#define SEC_COMMIT
Definition: mmtypes.h:100
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3952
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
#define PAGE_READWRITE
Definition: nt_native.h:1304
NTSYSAPI NTSTATUS NTAPI NtWriteFile(IN HANDLE hFile, IN HANDLE hEvent OPTIONAL, IN PIO_APC_ROUTINE IoApcRoutine OPTIONAL, IN PVOID IoApcContext OPTIONAL, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID WriteBuffer, IN ULONG WriteBufferLength, IN PLARGE_INTEGER FileOffset OPTIONAL, IN PULONG LockOperationKey OPTIONAL)
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_LIST_DIRECTORY
Definition: nt_native.h:629
#define SECTION_QUERY
Definition: nt_native.h:1287
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSYSAPI NTSTATUS NTAPI NtSetInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
Definition: iofunc.c:3096
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
@ ViewUnmap
Definition: nt_native.h:1279
@ ViewShare
Definition: nt_native.h:1278
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
#define DELETE
Definition: nt_native.h:57
NTSTATUS NTAPI NtCreateFile(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PLARGE_INTEGER AllocationSize OPTIONAL, IN ULONG FileAttributes, IN ULONG ShareAccess, IN ULONG CreateDisposition, IN ULONG CreateOptions, IN PVOID EaBuffer OPTIONAL, IN ULONG EaLength)
#define GENERIC_WRITE
Definition: nt_native.h:90
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
CONST WCHAR * PCWCH
Definition: ntbasedef.h:411
#define UNICODE_NULL
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
NTSTRSAFEAPI RtlStringCchCatW(_Inout_updates_(cchDest) _Always_(_Post_z_) NTSTRSAFE_PWSTR pszDest, _In_ size_t cchDest, _In_ NTSTRSAFE_PCWSTR pszSrc)
Definition: ntstrsafe.h:601
#define L(x)
Definition: ntvdm.h:50
#define FileStandardInformation
Definition: propsheet.cpp:61
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:73
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG
Definition: typedefs.h:59
const uint16_t * PCWSTR
Definition: typedefs.h:57
ULONG_PTR SIZE_T
Definition: typedefs.h:80
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
struct _LARGE_INTEGER::@2299 u
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ PSTRING FullName
Definition: rtlfuncs.h:1648
__wchar_t WCHAR
Definition: xmlstorage.h:180