[SETUPLIB][USETUP] Move all the code that performs file copying into the SETUPLIB.

This commit is contained in:
Hermès Bélusca-Maïto 2018-01-07 01:35:48 +01:00
parent f894631472
commit 3d137b05d1
No known key found for this signature in database
GPG key ID: 3B2539C65E7B93D0
5 changed files with 699 additions and 530 deletions

View file

@ -17,6 +17,7 @@ list(APPEND SOURCE
utils/regutil.c
bootsup.c
fsutil.c
install.c
mui.c
registry.c
settings.c

643
base/setup/lib/install.c Normal file
View file

@ -0,0 +1,643 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Setup Library
* FILE: base/setup/lib/install.c
* PURPOSE: Installation functions
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
/* INCLUDES *****************************************************************/
#include "precomp.h"
#include "filesup.h"
#include "infsupp.h"
#include "setuplib.h" // HAXX for USETUP_DATA!!
#include "install.h"
#define NDEBUG
#include <debug.h>
/* FUNCTIONS ****************************************************************/
/*
* This code enumerates the list of files in reactos.dff / reactos.inf
* that need to be extracted from reactos.cab and be installed in their
* respective directories.
*/
/*
* IMPORTANT NOTE: The INF file specification used for the .CAB in ReactOS
* is not compliant with respect to TXTSETUP.SIF syntax or the standard syntax.
*/
static BOOLEAN
AddSectionToCopyQueueCab(
IN PUSETUP_DATA pSetupData,
IN HINF InfFile,
IN PCWSTR SectionName,
IN PCWSTR SourceCabinet,
IN PCUNICODE_STRING DestinationPath)
{
INFCONTEXT FilesContext;
INFCONTEXT DirContext;
PCWSTR FileKeyName;
PCWSTR FileKeyValue;
PCWSTR DirKeyValue;
PCWSTR TargetFileName;
WCHAR FileDstPath[MAX_PATH];
/* Search for the SectionName section */
if (!SpInfFindFirstLine(InfFile, SectionName, NULL, &FilesContext))
{
pSetupData->LastErrorNumber = ERROR_TXTSETUP_SECTION;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, SectionName);
return FALSE;
}
/*
* Enumerate the files in the section and add them to the file queue.
*/
do
{
/* Get source file name and target directory id */
if (!INF_GetData(&FilesContext, &FileKeyName, &FileKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
break;
}
/* Get optional target file name */
if (!INF_GetDataField(&FilesContext, 2, &TargetFileName))
TargetFileName = NULL;
DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
/* Lookup target directory */
if (!SpInfFindFirstLine(InfFile, L"Directories", FileKeyValue, &DirContext))
{
/* FIXME: Handle error! */
DPRINT1("SetupFindFirstLine() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(FileKeyValue);
INF_FreeData(TargetFileName);
break;
}
INF_FreeData(FileKeyValue);
if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
break;
}
#if 1 // HACK moved! (r66604)
{
ULONG Length = wcslen(DirKeyValue);
if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
Length--;
*((PWSTR)DirKeyValue + Length) = UNICODE_NULL;
}
/* Build the full target path */
RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
pSetupData->DestinationRootPath.Buffer);
if (DirKeyValue[0] == UNICODE_NULL)
{
/* Installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, pSetupData->InstallPath.Buffer);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
// if (DirKeyValue[1] != UNICODE_NULL)
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, DirKeyValue);
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
pSetupData->InstallPath.Buffer, DirKeyValue);
}
#endif
if (!SpFileQueueCopy((HSPFILEQ)pSetupData->SetupFileQueue,
pSetupData->SourceRootPath.Buffer,
pSetupData->SourceRootDir.Buffer,
FileKeyName,
NULL,
SourceCabinet,
NULL,
FileDstPath,
TargetFileName,
0 /* FIXME */))
{
/* FIXME: Handle error! */
DPRINT1("SpFileQueueCopy() failed\n");
}
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
INF_FreeData(DirKeyValue);
} while (SpInfFindNextLine(&FilesContext, &FilesContext));
return TRUE;
}
// Note: Modeled after the SetupQueueCopySection() API
/*
BOOL SetupQueueCopySection(
_In_ HSPFILEQ QueueHandle,
_In_ PCTSTR SourceRootPath,
_In_ HINF InfHandle,
_In_ HINF ListInfHandle,
_In_ PCTSTR Section,
_In_ DWORD CopyStyle
);
*/
static BOOLEAN
AddSectionToCopyQueue(
IN PUSETUP_DATA pSetupData,
IN HINF InfFile,
IN PCWSTR SectionName,
IN PCWSTR SourceCabinet,
IN PCUNICODE_STRING DestinationPath)
{
INFCONTEXT FilesContext;
INFCONTEXT DirContext;
PCWSTR FileKeyName;
PCWSTR FileKeyValue;
PCWSTR DirKeyValue;
PCWSTR TargetFileName;
WCHAR CompleteOrigDirName[512]; // FIXME: MAX_PATH is not enough?
WCHAR FileDstPath[MAX_PATH];
if (SourceCabinet)
return AddSectionToCopyQueueCab(pSetupData, InfFile, L"SourceFiles", SourceCabinet, DestinationPath);
/*
* This code enumerates the list of files in txtsetup.sif
* that need to be installed in their respective directories.
*/
/* Search for the SectionName section */
if (!SpInfFindFirstLine(InfFile, SectionName, NULL, &FilesContext))
{
pSetupData->LastErrorNumber = ERROR_TXTSETUP_SECTION;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, SectionName);
return FALSE;
}
/*
* Enumerate the files in the section and add them to the file queue.
*/
do
{
/* Get source file name */
if (!INF_GetDataField(&FilesContext, 0, &FileKeyName))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
break;
}
/* Get target directory id */
if (!INF_GetDataField(&FilesContext, 13, &FileKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
INF_FreeData(FileKeyName);
break;
}
/* Get optional target file name */
if (!INF_GetDataField(&FilesContext, 11, &TargetFileName))
TargetFileName = NULL;
else if (!*TargetFileName)
TargetFileName = NULL;
DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
/* Lookup target directory */
if (!SpInfFindFirstLine(InfFile, L"Directories", FileKeyValue, &DirContext))
{
/* FIXME: Handle error! */
DPRINT1("SetupFindFirstLine() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(FileKeyValue);
INF_FreeData(TargetFileName);
break;
}
INF_FreeData(FileKeyValue);
if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
break;
}
if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL))
{
/* Installation path */
DPRINT("InstallationPath: '%S'\n", DirKeyValue);
RtlStringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName),
pSetupData->SourceRootDir.Buffer);
DPRINT("InstallationPath(2): '%S'\n", CompleteOrigDirName);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
DPRINT("AbsolutePath: '%S'\n", DirKeyValue);
RtlStringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName),
DirKeyValue);
DPRINT("AbsolutePath(2): '%S'\n", CompleteOrigDirName);
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
DPRINT("RelativePath: '%S'\n", DirKeyValue);
CombinePaths(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), 2,
pSetupData->SourceRootDir.Buffer, DirKeyValue);
DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName);
}
#if 1 // HACK moved! (r66604)
{
ULONG Length = wcslen(DirKeyValue);
if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
Length--;
*((PWSTR)DirKeyValue + Length) = UNICODE_NULL;
}
/* Build the full target path */
RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
pSetupData->DestinationRootPath.Buffer);
if (DirKeyValue[0] == UNICODE_NULL)
{
/* Installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, pSetupData->InstallPath.Buffer);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
// if (DirKeyValue[1] != UNICODE_NULL)
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, DirKeyValue);
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
pSetupData->InstallPath.Buffer, DirKeyValue);
}
#endif
if (!SpFileQueueCopy((HSPFILEQ)pSetupData->SetupFileQueue,
pSetupData->SourceRootPath.Buffer,
CompleteOrigDirName,
FileKeyName,
NULL,
SourceCabinet,
NULL,
FileDstPath,
TargetFileName,
0 /* FIXME */))
{
/* FIXME: Handle error! */
DPRINT1("SpFileQueueCopy() failed\n");
}
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
INF_FreeData(DirKeyValue);
} while (SpInfFindNextLine(&FilesContext, &FilesContext));
return TRUE;
}
BOOLEAN // ERROR_NUMBER
PrepareCopyInfFile(
IN OUT PUSETUP_DATA pSetupData,
IN HINF InfFile,
IN PCWSTR SourceCabinet OPTIONAL)
{
NTSTATUS Status;
INFCONTEXT DirContext;
PWCHAR AdditionalSectionName = NULL;
PCWSTR DirKeyValue;
WCHAR PathBuffer[MAX_PATH];
/* Add common files */
if (!AddSectionToCopyQueue(pSetupData, InfFile, L"SourceDisksFiles", SourceCabinet, &pSetupData->DestinationPath))
return FALSE;
/* Add specific files depending of computer type */
if (SourceCabinet == NULL)
{
if (!ProcessComputerFiles(InfFile, pSetupData->ComputerList, &AdditionalSectionName))
return FALSE;
if (AdditionalSectionName)
{
if (!AddSectionToCopyQueue(pSetupData, InfFile, AdditionalSectionName, SourceCabinet, &pSetupData->DestinationPath))
return FALSE;
}
}
/* Create directories */
/*
* FIXME:
* Copying files to pSetupData->DestinationRootPath should be done from within
* the SystemPartitionFiles section.
* At the moment we check whether we specify paths like '\foo' or '\\' for that.
* For installing to pSetupData->DestinationPath specify just '\' .
*/
/* Get destination path */
RtlStringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), pSetupData->DestinationPath.Buffer);
DPRINT("FullPath(1): '%S'\n", PathBuffer);
/* Create the install directory */
Status = SetupCreateDirectory(PathBuffer);
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
{
DPRINT1("Creating directory '%S' failed: Status = 0x%08lx\n", PathBuffer, Status);
pSetupData->LastErrorNumber = ERROR_CREATE_INSTALL_DIR;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, PathBuffer);
return FALSE;
}
/* Search for the 'Directories' section */
if (!SpInfFindFirstLine(InfFile, L"Directories", NULL, &DirContext))
{
if (SourceCabinet)
pSetupData->LastErrorNumber = ERROR_CABINET_SECTION;
else
pSetupData->LastErrorNumber = ERROR_TXTSETUP_SECTION;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, L"Directories");
return FALSE;
}
/* Enumerate the directory values and create the subdirectories */
do
{
if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
{
DPRINT1("break\n");
break;
}
if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL))
{
/* Installation path */
DPRINT("InstallationPath: '%S'\n", DirKeyValue);
RtlStringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer),
pSetupData->DestinationPath.Buffer);
DPRINT("InstallationPath(2): '%S'\n", PathBuffer);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
DPRINT("AbsolutePath: '%S'\n", DirKeyValue);
CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
pSetupData->DestinationRootPath.Buffer, DirKeyValue);
DPRINT("AbsolutePath(2): '%S'\n", PathBuffer);
Status = SetupCreateDirectory(PathBuffer);
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
{
INF_FreeData(DirKeyValue);
DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
pSetupData->LastErrorNumber = ERROR_CREATE_DIR;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, PathBuffer);
return FALSE;
}
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
DPRINT("RelativePath: '%S'\n", DirKeyValue);
CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
pSetupData->DestinationPath.Buffer, DirKeyValue);
DPRINT("RelativePath(2): '%S'\n", PathBuffer);
Status = SetupCreateDirectory(PathBuffer);
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
{
INF_FreeData(DirKeyValue);
DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
pSetupData->LastErrorNumber = ERROR_CREATE_DIR;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, PathBuffer);
return FALSE;
}
}
INF_FreeData(DirKeyValue);
} while (SpInfFindNextLine(&DirContext, &DirContext));
return TRUE;
}
// #define USE_CABINET_INF
BOOLEAN // ERROR_NUMBER
PrepareFileCopy(
IN OUT PUSETUP_DATA pSetupData,
IN PFILE_COPY_STATUS_ROUTINE StatusRoutine OPTIONAL)
{
HINF InfHandle;
INFCONTEXT CabinetsContext;
PCWSTR CabinetName;
UINT ErrorLine;
#if defined(__REACTOS__) && defined(USE_CABINET_INF)
ULONG InfFileSize;
PVOID InfFileData;
CABINET_CONTEXT CabinetContext;
#endif
WCHAR PathBuffer[MAX_PATH];
/* Create the file queue */
pSetupData->SetupFileQueue = (PVOID)SpFileQueueOpen();
if (pSetupData->SetupFileQueue == NULL)
{
pSetupData->LastErrorNumber = ERROR_COPY_QUEUE;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData);
return FALSE;
}
/* Prepare the copy of the common files that are not in installation cabinets */
if (!PrepareCopyInfFile(pSetupData, pSetupData->SetupInf, NULL))
{
/* FIXME: show an error dialog */
return FALSE;
}
/* Search for the 'Cabinets' section */
if (!SpInfFindFirstLine(pSetupData->SetupInf, L"Cabinets", NULL, &CabinetsContext))
{
/* Skip this step and return success if no cabinet file is listed */
return TRUE;
}
/*
* Enumerate the installation cabinets listed in the
* 'Cabinets' section and parse their inf files.
*/
do
{
if (!INF_GetData(&CabinetsContext, NULL, &CabinetName))
break;
CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
pSetupData->SourcePath.Buffer, CabinetName);
#if defined(__REACTOS__) && defined(USE_CABINET_INF)
INF_FreeData(CabinetName);
CabinetInitialize(&CabinetContext);
CabinetSetEventHandlers(&CabinetContext, NULL, NULL, NULL);
CabinetSetCabinetName(&CabinetContext, PathBuffer);
if (CabinetOpen(&CabinetContext) == CAB_STATUS_SUCCESS)
{
DPRINT("Cabinet %S\n", PathBuffer);
InfFileData = CabinetGetCabinetReservedArea(&CabinetContext, &InfFileSize);
if (InfFileData == NULL)
{
CabinetCleanup(&CabinetContext);
pSetupData->LastErrorNumber = ERROR_CABINET_SCRIPT;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, PathBuffer);
return FALSE;
}
}
else
{
DPRINT("Cannot open cabinet: %S.\n", PathBuffer);
CabinetCleanup(&CabinetContext);
pSetupData->LastErrorNumber = ERROR_CABINET_MISSING;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, PathBuffer);
return FALSE;
}
InfHandle = INF_OpenBufferedFileA((PSTR)InfFileData,
InfFileSize,
NULL,
INF_STYLE_WIN4,
pSetupData->LanguageId,
&ErrorLine);
CabinetCleanup(&CabinetContext);
#else
{
PWCHAR ptr;
/* First find the filename */
ptr = wcsrchr(PathBuffer, L'\\');
if (!ptr) ptr = PathBuffer;
/* Then find its extension */
ptr = wcsrchr(ptr, L'.');
if (!ptr)
ptr = PathBuffer + wcslen(PathBuffer);
/* Replace it by '.inf' */
wcscpy(ptr, L".inf");
InfHandle = SpInfOpenInfFile(PathBuffer,
NULL,
INF_STYLE_OLDNT, // INF_STYLE_WIN4,
pSetupData->LanguageId,
&ErrorLine);
}
#endif
if (InfHandle == INVALID_HANDLE_VALUE)
{
pSetupData->LastErrorNumber = ERROR_INVALID_CABINET_INF;
if (pSetupData->ErrorRoutine)
pSetupData->ErrorRoutine(pSetupData, PathBuffer);
return FALSE;
}
if (!PrepareCopyInfFile(pSetupData, InfHandle, CabinetName))
{
#if !(defined(__REACTOS__) && defined(USE_CABINET_INF))
SpInfCloseInfFile(InfHandle);
#endif
/* FIXME: show an error dialog */
return FALSE;
}
#if !(defined(__REACTOS__) && defined(USE_CABINET_INF))
SpInfCloseInfFile(InfHandle);
#endif
} while (SpInfFindNextLine(&CabinetsContext, &CabinetsContext));
return TRUE;
}
BOOLEAN
DoFileCopy(
IN OUT PUSETUP_DATA pSetupData,
IN PSP_FILE_CALLBACK_W MsgHandler,
IN PVOID Context OPTIONAL)
{
BOOLEAN Success;
Success = SpFileQueueCommit(NULL,
(HSPFILEQ)pSetupData->SetupFileQueue,
MsgHandler,
Context);
SpFileQueueClose((HSPFILEQ)pSetupData->SetupFileQueue);
pSetupData->SetupFileQueue = NULL;
return Success;
}
/* EOF */

40
base/setup/lib/install.h Normal file
View file

@ -0,0 +1,40 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Setup Library
* FILE: base/setup/lib/install.c
* PURPOSE: Installation functions
* PROGRAMMERS: Hervé Poussineau (hpoussin@reactos.org)
* Hermes Belusca-Maito (hermes.belusca@sfr.fr)
*/
#pragma once
typedef enum _FILE_COPY_STATUS
{
None = 0,
// Success = 0,
} FILE_COPY_STATUS;
typedef VOID
(__cdecl *PFILE_COPY_STATUS_ROUTINE)(IN FILE_COPY_STATUS, ...);
#if 0
BOOLEAN // ERROR_NUMBER
PrepareCopyInfFile(
IN OUT PUSETUP_DATA pSetupData,
IN HINF InfFile,
IN PCWSTR SourceCabinet OPTIONAL);
#endif
BOOLEAN // ERROR_NUMBER
PrepareFileCopy(
IN OUT PUSETUP_DATA pSetupData,
IN PFILE_COPY_STATUS_ROUTINE StatusRoutine OPTIONAL);
BOOLEAN
DoFileCopy(
IN OUT PUSETUP_DATA pSetupData,
IN PSP_FILE_CALLBACK_W MsgHandler,
IN PVOID Context OPTIONAL);
/* EOF */

View file

@ -44,6 +44,8 @@ extern HANDLE ProcessHeap;
#include "mui.h"
#include "settings.h"
// #include "install.h" // See at the end...
/* DEFINES ******************************************************************/
@ -124,6 +126,10 @@ typedef struct _USETUP_DATA
WCHAR InstallationDirectory[MAX_PATH];
} USETUP_DATA, *PUSETUP_DATA;
#include "install.h"
// HACK!!
extern BOOLEAN IsUnattendedSetup;

View file

@ -69,19 +69,6 @@ static PNTOS_INSTALLATION CurrentInstallation = NULL;
static PGENERIC_LIST NtOsInstallsList = NULL;
// HACK: Temporary compatibility code.
#if 1
static CABINET_CONTEXT CabinetContext;
#define CabinetInitialize() (CabinetInitialize(&CabinetContext))
#define CabinetSetEventHandlers(a,b,c) (CabinetSetEventHandlers(&CabinetContext,(a),(b),(c)))
#define CabinetSetCabinetName(a) (CabinetSetCabinetName(&CabinetContext,(a)))
#define CabinetOpen() (CabinetOpen(&CabinetContext))
#define CabinetGetCabinetName() (CabinetGetCabinetName(&CabinetContext))
#define CabinetGetCabinetReservedArea(a) (CabinetGetCabinetReservedArea(&CabinetContext,(a)))
#define CabinetCleanup() (CabinetCleanup(&CabinetContext))
#endif
/* FUNCTIONS ****************************************************************/
static VOID
@ -3503,434 +3490,6 @@ USetupErrorRoutine(
va_end(arg_ptr);
}
static BOOLEAN
AddSectionToCopyQueueCab(HINF InfFile,
PCWSTR SectionName,
PCWSTR SourceCabinet,
PCUNICODE_STRING DestinationPath,
PINPUT_RECORD Ir)
{
INFCONTEXT FilesContext;
INFCONTEXT DirContext;
PCWSTR FileKeyName;
PCWSTR FileKeyValue;
PCWSTR DirKeyValue;
PCWSTR TargetFileName;
WCHAR FileDstPath[MAX_PATH];
/*
* This code enumerates the list of files in reactos.dff / reactos.inf
* that need to be extracted from reactos.cab and be installed in their
* respective directories.
*/
/* Search for the SectionName section */
if (!SpInfFindFirstLine(InfFile, SectionName, NULL, &FilesContext))
{
MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, SectionName);
return FALSE;
}
/*
* Enumerate the files in the section and add them to the file queue.
*/
do
{
/* Get source file name and target directory id */
if (!INF_GetData(&FilesContext, &FileKeyName, &FileKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
break;
}
/* Get optional target file name */
if (!INF_GetDataField(&FilesContext, 2, &TargetFileName))
TargetFileName = NULL;
DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
/* Lookup target directory */
if (!SpInfFindFirstLine(InfFile, L"Directories", FileKeyValue, &DirContext))
{
/* FIXME: Handle error! */
DPRINT1("SetupFindFirstLine() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(FileKeyValue);
INF_FreeData(TargetFileName);
break;
}
INF_FreeData(FileKeyValue);
if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
break;
}
#if 1 // HACK moved! (r66604)
{
ULONG Length = wcslen(DirKeyValue);
if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
Length--;
*((PWSTR)DirKeyValue + Length) = UNICODE_NULL;
}
/* Build the full target path */
RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
USetupData.DestinationRootPath.Buffer);
if (DirKeyValue[0] == UNICODE_NULL)
{
/* Installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, USetupData.InstallPath.Buffer);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
// if (DirKeyValue[1] != UNICODE_NULL)
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, DirKeyValue);
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
USetupData.InstallPath.Buffer, DirKeyValue);
}
#endif
if (!SpFileQueueCopy((HSPFILEQ)USetupData.SetupFileQueue,
USetupData.SourceRootPath.Buffer,
USetupData.SourceRootDir.Buffer,
FileKeyName,
NULL,
SourceCabinet,
NULL,
FileDstPath,
TargetFileName,
0 /* FIXME */))
{
/* FIXME: Handle error! */
DPRINT1("SpFileQueueCopy() failed\n");
}
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
INF_FreeData(DirKeyValue);
} while (SpInfFindNextLine(&FilesContext, &FilesContext));
return TRUE;
}
static BOOLEAN
AddSectionToCopyQueue(HINF InfFile,
PCWSTR SectionName,
PCWSTR SourceCabinet,
PCUNICODE_STRING DestinationPath,
PINPUT_RECORD Ir)
{
INFCONTEXT FilesContext;
INFCONTEXT DirContext;
PCWSTR FileKeyName;
PCWSTR FileKeyValue;
PCWSTR DirKeyValue;
PCWSTR TargetFileName;
WCHAR CompleteOrigDirName[512]; // FIXME: MAX_PATH is not enough?
WCHAR FileDstPath[MAX_PATH];
if (SourceCabinet)
return AddSectionToCopyQueueCab(InfFile, L"SourceFiles", SourceCabinet, DestinationPath, Ir);
/*
* This code enumerates the list of files in txtsetup.sif
* that need to be installed in their respective directories.
*/
/* Search for the SectionName section */
if (!SpInfFindFirstLine(InfFile, SectionName, NULL, &FilesContext))
{
MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, SectionName);
return FALSE;
}
/*
* Enumerate the files in the section and add them to the file queue.
*/
do
{
/* Get source file name */
if (!INF_GetDataField(&FilesContext, 0, &FileKeyName))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
break;
}
/* Get target directory id */
if (!INF_GetDataField(&FilesContext, 13, &FileKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
INF_FreeData(FileKeyName);
break;
}
/* Get optional target file name */
if (!INF_GetDataField(&FilesContext, 11, &TargetFileName))
TargetFileName = NULL;
else if (!*TargetFileName)
TargetFileName = NULL;
DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
/* Lookup target directory */
if (!SpInfFindFirstLine(InfFile, L"Directories", FileKeyValue, &DirContext))
{
/* FIXME: Handle error! */
DPRINT1("SetupFindFirstLine() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(FileKeyValue);
INF_FreeData(TargetFileName);
break;
}
INF_FreeData(FileKeyValue);
if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
{
/* FIXME: Handle error! */
DPRINT1("INF_GetData() failed\n");
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
break;
}
if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL))
{
/* Installation path */
DPRINT("InstallationPath: '%S'\n", DirKeyValue);
RtlStringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName),
USetupData.SourceRootDir.Buffer);
DPRINT("InstallationPath(2): '%S'\n", CompleteOrigDirName);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
DPRINT("AbsolutePath: '%S'\n", DirKeyValue);
RtlStringCchCopyW(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName),
DirKeyValue);
DPRINT("AbsolutePath(2): '%S'\n", CompleteOrigDirName);
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
DPRINT("RelativePath: '%S'\n", DirKeyValue);
CombinePaths(CompleteOrigDirName, ARRAYSIZE(CompleteOrigDirName), 2,
USetupData.SourceRootDir.Buffer, DirKeyValue);
DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName);
}
#if 1 // HACK moved! (r66604)
{
ULONG Length = wcslen(DirKeyValue);
if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
Length--;
*((PWSTR)DirKeyValue + Length) = UNICODE_NULL;
}
/* Build the full target path */
RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
USetupData.DestinationRootPath.Buffer);
if (DirKeyValue[0] == UNICODE_NULL)
{
/* Installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, USetupData.InstallPath.Buffer);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
// if (DirKeyValue[1] != UNICODE_NULL)
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, DirKeyValue);
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
/* Add the installation path */
ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
USetupData.InstallPath.Buffer, DirKeyValue);
}
#endif
if (!SpFileQueueCopy((HSPFILEQ)USetupData.SetupFileQueue,
USetupData.SourceRootPath.Buffer,
CompleteOrigDirName,
FileKeyName,
NULL,
SourceCabinet,
NULL,
FileDstPath,
TargetFileName,
0 /* FIXME */))
{
/* FIXME: Handle error! */
DPRINT1("SpFileQueueCopy() failed\n");
}
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
INF_FreeData(DirKeyValue);
} while (SpInfFindNextLine(&FilesContext, &FilesContext));
return TRUE;
}
static BOOLEAN
PrepareCopyPageInfFile(HINF InfFile,
PCWSTR SourceCabinet,
PINPUT_RECORD Ir)
{
NTSTATUS Status;
INFCONTEXT DirContext;
PWCHAR AdditionalSectionName = NULL;
PCWSTR DirKeyValue;
WCHAR PathBuffer[MAX_PATH];
/* Add common files */
if (!AddSectionToCopyQueue(InfFile, L"SourceDisksFiles", SourceCabinet, &USetupData.DestinationPath, Ir))
return FALSE;
/* Add specific files depending of computer type */
if (SourceCabinet == NULL)
{
if (!ProcessComputerFiles(InfFile, USetupData.ComputerList, &AdditionalSectionName))
return FALSE;
if (AdditionalSectionName)
{
if (!AddSectionToCopyQueue(InfFile, AdditionalSectionName, SourceCabinet, &USetupData.DestinationPath, Ir))
return FALSE;
}
}
/* Create directories */
/*
* FIXME:
* Copying files to USetupData.DestinationRootPath should be done from within
* the SystemPartitionFiles section.
* At the moment we check whether we specify paths like '\foo' or '\\' for that.
* For installing to USetupData.DestinationPath specify just '\' .
*/
/* Get destination path */
RtlStringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer), USetupData.DestinationPath.Buffer);
DPRINT("FullPath(1): '%S'\n", PathBuffer);
/* Create the install directory */
Status = SetupCreateDirectory(PathBuffer);
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
{
DPRINT1("Creating directory '%S' failed: Status = 0x%08lx\n", PathBuffer, Status);
MUIDisplayError(ERROR_CREATE_INSTALL_DIR, Ir, POPUP_WAIT_ENTER);
return FALSE;
}
/* Search for the 'Directories' section */
if (!SpInfFindFirstLine(InfFile, L"Directories", NULL, &DirContext))
{
if (SourceCabinet)
MUIDisplayError(ERROR_CABINET_SECTION, Ir, POPUP_WAIT_ENTER, L"Directories");
else
MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, L"Directories");
return FALSE;
}
/* Enumerate the directory values and create the subdirectories */
do
{
if (!INF_GetData(&DirContext, NULL, &DirKeyValue))
{
DPRINT1("break\n");
break;
}
if ((DirKeyValue[0] == UNICODE_NULL) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == UNICODE_NULL))
{
/* Installation path */
DPRINT("InstallationPath: '%S'\n", DirKeyValue);
RtlStringCchCopyW(PathBuffer, ARRAYSIZE(PathBuffer),
USetupData.DestinationPath.Buffer);
DPRINT("InstallationPath(2): '%S'\n", PathBuffer);
}
else if (DirKeyValue[0] == L'\\')
{
/* Absolute path */
DPRINT("AbsolutePath: '%S'\n", DirKeyValue);
CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
USetupData.DestinationRootPath.Buffer, DirKeyValue);
DPRINT("AbsolutePath(2): '%S'\n", PathBuffer);
Status = SetupCreateDirectory(PathBuffer);
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
{
INF_FreeData(DirKeyValue);
DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER);
return FALSE;
}
}
else // if (DirKeyValue[0] != L'\\')
{
/* Path relative to the installation path */
DPRINT("RelativePath: '%S'\n", DirKeyValue);
CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
USetupData.DestinationPath.Buffer, DirKeyValue);
DPRINT("RelativePath(2): '%S'\n", PathBuffer);
Status = SetupCreateDirectory(PathBuffer);
if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION)
{
INF_FreeData(DirKeyValue);
DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status);
MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER);
return FALSE;
}
}
INF_FreeData(DirKeyValue);
} while (SpInfFindNextLine(&DirContext, &DirContext));
return TRUE;
}
/*
* Displays the PrepareCopyPage.
*
@ -3939,8 +3498,7 @@ PrepareCopyPageInfFile(HINF InfFile,
* QuitPage
*
* SIDEEFFECTS
* Inits SetupFileQueue
* Calls PrepareCopyPageInfFile
* Calls PrepareFileCopy
*
* RETURNS
* Number of the next page.
@ -3948,92 +3506,18 @@ PrepareCopyPageInfFile(HINF InfFile,
static PAGE_NUMBER
PrepareCopyPage(PINPUT_RECORD Ir)
{
HINF InfHandle;
WCHAR PathBuffer[MAX_PATH];
INFCONTEXT CabinetsContext;
ULONG InfFileSize;
PCWSTR KeyValue;
UINT ErrorLine;
PVOID InfFileData;
// ERROR_NUMBER ErrorNumber;
BOOLEAN Success;
MUIDisplayPage(PREPARE_COPY_PAGE);
/* Create the file queue */
USetupData.SetupFileQueue = SpFileQueueOpen();
if (USetupData.SetupFileQueue == NULL)
/* ErrorNumber = */ Success = PrepareFileCopy(&USetupData, NULL);
if (/*ErrorNumber != ERROR_SUCCESS*/ !Success)
{
MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER);
// MUIDisplayError(ErrorNumber, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
if (!PrepareCopyPageInfFile(USetupData.SetupInf, NULL, Ir))
{
/* FIXME: show an error dialog */
return QUIT_PAGE;
}
/* Search for the 'Cabinets' section */
if (!SpInfFindFirstLine(USetupData.SetupInf, L"Cabinets", NULL, &CabinetsContext))
{
return FILE_COPY_PAGE;
}
/*
* Enumerate the directory values in the 'Cabinets'
* section and parse their inf files.
*/
do
{
if (!INF_GetData(&CabinetsContext, NULL, &KeyValue))
break;
CombinePaths(PathBuffer, ARRAYSIZE(PathBuffer), 2,
USetupData.SourcePath.Buffer, KeyValue);
CabinetInitialize();
CabinetSetEventHandlers(NULL, NULL, NULL);
CabinetSetCabinetName(PathBuffer);
if (CabinetOpen() == CAB_STATUS_SUCCESS)
{
DPRINT("Cabinet %S\n", CabinetGetCabinetName());
InfFileData = CabinetGetCabinetReservedArea(&InfFileSize);
if (InfFileData == NULL)
{
MUIDisplayError(ERROR_CABINET_SCRIPT, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
}
else
{
DPRINT("Cannot open cabinet: %S.\n", CabinetGetCabinetName());
MUIDisplayError(ERROR_CABINET_MISSING, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
InfHandle = INF_OpenBufferedFileA((PSTR)InfFileData,
InfFileSize,
NULL,
INF_STYLE_WIN4,
USetupData.LanguageId,
&ErrorLine);
if (InfHandle == INVALID_HANDLE_VALUE)
{
MUIDisplayError(ERROR_INVALID_CABINET_INF, Ir, POPUP_WAIT_ENTER);
return QUIT_PAGE;
}
CabinetCleanup();
if (!PrepareCopyPageInfFile(InfHandle, KeyValue, Ir))
{
/* FIXME: show an error dialog */
return QUIT_PAGE;
}
} while (SpInfFindNextLine(&CabinetsContext, &CabinetsContext));
return FILE_COPY_PAGE;
}
@ -4188,8 +3672,7 @@ FileCopyCallback(PVOID Context,
* RegistryPage(At once)
*
* SIDEEFFECTS
* Calls SetupCommitFileQueueW
* Calls SpFileQueueClose
* Calls DoFileCopy
*
* RETURNS
* Number of the next page.
@ -4251,13 +3734,9 @@ FileCopyPage(PINPUT_RECORD Ir)
"Free Memory");
/* Do the file copying */
SpFileQueueCommit(NULL,
USetupData.SetupFileQueue,
FileCopyCallback,
&CopyContext);
DoFileCopy(&USetupData, FileCopyCallback, &CopyContext);
/* If we get here, we're done, so cleanup the queue and progress bar */
SpFileQueueClose(USetupData.SetupFileQueue);
/* If we get here, we're done, so cleanup the progress bar */
DestroyProgressBar(CopyContext.ProgressBar);
DestroyProgressBar(CopyContext.MemoryBars[0]);
DestroyProgressBar(CopyContext.MemoryBars[1]);