https://git.reactos.org/?p=reactos.git;a=commitdiff;h=38e988ace7a68e1890bdd…
commit 38e988ace7a68e1890bdd3625fe73a5341cc1bad
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun May 21 23:45:43 2017 +0000
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sun May 27 20:18:53 2018 +0200
[USETUP] Improve the FileSup module.
- Add a NtPathToDiskPartComponents() helper, that takes in input a fully qualified NT path to a file on hard disk,
e.g.: \Device\Harddisk1\Partition2\foo\bar, and returns in output the disk number ('1'), the partition number ('2'),
and the the path component "\foo\bar" that is after the device-harddisk-partition identifier.
- Make the OpenAndMapFile() return the file size of the opened file.
Both of these additions will be used soon.
- Turn a isspace() call into a iswspace() one.
svn path=/branches/setup_improvements/; revision=74619
---
base/setup/usetup/filesup.c | 141 +++++++++++++++++++++++++++++++++++++++++++-
base/setup/usetup/filesup.h | 10 +++-
2 files changed, 148 insertions(+), 3 deletions(-)
diff --git a/base/setup/usetup/filesup.c b/base/setup/usetup/filesup.c
index 293e590b76..49defff553 100644
--- a/base/setup/usetup/filesup.c
+++ b/base/setup/usetup/filesup.c
@@ -501,7 +501,7 @@ IsValidPath(
/* Path must not contain whitespace characters */
for (i = 0; i < Length; i++)
{
- if (isspace(InstallDir[i]))
+ if (iswspace(InstallDir[i]))
return FALSE;
}
@@ -633,6 +633,117 @@ DoesFileExist(
return NT_SUCCESS(Status);
}
+/*
+ * The format of NtPath should be:
+ * \Device\HarddiskXXX\PartitionYYY[\path] ,
+ * where XXX and YYY respectively represent the hard disk and partition numbers,
+ * and [\path] represent an optional path (separated by '\\').
+ *
+ * If a NT path of such a form is correctly parsed, the function returns respectively:
+ * - in pDiskNumber: the hard disk number XXX,
+ * - in pPartNumber: the partition number YYY,
+ * - in PathComponent: pointer value (inside NtPath) to the beginning of \path.
+ *
+ * NOTE: The function does not accept leading whitespace.
+ */
+BOOLEAN
+NtPathToDiskPartComponents(
+ IN PCWSTR NtPath,
+ OUT PULONG pDiskNumber,
+ OUT PULONG pPartNumber,
+ OUT PCWSTR* PathComponent OPTIONAL)
+{
+ ULONG DiskNumber, PartNumber;
+ PCWSTR Path;
+
+ *pDiskNumber = 0;
+ *pPartNumber = 0;
+ if (PathComponent) *PathComponent = NULL;
+
+ Path = NtPath;
+
+ if (_wcsnicmp(Path, L"\\Device\\Harddisk", 16) != 0)
+ {
+ /* The NT path doesn't start with the prefix string, thus it cannot be a hard disk device path */
+ DPRINT1("'%S' : Not a possible hard disk device.\n", NtPath);
+ return FALSE;
+ }
+
+ Path += 16;
+
+ /* A number must be present now */
+ if (!iswdigit(*Path))
+ {
+ DPRINT1("'%S' : expected a number! Not a regular hard disk device.\n", Path);
+ return FALSE;
+ }
+ DiskNumber = wcstoul(Path, (PWSTR*)&Path, 10);
+
+ /* Either NULL termination, or a path separator must be present now */
+ if (!Path)
+ {
+ DPRINT1("An error happened!\n");
+ return FALSE;
+ }
+ else if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
+ {
+ DPRINT1("'%S' : expected a path separator!\n", Path);
+ return FALSE;
+ }
+
+ if (!*Path)
+ {
+ DPRINT1("The path only specified a hard disk (and nothing else, like a partition...), so we stop there.\n");
+ goto Quit;
+ }
+
+ /* Here, *Path == L'\\' */
+
+ if (_wcsnicmp(Path, L"\\Partition", 10) != 0)
+ {
+ /* Actually, \Partition is optional so, if we don't have it, we still return success. Or should we? */
+ DPRINT1("'%S' : unexpected format!\n", NtPath);
+ goto Quit;
+ }
+
+ Path += 10;
+
+ /* A number must be present now */
+ if (!iswdigit(*Path))
+ {
+ /* 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? */
+ DPRINT1("'%S' : expected a number!\n", Path);
+ goto Quit;
+ }
+ PartNumber = wcstoul(Path, (PWSTR*)&Path, 10);
+
+ /* Either NULL termination, or a path separator must be present now */
+ if (!Path)
+ {
+ /* We fail here because wcstoul failed for whatever reason */
+ DPRINT1("An error happened!\n");
+ return FALSE;
+ }
+ else if (*Path && *Path != OBJ_NAME_PATH_SEPARATOR)
+ {
+ /* We shouldn't fail here because it just means this part of path is actually not a partition specifier. Or should we? */
+ DPRINT1("'%S' : expected a path separator!\n", Path);
+ goto Quit;
+ }
+
+ /* OK, here we really have a partition specifier: return its number */
+ *pPartNumber = PartNumber;
+
+Quit:
+ /* Return the disk number */
+ *pDiskNumber = DiskNumber;
+
+ /* Return the path component also, if the user wants it */
+ if (PathComponent) *PathComponent = Path;
+
+ return TRUE;
+}
+
NTSTATUS
OpenAndMapFile(
IN HANDLE RootDirectory OPTIONAL,
@@ -640,7 +751,8 @@ OpenAndMapFile(
IN PCWSTR FileName, // OPTIONAL
OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
OUT PHANDLE SectionHandle,
- OUT PVOID* BaseAddress)
+ OUT PVOID* BaseAddress,
+ OUT PULONG FileSize OPTIONAL)
{
NTSTATUS Status;
OBJECT_ATTRIBUTES ObjectAttributes;
@@ -681,6 +793,31 @@ OpenAndMapFile(
return Status;
}
+ if (FileSize)
+ {
+ /* Query the file size */
+ FILE_STANDARD_INFORMATION FileInfo;
+ Status = NtQueryInformationFile(*FileHandle,
+ &IoStatusBlock,
+ &FileInfo,
+ sizeof(FileInfo),
+ FileStandardInformation);
+ if (!NT_SUCCESS(Status))
+ {
+ DPRINT("NtQueryInformationFile() failed (Status %lx)\n", Status);
+ NtClose(*FileHandle);
+ *FileHandle = NULL;
+ return Status;
+ }
+
+ if (FileInfo.EndOfFile.HighPart != 0)
+ DPRINT1("WARNING!! The file %wZ is too large!\n", Name);
+
+ *FileSize = FileInfo.EndOfFile.LowPart;
+
+ DPRINT("File size: %lu\n", *FileSize);
+ }
+
/* Map the file in memory */
/* Create the section */
diff --git a/base/setup/usetup/filesup.h b/base/setup/usetup/filesup.h
index 492dff0e87..317fad93be 100644
--- a/base/setup/usetup/filesup.h
+++ b/base/setup/usetup/filesup.h
@@ -63,6 +63,13 @@ DoesFileExist(
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,
@@ -70,7 +77,8 @@ OpenAndMapFile(
IN PCWSTR FileName, // OPTIONAL
OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
OUT PHANDLE SectionHandle,
- OUT PVOID* BaseAddress);
+ OUT PVOID* BaseAddress,
+ OUT PULONG FileSize OPTIONAL);
BOOLEAN
UnMapFile(