ReactOS 0.4.16-dev-91-g764881a
filesup.c File Reference
#include "precomp.h"
#include "filesup.h"
#include <debug.h>
Include dependency graph for filesup.c:

Go to the source code of this file.

Macros

#define NDEBUG
 
#define _SEH2_TRY
 
#define _SEH2_LEAVE   goto __SEH2_FINALLY__label;
 
#define _SEH2_FINALLY   __SEH2_FINALLY__label:
 
#define _SEH2_END
 

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

◆ _SEH2_END

#define _SEH2_END

Definition at line 22 of file filesup.c.

◆ _SEH2_FINALLY

#define _SEH2_FINALLY   __SEH2_FINALLY__label:

Definition at line 21 of file filesup.c.

◆ _SEH2_LEAVE

#define _SEH2_LEAVE   goto __SEH2_FINALLY__label;

Definition at line 20 of file filesup.c.

◆ _SEH2_TRY

#define _SEH2_TRY

Definition at line 19 of file filesup.c.

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file filesup.c.

Function Documentation

◆ CombinePaths()

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

Definition at line 671 of file filesup.c.

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}
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:633
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(), InstallBtrfsBootcodeToPartition(), InstallFatBootcodeToFloppy(), 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 633 of file filesup.c.

638{
639 if (cchPathSize < 1)
640 return STATUS_SUCCESS;
641
642 *PathBuffer = UNICODE_NULL;
643 return ConcatPathsV(PathBuffer, cchPathSize,
644 NumberOfPathComponents,
645 PathComponentsList);
646}
NTSTATUS ConcatPathsV(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:586

Referenced by CombinePaths().

◆ ConcatPaths()

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

Definition at line 649 of file filesup.c.

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}

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 586 of file filesup.c.

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}
#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 747 of file filesup.c.

750{
753 return DoesFileExist(NULL, FullName);
754}
#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:671
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:83
_In_ PSTRING FullName
Definition: rtlfuncs.h:1662
__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 735 of file filesup.c.

739{
740 UNICODE_STRING PathNameU;
741 RtlInitUnicodeString(&PathNameU, PathName);
742 return DoesPathExist_UStr(RootDirectory, &PathNameU, IsDirectory);
743}
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:695
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 695 of file filesup.c.

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}
#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 988 of file filesup.c.

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}
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 770 of file filesup.c.

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}
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 886 of file filesup.c.

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}
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:988
_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 230 of file filesup.c.

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}
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::@2299 u

Referenced by InstallBtrfsBootcodeToPartition(), InstallFatBootcodeToFloppy(), InstallFatBootcodeToPartition(), InstallNtfsBootcodeToPartition(), 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 79 of file filesup.c.

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

Referenced by PrepareCopyInfFile().

◆ SetupCreateSingleDirectory()

static NTSTATUS SetupCreateSingleDirectory ( _In_ PCUNICODE_STRING  DirectoryName)
static

Definition at line 29 of file filesup.c.

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}
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 141 of file filesup.c.

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}
_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 470 of file filesup.c.

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}
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 _SEH2_FINALLY
Definition: filesup.c:21
#define _SEH2_END
Definition: filesup.c:22
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
#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_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define STATUS_NOT_SAME_DEVICE
Definition: ntstatus.h:448
#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 1058 of file filesup.c.

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