https://git.reactos.org/?p=reactos.git;a=commitdiff;h=60532e9c4394b0ee7860a…
commit 60532e9c4394b0ee7860a1fda2f6cc2435be610b
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sat May 13 16:13:49 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat May 26 19:09:38 2018 +0200
[USETUP] Add & modify some file utility functions that are going to be used next.
- ConcatPaths that concatenates paths (or a path and a file name);
- OpenAndMapFile (resp. UnMapFile), whose purpose is to open a file and map it in
memory (resp. unmap it from memory).
- Add extra optional parameters to DoesPathExist and DoesFileExist: an optional
"RootDirectory" handle and, for DoesFileExist only, an optional PathName.
- Close the opened file handles only on success.
svn path=/branches/setup_improvements/; revision=74528
svn path=/branches/setup_improvements/; revision=74538
svn path=/branches/setup_improvements/; revision=74549
---
base/setup/usetup/bootsup.c | 14 +-
base/setup/usetup/filesup.c | 357 +++++++++++++++++++++++++++++++-------------
base/setup/usetup/filesup.h | 35 ++++-
base/setup/usetup/usetup.c | 4 +-
base/setup/usetup/usetup.h | 4 +-
5 files changed, 293 insertions(+), 121 deletions(-)
diff --git a/base/setup/usetup/bootsup.c b/base/setup/usetup/bootsup.c
index 75319fba95..674808ace7 100644
--- a/base/setup/usetup/bootsup.c
+++ b/base/setup/usetup/bootsup.c
@@ -2275,7 +2275,7 @@ InstallFatBootcodeToPartition(
wcscpy(DstPath, SystemRootPath->Buffer);
wcscat(DstPath, L"\\freeldr.ini");
- DoesFreeLdrExist = DoesFileExist(SystemRootPath->Buffer,
L"freeldr.ini");
+ DoesFreeLdrExist = DoesFileExist(NULL, SystemRootPath->Buffer,
L"freeldr.ini");
if (DoesFreeLdrExist)
{
/* Update existing 'freeldr.ini' */
@@ -2292,8 +2292,8 @@ InstallFatBootcodeToPartition(
/* Check for NT and other bootloaders */
// FIXME: Check for Vista+ bootloader!
- if (DoesFileExist(SystemRootPath->Buffer, L"ntldr") == TRUE ||
- DoesFileExist(SystemRootPath->Buffer, L"boot.ini") == TRUE)
+ if (DoesFileExist(NULL, SystemRootPath->Buffer, L"ntldr") == TRUE ||
+ DoesFileExist(NULL, SystemRootPath->Buffer, L"boot.ini") == TRUE)
{
/* Search root directory for 'ntldr' and 'boot.ini' */
DPRINT1("Found Microsoft Windows NT/2000/XP boot loader\n");
@@ -2375,8 +2375,8 @@ InstallFatBootcodeToPartition(
PWCHAR BootSector;
PWCHAR BootSectorFileName;
- if (DoesFileExist(SystemRootPath->Buffer, L"io.sys") == TRUE ||
- DoesFileExist(SystemRootPath->Buffer, L"msdos.sys") == TRUE)
+ if (DoesFileExist(NULL, SystemRootPath->Buffer, L"io.sys") == TRUE
||
+ DoesFileExist(NULL, SystemRootPath->Buffer, L"msdos.sys") ==
TRUE)
{
/* Search for root directory for 'io.sys' and 'msdos.sys' */
DPRINT1("Found Microsoft DOS or Windows 9x boot loader\n");
@@ -2390,7 +2390,7 @@ InstallFatBootcodeToPartition(
BootSectorFileName = L"\\bootsect.dos";
}
else
- if (DoesFileExist(SystemRootPath->Buffer, L"kernel.sys") == TRUE)
+ if (DoesFileExist(NULL, SystemRootPath->Buffer, L"kernel.sys") ==
TRUE)
{
/* Search for root directory for 'kernel.sys' */
DPRINT1("Found FreeDOS boot loader\n");
@@ -2529,7 +2529,7 @@ InstallExt2BootcodeToPartition(
wcscpy(DstPath, SystemRootPath->Buffer);
wcscat(DstPath, L"\\freeldr.ini");
- DoesFreeLdrExist = DoesFileExist(SystemRootPath->Buffer,
L"freeldr.ini");
+ DoesFreeLdrExist = DoesFileExist(NULL, SystemRootPath->Buffer,
L"freeldr.ini");
if (DoesFreeLdrExist)
{
/* Update existing 'freeldr.ini' */
diff --git a/base/setup/usetup/filesup.c b/base/setup/usetup/filesup.c
index 568525d095..293e590b76 100644
--- a/base/setup/usetup/filesup.c
+++ b/base/setup/usetup/filesup.c
@@ -93,90 +93,6 @@ SetupCreateSingleDirectory(
return Status;
}
-
-static
-BOOLEAN
-DoesPathExist(
- PWSTR PathName)
-{
- OBJECT_ATTRIBUTES ObjectAttributes;
- IO_STATUS_BLOCK IoStatusBlock;
- UNICODE_STRING Name;
- HANDLE FileHandle;
- NTSTATUS Status;
-
- RtlInitUnicodeString(&Name,
- PathName);
-
- InitializeObjectAttributes(&ObjectAttributes,
- &Name,
- OBJ_CASE_INSENSITIVE,
- NULL,
- NULL);
-
- Status = NtOpenFile(&FileHandle,
- GENERIC_READ | SYNCHRONIZE,
- &ObjectAttributes,
- &IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
- if (!NT_SUCCESS(Status))
- {
- return FALSE;
- }
-
- NtClose(FileHandle);
-
- return TRUE;
-}
-
-
-BOOLEAN
-IsValidPath(
- PWCHAR InstallDir)
-{
- UINT i, Length;
-
- Length = wcslen(InstallDir);
-
- // TODO: Add check for 8.3 too.
-
- /* Path must be at least 2 characters long */
-// if (Length < 2)
-// return FALSE;
-
- /* Path must start with a backslash */
-// if (InstallDir[0] != L'\\')
-// return FALSE;
-
- /* Path must not end with a backslash */
- if (InstallDir[Length - 1] == L'\\')
- return FALSE;
-
- /* Path must not contain whitespace characters */
- for (i = 0; i < Length; i++)
- {
- if (isspace(InstallDir[i]))
- return FALSE;
- }
-
- /* Path component must not end with a dot */
- for (i = 0; i < Length; i++)
- {
- if (InstallDir[i] == L'\\' && i > 0)
- {
- if (InstallDir[i - 1] == L'.')
- return FALSE;
- }
- }
-
- if (InstallDir[Length - 1] == L'.')
- return FALSE;
-
- return TRUE;
-}
-
-
NTSTATUS
SetupCreateDirectory(
PWCHAR PathName)
@@ -214,7 +130,7 @@ SetupCreateDirectory(
*Ptr = 0;
DPRINT("PathBuffer: %S\n", PathBuffer);
- if (!DoesPathExist(PathBuffer))
+ if (!DoesPathExist(NULL, PathBuffer))
{
DPRINT("Create: %S\n", PathBuffer);
Status = SetupCreateSingleDirectory(PathBuffer);
@@ -228,7 +144,7 @@ SetupCreateDirectory(
Ptr++;
}
- if (!DoesPathExist(PathBuffer))
+ if (!DoesPathExist(NULL, PathBuffer))
{
DPRINT("Create: %S\n", PathBuffer);
Status = SetupCreateSingleDirectory(PathBuffer);
@@ -244,7 +160,6 @@ done:
return Status;
}
-
NTSTATUS
SetupCopyFile(
PWCHAR SourceFileName,
@@ -561,49 +476,279 @@ SetupExtractFile(
}
+BOOLEAN
+IsValidPath(
+ IN PCWSTR InstallDir)
+{
+ UINT i, Length;
+
+ Length = wcslen(InstallDir);
+
+ // TODO: Add check for 8.3 too.
+
+ /* Path must be at least 2 characters long */
+// if (Length < 2)
+// return FALSE;
+
+ /* Path must start with a backslash */
+// if (InstallDir[0] != L'\\')
+// return FALSE;
+
+ /* Path must not end with a backslash */
+ if (InstallDir[Length - 1] == L'\\')
+ return FALSE;
+
+ /* Path must not contain whitespace characters */
+ for (i = 0; i < Length; i++)
+ {
+ if (isspace(InstallDir[i]))
+ return FALSE;
+ }
+
+ /* Path component must not end with a dot */
+ for (i = 0; i < Length; i++)
+ {
+ if (InstallDir[i] == L'\\' && i > 0)
+ {
+ if (InstallDir[i - 1] == L'.')
+ return FALSE;
+ }
+ }
+
+ if (InstallDir[Length - 1] == L'.')
+ return FALSE;
+
+ return TRUE;
+}
+
+NTSTATUS
+ConcatPaths(
+ IN OUT PWSTR PathElem1,
+ IN SIZE_T cchPathSize,
+ IN PCWSTR PathElem2 OPTIONAL)
+{
+ NTSTATUS Status;
+ SIZE_T cchPathLen;
+
+ if (!PathElem2)
+ return STATUS_SUCCESS;
+ if (cchPathSize <= 1)
+ return STATUS_SUCCESS;
+
+ cchPathLen = min(cchPathSize, wcslen(PathElem1));
+
+ if (PathElem2[0] != L'\\' && cchPathLen > 0 &&
PathElem1[cchPathLen-1] != L'\\')
+ {
+ /* PathElem2 does not start with '\' and PathElem1 does not end with
'\' */
+ Status = RtlStringCchCatW(PathElem1, cchPathSize, L"\\");
+ if (!NT_SUCCESS(Status))
+ return Status;
+ }
+ else if (PathElem2[0] == L'\\' && cchPathLen > 0 &&
PathElem1[cchPathLen-1] == L'\\')
+ {
+ /* PathElem2 starts with '\' and PathElem1 ends with '\' */
+ while (*PathElem2 == L'\\')
+ ++PathElem2; // Skip any backslash
+ }
+ Status = RtlStringCchCatW(PathElem1, cchPathSize, PathElem2);
+ return Status;
+}
+
+//
+// NOTE: It may be possible to merge both DoesPathExist and DoesFileExist...
+//
+BOOLEAN
+DoesPathExist(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName)
+{
+ NTSTATUS Status;
+ HANDLE FileHandle;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ UNICODE_STRING Name;
+
+ RtlInitUnicodeString(&Name, PathName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ RootDirectory,
+ NULL);
+
+ Status = NtOpenFile(&FileHandle,
+ FILE_LIST_DIRECTORY | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_DIRECTORY_FILE);
+ if (NT_SUCCESS(Status))
+ NtClose(FileHandle);
+ else
+ DPRINT1("Failed to open directory %wZ, Status 0x%08lx\n", &Name,
Status);
+
+ return NT_SUCCESS(Status);
+}
+
BOOLEAN
DoesFileExist(
- PWSTR PathName,
- PWSTR FileName)
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName)
{
+ NTSTATUS Status;
+ HANDLE FileHandle;
OBJECT_ATTRIBUTES ObjectAttributes;
IO_STATUS_BLOCK IoStatusBlock;
UNICODE_STRING Name;
WCHAR FullName[MAX_PATH];
- HANDLE FileHandle;
- NTSTATUS Status;
- wcscpy(FullName, PathName);
- if (FileName != NULL)
- {
- if (FileName[0] != L'\\')
- wcscat(FullName, L"\\");
- wcscat(FullName, FileName);
- }
+ if (PathName)
+ RtlStringCchCopyW(FullName, ARRAYSIZE(FullName), PathName);
+ else
+ FullName[0] = UNICODE_NULL;
- RtlInitUnicodeString(&Name,
- FullName);
+ if (FileName)
+ ConcatPaths(FullName, ARRAYSIZE(FullName), FileName);
+
+ RtlInitUnicodeString(&Name, FullName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
- NULL,
+ RootDirectory,
NULL);
Status = NtOpenFile(&FileHandle,
GENERIC_READ | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
- 0,
- FILE_SYNCHRONOUS_IO_NONALERT);
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
+ if (NT_SUCCESS(Status))
+ NtClose(FileHandle);
+ else
+ DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &Name,
Status);
+
+ return NT_SUCCESS(Status);
+}
+
+NTSTATUS
+OpenAndMapFile(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName, // OPTIONAL
+ OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
+ OUT PHANDLE SectionHandle,
+ OUT PVOID* BaseAddress)
+{
+ NTSTATUS Status;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ IO_STATUS_BLOCK IoStatusBlock;
+ SIZE_T ViewSize;
+ PVOID ViewBase;
+ UNICODE_STRING Name;
+ WCHAR FullName[MAX_PATH];
+
+ if (PathName)
+ RtlStringCchCopyW(FullName, ARRAYSIZE(FullName), PathName);
+ else
+ FullName[0] = UNICODE_NULL;
+
+ if (FileName)
+ ConcatPaths(FullName, ARRAYSIZE(FullName), FileName);
+
+ RtlInitUnicodeString(&Name, FullName);
+
+ InitializeObjectAttributes(&ObjectAttributes,
+ &Name,
+ OBJ_CASE_INSENSITIVE,
+ RootDirectory,
+ NULL);
+
+ *FileHandle = NULL;
+ *SectionHandle = NULL;
+
+ Status = NtOpenFile(FileHandle,
+ GENERIC_READ | SYNCHRONIZE,
+ &ObjectAttributes,
+ &IoStatusBlock,
+ FILE_SHARE_READ,
+ FILE_SYNCHRONOUS_IO_NONALERT | FILE_NON_DIRECTORY_FILE);
if (!NT_SUCCESS(Status))
{
- return FALSE;
+ DPRINT1("Failed to open file %wZ, Status 0x%08lx\n", &Name,
Status);
+ return Status;
}
- NtClose(FileHandle);
+ /* Map the file in memory */
- return TRUE;
+ /* Create the section */
+ Status = NtCreateSection(SectionHandle,
+ SECTION_MAP_READ,
+ NULL,
+ NULL,
+ PAGE_READONLY,
+ SEC_COMMIT /* | SEC_IMAGE (_NO_EXECUTE) */,
+ *FileHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to create a memory section for file %wZ, Status
0x%08lx\n", &Name, Status);
+ NtClose(*FileHandle);
+ *FileHandle = NULL;
+ return Status;
+ }
+
+ /* Map the section */
+ ViewSize = 0;
+ ViewBase = NULL;
+ Status = NtMapViewOfSection(*SectionHandle,
+ NtCurrentProcess(),
+ &ViewBase,
+ 0, 0,
+ NULL,
+ &ViewSize,
+ ViewShare,
+ 0,
+ PAGE_READONLY);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("Failed to map a view for file %wZ, Status 0x%08lx\n",
&Name, Status);
+ NtClose(*SectionHandle);
+ *SectionHandle = NULL;
+ NtClose(*FileHandle);
+ *FileHandle = NULL;
+ return Status;
+ }
+
+ *BaseAddress = ViewBase;
+ return STATUS_SUCCESS;
+}
+
+BOOLEAN
+UnMapFile(
+ IN HANDLE SectionHandle,
+ IN PVOID BaseAddress)
+{
+ NTSTATUS Status;
+ BOOLEAN Success = TRUE;
+
+ Status = NtUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UnMapFile: NtUnmapViewOfSection(0x%p) failed with Status
0x%08lx\n",
+ BaseAddress, Status);
+ Success = FALSE;
+ }
+ Status = NtClose(SectionHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT1("UnMapFile: NtClose(0x%p) failed with Status 0x%08lx\n",
+ SectionHandle, Status);
+ Success = FALSE;
+ }
+
+ return Success;
}
/* EOF */
diff --git a/base/setup/usetup/filesup.h b/base/setup/usetup/filesup.h
index e09a08c673..492dff0e87 100644
--- a/base/setup/usetup/filesup.h
+++ b/base/setup/usetup/filesup.h
@@ -41,13 +41,40 @@ SetupExtractFile(
PWCHAR SourceFileName,
PWCHAR DestinationFileName);
+
+BOOLEAN
+IsValidPath(
+ IN PCWSTR InstallDir);
+
+NTSTATUS
+ConcatPaths(
+ IN OUT PWSTR PathElem1,
+ IN SIZE_T cchPathSize,
+ IN PCWSTR PathElem2 OPTIONAL);
+
+BOOLEAN
+DoesPathExist(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName);
+
BOOLEAN
DoesFileExist(
- PWSTR PathName,
- PWSTR FileName);
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName);
+
+NTSTATUS
+OpenAndMapFile(
+ IN HANDLE RootDirectory OPTIONAL,
+ IN PCWSTR PathName OPTIONAL,
+ IN PCWSTR FileName, // OPTIONAL
+ OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
+ OUT PHANDLE SectionHandle,
+ OUT PVOID* BaseAddress);
BOOLEAN
-IsValidPath(
- PWCHAR InstallDir);
+UnMapFile(
+ IN HANDLE SectionHandle,
+ IN PVOID BaseAddress);
/* EOF */
diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c
index 8c80812265..234bfa45be 100644
--- a/base/setup/usetup/usetup.c
+++ b/base/setup/usetup/usetup.c
@@ -424,7 +424,7 @@ CheckUnattendedSetup(VOID)
INT IntValue;
PWCHAR Value;
- if (DoesFileExist(SourcePath.Buffer, L"unattend.inf") == FALSE)
+ if (DoesFileExist(NULL, SourcePath.Buffer, L"unattend.inf") == FALSE)
{
DPRINT("Does not exist: %S\\%S\n", SourcePath.Buffer,
L"unattend.inf");
return;
@@ -4462,7 +4462,7 @@ BootLoaderFloppyPage(PINPUT_RECORD Ir)
}
else if (Ir->Event.KeyEvent.uChar.AsciiChar == 0x0D) /* ENTER */
{
- if (DoesFileExist(L"\\Device\\Floppy0", L"\\") == FALSE)
+ if (DoesFileExist(NULL, L"\\Device\\Floppy0", L"\\") ==
FALSE)
{
MUIDisplayError(ERROR_NO_FLOPPY, Ir, POPUP_WAIT_ENTER);
return BOOT_LOADER_FLOPPY_PAGE;
diff --git a/base/setup/usetup/usetup.h b/base/setup/usetup/usetup.h
index 37cae20f7f..53be28b3dc 100644
--- a/base/setup/usetup/usetup.h
+++ b/base/setup/usetup/usetup.h
@@ -39,8 +39,6 @@
#include <winuser.h>
#include <wincon.h>
-#include <strsafe.h>
-
#define NTOS_MODE_USER
#include <ndk/cmfuncs.h>
#include <ndk/exfuncs.h>
@@ -52,6 +50,8 @@
#include <ndk/rtlfuncs.h>
#include <ndk/setypes.h>
+#include <ntstrsafe.h>
+
/* Filesystem headers */
#include <reactos/rosioctl.h>
#include <fslib/vfatlib.h>