mirror of
https://github.com/reactos/reactos.git
synced 2024-12-29 02:25:17 +00:00
[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:
parent
14284ddc61
commit
60532e9c43
5 changed files with 297 additions and 125 deletions
|
@ -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' */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue