[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
This commit is contained in:
Hermès Bélusca-Maïto 2017-05-13 16:13:49 +00:00
parent 14284ddc61
commit 60532e9c43
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
5 changed files with 297 additions and 125 deletions

View file

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

View file

@ -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,
@ -562,48 +477,278 @@ SetupExtractFile(
BOOLEAN
DoesFileExist(
PWSTR PathName,
PWSTR FileName)
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;
WCHAR FullName[MAX_PATH];
HANDLE FileHandle;
NTSTATUS Status;
wcscpy(FullName, PathName);
if (FileName != NULL)
{
if (FileName[0] != L'\\')
wcscat(FullName, L"\\");
wcscat(FullName, FileName);
}
RtlInitUnicodeString(&Name,
FullName);
RtlInitUnicodeString(&Name, PathName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE,
NULL,
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(
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];
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);
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 */

View file

@ -41,13 +41,40 @@ SetupExtractFile(
PWCHAR SourceFileName,
PWCHAR DestinationFileName);
BOOLEAN
DoesFileExist(
PWSTR PathName,
PWSTR FileName);
BOOLEAN
IsValidPath(
PWCHAR InstallDir);
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(
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
UnMapFile(
IN HANDLE SectionHandle,
IN PVOID BaseAddress);
/* EOF */

View file

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

View file

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