mirror of
https://github.com/reactos/reactos.git
synced 2025-07-31 21:11:54 +00:00
[SETUPLIB][USETUP] Move all the code that performs file copying into the SETUPLIB.
This commit is contained in:
parent
f894631472
commit
3d137b05d1
5 changed files with 699 additions and 530 deletions
|
@ -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
643
base/setup/lib/install.c
Normal 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
40
base/setup/lib/install.h
Normal 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 */
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue