ReactOS 0.4.16-dev-319-g6cf4263
filesup.c File Reference
#include "precomp.h"
#include "filesup.h"
#include <pseh/pseh2.h>
#include <debug.h>
Include dependency graph for filesup.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

static NTSTATUS SetupCreateSingleDirectory (_In_ PCUNICODE_STRING DirectoryName)
 
NTSTATUS SetupCreateDirectory (_In_ PCWSTR PathName)
 Create a new directory, specified by the given path. Any intermediate non-existing directory is created as well.
 
NTSTATUS SetupDeleteFile (IN PCWSTR FileName, IN BOOLEAN ForceDelete)
 
NTSTATUS SetupCopyFile (IN PCWSTR SourceFileName, IN PCWSTR DestinationFileName, IN BOOLEAN FailIfExists)
 
NTSTATUS SetupMoveFile (IN PCWSTR ExistingFileName, IN PCWSTR NewFileName, IN ULONG Flags)
 
NTSTATUS ConcatPathsV (IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
 
NTSTATUS CombinePathsV (OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
 
NTSTATUS ConcatPaths (IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
 
NTSTATUS CombinePaths (OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
 
BOOLEAN DoesPathExist_UStr (_In_opt_ HANDLE RootDirectory, _In_ PCUNICODE_STRING PathName, _In_ BOOLEAN IsDirectory)
 
BOOLEAN DoesPathExist (_In_opt_ HANDLE RootDirectory, _In_ PCWSTR PathName, _In_ BOOLEAN IsDirectory)
 
BOOLEAN DoesFileExist_2 (IN PCWSTR PathName OPTIONAL, IN PCWSTR FileName)
 
BOOLEAN NtPathToDiskPartComponents (IN PCWSTR NtPath, OUT PULONG pDiskNumber, OUT PULONG pPartNumber, OUT PCWSTR *PathComponent OPTIONAL)
 
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.
 
NTSTATUS MapFile (_In_ HANDLE FileHandle, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
 Maps an opened file in memory.
 
BOOLEAN UnMapFile (_In_ HANDLE SectionHandle, _In_ PVOID BaseAddress)
 Unmaps a mapped file by section.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file filesup.c.

Function Documentation

◆ CombinePaths()

NTSTATUS CombinePaths ( OUT PWSTR  PathBuffer,
IN SIZE_T  cchPathSize,
IN ULONG  NumberOfPathComponents,
IN ...   
)

Definition at line 664 of file filesup.c.

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}
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS CombinePathsV(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:626
Status
Definition: gdiplustypes.h:25
#define UNICODE_NULL
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by AddSectionToCopyQueue(), AddSectionToCopyQueueCab(), BuildFullDirectoryPath(), CheckUnattendedSetup(), ConnectRegistry(), CreateRegistryFile(), DoesFileExist_2(), ImportRegistryFile(), InitDestinationPaths(), InstallBootloaderFiles(), InstallBootManagerAndBootEntriesWorker(), InstallBtrfsBootcodeToPartition(), InstallFatBootcodeToPartition(), InstallMbrBootCodeToDisk(), InstallNtfsBootcodeToPartition(), InstallSetupInfFile(), LoadSetupInf(), PrepareFileCopy(), RegCleanupRegistry(), and SetupCommitFileQueueW().

◆ CombinePathsV()

NTSTATUS CombinePathsV ( OUT PWSTR  PathBuffer,
IN SIZE_T  cchPathSize,
IN ULONG  NumberOfPathComponents,
IN va_list  PathComponentsList 
)

Definition at line 626 of file filesup.c.

631{
632 if (cchPathSize < 1)
633 return STATUS_SUCCESS;
634
635 *PathBuffer = UNICODE_NULL;
636 return ConcatPathsV(PathBuffer, cchPathSize,
637 NumberOfPathComponents,
638 PathComponentsList);
639}
NTSTATUS ConcatPathsV(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:579

Referenced by CombinePaths().

◆ ConcatPaths()

NTSTATUS ConcatPaths ( IN OUT PWSTR  PathBuffer,
IN SIZE_T  cchPathSize,
IN ULONG  NumberOfPathComponents,
IN ...   
)

Definition at line 642 of file filesup.c.

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}

Referenced by ArcPathToNtPath(), InitDestinationPaths(), and SetupCommitFileQueueW().

◆ ConcatPathsV()

NTSTATUS ConcatPathsV ( IN OUT PWSTR  PathBuffer,
IN SIZE_T  cchPathSize,
IN ULONG  NumberOfPathComponents,
IN va_list  PathComponentsList 
)

Definition at line 579 of file filesup.c.

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}
#define va_arg(ap, T)
Definition: acmsvcex.h:89
#define OBJ_NAME_PATH_SEPARATOR
Definition: arcname_tests.c:25
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define min(a, b)
Definition: monoChain.cc:55
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 STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
const uint16_t * PCWSTR
Definition: typedefs.h:57
ULONG_PTR SIZE_T
Definition: typedefs.h:80

Referenced by CombinePathsV(), and ConcatPaths().

◆ DoesFileExist_2()

BOOLEAN DoesFileExist_2 ( IN PCWSTR PathName  OPTIONAL,
IN PCWSTR  FileName 
)

Definition at line 740 of file filesup.c.

743{
746 return DoesFileExist(NULL, FullName);
747}
#define NULL
Definition: types.h:112
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define MAX_PATH
Definition: compat.h:34
NTSTATUS CombinePaths(OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN ...)
Definition: filesup.c:664
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:83
_In_ PSTRING FullName
Definition: rtlfuncs.h:1665
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by InstallBtrfsBootcodeToPartition(), InstallFatBootcodeToPartition(), and InstallNtfsBootcodeToPartition().

◆ DoesPathExist()

BOOLEAN DoesPathExist ( _In_opt_ HANDLE  RootDirectory,
_In_ PCWSTR  PathName,
_In_ BOOLEAN  IsDirectory 
)

Definition at line 728 of file filesup.c.

732{
733 UNICODE_STRING PathNameU;
734 RtlInitUnicodeString(&PathNameU, PathName);
735 return DoesPathExist_UStr(RootDirectory, &PathNameU, IsDirectory);
736}
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
BOOLEAN DoesPathExist_UStr(_In_opt_ HANDLE RootDirectory, _In_ PCUNICODE_STRING PathName, _In_ BOOLEAN IsDirectory)
Definition: filesup.c:688
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)

◆ DoesPathExist_UStr()

BOOLEAN DoesPathExist_UStr ( _In_opt_ HANDLE  RootDirectory,
_In_ PCUNICODE_STRING  PathName,
_In_ BOOLEAN  IsDirectory 
)

Definition at line 688 of file filesup.c.

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}
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FILE_SHARE_READ
Definition: compat.h:136
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
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 FILE_LIST_DIRECTORY
Definition: nt_native.h:629
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define DPRINT
Definition: sndvol32.h:73

Referenced by DoesPathExist(), and SetupCreateDirectory().

◆ MapFile()

NTSTATUS MapFile ( _In_ HANDLE  FileHandle,
_Out_ PHANDLE  SectionHandle,
_Out_ PVOID BaseAddress,
_In_ BOOLEAN  ReadWriteAccess 
)

Maps an opened file in memory.

Parameters
[in]FileHandleA handle to an opened file to map.
[out]SectionHandleA pointer to a variable receiving a handle to a section mapping the file.
[out]BaseAddressA pointer to a variable receiving the address where the file is mapped.
[in]ReadWriteAccessA boolean variable specifying whether to map the file for read and write access (TRUE), or read-only access (FALSE).
Returns
STATUS_SUCCESS in case of success, or a status code in case of error.

Definition at line 981 of file filesup.c.

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}
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
#define DPRINT1
Definition: precomp.h:8
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
_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
#define SEC_COMMIT
Definition: mmtypes.h:100
#define SECTION_MAP_WRITE
Definition: nt_native.h:1288
#define PAGE_READWRITE
Definition: nt_native.h:1304
#define SECTION_QUERY
Definition: nt_native.h:1287
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ ViewShare
Definition: nt_native.h:1278
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
uint32_t ULONG
Definition: typedefs.h:59

Referenced by OpenAndMapFile(), and OpenIniBootLoaderStore().

◆ NtPathToDiskPartComponents()

BOOLEAN NtPathToDiskPartComponents ( IN PCWSTR  NtPath,
OUT PULONG  pDiskNumber,
OUT PULONG  pPartNumber,
OUT PCWSTR *PathComponent  OPTIONAL 
)

Definition at line 763 of file filesup.c.

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}
PRTL_UNICODE_STRING_BUFFER Path
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#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)
_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)
uint16_t * PWSTR
Definition: typedefs.h:56

Referenced by CreateFreeLoaderIniForReactOSAndBootSector(), and EnumerateInstallations().

◆ OpenAndMapFile()

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.

Parameters
[in]RootDirectory
[in]PathNameToFilePath to the file, either in absolute form, or relative to the opened root directory given by the RootDirectory handle.
[out]FileHandleAn optional pointer to a variable receiving a handle to the opened file. If NULL, the underlying file handle is closed.
[out]FileSizeAn optional pointer to a variable receiving the size of the opened file.
[out]SectionHandleA pointer to a variable receiving a handle to a section mapping the file.
[out]BaseAddressA pointer to a variable receiving the address where the file is mapped.
[in]ReadWriteAccessA boolean variable specifying whether to map the file for read and write access (TRUE), or read-only access (FALSE).
Returns
STATUS_SUCCESS in case of success, or a status code in case of error.

Definition at line 879 of file filesup.c.

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}
struct _FileName FileName
Definition: fatprocs.h:897
NTSTATUS MapFile(_In_ HANDLE FileHandle, _Out_ PHANDLE SectionHandle, _Out_ PVOID *BaseAddress, _In_ BOOLEAN ReadWriteAccess)
Maps an opened file in memory.
Definition: filesup.c:981
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
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_GENERIC_WRITE
Definition: nt_native.h:660
#define FileStandardInformation
Definition: propsheet.cpp:61

Referenced by CheckForValidPEAndVendor(), FindBootStore(), and InstallSetupInfFile().

◆ SetupCopyFile()

NTSTATUS SetupCopyFile ( IN PCWSTR  SourceFileName,
IN PCWSTR  DestinationFileName,
IN BOOLEAN  FailIfExists 
)

Definition at line 223 of file filesup.c.

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}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3481
#define GENERIC_READ
Definition: compat.h:135
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
IN PDCB IN PCCB IN VBO IN OUT PULONG OUT PDIRENT OUT PBCB OUT PVBO ByteOffset
Definition: fatprocs.h:732
@ FileEndOfFileInformation
Definition: from_kernel.h:81
@ FileBasicInformation
Definition: from_kernel.h:65
#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_NO_INTERMEDIATE_BUFFERING
Definition: from_kernel.h:28
#define FILE_SEQUENTIAL_ONLY
Definition: from_kernel.h:27
#define ULL(a, b)
Definition: format_msg.c:27
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
#define PAGE_ROUND_UP(x)
Definition: mmtypes.h:38
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)
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
@ ViewUnmap
Definition: nt_native.h:1279
#define FILE_WRITE_ATTRIBUTES
Definition: nt_native.h:649
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 RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
struct _LARGE_INTEGER::@2303 u

Referenced by InstallBootloaderFiles(), RegCleanupRegistry(), SetupCommitFileQueueW(), and SetupMoveFile().

◆ SetupCreateDirectory()

NTSTATUS SetupCreateDirectory ( _In_ PCWSTR  PathName)

Create a new directory, specified by the given path. Any intermediate non-existing directory is created as well.

Parameters
[in]PathNameThe path of the directory to be created.
Returns
An NTSTATUS code indicating success or failure.

Definition at line 72 of file filesup.c.

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}
unsigned char BOOLEAN
Definition: bufpool.h:45
#define ULONG_PTR
Definition: config.h:101
static NTSTATUS SetupCreateSingleDirectory(_In_ PCUNICODE_STRING DirectoryName)
Definition: filesup.c:22
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
CONST WCHAR * PCWCH
Definition: ntbasedef.h:419
uint32_t ULONG_PTR
Definition: typedefs.h:65

Referenced by PrepareCopyInfFile().

◆ SetupCreateSingleDirectory()

static NTSTATUS SetupCreateSingleDirectory ( _In_ PCUNICODE_STRING  DirectoryName)
static

Definition at line 22 of file filesup.c.

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}
static HANDLE DirectoryHandle
Definition: ObType.c:48
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705

Referenced by SetupCreateDirectory().

◆ SetupDeleteFile()

NTSTATUS SetupDeleteFile ( IN PCWSTR  FileName,
IN BOOLEAN  ForceDelete 
)

Definition at line 134 of file filesup.c.

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}
_In_ PSCSI_REQUEST_BLOCK _Out_ NTSTATUS _Inout_ BOOLEAN * Retry
Definition: classpnp.h:312
@ FileDispositionInformation
Definition: from_kernel.h:74
static OUT PIO_STATUS_BLOCK OUT PVOID FileInformation
Definition: pipe.c:75
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define DELETE
Definition: nt_native.h:57

Referenced by SetupCommitFileQueueW(), and SetupMoveFile().

◆ SetupMoveFile()

NTSTATUS SetupMoveFile ( IN PCWSTR  ExistingFileName,
IN PCWSTR  NewFileName,
IN ULONG  Flags 
)

Definition at line 463 of file filesup.c.

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}
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
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
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
#define MOVEFILE_WRITE_THROUGH
Definition: filesup.h:30
#define MOVEFILE_REPLACE_EXISTING
Definition: filesup.h:28
#define MOVEFILE_COPY_ALLOWED
Definition: filesup.h:29
@ FileRenameInformation
Definition: from_kernel.h:71
#define FILE_WRITE_THROUGH
Definition: from_kernel.h:26
#define ASSERT(a)
Definition: mode.c:44
_In_ HANDLE SourceHandle
Definition: obfuncs.h:429
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
#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
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

Referenced by CreateRegistryFile(), and SetupCommitFileQueueW().

◆ UnMapFile()

BOOLEAN UnMapFile ( _In_ HANDLE  SectionHandle,
_In_ PVOID  BaseAddress 
)

Unmaps a mapped file by section.

Parameters
[in]SectionHandleThe handle to the section mapping the file.
[in]BaseAddressThe base address where the file is mapped.
Returns
TRUE if the file was successfully unmapped; FALSE if an error occurred.

Definition at line 1051 of file filesup.c.

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}
@ Success
Definition: eventcreate.c:712