[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
This commit is contained in:
Hermès Bélusca-Maïto 2017-05-21 23:45:43 +00:00
parent 1ed0e1c84a
commit 38e988ace7
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
2 changed files with 148 additions and 3 deletions

View file

@ -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 */

View file

@ -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(