mirror of
https://github.com/reactos/reactos.git
synced 2024-11-24 03:53:31 +08:00
[SETUPLIB][USETUP] Move some code to the SetupLib.
- filesup.c's functions ConcatPaths(), Does[Path|File]Exist(), NtPathToDiskPartComponents(), OpenAndMapFile(), UnMapFile(); - Move the inicache library to setuplib as it'll be used for the 1st stage GUI setup too (indeed, there is no good INI file API under Win32; the Win32 profile "API" is just good enough to manipulate the win16 ini files, and are here anyways for backward compatibility purposes only); - Move the OS detector too. - Remove the duplicated ConcatPaths() code in arcname.c. svn path=/branches/setup_improvements/; revision=74634 svn path=/branches/setup_improvements/; revision=74638
This commit is contained in:
parent
c7eb46d9fd
commit
92b99b865e
@ -1,9 +1,12 @@
|
||||
|
||||
list(APPEND SOURCE
|
||||
arcname.c
|
||||
filesup.c
|
||||
fsutil.c
|
||||
genlist.c
|
||||
inicache.c
|
||||
ntverrsrc.c
|
||||
osdetect.c
|
||||
partlist.c
|
||||
precomp.h)
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "filesup.h"
|
||||
#include "partlist.h"
|
||||
#include "arcname.h"
|
||||
|
||||
@ -114,7 +115,7 @@ ArcGetNextTokenA(
|
||||
OUT PANSI_STRING TokenSpecifier,
|
||||
OUT PULONG Key)
|
||||
{
|
||||
HRESULT hr;
|
||||
NTSTATUS Status;
|
||||
PCSTR p = ArcPath;
|
||||
ULONG SpecifierLength;
|
||||
ULONG KeyValue;
|
||||
@ -154,9 +155,10 @@ ArcGetNextTokenA(
|
||||
#endif
|
||||
|
||||
/* We should have succeeded, copy the token specifier in the buffer */
|
||||
hr = StringCbCopyNA(TokenSpecifier->Buffer, TokenSpecifier->MaximumLength,
|
||||
ArcPath, SpecifierLength);
|
||||
if (FAILED(hr))
|
||||
Status = RtlStringCbCopyNA(TokenSpecifier->Buffer,
|
||||
TokenSpecifier->MaximumLength,
|
||||
ArcPath, SpecifierLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
|
||||
TokenSpecifier->Length = strlen(TokenSpecifier->Buffer) * sizeof(CHAR);
|
||||
@ -174,7 +176,7 @@ ArcGetNextTokenU(
|
||||
OUT PUNICODE_STRING TokenSpecifier,
|
||||
OUT PULONG Key)
|
||||
{
|
||||
HRESULT hr;
|
||||
NTSTATUS Status;
|
||||
PCWSTR p = ArcPath;
|
||||
ULONG SpecifierLength;
|
||||
ULONG KeyValue;
|
||||
@ -216,9 +218,10 @@ ArcGetNextTokenU(
|
||||
#endif
|
||||
|
||||
/* We should have succeeded, copy the token specifier in the buffer */
|
||||
hr = StringCbCopyNW(TokenSpecifier->Buffer, TokenSpecifier->MaximumLength,
|
||||
ArcPath, SpecifierLength);
|
||||
if (FAILED(hr))
|
||||
Status = RtlStringCbCopyNW(TokenSpecifier->Buffer,
|
||||
TokenSpecifier->MaximumLength,
|
||||
ArcPath, SpecifierLength);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return NULL;
|
||||
|
||||
TokenSpecifier->Length = wcslen(TokenSpecifier->Buffer) * sizeof(WCHAR);
|
||||
@ -298,7 +301,7 @@ ArcPathNormalize(
|
||||
OUT PUNICODE_STRING NormalizedArcPath,
|
||||
IN PCWSTR ArcPath)
|
||||
{
|
||||
HRESULT hr;
|
||||
NTSTATUS Status;
|
||||
PCWSTR EndOfArcName;
|
||||
PCWSTR p;
|
||||
|
||||
@ -315,24 +318,32 @@ ArcPathNormalize(
|
||||
while ((p = wcsstr(ArcPath, L"()")) && (p < EndOfArcName))
|
||||
{
|
||||
#if 0
|
||||
hr = StringCbCopyNW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength,
|
||||
ArcPath, (p - ArcPath) * sizeof(WCHAR));
|
||||
Status = RtlStringCbCopyNW(NormalizedArcPath->Buffer,
|
||||
NormalizedArcPath->MaximumLength,
|
||||
ArcPath, (p - ArcPath) * sizeof(WCHAR));
|
||||
#else
|
||||
hr = StringCbCatNW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength,
|
||||
ArcPath, (p - ArcPath) * sizeof(WCHAR));
|
||||
Status = RtlStringCbCatNW(NormalizedArcPath->Buffer,
|
||||
NormalizedArcPath->MaximumLength,
|
||||
ArcPath, (p - ArcPath) * sizeof(WCHAR));
|
||||
#endif
|
||||
if (FAILED(hr))
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
hr = StringCbCatW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength, L"(0)");
|
||||
if (FAILED(hr))
|
||||
|
||||
Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
|
||||
NormalizedArcPath->MaximumLength,
|
||||
L"(0)");
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
#if 0
|
||||
NormalizedArcPath->Buffer += wcslen(NormalizedArcPath->Buffer);
|
||||
#endif
|
||||
ArcPath = p + 2;
|
||||
}
|
||||
hr = StringCbCatW(NormalizedArcPath->Buffer, NormalizedArcPath->MaximumLength, ArcPath);
|
||||
if (FAILED(hr))
|
||||
|
||||
Status = RtlStringCbCatW(NormalizedArcPath->Buffer,
|
||||
NormalizedArcPath->MaximumLength,
|
||||
ArcPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
return FALSE;
|
||||
|
||||
NormalizedArcPath->Length = wcslen(NormalizedArcPath->Buffer) * sizeof(WCHAR);
|
||||
@ -450,7 +461,7 @@ ResolveArcNameManually(
|
||||
IN OUT PCWSTR* ArcNamePath,
|
||||
IN PPARTLIST PartList OPTIONAL)
|
||||
{
|
||||
HRESULT hr;
|
||||
NTSTATUS Status;
|
||||
WCHAR TokenBuffer[50];
|
||||
UNICODE_STRING Token;
|
||||
PCWSTR p, q;
|
||||
@ -525,7 +536,8 @@ ResolveArcNameManually(
|
||||
return STATUS_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Ramdisk%lu", AdapterKey);
|
||||
Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
|
||||
L"\\Device\\Ramdisk%lu", AdapterKey);
|
||||
goto Quit;
|
||||
}
|
||||
}
|
||||
@ -644,14 +656,23 @@ ResolveArcNameManually(
|
||||
|
||||
|
||||
if (ControllerType == CdRomController) // and so, AdapterType == ScsiAdapter and PeripheralType == FDiskPeripheral
|
||||
hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Scsi\\CdRom%lu", ControllerKey);
|
||||
{
|
||||
Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
|
||||
L"\\Device\\Scsi\\CdRom%lu", ControllerKey);
|
||||
}
|
||||
else
|
||||
/* Now, ControllerType == DiskController */
|
||||
if (PeripheralType == CdRomPeripheral)
|
||||
hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\CdRom%lu", PeripheralKey);
|
||||
{
|
||||
Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
|
||||
L"\\Device\\CdRom%lu", PeripheralKey);
|
||||
}
|
||||
else
|
||||
if (PeripheralType == FDiskPeripheral)
|
||||
hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Floppy%lu", PeripheralKey);
|
||||
{
|
||||
Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
|
||||
L"\\Device\\Floppy%lu", PeripheralKey);
|
||||
}
|
||||
else
|
||||
if (PeripheralType == RDiskPeripheral)
|
||||
{
|
||||
@ -676,78 +697,30 @@ ResolveArcNameManually(
|
||||
ASSERT(PartEntry->DiskEntry == DiskEntry);
|
||||
}
|
||||
|
||||
hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\Harddisk%lu\\Partition%lu",
|
||||
DiskEntry->DiskNumber, PartitionNumber);
|
||||
Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
|
||||
L"\\Device\\Harddisk%lu\\Partition%lu",
|
||||
DiskEntry->DiskNumber, PartitionNumber);
|
||||
}
|
||||
#if 0
|
||||
else
|
||||
if (PeripheralType == VDiskPeripheral)
|
||||
{
|
||||
// TODO: Check how Win 7+ deals with virtual disks.
|
||||
hr = StringCbPrintfW(NtName->Buffer, NtName->MaximumLength, L"\\Device\\VirtualHarddisk%lu\\Partition%lu",
|
||||
PeripheralKey, PartitionNumber);
|
||||
Status = RtlStringCbPrintfW(NtName->Buffer, NtName->MaximumLength,
|
||||
L"\\Device\\VirtualHarddisk%lu\\Partition%lu",
|
||||
PeripheralKey, PartitionNumber);
|
||||
}
|
||||
#endif
|
||||
|
||||
Quit:
|
||||
if (FAILED(hr))
|
||||
{
|
||||
/*
|
||||
* We can directly cast the HRESULTs into NTSTATUS since the error codes
|
||||
* returned by StringCbPrintfW:
|
||||
* STRSAFE_E_INVALID_PARAMETER == 0x80070057,
|
||||
* STRSAFE_E_INSUFFICIENT_BUFFER == 0x8007007a,
|
||||
* do not have assigned values in the NTSTATUS space.
|
||||
*/
|
||||
return (NTSTATUS)hr;
|
||||
}
|
||||
if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
*ArcNamePath = p;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**** FIXME: Redundant with filesup.c ! ****\
|
||||
|** (but filesup.c is not yet included in **|
|
||||
\** setuplib, hence this code copy) **/
|
||||
|
||||
static
|
||||
HRESULT
|
||||
ConcatPaths(
|
||||
IN OUT PWSTR PathElem1,
|
||||
IN SIZE_T cchPathSize,
|
||||
IN PCWSTR PathElem2 OPTIONAL)
|
||||
{
|
||||
HRESULT hr;
|
||||
SIZE_T cchPathLen;
|
||||
|
||||
if (!PathElem2)
|
||||
return S_OK;
|
||||
if (cchPathSize <= 1)
|
||||
return S_OK;
|
||||
|
||||
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 '\' */
|
||||
hr = StringCchCatW(PathElem1, cchPathSize, L"\\");
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
}
|
||||
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
|
||||
}
|
||||
hr = StringCchCatW(PathElem1, cchPathSize, PathElem2);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/*******************************************/
|
||||
|
||||
|
||||
BOOLEAN
|
||||
ArcPathToNtPath(
|
||||
OUT PUNICODE_STRING NtPath,
|
||||
@ -825,9 +798,8 @@ ArcPathToNtPath(
|
||||
*/
|
||||
if (BeginOfPath && *BeginOfPath)
|
||||
{
|
||||
HRESULT hr;
|
||||
hr = ConcatPaths(NtPath->Buffer, NtPath->MaximumLength / sizeof(WCHAR), BeginOfPath);
|
||||
if (FAILED(hr))
|
||||
Status = ConcatPaths(NtPath->Buffer, NtPath->MaximumLength / sizeof(WCHAR), BeginOfPath);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Buffer not large enough, or whatever...: just bail out */
|
||||
return FALSE;
|
||||
|
372
base/setup/lib/filesup.c
Normal file
372
base/setup/lib/filesup.c
Normal file
@ -0,0 +1,372 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Setup Library
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: File support functions.
|
||||
* COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS ****************************************************************/
|
||||
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(
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 && *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 && *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,
|
||||
IN PCWSTR PathName OPTIONAL,
|
||||
IN PCWSTR FileName, // OPTIONAL
|
||||
OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
|
||||
OUT PHANDLE SectionHandle,
|
||||
OUT PVOID* BaseAddress,
|
||||
OUT PULONG FileSize OPTIONAL)
|
||||
{
|
||||
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))
|
||||
{
|
||||
DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &Name, Status);
|
||||
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 */
|
||||
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 */
|
57
base/setup/lib/filesup.h
Normal file
57
base/setup/lib/filesup.h
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Setup Library
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: File support functions.
|
||||
* COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if 0
|
||||
|
||||
BOOLEAN
|
||||
IsValidPath(
|
||||
IN PCWSTR InstallDir);
|
||||
|
||||
#endif
|
||||
|
||||
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);
|
||||
|
||||
BOOLEAN
|
||||
NtPathToDiskPartComponents(
|
||||
IN PCWSTR NtPath,
|
||||
OUT PULONG pDiskNumber,
|
||||
OUT PULONG pPartNumber,
|
||||
OUT PCWSTR* PathComponent OPTIONAL);
|
||||
|
||||
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,
|
||||
OUT PULONG FileSize OPTIONAL);
|
||||
|
||||
BOOLEAN
|
||||
UnMapFile(
|
||||
IN HANDLE SectionHandle,
|
||||
IN PVOID BaseAddress);
|
||||
|
||||
/* EOF */
|
@ -1,32 +1,15 @@
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: base/setup/usetup/inicache.c
|
||||
* PURPOSE: INI file parser that caches contents of INI file in memory
|
||||
* PROGRAMMER: Royce Mitchell III
|
||||
* PROJECT: ReactOS Setup Library
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: INI file parser that caches contents of INI file in memory.
|
||||
* COPYRIGHT: Copyright 2002-2018 Royce Mitchell III
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "usetup.h"
|
||||
#include "precomp.h"
|
||||
|
||||
#include "inicache.h"
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
@ -1,27 +1,8 @@
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: base/setup/usetup/inicache.h
|
||||
* PURPOSE: INI file parser that caches contents of INI file in memory
|
||||
* PROGRAMMER: Royce Mitchell III
|
||||
* PROJECT: ReactOS Setup Library
|
||||
* LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
|
||||
* PURPOSE: INI file parser that caches contents of INI file in memory.
|
||||
* COPYRIGHT: Copyright 2002-2018 Royce Mitchell III
|
||||
*/
|
||||
|
||||
#pragma once
|
@ -6,7 +6,18 @@
|
||||
* COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
|
||||
*/
|
||||
|
||||
#include "usetup.h"
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
#include "ntverrsrc.h"
|
||||
// #include "arcname.h"
|
||||
#include "filesup.h"
|
||||
#include "genlist.h"
|
||||
#include "inicache.h"
|
||||
#include "partlist.h"
|
||||
#include "arcname.h"
|
||||
#include "osdetect.h"
|
||||
|
||||
// HACK!
|
||||
#include <strsafe.h>
|
||||
@ -17,8 +28,6 @@
|
||||
|
||||
/* GLOBALS ******************************************************************/
|
||||
|
||||
extern PPARTLIST PartitionList;
|
||||
|
||||
/* Language-independent Vendor strings */
|
||||
static const PCWSTR KnownVendors[] = { L"ReactOS", L"Microsoft" };
|
||||
|
@ -6,6 +6,8 @@
|
||||
* COPYRIGHT: Copyright 2017-2018 Hermes Belusca-Maito
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef struct _NTOS_INSTALLATION
|
||||
{
|
||||
LIST_ENTRY ListEntry;
|
||||
@ -24,3 +26,5 @@ typedef struct _NTOS_INSTALLATION
|
||||
PGENERIC_LIST
|
||||
CreateNTOSInstallationsList(
|
||||
IN PPARTLIST List);
|
||||
|
||||
/* EOF */
|
@ -16,8 +16,6 @@
|
||||
#include <winreg.h>
|
||||
#include <winuser.h>
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
#define NTOS_MODE_USER
|
||||
#include <ndk/cmfuncs.h>
|
||||
#include <ndk/exfuncs.h>
|
||||
@ -29,6 +27,9 @@
|
||||
#include <ndk/rtlfuncs.h>
|
||||
#include <ndk/setypes.h>
|
||||
|
||||
#include <ntstrsafe.h>
|
||||
|
||||
|
||||
/* Filesystem headers */
|
||||
#include <reactos/rosioctl.h> // For extra partition IDs
|
||||
|
||||
|
@ -29,9 +29,12 @@ extern HANDLE ProcessHeap;
|
||||
#include "linklist.h"
|
||||
#include "ntverrsrc.h"
|
||||
// #include "arcname.h"
|
||||
#include "filesup.h"
|
||||
#include "fsutil.h"
|
||||
#include "genlist.h"
|
||||
#include "inicache.h"
|
||||
#include "partlist.h"
|
||||
#include "arcname.h"
|
||||
#include "osdetect.h"
|
||||
|
||||
/* EOF */
|
||||
|
@ -24,10 +24,8 @@ list(APPEND SOURCE
|
||||
fslist.c
|
||||
genlist.c
|
||||
inffile.c
|
||||
inicache.c
|
||||
keytrans.c
|
||||
mui.c
|
||||
osdetect.c
|
||||
partlist.c
|
||||
progress.c
|
||||
registry.c
|
||||
|
@ -1,22 +1,5 @@
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/* COPYRIGHT: See COPYING in the top level directory
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
* FILE: base/setup/usetup/filesup.c
|
||||
* PURPOSE: File support functions
|
||||
@ -520,360 +503,4 @@ IsValidPath(
|
||||
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(
|
||||
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,
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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 && *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 && *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,
|
||||
IN PCWSTR PathName OPTIONAL,
|
||||
IN PCWSTR FileName, // OPTIONAL
|
||||
OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
|
||||
OUT PHANDLE SectionHandle,
|
||||
OUT PVOID* BaseAddress,
|
||||
OUT PULONG FileSize OPTIONAL)
|
||||
{
|
||||
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))
|
||||
{
|
||||
DPRINT1("Failed to open file '%wZ', Status 0x%08lx\n", &Name, Status);
|
||||
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 */
|
||||
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 */
|
||||
|
@ -1,21 +1,3 @@
|
||||
/*
|
||||
* ReactOS kernel
|
||||
* Copyright (C) 2002 ReactOS Team
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS text-mode setup
|
||||
@ -46,43 +28,4 @@ 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(
|
||||
IN HANDLE RootDirectory OPTIONAL,
|
||||
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,
|
||||
IN PCWSTR PathName OPTIONAL,
|
||||
IN PCWSTR FileName, // OPTIONAL
|
||||
OUT PHANDLE FileHandle, // IN OUT PHANDLE OPTIONAL
|
||||
OUT PHANDLE SectionHandle,
|
||||
OUT PVOID* BaseAddress,
|
||||
OUT PULONG FileSize OPTIONAL);
|
||||
|
||||
BOOLEAN
|
||||
UnMapFile(
|
||||
IN HANDLE SectionHandle,
|
||||
IN PVOID BaseAddress);
|
||||
|
||||
/* EOF */
|
||||
|
@ -60,7 +60,6 @@
|
||||
/* Internal Headers */
|
||||
#include "consup.h"
|
||||
#include "inffile.h"
|
||||
#include "inicache.h"
|
||||
#include "progress.h"
|
||||
#include "infros.h"
|
||||
#include "filequeue.h"
|
||||
@ -70,7 +69,6 @@
|
||||
#include "cabinet.h"
|
||||
#include "filesup.h"
|
||||
#include "genlist.h"
|
||||
#include "osdetect.h"
|
||||
#include "mui.h"
|
||||
|
||||
extern HANDLE ProcessHeap;
|
||||
|
Loading…
Reference in New Issue
Block a user