ReactOS 0.4.15-dev-7660-g0086d05
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 PCWSTR DirectoryName)
 
NTSTATUS SetupCreateDirectory (IN PCWSTR PathName)
 
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 (IN HANDLE RootDirectory OPTIONAL, 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 HANDLE RootDirectory OPTIONAL, IN PCWSTR PathNameToFile, OUT PHANDLE FileHandle, OUT PHANDLE SectionHandle, OUT PVOID *BaseAddress, OUT PULONG FileSize OPTIONAL, IN BOOLEAN ReadWriteAccess)
 
BOOLEAN UnMapFile (IN HANDLE SectionHandle, IN PVOID BaseAddress)
 

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

686{
688 va_list PathComponentsList;
689
690 if (cchPathSize < 1)
691 return STATUS_SUCCESS;
692
693 *PathBuffer = UNICODE_NULL;
694
695 va_start(PathComponentsList, NumberOfPathComponents);
696 Status = CombinePathsV(PathBuffer, cchPathSize,
697 NumberOfPathComponents,
698 PathComponentsList);
699 va_end(PathComponentsList);
700
701 return Status;
702}
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:643
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 643 of file filesup.c.

648{
649 if (cchPathSize < 1)
650 return STATUS_SUCCESS;
651
652 *PathBuffer = UNICODE_NULL;
653 return ConcatPathsV(PathBuffer, cchPathSize,
654 NumberOfPathComponents,
655 PathComponentsList);
656}
NTSTATUS ConcatPathsV(IN OUT PWSTR PathBuffer, IN SIZE_T cchPathSize, IN ULONG NumberOfPathComponents, IN va_list PathComponentsList)
Definition: filesup.c:596

Referenced by CombinePaths().

◆ ConcatPaths()

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

Definition at line 659 of file filesup.c.

664{
666 va_list PathComponentsList;
667
668 if (cchPathSize < 1)
669 return STATUS_SUCCESS;
670
671 va_start(PathComponentsList, NumberOfPathComponents);
672 Status = ConcatPathsV(PathBuffer, cchPathSize,
673 NumberOfPathComponents,
674 PathComponentsList);
675 va_end(PathComponentsList);
676
677 return Status;
678}

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

601{
603 SIZE_T cchPathLen;
605
606 if (cchPathSize < 1)
607 return STATUS_SUCCESS;
608
609 while (NumberOfPathComponents--)
610 {
611 PathComponent = va_arg(PathComponentsList, PCWSTR);
612 if (!PathComponent)
613 continue;
614
615 cchPathLen = min(cchPathSize, wcslen(PathBuffer));
616 if (cchPathLen >= cchPathSize)
618
620 cchPathLen > 0 && PathBuffer[cchPathLen-1] != OBJ_NAME_PATH_SEPARATOR)
621 {
622 /* PathComponent does not start with '\' and PathBuffer does not end with '\' */
623 Status = RtlStringCchCatW(PathBuffer, cchPathSize, L"\\");
624 if (!NT_SUCCESS(Status))
625 return Status;
626 }
627 else if (PathComponent[0] == OBJ_NAME_PATH_SEPARATOR &&
628 cchPathLen > 0 && PathBuffer[cchPathLen-1] == OBJ_NAME_PATH_SEPARATOR)
629 {
630 /* PathComponent starts with '\' and PathBuffer ends with '\' */
632 ++PathComponent; // Skip any backslash
633 }
634 Status = RtlStringCchCatW(PathBuffer, cchPathSize, PathComponent);
635 if (!NT_SUCCESS(Status))
636 return Status;
637 }
638
639 return Status;
640}
#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:32
_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 748 of file filesup.c.

751{
754 return DoesFileExist(NULL, FullName);
755}
#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:681
#define DoesFileExist(RootDirectory, FileName)
Definition: filesup.h:77
_In_ PSTRING FullName
Definition: rtlfuncs.h:1648
__wchar_t WCHAR
Definition: xmlstorage.h:180

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

◆ DoesPathExist()

BOOLEAN DoesPathExist ( IN HANDLE RootDirectory  OPTIONAL,
IN PCWSTR  PathName,
IN BOOLEAN  IsDirectory 
)

Definition at line 705 of file filesup.c.

709{
715
716 RtlInitUnicodeString(&Name, PathName);
718 &Name,
721 NULL);
722
725 : FILE_GENERIC_READ, // Contains SYNCHRONIZE
732 if (NT_SUCCESS(Status))
733 {
735 }
736 else
737 {
738 DPRINT("Failed to open %s '%wZ', Status 0x%08lx\n",
739 IsDirectory ? "directory" : "file",
740 &Name, Status);
741 }
742
743 return NT_SUCCESS(Status);
744}
struct NameRec_ * Name
Definition: cdprocs.h:460
#define FILE_DIRECTORY_FILE
Definition: constants.h:491
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
WCHAR RootDirectory[MAX_PATH]
Definition: format.c:74
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define FILE_SHARE_READ
Definition: compat.h:136
#define IsDirectory(Fcb)
Definition: ext2fs.h:283
_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
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define FILE_GENERIC_READ
Definition: nt_native.h:653
#define DPRINT
Definition: sndvol32.h:71

◆ NtPathToDiskPartComponents()

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

Definition at line 771 of file filesup.c.

776{
777 ULONG DiskNumber, PartNumber;
778 PCWSTR Path;
779
780 *pDiskNumber = 0;
781 *pPartNumber = 0;
783
784 Path = NtPath;
785
786 if (_wcsnicmp(Path, L"\\Device\\Harddisk", 16) != 0)
787 {
788 /* The NT path doesn't start with the prefix string, thus it cannot be a hard disk device path */
789 DPRINT1("'%S' : Not a possible hard disk device.\n", NtPath);
790 return FALSE;
791 }
792
793 Path += 16;
794
795 /* A number must be present now */
796 if (!iswdigit(*Path))
797 {
798 DPRINT1("'%S' : expected a number! Not a regular hard disk device.\n", Path);
799 return FALSE;
800 }
801 DiskNumber = wcstoul(Path, (PWSTR*)&Path, 10);
802
803 /* Either NULL termination, or a path separator must be present now */
805 {
806 DPRINT1("'%S' : expected a path separator!\n", Path);
807 return FALSE;
808 }
809
810 if (!*Path)
811 {
812 DPRINT1("The path only specified a hard disk (and nothing else, like a partition...), so we stop there.\n");
813 goto Quit;
814 }
815
816 /* Here, *Path == L'\\' */
817
818 if (_wcsnicmp(Path, L"\\Partition", 10) != 0)
819 {
820 /* Actually, \Partition is optional so, if we don't have it, we still return success. Or should we? */
821 DPRINT1("'%S' : unexpected format!\n", NtPath);
822 goto Quit;
823 }
824
825 Path += 10;
826
827 /* A number must be present now */
828 if (!iswdigit(*Path))
829 {
830 /* 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? */
831 DPRINT1("'%S' : expected a number!\n", Path);
832 goto Quit;
833 }
834 PartNumber = wcstoul(Path, (PWSTR*)&Path, 10);
835
836 /* Either NULL termination, or a path separator must be present now */
838 {
839 /* We shouldn't fail here because it just means this part of path is actually not a partition specifier. Or should we? */
840 DPRINT1("'%S' : expected a path separator!\n", Path);
841 goto Quit;
842 }
843
844 /* OK, here we really have a partition specifier: return its number */
845 *pPartNumber = PartNumber;
846
847Quit:
848 /* Return the disk number */
849 *pDiskNumber = DiskNumber;
850
851 /* Return the path component also, if the user wants it */
853
854 return TRUE;
855}
PRTL_UNICODE_STRING_BUFFER Path
#define DPRINT1
Definition: precomp.h:8
#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
uint32_t ULONG
Definition: typedefs.h:59

Referenced by EnumerateInstallations().

◆ OpenAndMapFile()

NTSTATUS OpenAndMapFile ( IN HANDLE RootDirectory  OPTIONAL,
IN PCWSTR  PathNameToFile,
OUT PHANDLE  FileHandle,
OUT PHANDLE  SectionHandle,
OUT PVOID BaseAddress,
OUT PULONG FileSize  OPTIONAL,
IN BOOLEAN  ReadWriteAccess 
)

Definition at line 858 of file filesup.c.

866{
873 PVOID ViewBase;
874
875 /* Open the file */
876
877 RtlInitUnicodeString(&FileName, PathNameToFile);
879 &FileName,
882 NULL);
883
884 *FileHandle = NULL;
885 *SectionHandle = NULL;
886
888 FILE_GENERIC_READ | // Contains SYNCHRONIZE
889 (ReadWriteAccess ? FILE_GENERIC_WRITE : 0),
894 if (!NT_SUCCESS(Status))
895 {
896 DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &FileName, Status);
897 return Status;
898 }
899
900 if (FileSize)
901 {
902 /* Query the file size */
906 &FileInfo,
907 sizeof(FileInfo),
909 if (!NT_SUCCESS(Status))
910 {
911 DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
913 *FileHandle = NULL;
914 return Status;
915 }
916
917 if (FileInfo.EndOfFile.HighPart != 0)
918 DPRINT1("WARNING!! The file '%wZ' is too large!\n", &FileName);
919
920 *FileSize = FileInfo.EndOfFile.LowPart;
921
922 DPRINT("File size: %lu\n", *FileSize);
923 }
924
925 /* Map the file in memory */
926
927 SectionPageProtection = (ReadWriteAccess ? PAGE_READWRITE : PAGE_READONLY);
928
929 /* Create the section */
930 Status = NtCreateSection(SectionHandle,
933 (ReadWriteAccess ? SECTION_MAP_WRITE : 0),
934 NULL,
935 NULL,
937 SEC_COMMIT /* | SEC_IMAGE (_NO_EXECUTE) */,
938 *FileHandle);
939 if (!NT_SUCCESS(Status))
940 {
941 DPRINT1("Failed to create a memory section for file '%wZ', Status 0x%08lx\n", &FileName, Status);
943 *FileHandle = NULL;
944 return Status;
945 }
946
947 /* Map the section */
948 ViewSize = 0;
949 ViewBase = NULL;
950 Status = NtMapViewOfSection(*SectionHandle,
952 &ViewBase,
953 0, 0,
954 NULL,
955 &ViewSize,
956 ViewShare,
957 0,
959 if (!NT_SUCCESS(Status))
960 {
961 DPRINT1("Failed to map a view for file '%wZ', Status 0x%08lx\n", &FileName, Status);
962 NtClose(*SectionHandle);
963 *SectionHandle = NULL;
965 *FileHandle = NULL;
966 return Status;
967 }
968
969 *BaseAddress = ViewBase;
970 return STATUS_SUCCESS;
971}
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:3441
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:3622
#define PAGE_READONLY
Definition: compat.h:138
#define SECTION_MAP_READ
Definition: compat.h:139
struct _FileName FileName
Definition: fatprocs.h:896
_Must_inspect_result_ _Out_ PLARGE_INTEGER FileSize
Definition: fsrtlfuncs.h:108
_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
NTSYSAPI NTSTATUS NTAPI NtQueryInformationFile(IN HANDLE hFile, OUT PIO_STATUS_BLOCK pIoStatusBlock, OUT PVOID FileInformationBuffer, IN ULONG FileInformationBufferLength, IN FILE_INFORMATION_CLASS FileInfoClass)
@ ViewShare
Definition: nt_native.h:1278
#define FILE_GENERIC_WRITE
Definition: nt_native.h:660
#define STANDARD_RIGHTS_REQUIRED
Definition: nt_native.h:63
#define FileStandardInformation
Definition: propsheet.cpp:61

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

◆ SetupCopyFile()

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

Definition at line 240 of file filesup.c.

244{
248 HANDLE FileHandleSource;
249 HANDLE FileHandleDest;
251 FILE_STANDARD_INFORMATION FileStandard;
252 FILE_BASIC_INFORMATION FileBasic;
254 HANDLE SourceFileSection;
255 PVOID SourceFileMap = NULL;
256 SIZE_T SourceSectionSize = 0;
258
259 RtlInitUnicodeString(&FileName, SourceFileName);
261 &FileName,
263 NULL,
264 NULL);
265
266 Status = NtOpenFile(&FileHandleSource,
272 if (!NT_SUCCESS(Status))
273 {
274 DPRINT1("NtOpenFile failed: %x, %wZ\n", Status, &FileName);
275 goto done;
276 }
277
278 Status = NtQueryInformationFile(FileHandleSource,
280 &FileStandard,
283 if (!NT_SUCCESS(Status))
284 {
285 DPRINT1("NtQueryInformationFile failed: %x\n", Status);
286 goto closesrc;
287 }
288
289 Status = NtQueryInformationFile(FileHandleSource,
291 &FileBasic,
294 if (!NT_SUCCESS(Status))
295 {
296 DPRINT1("NtQueryInformationFile failed: %x\n", Status);
297 goto closesrc;
298 }
299
300 Status = NtCreateSection(&SourceFileSection,
302 NULL,
303 NULL,
306 FileHandleSource);
307 if (!NT_SUCCESS(Status))
308 {
309 DPRINT1("NtCreateSection failed: %x, %S\n", Status, SourceFileName);
310 goto closesrc;
311 }
312
313 Status = NtMapViewOfSection(SourceFileSection,
315 &SourceFileMap,
316 0,
317 0,
318 NULL,
319 &SourceSectionSize,
320 ViewUnmap,
321 0,
323 if (!NT_SUCCESS(Status))
324 {
325 DPRINT1("NtMapViewOfSection failed: %x, %S\n", Status, SourceFileName);
326 goto closesrcsec;
327 }
328
329 RtlInitUnicodeString(&FileName, DestinationFileName);
331 &FileName,
333 NULL,
334 NULL);
335
336 Status = NtCreateFile(&FileHandleDest,
340 NULL,
341 FileBasic.FileAttributes, // FILE_ATTRIBUTE_NORMAL,
342 0,
343 FailIfExists ? FILE_CREATE : FILE_OVERWRITE_IF,
347 NULL,
348 0);
349 if (!NT_SUCCESS(Status))
350 {
351 /*
352 * Open may have failed because the file to overwrite
353 * is in readonly mode.
354 */
356 {
357 FILE_BASIC_INFORMATION FileBasicInfo;
358
359 /* Reattempt to open it with limited access */
360 Status = NtCreateFile(&FileHandleDest,
364 NULL,
366 0,
367 FILE_OPEN,
371 NULL,
372 0);
373 /* Fail for real if we cannot open it that way */
374 if (!NT_SUCCESS(Status))
375 {
376 DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
377 goto unmapsrcsec;
378 }
379
380 /* Zero our basic info, just to set attributes */
381 RtlZeroMemory(&FileBasicInfo, sizeof(FileBasicInfo));
382 /* Reset attributes to normal, no read-only */
384 /*
385 * We basically don't care about whether it succeed:
386 * if it didn't, later open will fail.
387 */
388 NtSetInformationFile(FileHandleDest, &IoStatusBlock, &FileBasicInfo,
389 sizeof(FileBasicInfo), FileBasicInformation);
390
391 /* Close file */
392 NtClose(FileHandleDest);
393
394 /* And re-attempt overwrite */
395 Status = NtCreateFile(&FileHandleDest,
399 NULL,
401 0,
406 NULL,
407 0);
408 }
409
410 /* We failed */
411 if (!NT_SUCCESS(Status))
412 {
413 DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName);
414 goto unmapsrcsec;
415 }
416 }
417
418 RegionSize = (ULONG)PAGE_ROUND_UP(FileStandard.EndOfFile.u.LowPart);
420 ByteOffset.QuadPart = 0ULL;
421 Status = NtWriteFile(FileHandleDest,
422 NULL,
423 NULL,
424 NULL,
426 SourceFileMap,
428 &ByteOffset,
429 NULL);
430 if (!NT_SUCCESS(Status))
431 {
432 DPRINT1("NtWriteFile failed: %x:%x, iosb: %p src: %p, size: %x\n",
434 goto closedest;
435 }
436
437 /* Copy file date/time from source file */
438 Status = NtSetInformationFile(FileHandleDest,
440 &FileBasic,
443 if (!NT_SUCCESS(Status))
444 {
445 DPRINT1("NtSetInformationFile failed: %x\n", Status);
446 goto closedest;
447 }
448
449 /* Shorten the file back to its real size after completing the write */
450 Status = NtSetInformationFile(FileHandleDest,
452 &FileStandard.EndOfFile,
455 if (!NT_SUCCESS(Status))
456 {
457 DPRINT1("NtSetInformationFile failed: %x\n", Status);
458 }
459
460closedest:
461 NtClose(FileHandleDest);
462
463unmapsrcsec:
464 NtUnmapViewOfSection(NtCurrentProcess(), SourceFileMap);
465
466closesrcsec:
467 NtClose(SourceFileSection);
468
469closesrc:
470 NtClose(FileHandleSource);
471
472done:
473 return Status;
474}
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3848
#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:731
@ 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::@2291 u

Referenced by InstallBtrfsBootcodeToPartition(), InstallFatBootcodeToFloppy(), InstallFatBootcodeToPartition(), InstallNtfsBootcodeToPartition(), RegCleanupRegistry(), SetupCommitFileQueueW(), and SetupMoveFile().

◆ SetupCreateDirectory()

NTSTATUS SetupCreateDirectory ( IN PCWSTR  PathName)

Definition at line 84 of file filesup.c.

86{
88 PWCHAR PathBuffer = NULL;
89 PWCHAR Ptr, EndPtr;
90 ULONG BackslashCount;
91 ULONG Size;
92
93 Size = (wcslen(PathName) + 1) * sizeof(WCHAR);
94 PathBuffer = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Size);
95 if (PathBuffer == NULL)
97
98 wcscpy(PathBuffer, PathName);
99 EndPtr = PathBuffer + wcslen(PathName);
100
101 Ptr = PathBuffer;
102
103 /* Skip the '\Device\HarddiskX\PartitionY\ part */
104 BackslashCount = 0;
105 while (Ptr < EndPtr && BackslashCount < 4)
106 {
107 if (*Ptr == L'\\')
108 BackslashCount++;
109
110 Ptr++;
111 }
112
113 while (Ptr < EndPtr)
114 {
115 if (*Ptr == L'\\')
116 {
117 *Ptr = 0;
118
119 DPRINT("PathBuffer: %S\n", PathBuffer);
120 if (!DoesDirExist(NULL, PathBuffer))
121 {
122 DPRINT("Create: %S\n", PathBuffer);
124 if (!NT_SUCCESS(Status))
125 goto done;
126 }
127
128 *Ptr = L'\\';
129 }
130
131 Ptr++;
132 }
133
134 if (!DoesDirExist(NULL, PathBuffer))
135 {
136 DPRINT("Create: %S\n", PathBuffer);
138 if (!NT_SUCCESS(Status))
139 goto done;
140 }
141
142done:
143 DPRINT("Done.\n");
144 if (PathBuffer != NULL)
145 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
146
147 return Status;
148}
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static NTSTATUS SetupCreateSingleDirectory(IN PCWSTR DirectoryName)
Definition: filesup.c:29
#define DoesDirExist(RootDirectory, DirName)
Definition: filesup.h:74
_Must_inspect_result_ _In_ PFSRTL_PER_STREAM_CONTEXT Ptr
Definition: fsrtlfuncs.h:898
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
uint16_t * PWCHAR
Definition: typedefs.h:56
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4533

Referenced by PrepareCopyInfFile().

◆ SetupCreateSingleDirectory()

static NTSTATUS SetupCreateSingleDirectory ( IN PCWSTR  DirectoryName)
static

Definition at line 29 of file filesup.c.

31{
34 UNICODE_STRING PathName;
37
38 if (!RtlCreateUnicodeString(&PathName, DirectoryName))
39 return STATUS_NO_MEMORY;
40
41 if (PathName.Length > sizeof(WCHAR) &&
42 PathName.Buffer[PathName.Length / sizeof(WCHAR) - 2] == L'\\' &&
43 PathName.Buffer[PathName.Length / sizeof(WCHAR) - 1] == L'.')
44 {
45 PathName.Length -= sizeof(WCHAR);
46 PathName.Buffer[PathName.Length / sizeof(WCHAR)] = UNICODE_NULL;
47 }
48
49 if (PathName.Length > sizeof(WCHAR) &&
50 PathName.Buffer[PathName.Length / sizeof(WCHAR) - 1] == L'\\')
51 {
52 PathName.Length -= sizeof(WCHAR);
53 PathName.Buffer[PathName.Length / sizeof(WCHAR)] = UNICODE_NULL;
54 }
55
57 &PathName,
59 NULL,
60 NULL);
61
66 NULL,
71 NULL,
72 0);
73 if (NT_SUCCESS(Status))
74 {
76 }
77
78 RtlFreeUnicodeString(&PathName);
79
80 return Status;
81}
static HANDLE DirectoryHandle
Definition: ObType.c:48
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define FILE_OPEN_IF
Definition: from_kernel.h:56
#define FILE_OPEN_FOR_BACKUP_INTENT
Definition: from_kernel.h:42
#define OBJ_INHERIT
Definition: winternl.h:225
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260

Referenced by SetupCreateDirectory().

◆ SetupDeleteFile()

NTSTATUS SetupDeleteFile ( IN PCWSTR  FileName,
IN BOOLEAN  ForceDelete 
)

Definition at line 151 of file filesup.c.

154{
156 UNICODE_STRING NtPathU;
160 FILE_DISPOSITION_INFORMATION FileDispInfo;
161 BOOLEAN RetryOnce = FALSE;
162
163 /* Open the directory name that was passed in */
166 &NtPathU,
168 NULL,
169 NULL);
170
171Retry: // We go back there once if RetryOnce == TRUE
174 (RetryOnce ? FILE_WRITE_ATTRIBUTES : 0),
179 if (!NT_SUCCESS(Status))
180 {
181 DPRINT1("NtOpenFile failed with Status 0x%08lx\n", Status);
182 return Status;
183 }
184
185 if (RetryOnce)
186 {
188
194 if (!NT_SUCCESS(Status))
195 {
196 DPRINT1("NtQueryInformationFile failed with Status 0x%08lx\n", Status);
198 return Status;
199 }
200
201 FileInformation.FileAttributes = FILE_ATTRIBUTE_NORMAL;
208 if (!NT_SUCCESS(Status))
209 {
210 DPRINT1("NtSetInformationFile failed with Status 0x%08lx\n", Status);
211 return Status;
212 }
213 }
214
215 /* Ask for the file to be deleted */
216 FileDispInfo.DeleteFile = TRUE;
219 &FileDispInfo,
223
224 if (!NT_SUCCESS(Status))
225 DPRINT1("Deletion of file '%S' failed, Status 0x%08lx\n", FileName, Status);
226
227 // FIXME: Check the precise value of Status!
228 if (!NT_SUCCESS(Status) && ForceDelete && !RetryOnce)
229 {
230 /* Retry once */
231 RetryOnce = TRUE;
232 goto Retry;
233 }
234
235 /* Return result to the caller */
236 return Status;
237}
unsigned char BOOLEAN
_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 480 of file filesup.c.

484{
488 PFILE_RENAME_INFORMATION RenameInfo;
489 UNICODE_STRING NewPathU, ExistingPathU;
491 BOOLEAN ReplaceIfExists;
492
493 RtlInitUnicodeString(&ExistingPathU, ExistingFileName);
494 RtlInitUnicodeString(&NewPathU, NewFileName);
495
497 {
498 ReplaceIfExists = !!(Flags & MOVEFILE_REPLACE_EXISTING);
499
500 /* Unless we manage a proper opening, we'll attempt to reopen without reparse support */
502 &ExistingPathU,
504 NULL,
505 NULL);
506 /* Attempt to open source file */
513 if (!NT_SUCCESS(Status))
514 {
516 {
518 }
519 }
520
521 /* At that point, we MUST have a source handle */
523
524 /* Allocate renaming buffer and fill it */
525 RenameInfo = RtlAllocateHeap(RtlGetProcessHeap(), 0, NewPathU.Length + sizeof(FILE_RENAME_INFORMATION));
526 if (RenameInfo == NULL)
527 {
530 }
531
532 RtlCopyMemory(&RenameInfo->FileName, NewPathU.Buffer, NewPathU.Length);
533 RenameInfo->ReplaceIfExists = ReplaceIfExists;
534 RenameInfo->RootDirectory = NULL;
535 RenameInfo->FileNameLength = NewPathU.Length;
536
537 /* Attempt to rename the file */
540 RenameInfo,
541 NewPathU.Length + sizeof(FILE_RENAME_INFORMATION),
543 RtlFreeHeap(RtlGetProcessHeap(), 0, RenameInfo);
544 if (NT_SUCCESS(Status))
545 {
546 /* If it succeeded, all fine, quit */
548 }
549 /*
550 * If we failed for any other reason than not the same device, fail.
551 * If we failed because of different devices, only allow renaming
552 * if user allowed copy.
553 */
555 {
556 /* ReactOS hack! To be removed once all FSD have proper renaming support
557 * Just leave status to error and leave
558 */
560 {
561 DPRINT1("Forcing copy, renaming not supported by FSD\n");
562 }
563 else
564 {
566 }
567 }
568
569 /* Close the source file */
572
573 /* Perform the file copy */
574 Status = SetupCopyFile(ExistingFileName,
575 NewFileName,
576 !ReplaceIfExists);
577
578 /* If it succeeded, delete the source file */
579 if (NT_SUCCESS(Status))
580 {
581 /* Force-delete files even if read-only */
582 SetupDeleteFile(ExistingFileName, TRUE);
583 }
584 }
586 {
587 if (SourceHandle)
589 }
590 _SEH2_END;
591
592 return Status;
593}
#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:240
#define _SEH2_TRY
Definition: filesup.c:19
NTSTATUS SetupDeleteFile(IN PCWSTR FileName, IN BOOLEAN ForceDelete)
Definition: filesup.c:151
#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_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 
)

Definition at line 974 of file filesup.c.

977{
980
982 if (!NT_SUCCESS(Status))
983 {
984 DPRINT1("UnMapFile: NtUnmapViewOfSection(0x%p) failed with Status 0x%08lx\n",
986 Success = FALSE;
987 }
988 Status = NtClose(SectionHandle);
989 if (!NT_SUCCESS(Status))
990 {
991 DPRINT1("UnMapFile: NtClose(0x%p) failed with Status 0x%08lx\n",
992 SectionHandle, Status);
993 Success = FALSE;
994 }
995
996 return Success;
997}
@ Success
Definition: eventcreate.c:712