ReactOS 0.4.16-dev-588-gf07ea94
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#include <pseh/pseh2.h>
14
15#define NDEBUG
16#include <debug.h>
17
18/* FUNCTIONS ****************************************************************/
19
20static
23 _In_ PCUNICODE_STRING DirectoryName)
24{
26 UNICODE_STRING PathName = *DirectoryName;
30
31 /* Remove the trailing separator if needed */
32 if (PathName.Length >= 2 * sizeof(WCHAR) &&
33 PathName.Buffer[PathName.Length / sizeof(WCHAR) - 1] == OBJ_NAME_PATH_SEPARATOR)
34 {
35 PathName.Length -= sizeof(WCHAR);
36 }
37
39 &PathName,
41 NULL,
42 NULL);
43
48 NULL,
53 NULL,
54 0);
55 if (NT_SUCCESS(Status))
57
58 return Status;
59}
60
73 _In_ PCWSTR PathName)
74{
76 UNICODE_STRING PathNameU;
78 PCWCH Ptr, End;
79
80 RtlInitUnicodeString(&PathNameU, PathName);
81 Buffer = PathNameU.Buffer;
82 End = Buffer + (PathNameU.Length / sizeof(WCHAR));
83
84 /* Find the deepest existing sub-directory: start from the
85 * end and go back, verifying each sub-directory in turn */
86 for (Ptr = End; Ptr > Buffer;)
87 {
88 BOOLEAN bExists;
89
90 /* If we are on a separator, truncate at the next character.
91 * The trailing separator is kept for the existence check. */
92 if ((Ptr < End) && (*Ptr == OBJ_NAME_PATH_SEPARATOR))
93 PathNameU.Length = (ULONG_PTR)(Ptr+1) - (ULONG_PTR)Buffer;
94
95 /* Check if the sub-directory exists and stop
96 * if so: this is the deepest existing one */
97 DPRINT("PathName: %wZ\n", &PathNameU);
98 bExists = DoesPathExist_UStr(NULL, &PathNameU, TRUE);
99 if (bExists)
100 break;
101
102 /* Skip back any consecutive path separators */
103 while ((Ptr > Buffer) && (*Ptr == OBJ_NAME_PATH_SEPARATOR))
104 --Ptr;
105 /* Go to the beginning of the path component, stop at the separator */
106 while ((Ptr > Buffer) && (*Ptr != OBJ_NAME_PATH_SEPARATOR))
107 --Ptr;
108 }
109
110 /* Skip any consecutive path separators */
111 while ((Ptr < End) && (*Ptr == OBJ_NAME_PATH_SEPARATOR))
112 ++Ptr;
113
114 /* Create all the remaining sub-directories */
115 for (; Ptr < End; ++Ptr)
116 {
117 /* Go to the end of the current path component, stop at
118 * the separator or terminating NUL and truncate it */
119 while ((Ptr < End) && (*Ptr != OBJ_NAME_PATH_SEPARATOR))
120 ++Ptr;
121 PathNameU.Length = (ULONG_PTR)Ptr - (ULONG_PTR)Buffer;
122
123 DPRINT("Create: %wZ\n", &PathNameU);
125 if (!NT_SUCCESS(Status))
126 break;
127 }
128
129 DPRINT("Done.\n");
130 return Status;
131}
132
136 IN BOOLEAN ForceDelete) // ForceDelete can be used to delete read-only files
137{
139 UNICODE_STRING NtPathU;
143 FILE_DISPOSITION_INFORMATION FileDispInfo;
144 BOOLEAN RetryOnce = FALSE;
145
146 /* Open the directory name that was passed in */
149 &NtPathU,
151 NULL,
152 NULL);
153
154Retry: // We go back there once if RetryOnce == TRUE
157 (RetryOnce ? FILE_WRITE_ATTRIBUTES : 0),
162 if (!NT_SUCCESS(Status))
163 {
164 DPRINT1("NtOpenFile failed with Status 0x%08lx\n", Status);
165 return Status;
166 }
167
168 if (RetryOnce)
169 {
171
177 if (!NT_SUCCESS(Status))
178 {
179 DPRINT1("NtQueryInformationFile failed with Status 0x%08lx\n", Status);
181 return Status;
182 }
183
184 FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
191 if (!NT_SUCCESS(Status))
192 {
193 DPRINT1("NtSetInformationFile failed with Status 0x%08lx\n", Status);
194 return Status;
195 }
196 }
197
198 /* Ask for the file to be deleted */
199 FileDispInfo.DeleteFile = TRUE;
202 &FileDispInfo,
206
207 if (!NT_SUCCESS(Status))
208 DPRINT1("Deletion of file '%S' failed, Status 0x%08lx\n", FileName, Status);
209
210 // FIXME: Check the precise value of Status!
211 if (!NT_SUCCESS(Status) && ForceDelete && !RetryOnce)
212 {
213 /* Retry once */
214 RetryOnce = TRUE;
215 goto Retry;
216 }
217
218 /* Return result to the caller */
219 return Status;
220}
221
224 IN PCWSTR SourceFileName,
225 IN PCWSTR DestinationFileName,
226 IN BOOLEAN FailIfExists)
227{
231 HANDLE FileHandleSource;
232 HANDLE FileHandleDest;
234 FILE_STANDARD_INFORMATION FileStandard;
235 FILE_BASIC_INFORMATION FileBasic;
237 HANDLE SourceFileSection;
238 PVOID SourceFileMap = NULL;
239 SIZE_T SourceSectionSize = 0;
241
242 RtlInitUnicodeString(&FileName, SourceFileName);
244 &FileName,
246 NULL,
247 NULL);
248
249 Status = NtOpenFile(&FileHandleSource,
255 if (!NT_SUCCESS(Status))
256 {
257 DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
258 goto done;
259 }
260
261 Status = NtQueryInformationFile(FileHandleSource,
263 &FileStandard,
266 if (!NT_SUCCESS(Status))
267 {
268 DPRINT1("NtQueryInformationFile failed: %x\n", Status);
269 goto closesrc;
270 }
271
272 Status = NtQueryInformationFile(FileHandleSource,
274 &FileBasic,
277 if (!NT_SUCCESS(Status))
278 {
279 DPRINT1("NtQueryInformationFile failed: %x\n", Status);
280 goto closesrc;
281 }
282
283 Status = NtCreateSection(&SourceFileSection,
285 NULL,
286 NULL,
289 FileHandleSource);
290 if (!NT_SUCCESS(Status))
291 {
292 DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
293 goto closesrc;
294 }
295
296 Status = NtMapViewOfSection(SourceFileSection,
298 &SourceFileMap,
299 0,
300 0,
301 NULL,
302 &SourceSectionSize,
303 ViewUnmap,
304 0,
306 if (!NT_SUCCESS(Status))
307 {
308 DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
309 goto closesrcsec;
310 }
311
312 RtlInitUnicodeString(&FileName, DestinationFileName);
314 &FileName,
316 NULL,
317 NULL);
318
319 Status = NtCreateFile(&FileHandleDest,
323 NULL,
324 FileBasic.FileAttributes, // FILE_ATTRIBUTE_NORMAL,
325 0,
326 FailIfExists ? FILE_CREATE : FILE_OVERWRITE_IF,
330 NULL,
331 0);
332 if (!NT_SUCCESS(Status))
333 {
334 /*
335 * Open may have failed because the file to overwrite
336 * is in readonly mode.
337 */
339 {
340 FILE_BASIC_INFORMATION FileBasicInfo;
341
342 /* Reattempt to open it with limited access */
343 Status = NtCreateFile(&FileHandleDest,
347 NULL,
349 0,
350 FILE_OPEN,
354 NULL,
355 0);
356 /* Fail for real if we cannot open it that way */
357 if (!NT_SUCCESS(Status))
358 {
359 DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
360 goto unmapsrcsec;
361 }
362
363 /* Zero our basic info, just to set attributes */
364 RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
365 /* Reset attributes to normal, no read-only */
367 /*
368 * We basically don't care about whether it succeed:
369 * if it didn't, later open will fail.
370 */
371 NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasicInfo,
372 sizeof(FileBasicInfo), FileBasicInformation);
373
374 /* Close file */
375 NtClose(FileHandleDest);
376
377 /* And re-attempt overwrite */
378 Status = NtCreateFile(&FileHandleDest,
382 NULL,
384 0,
389 NULL,
390 0);
391 }
392
393 /* We failed */
394 if (!NT_SUCCESS(Status))
395 {
396 DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
397 goto unmapsrcsec;
398 }
399 }
400
401 RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
403 ByteOffset.QuadPart = 0ULL;
404 Status = NtWriteFile(FileHandleDest,
405 NULL,
406 NULL,
407 NULL,
409 SourceFileMap,
411 &ByteOffset,
412 NULL);
413 if (!NT_SUCCESS(Status))
414 {
415 DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n",
417 goto closedest;
418 }
419
420 /* Copy file date/time from source file */
421 Status = NtSetInformationFile(FileHandleDest,
423 &FileBasic,
426 if (!NT_SUCCESS(Status))
427 {
428 DPRINT1("NtSetInformationFile failed: %x\n", Status);
429 goto closedest;
430 }
431
432 /* Shorten the file back to its real size after completing the write */
433 Status = NtSetInformationFile(FileHandleDest,
435 &FileStandard.EndOfFile,
438 if (!NT_SUCCESS(Status))
439 {
440 DPRINT1("NtSetInformationFile failed: %x\n", Status);
441 }
442
443closedest:
444 NtClose(FileHandleDest);
445
446unmapsrcsec:
447 NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);
448
449closesrcsec:
450 NtClose(SourceFileSection);
451
452closesrc:
453 NtClose(FileHandleSource);
454
455done:
456 return Status;
457}
458
459/*
460 * Synchronized with its kernel32 counterpart, but we don't manage reparse points here.
461 */
464 IN PCWSTR ExistingFileName,
465 IN PCWSTR NewFileName,
466 IN ULONG Flags)
467{
471 PFILE_RENAME_INFORMATION RenameInfo;
472 UNICODE_STRING NewPathU, ExistingPathU;
474 BOOLEAN ReplaceIfExists;
475
476 RtlInitUnicodeString(&ExistingPathU, ExistingFileName);
477 RtlInitUnicodeString(&NewPathU, NewFileName);
478
480 {
481 ReplaceIfExists = !!(Flags & MOVEFILE_REPLACE_EXISTING);
482
483 /* Unless we manage a proper opening, we'll attempt to reopen without reparse support */
485 &ExistingPathU,
487 NULL,
488 NULL);
489 /* Attempt to open source file */
496 if (!NT_SUCCESS(Status))
497 {
499 {
501 }
502 }
503
504 /* At that point, we MUST have a source handle */
506
507 /* Allocate renaming buffer and fill it */
508 RenameInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(FILE_RENAME_INFORMATION));
509 if (RenameInfo == NULL)
510 {
513 }
514
515 RtlCopyMemory(&RenameInfo->FileName, NewPathU.Buffer, NewPathU.Length);
516 RenameInfo->ReplaceIfExists = ReplaceIfExists;
517 RenameInfo->RootDirectory = NULL;
518 RenameInfo->FileNameLength = NewPathU.Length;
519
520 /* Attempt to rename the file */
523 RenameInfo,
524 NewPathU.Length + sizeof(FILE_RENAME_INFORMATION),
526 RtlFreeHeap(RtlGetProcessHeap(), 0, RenameInfo);
527 if (NT_SUCCESS(Status))
528 {
529 /* If it succeeded, all fine, quit */
531 }
532 /*
533 * If we failed for any other reason than not the same device, fail.
534 * If we failed because of different devices, only allow renaming
535 * if user allowed copy.
536 */
538 {
539 /* ReactOS hack! To be removed once all FSD have proper renaming support
540 * Just leave status to error and leave
541 */
543 {
544 DPRINT1("Forcing copy, renaming not supported by FSD\n");
545 }
546 else
547 {
549 }
550 }
551
552 /* Close the source file */
555
556 /* Perform the file copy */
557 Status = SetupCopyFile(ExistingFileName,
558 NewFileName,
559 !ReplaceIfExists);
560
561 /* If it succeeded, delete the source file */
562 if (NT_SUCCESS(Status))
563 {
564 /* Force-delete files even if read-only */
565 SetupDeleteFile(ExistingFileName, TRUE);
566 }
567 }
569 {
570 if (SourceHandle)
572 }
573 _SEH2_END;
574
575 return Status;
576}
577
580 IN OUT PWSTR PathBuffer,
581 IN SIZE_T cchPathSize,
582 IN ULONG NumberOfPathComponents,
583 IN va_list PathComponentsList)
584{
586 SIZE_T cchPathLen;
588
589 if (cchPathSize < 1)
590 return STATUS_SUCCESS;
591
592 while (NumberOfPathComponents--)
593 {
594 PathComponent = va_arg(PathComponentsList, PCWSTR);
595 if (!PathComponent)
596 continue;
597
598 cchPathLen = min(cchPathSize, wcslen(PathBuffer));
599 if (cchPathLen >= cchPathSize)
601
603 cchPathLen > 0 && PathBuffer[cchPathLen-1] != OBJ_NAME_PATH_SEPARATOR)
604 {
605 /* PathComponent does not start with '\' and PathBuffer does not end with '\' */
606 Status = RtlStringCchCatW(PathBuffer, cchPathSize, L"\\");
607 if (!NT_SUCCESS(Status))
608 return Status;
609 }
610 else if (PathComponent[0] == OBJ_NAME_PATH_SEPARATOR &&
611 cchPathLen > 0 && PathBuffer[cchPathLen-1] == OBJ_NAME_PATH_SEPARATOR)
612 {
613 /* PathComponent starts with '\' and PathBuffer ends with '\' */
615 ++PathComponent; // Skip any backslash
616 }
617 Status = RtlStringCchCatW(PathBuffer, cchPathSize, PathComponent);
618 if (!NT_SUCCESS(Status))
619 return Status;
620 }
621
622 return Status;
623}
624
627 OUT PWSTR PathBuffer,
628 IN SIZE_T cchPathSize,
629 IN ULONG NumberOfPathComponents,
630 IN va_list PathComponentsList)
631{
632 if (cchPathSize < 1)
633 return STATUS_SUCCESS;
634
635 *PathBuffer = UNICODE_NULL;
636 return ConcatPathsV(PathBuffer, cchPathSize,
637 NumberOfPathComponents,
638 PathComponentsList);
639}
640
643 IN OUT PWSTR PathBuffer,
644 IN SIZE_T cchPathSize,
645 IN ULONG NumberOfPathComponents,
646 IN /* PCWSTR */ ...)
647{
649 va_list PathComponentsList;
650
651 if (cchPathSize < 1)
652 return STATUS_SUCCESS;
653
654 va_start(PathComponentsList, NumberOfPathComponents);
655 Status = ConcatPathsV(PathBuffer, cchPathSize,
656 NumberOfPathComponents,
657 PathComponentsList);
658 va_end(PathComponentsList);
659
660 return Status;
661}
662
665 OUT PWSTR PathBuffer,
666 IN SIZE_T cchPathSize,
667 IN ULONG NumberOfPathComponents,
668 IN /* PCWSTR */ ...)
669{
671 va_list PathComponentsList;
672
673 if (cchPathSize < 1)
674 return STATUS_SUCCESS;
675
676 *PathBuffer = UNICODE_NULL;
677
678 va_start(PathComponentsList, NumberOfPathComponents);
679 Status = CombinePathsV(PathBuffer, cchPathSize,
680 NumberOfPathComponents,
681 PathComponentsList);
682 va_end(PathComponentsList);
683
684 return Status;
685}
686
690 _In_ PCUNICODE_STRING PathName,
692{
697
699 (PUNICODE_STRING)PathName,
702 NULL);
703
706 : FILE_GENERIC_READ, // Contains SYNCHRONIZE
713 if (NT_SUCCESS(Status))
714 {
716 }
717 else
718 {
719 DPRINT("Failed to open %s '%wZ', Status 0x%08lx\n",
720 IsDirectory ? "directory" : "file",
721 PathName, Status);
722 }
723
724 return NT_SUCCESS(Status);
725}
726
730 _In_ PCWSTR PathName,
732{
733 UNICODE_STRING PathNameU;
734 RtlInitUnicodeString(&PathNameU, PathName);
735 return DoesPathExist_UStr(RootDirectory, &PathNameU, IsDirectory);
736}
737
738// FIXME: DEPRECATED! HACKish function that needs to be deprecated!
741 IN PCWSTR PathName OPTIONAL,
743{
746 return DoesFileExist(NULL, FullName);
747}
748
749/*
750 * The format of NtPath should be:
751 * \Device\HarddiskXXX\PartitionYYY[\path] ,
752 * where XXX and YYY respectively represent the hard disk and partition numbers,
753 * and [\path] represent an optional path (separated by '\\').
754 *
755 * If a NT path of such a form is correctly parsed, the function returns respectively:
756 * - in pDiskNumber: the hard disk number XXX,
757 * - in pPartNumber: the partition number YYY,
758 * - in PathComponent: pointer value (inside NtPath) to the beginning of \path.
759 *
760 * NOTE: The function does not accept leading whitespace.
761 */
764 IN PCWSTR NtPath,
765 OUT PULONG pDiskNumber,
766 OUT PULONG pPartNumber,
768{
769 ULONG DiskNumber, PartNumber;
770 PCWSTR Path;
771
772 *pDiskNumber = 0;
773 *pPartNumber = 0;
775
776 Path = NtPath;
777
778 if (_wcsnicmp(Path, L"\\Device\\Harddisk", 16) != 0)
779 {
780 /* The NT path doesn't start with the prefix string, thus it cannot be a hard disk device path */
781 DPRINT1("'%S' : Not a possible hard disk device.\n", NtPath);
782 return FALSE;
783 }
784
785 Path += 16;
786
787 /* A number must be present now */
788 if (!iswdigit(*Path))
789 {
790 DPRINT1("'%S' : expected a number! Not a regular hard disk device.\n", Path);
791 return FALSE;
792 }
793 DiskNumber = wcstoul(Path, (PWSTR*)&Path, 10);
794
795 /* Either NULL termination, or a path separator must be present now */
797 {
798 DPRINT1("'%S' : expected a path separator!\n", Path);
799 return FALSE;
800 }
801
802 if (!*Path)
803 {
804 DPRINT1("The path only specified a hard disk (and nothing else, like a partition...), so we stop there.\n");
805 goto Quit;
806 }
807
808 /* Here, *Path == L'\\' */
809
810 if (_wcsnicmp(Path, L"\\Partition", 10) != 0)
811 {
812 /* Actually, \Partition is optional so, if we don't have it, we still return success. Or should we? */
813 DPRINT1("'%S' : unexpected format!\n", NtPath);
814 goto Quit;
815 }
816
817 Path += 10;
818
819 /* A number must be present now */
820 if (!iswdigit(*Path))
821 {
822 /* 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? */
823 DPRINT1("'%S' : expected a number!\n", Path);
824 goto Quit;
825 }
826 PartNumber = wcstoul(Path, (PWSTR*)&Path, 10);
827
828 /* Either NULL termination, or a path separator must be present now */
830 {
831 /* We shouldn't fail here because it just means this part of path is actually not a partition specifier. Or should we? */
832 DPRINT1("'%S' : expected a path separator!\n", Path);
833 goto Quit;
834 }
835
836 /* OK, here we really have a partition specifier: return its number */
837 *pPartNumber = PartNumber;
838
839Quit:
840 /* Return the disk number */
841 *pDiskNumber = DiskNumber;
842
843 /* Return the path component also, if the user wants it */
845
846 return TRUE;
847}
848
881 _In_ PCWSTR PathNameToFile,
884 _Out_ PHANDLE SectionHandle,
886 _In_ BOOLEAN ReadWriteAccess)
887{
892 HANDLE LocalFileHandle;
893
894 /* Open the file */
895 RtlInitUnicodeString(&FileName, PathNameToFile);
897 &FileName,
900 NULL);
901
902 if (FileHandle) *FileHandle = NULL;
903 Status = NtOpenFile(&LocalFileHandle,
904 FILE_GENERIC_READ | // Contains SYNCHRONIZE
905 (ReadWriteAccess ? FILE_GENERIC_WRITE : 0),
910 if (!NT_SUCCESS(Status))
911 {
912 DPRINT1("Failed to open file '%wZ' (Status 0x%08lx)\n", &FileName, Status);
913 return Status;
914 }
915
916 if (FileSize)
917 {
918 /* Query the file size */
920 Status = NtQueryInformationFile(LocalFileHandle,
922 &FileInfo,
923 sizeof(FileInfo),
925 if (!NT_SUCCESS(Status))
926 {
927 DPRINT("NtQueryInformationFile() failed (Status 0x%08lx)\n", Status);
928 goto Quit;
929 }
930
931 if (FileInfo.EndOfFile.HighPart != 0)
932 DPRINT1("WARNING!! The file '%wZ' is too large!\n", &FileName);
933
934 *FileSize = FileInfo.EndOfFile.LowPart;
935 DPRINT("File size: %lu\n", *FileSize);
936 }
937
938 /* Map the whole file into memory */
939 Status = MapFile(LocalFileHandle,
940 SectionHandle,
942 ReadWriteAccess);
943 if (!NT_SUCCESS(Status))
944 {
945 DPRINT1("Failed to map file '%wZ' (Status 0x%08lx)\n", &FileName, Status);
946 goto Quit;
947 }
948
949Quit:
950 /* If we succeeded, return the opened file handle if needed.
951 * If we failed or the caller does not need the handle, close it now. */
953 *FileHandle = LocalFileHandle;
954 else
955 NtClose(LocalFileHandle);
956
957 return Status;
958}
959
983 _Out_ PHANDLE SectionHandle,
985 _In_ BOOLEAN ReadWriteAccess)
986{
990 PVOID ViewBase;
991
992 SectionPageProtection = (ReadWriteAccess ? PAGE_READWRITE : PAGE_READONLY);
993
994 /* Create the section */
995 *SectionHandle = NULL;
996 Status = NtCreateSection(SectionHandle,
999 (ReadWriteAccess ? SECTION_MAP_WRITE : 0),
1000 NULL,
1001 NULL,
1003 SEC_COMMIT /* | SEC_IMAGE (_NO_EXECUTE) */,
1004 FileHandle);
1005 if (!NT_SUCCESS(Status))
1006 {
1007 DPRINT1("Failed to create a memory section for file 0x%p (Status 0x%08lx)\n",
1009 return Status;
1010 }
1011
1012 /* Map the section */
1013 ViewSize = 0;
1014 ViewBase = NULL;
1015 Status = NtMapViewOfSection(*SectionHandle,
1017 &ViewBase,
1018 0, 0,
1019 NULL,
1020 &ViewSize,
1021 ViewShare,
1022 0,
1024 if (!NT_SUCCESS(Status))
1025 {
1026 DPRINT1("Failed to map a view for file 0x%p (Status 0x%08lx)\n",
1028 NtClose(*SectionHandle);
1029 *SectionHandle = NULL;
1030 return Status;
1031 }
1032
1033 *BaseAddress = ViewBase;
1034 return STATUS_SUCCESS;
1035}
1036
1050BOOLEAN
1052 _In_ HANDLE SectionHandle,
1054{
1057
1059 if (!NT_SUCCESS(Status))
1060 {
1061 DPRINT1("NtUnmapViewOfSection(0x%p) failed (Status 0x%08lx)\n",
1063 Success = FALSE;
1064 }
1065 Status = NtClose(SectionHandle);
1066 if (!NT_SUCCESS(Status))
1067 {
1068 DPRINT1("NtClose(0x%p) failed (Status 0x%08lx)\n",
1069 SectionHandle, Status);
1070 Success = FALSE;
1071 }
1072
1073 return Success;
1074}
1075
1076/* 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 STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#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:732
struct _FileName FileName
Definition: fatprocs.h:897
BOOLEAN DoesPathExist(_In_opt_ HANDLE RootDirectory, _In_ PCWSTR PathName, _In_ BOOLEAN IsDirectory)
Definition: filesup.c:728
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:664
NTSTATUS MapFile(_In_ HANDLE FileHandle, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
Maps an opened file in memory.
Definition: filesup.c:981
static NTSTATUS SetupCreateSingleDirectory(_In_ PCUNICODE_STRING DirectoryName)
Definition: filesup.c:22
BOOLEAN DoesFileExist_2(IN PCWSTR PathName OPTIONAL, IN PCWSTR FileName)
Definition: filesup.c:740
BOOLEAN NtPathToDiskPartComponents(IN PCWSTR NtPath, OUT PULONG pDiskNumber, OUT PULONG pPartNumber, OUT PCWSTR *PathComponent OPTIONAL)
Definition: filesup.c:763
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:879
NTSTATUS ConcatPathsV(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:579
NTSTATUS CombinePathsV(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:626
NTSTATUS SetupMoveFile(IN PCWSTR ExistingFileName, IN PCWSTR NewFileName, IN ULONG Flags)
Definition: filesup.c:463
NTSTATUS SetupCreateDirectory(_In_ PCWSTR PathName)
Create a new directory, specified by the given path. Any intermediate non-existing directory is creat...
Definition: filesup.c:72
NTSTATUS ConcatPaths(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:642
BOOLEAN UnMapFile(_In_ HANDLE SectionHandle, _In_ PVOID BaseAddress)
Unmaps a mapped file by section.
Definition: filesup.c:1051
NTSTATUS SetupCopyFile(IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
Definition: filesup.c:223
NTSTATUS SetupDeleteFile(IN PCWSTR FileName, IN BOOLEAN ForceDelete)
Definition: filesup.c:134
BOOLEAN DoesPathExist_UStr(_In_opt_ HANDLE RootDirectory, _In_ PCUNICODE_STRING PathName, _In_ BOOLEAN IsDirectory)
Definition: filesup.c:688
#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
_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
#define _Out_opt_
Definition: no_sal2.h:214
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
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:3953
#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:419
#define UNICODE_NULL
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#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 _SEH2_FINALLY
Definition: pseh2_64.h:114
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_LEAVE
Definition: pseh2_64.h:167
_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 FileStandardInformation
Definition: propsheet.cpp:61
#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::@2306 u
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_ PSTRING FullName
Definition: rtlfuncs.h:1665
__wchar_t WCHAR
Definition: xmlstorage.h:180