https://git.reactos.org/?p=reactos.git;a=commitdiff;h=3d137b05d16dfbd8a2c93…
commit 3d137b05d16dfbd8a2c93e6485d28374acd3aeee
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Sun Jan 7 01:35:48 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Mon Nov 5 23:18:47 2018 +0100
[SETUPLIB][USETUP] Move all the code that performs file copying into the SETUPLIB.
---
base/setup/lib/CMakeLists.txt | 1 +
base/setup/lib/install.c | 643 ++++++++++++++++++++++++++++++++++++++++++
base/setup/lib/install.h | 40 +++
base/setup/lib/setuplib.h | 6 +
base/setup/usetup/usetup.c | 539 +----------------------------------
5 files changed, 699 insertions(+), 530 deletions(-)
diff --git a/base/setup/lib/CMakeLists.txt b/base/setup/lib/CMakeLists.txt
index 7c23e24045..0d2f3a8aeb 100644
--- a/base/setup/lib/CMakeLists.txt
+++ b/base/setup/lib/CMakeLists.txt
@@ -17,6 +17,7 @@ list(APPEND SOURCE
utils/regutil.c
bootsup.c
fsutil.c
+ install.c
mui.c
registry.c
settings.c
diff --git a/base/setup/lib/install.c b/base/setup/lib/install.c
new file mode 100644
index 0000000000..31ece47b0d
--- /dev/null
+++ b/base/setup/lib/install.c
@@ -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(a)reactos.org)
+ * Hermes Belusca-Maito (hermes.belusca(a)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 */
diff --git a/base/setup/lib/install.h b/base/setup/lib/install.h
new file mode 100644
index 0000000000..8c3e84b325
--- /dev/null
+++ b/base/setup/lib/install.h
@@ -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(a)reactos.org)
+ * Hermes Belusca-Maito (hermes.belusca(a)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 */
diff --git a/base/setup/lib/setuplib.h b/base/setup/lib/setuplib.h
index 837633a7e7..4bd5981ff2 100644
--- a/base/setup/lib/setuplib.h
+++ b/base/setup/lib/setuplib.h
@@ -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;
diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c
index 4dbf3885c3..518194937f 100644
--- a/base/setup/usetup/usetup.c
+++ b/base/setup/usetup/usetup.c
@@ -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)
- {
- MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER);
- return QUIT_PAGE;
- }
-
- if (!PrepareCopyPageInfFile(USetupData.SetupInf, NULL, Ir))
+ /* ErrorNumber = */ Success = PrepareFileCopy(&USetupData, NULL);
+ if (/*ErrorNumber != ERROR_SUCCESS*/ !Success)
{
- /* FIXME: show an error dialog */
+ // MUIDisplayError(ErrorNumber, Ir, POPUP_WAIT_ENTER);
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]);