https://git.reactos.org/?p=reactos.git;a=commitdiff;h=44c101c9dcec40e8c87b9…
commit 44c101c9dcec40e8c87b96391501de59a53c4565
Author: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
AuthorDate: Fri Jan 5 02:08:59 2018 +0100
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Thu Nov 1 18:55:35 2018 +0100
[USETUP] Improvements for the File-queues code.
- Add support for delete and move/rename operations, which are needed
for implementing ReactOS upgrading support.
- Use cabinet contexts.
- Use standard LIST_ENTRY structures for implementing the lists.
- Move the path-building hack code in SetupCommitFileQueueW() that had
been introduced in r66604 (97bb83f) out of the file-queues code.
- Make the function prototypes compatible with win32's setupapi functions.
- Fix the format of the data passed to the custom notification handler.
- Adjust the file-copy callback to correctly use its arguments (setupapi-compatible).
---
base/setup/usetup/filequeue.c | 797 +++++++++++++++++++++++++++++-------------
base/setup/usetup/filequeue.h | 116 +++---
base/setup/usetup/usetup.c | 172 +++++++--
3 files changed, 771 insertions(+), 314 deletions(-)
diff --git a/base/setup/usetup/filequeue.c b/base/setup/usetup/filequeue.c
index bb1f71218c..c50203c361 100644
--- a/base/setup/usetup/filequeue.c
+++ b/base/setup/usetup/filequeue.c
@@ -34,98 +34,95 @@
typedef struct _QUEUEENTRY
{
- struct _QUEUEENTRY *Prev;
- struct _QUEUEENTRY *Next;
-
+ LIST_ENTRY ListEntry;
PWSTR SourceCabinet; /* May be NULL if the file is not in a cabinet */
PWSTR SourceRootPath;
PWSTR SourcePath;
- PWSTR SourceFilename;
+ PWSTR SourceFileName;
PWSTR TargetDirectory;
- PWSTR TargetFilename;
+ PWSTR TargetFileName;
} QUEUEENTRY, *PQUEUEENTRY;
-
typedef struct _FILEQUEUEHEADER
{
- PQUEUEENTRY CopyHead;
- PQUEUEENTRY CopyTail;
+ LIST_ENTRY DeleteQueue; // PQUEUEENTRY entries
+ ULONG DeleteCount;
+
+ LIST_ENTRY RenameQueue; // PQUEUEENTRY entries
+ ULONG RenameCount;
+
+ LIST_ENTRY CopyQueue; // PQUEUEENTRY entries
ULONG CopyCount;
+
+ BOOLEAN HasCurrentCabinet;
+ CABINET_CONTEXT CabinetContext;
+ CAB_SEARCH Search;
+ WCHAR CurrentCabinetName[MAX_PATH];
} FILEQUEUEHEADER, *PFILEQUEUEHEADER;
-/* FUNCTIONS ****************************************************************/
-
-static BOOLEAN HasCurrentCabinet = FALSE;
-static WCHAR CurrentCabinetName[MAX_PATH];
-static CAB_SEARCH Search;
-
-// 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 CabinetFindNextFileSequential(a,b)
(CabinetFindNextFileSequential(&CabinetContext,(a),(b)))
- #define CabinetFindFirst(a,b) (CabinetFindFirst(&CabinetContext,(a),(b)))
- #define CabinetSetDestinationPath(a)
(CabinetSetDestinationPath(&CabinetContext,(a)))
- #define CabinetExtractFile(a) (CabinetExtractFile(&CabinetContext,(a)))
- #define CabinetCleanup() (CabinetCleanup(&CabinetContext))
-#endif
-
-NTSTATUS
+/* SETUP* API COMPATIBILITY FUNCTIONS ****************************************/
+
+static NTSTATUS
SetupExtractFile(
- PWCHAR CabinetFileName,
- PWCHAR SourceFileName,
- PWCHAR DestinationPathName)
+ IN OUT PFILEQUEUEHEADER QueueHeader,
+ IN PCWSTR CabinetFileName,
+ IN PCWSTR SourceFileName,
+ IN PCWSTR DestinationPathName)
{
ULONG CabStatus;
- DPRINT("SetupExtractFile(CabinetFileName %S, SourceFileName %S,
DestinationPathName %S)\n",
+ DPRINT("SetupExtractFile(CabinetFileName: '%S', SourceFileName:
'%S', DestinationPathName: '%S')\n",
CabinetFileName, SourceFileName, DestinationPathName);
- if (HasCurrentCabinet)
+ if (QueueHeader->HasCurrentCabinet)
{
- DPRINT("CurrentCabinetName: %S\n", CurrentCabinetName);
+ DPRINT("CurrentCabinetName: '%S'\n",
QueueHeader->CurrentCabinetName);
}
- if ((HasCurrentCabinet) && (wcscmp(CabinetFileName, CurrentCabinetName) ==
0))
+ if (QueueHeader->HasCurrentCabinet &&
+ (wcscmp(CabinetFileName, QueueHeader->CurrentCabinetName) == 0))
{
DPRINT("Using same cabinet as last time\n");
/* Use our last location because the files should be sequential */
- CabStatus = CabinetFindNextFileSequential(SourceFileName, &Search);
+ CabStatus = CabinetFindNextFileSequential(&QueueHeader->CabinetContext,
+ SourceFileName,
+ &QueueHeader->Search);
if (CabStatus != CAB_STATUS_SUCCESS)
{
DPRINT("Sequential miss on file: %S\n", SourceFileName);
/* Looks like we got unlucky */
- CabStatus = CabinetFindFirst(SourceFileName, &Search);
+ CabStatus = CabinetFindFirst(&QueueHeader->CabinetContext,
+ SourceFileName,
+ &QueueHeader->Search);
}
}
else
{
DPRINT("Using new cabinet\n");
- if (HasCurrentCabinet)
+ if (QueueHeader->HasCurrentCabinet)
{
- CabinetCleanup();
+ QueueHeader->HasCurrentCabinet = FALSE;
+ CabinetCleanup(&QueueHeader->CabinetContext);
}
- wcscpy(CurrentCabinetName, CabinetFileName);
+ RtlStringCchCopyW(QueueHeader->CurrentCabinetName,
+ ARRAYSIZE(QueueHeader->CurrentCabinetName),
+ CabinetFileName);
- CabinetInitialize();
- CabinetSetEventHandlers(NULL, NULL, NULL);
- CabinetSetCabinetName(CabinetFileName);
+ CabinetInitialize(&QueueHeader->CabinetContext);
+ CabinetSetEventHandlers(&QueueHeader->CabinetContext,
+ NULL, NULL, NULL);
+ CabinetSetCabinetName(&QueueHeader->CabinetContext, CabinetFileName);
- CabStatus = CabinetOpen();
+ CabStatus = CabinetOpen(&QueueHeader->CabinetContext);
if (CabStatus == CAB_STATUS_SUCCESS)
{
- DPRINT("Opened cabinet %S\n", CabinetGetCabinetName());
- HasCurrentCabinet = TRUE;
+ DPRINT("Opened cabinet %S\n", CabinetFileName
/*CabinetGetCabinetName(&QueueHeader->CabinetContext)*/);
+ QueueHeader->HasCurrentCabinet = TRUE;
}
else
{
@@ -134,17 +131,20 @@ SetupExtractFile(
}
/* We have to start at the beginning here */
- CabStatus = CabinetFindFirst(SourceFileName, &Search);
+ CabStatus = CabinetFindFirst(&QueueHeader->CabinetContext,
+ SourceFileName,
+ &QueueHeader->Search);
}
if (CabStatus != CAB_STATUS_SUCCESS)
{
- DPRINT1("Unable to find '%S' in cabinet '%S'\n",
SourceFileName, CabinetGetCabinetName());
+ DPRINT1("Unable to find '%S' in cabinet '%S'\n",
+ SourceFileName,
CabinetGetCabinetName(&QueueHeader->CabinetContext));
return STATUS_UNSUCCESSFUL;
}
- CabinetSetDestinationPath(DestinationPathName);
- CabStatus = CabinetExtractFile(&Search);
+ CabinetSetDestinationPath(&QueueHeader->CabinetContext, DestinationPathName);
+ CabStatus = CabinetExtractFile(&QueueHeader->CabinetContext,
&QueueHeader->Search);
if (CabStatus != CAB_STATUS_SUCCESS)
{
DPRINT("Cannot extract file %S (%d)\n", SourceFileName, CabStatus);
@@ -160,27 +160,63 @@ SetupOpenFileQueue(VOID)
{
PFILEQUEUEHEADER QueueHeader;
- /* Allocate queue header */
- QueueHeader = (PFILEQUEUEHEADER)RtlAllocateHeap(ProcessHeap,
- 0,
- sizeof(FILEQUEUEHEADER));
+ /* Allocate the queue header */
+ QueueHeader = RtlAllocateHeap(ProcessHeap, 0, sizeof(FILEQUEUEHEADER));
if (QueueHeader == NULL)
return NULL;
- /* Initialize queue header */
- RtlZeroMemory(QueueHeader,
- sizeof(FILEQUEUEHEADER));
+ RtlZeroMemory(QueueHeader, sizeof(FILEQUEUEHEADER));
+
+ /* Initialize the file queues */
+ InitializeListHead(&QueueHeader->DeleteQueue);
+ QueueHeader->DeleteCount = 0;
+ InitializeListHead(&QueueHeader->RenameQueue);
+ QueueHeader->RenameCount = 0;
+ InitializeListHead(&QueueHeader->CopyQueue);
+ QueueHeader->CopyCount = 0;
+
+ QueueHeader->HasCurrentCabinet = FALSE;
return (HSPFILEQ)QueueHeader;
}
+static VOID
+SetupDeleteQueueEntry(
+ IN PQUEUEENTRY Entry)
+{
+ if (Entry == NULL)
+ return;
+
+ /* Delete all strings */
+ if (Entry->SourceCabinet != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
+
+ if (Entry->SourceRootPath != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
+
+ if (Entry->SourcePath != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
+
+ if (Entry->SourceFileName != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
+
+ if (Entry->TargetDirectory != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
+
+ if (Entry->TargetFileName != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->TargetFileName);
+
+ /* Delete queue entry */
+ RtlFreeHeap(ProcessHeap, 0, Entry);
+}
VOID
WINAPI
SetupCloseFileQueue(
- HSPFILEQ QueueHandle)
+ IN HSPFILEQ QueueHandle)
{
PFILEQUEUEHEADER QueueHeader;
+ PLIST_ENTRY ListEntry;
PQUEUEENTRY Entry;
if (QueueHandle == NULL)
@@ -188,71 +224,53 @@ SetupCloseFileQueue(
QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
- /* Delete copy queue */
- Entry = QueueHeader->CopyHead;
- while (Entry != NULL)
+ /* Delete the delete queue */
+ while (!IsListEmpty(&QueueHeader->DeleteQueue))
{
- /* Delete all strings */
- if (Entry->SourceCabinet != NULL)
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
-
- if (Entry->SourceRootPath != NULL)
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
-
- if (Entry->SourcePath != NULL)
- RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
-
- if (Entry->SourceFilename != NULL)
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename);
-
- if (Entry->TargetDirectory != NULL)
- RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
-
- if (Entry->TargetFilename != NULL)
- RtlFreeHeap(ProcessHeap, 0, Entry->TargetFilename);
-
- /* Unlink current queue entry */
- if (Entry->Next != NULL)
- {
- QueueHeader->CopyHead = Entry->Next;
- QueueHeader->CopyHead->Prev = NULL;
- }
- else
- {
- QueueHeader->CopyHead = NULL;
- QueueHeader->CopyTail = NULL;
- }
+ ListEntry = RemoveHeadList(&QueueHeader->DeleteQueue);
+ Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
+ SetupDeleteQueueEntry(Entry);
+ }
- /* Delete queue entry */
- RtlFreeHeap(ProcessHeap, 0, Entry);
+ /* Delete the rename queue */
+ while (!IsListEmpty(&QueueHeader->RenameQueue))
+ {
+ ListEntry = RemoveHeadList(&QueueHeader->RenameQueue);
+ Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
+ SetupDeleteQueueEntry(Entry);
+ }
- /* Get next queue entry */
- Entry = QueueHeader->CopyHead;
+ /* Delete the copy queue */
+ while (!IsListEmpty(&QueueHeader->CopyQueue))
+ {
+ ListEntry = RemoveHeadList(&QueueHeader->CopyQueue);
+ Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
+ SetupDeleteQueueEntry(Entry);
}
/* Delete queue header */
RtlFreeHeap(ProcessHeap, 0, QueueHeader);
}
-
+/* A simplified version of SetupQueueCopyW that wraps Cabinet support around */
BOOL
-SetupQueueCopy(
- HSPFILEQ QueueHandle,
- PCWSTR SourceCabinet,
- PCWSTR SourceRootPath,
- PCWSTR SourcePath,
- PCWSTR SourceFilename,
- PCWSTR TargetDirectory,
- PCWSTR TargetFilename)
+WINAPI
+SetupQueueCopyWithCab( // SetupQueueCopyW
+ IN HSPFILEQ QueueHandle,
+ IN PCWSTR SourceCabinet OPTIONAL,
+ IN PCWSTR SourceRootPath,
+ IN PCWSTR SourcePath OPTIONAL,
+ IN PCWSTR SourceFileName,
+ IN PCWSTR TargetDirectory,
+ IN PCWSTR TargetFileName OPTIONAL)
{
PFILEQUEUEHEADER QueueHeader;
PQUEUEENTRY Entry;
ULONG Length;
- /* SourceCabinet may be NULL */
if (QueueHandle == NULL ||
SourceRootPath == NULL ||
- SourceFilename == NULL ||
+ SourceFileName == NULL ||
TargetDirectory == NULL)
{
return FALSE;
@@ -260,194 +278,351 @@ SetupQueueCopy(
QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
+ DPRINT("SetupQueueCopy(Cab '%S', SrcRootPath '%S', SrcPath
'%S', SrcFN '%S' --> DstPath '%S', DstFN
'%S')\n",
+ SourceCabinet ? SourceCabinet : L"n/a",
+ SourceRootPath, SourcePath, SourceFileName,
+ TargetDirectory, TargetFileName);
+
/* Allocate new queue entry */
- Entry = (PQUEUEENTRY)RtlAllocateHeap(ProcessHeap,
- 0,
- sizeof(QUEUEENTRY));
+ Entry = RtlAllocateHeap(ProcessHeap, 0, sizeof(QUEUEENTRY));
if (Entry == NULL)
return FALSE;
- RtlZeroMemory(Entry,
- sizeof(QUEUEENTRY));
+ RtlZeroMemory(Entry, sizeof(QUEUEENTRY));
/* Copy source cabinet if available */
+ Entry->SourceCabinet = NULL;
if (SourceCabinet != NULL)
{
Length = wcslen(SourceCabinet);
- Entry->SourceCabinet = (WCHAR*)RtlAllocateHeap(ProcessHeap,
- 0,
- (Length + 1) * sizeof(WCHAR));
+ Entry->SourceCabinet = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
if (Entry->SourceCabinet == NULL)
{
RtlFreeHeap(ProcessHeap, 0, Entry);
return FALSE;
}
-
- wcsncpy(Entry->SourceCabinet, SourceCabinet, Length);
- Entry->SourceCabinet[Length] = UNICODE_NULL;
- }
- else
- {
- Entry->SourceCabinet = NULL;
+ RtlStringCchCopyW(Entry->SourceCabinet, Length + 1, SourceCabinet);
}
/* Copy source root path */
Length = wcslen(SourceRootPath);
- Entry->SourceRootPath = (WCHAR*)RtlAllocateHeap(ProcessHeap,
- 0,
- (Length + 1) * sizeof(WCHAR));
+ Entry->SourceRootPath = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
if (Entry->SourceRootPath == NULL)
{
if (Entry->SourceCabinet != NULL)
- {
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
- }
RtlFreeHeap(ProcessHeap, 0, Entry);
return FALSE;
}
-
- wcsncpy(Entry->SourceRootPath, SourceRootPath, Length);
- Entry->SourceRootPath[Length] = UNICODE_NULL;
+ RtlStringCchCopyW(Entry->SourceRootPath, Length + 1, SourceRootPath);
/* Copy source path */
+ Entry->SourcePath = NULL;
if (SourcePath != NULL)
{
Length = wcslen(SourcePath);
if ((Length > 0) && (SourcePath[Length - 1] == L'\\'))
Length--;
- Entry->SourcePath = (WCHAR*)RtlAllocateHeap(ProcessHeap,
- 0,
- (Length + 1) * sizeof(WCHAR));
+ Entry->SourcePath = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
if (Entry->SourcePath == NULL)
{
if (Entry->SourceCabinet != NULL)
- {
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
- }
RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
RtlFreeHeap(ProcessHeap, 0, Entry);
return FALSE;
}
-
- wcsncpy(Entry->SourcePath, SourcePath, Length);
- Entry->SourcePath[Length] = UNICODE_NULL;
+ RtlStringCchCopyW(Entry->SourcePath, Length + 1, SourcePath);
}
/* Copy source file name */
- Length = wcslen(SourceFilename);
- Entry->SourceFilename = (WCHAR*)RtlAllocateHeap(ProcessHeap,
+ Length = wcslen(SourceFileName);
+ Entry->SourceFileName = (WCHAR*)RtlAllocateHeap(ProcessHeap,
0,
(Length + 1) * sizeof(WCHAR));
- if (Entry->SourceFilename == NULL)
+ if (Entry->SourceFileName == NULL)
{
+ if (Entry->SourcePath != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
+
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
+
if (Entry->SourceCabinet != NULL)
- {
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
- }
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
- RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
RtlFreeHeap(ProcessHeap, 0, Entry);
return FALSE;
}
-
- wcsncpy(Entry->SourceFilename, SourceFilename, Length);
- Entry->SourceFilename[Length] = UNICODE_NULL;
+ RtlStringCchCopyW(Entry->SourceFileName, Length + 1, SourceFileName);
/* Copy target directory */
Length = wcslen(TargetDirectory);
if ((Length > 0) && (TargetDirectory[Length - 1] == L'\\'))
Length--;
- Entry->TargetDirectory = (WCHAR*)RtlAllocateHeap(ProcessHeap,
- 0,
- (Length + 1) * sizeof(WCHAR));
+ Entry->TargetDirectory = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
if (Entry->TargetDirectory == NULL)
{
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
+
+ if (Entry->SourcePath != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
+
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
+
if (Entry->SourceCabinet != NULL)
- {
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
- }
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
- RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename);
RtlFreeHeap(ProcessHeap, 0, Entry);
return FALSE;
}
-
- wcsncpy(Entry->TargetDirectory, TargetDirectory, Length);
- Entry->TargetDirectory[Length] = UNICODE_NULL;
+ RtlStringCchCopyW(Entry->TargetDirectory, Length + 1, TargetDirectory);
/* Copy optional target filename */
- if (TargetFilename != NULL)
+ Entry->TargetFileName = NULL;
+ if (TargetFileName != NULL)
{
- Length = wcslen(TargetFilename);
- Entry->TargetFilename = (WCHAR*)RtlAllocateHeap(ProcessHeap,
- 0,
- (Length + 1) * sizeof(WCHAR));
- if (Entry->TargetFilename == NULL)
+ Length = wcslen(TargetFileName);
+ Entry->TargetFileName = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
+ if (Entry->TargetFileName == NULL)
{
+ RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
+
+ if (Entry->SourcePath != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
+
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
+
if (Entry->SourceCabinet != NULL)
- {
RtlFreeHeap(ProcessHeap, 0, Entry->SourceCabinet);
- }
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceRootPath);
- RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
- RtlFreeHeap(ProcessHeap, 0, Entry->SourceFilename);
- RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
RtlFreeHeap(ProcessHeap, 0, Entry);
return FALSE;
}
-
- wcsncpy(Entry->TargetFilename, TargetFilename, Length);
- Entry->TargetFilename[Length] = UNICODE_NULL;
+ RtlStringCchCopyW(Entry->TargetFileName, Length + 1, TargetFileName);
}
/* Append queue entry */
- if (QueueHeader->CopyHead == NULL) // && QueueHeader->CopyTail ==
NULL)
+ InsertTailList(&QueueHeader->CopyQueue, &Entry->ListEntry);
+ ++QueueHeader->CopyCount;
+
+ return TRUE;
+}
+
+BOOL
+WINAPI
+SetupQueueDeleteW(
+ IN HSPFILEQ QueueHandle,
+ IN PCWSTR PathPart1,
+ IN PCWSTR PathPart2 OPTIONAL)
+{
+ PFILEQUEUEHEADER QueueHeader;
+ PQUEUEENTRY Entry;
+ ULONG Length;
+
+ if (QueueHandle == NULL || PathPart1 == NULL)
{
- Entry->Prev = NULL;
- Entry->Next = NULL;
- QueueHeader->CopyHead = Entry;
- QueueHeader->CopyTail = Entry;
+ return FALSE;
}
- else
+
+ QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
+
+ DPRINT1("SetupQueueDeleteW(PathPart1 '%S', PathPart2
'%S')\n",
+ PathPart1, PathPart2);
+
+ /* Allocate new queue entry */
+ Entry = RtlAllocateHeap(ProcessHeap, 0, sizeof(QUEUEENTRY));
+ if (Entry == NULL)
+ return FALSE;
+
+ RtlZeroMemory(Entry, sizeof(QUEUEENTRY));
+
+ Entry->SourceCabinet = NULL;
+ Entry->SourceRootPath = NULL;
+ Entry->SourcePath = NULL;
+ Entry->SourceFileName = NULL;
+
+ /* Copy first part of path */
+ Length = wcslen(PathPart1);
+ // if ((Length > 0) && (SourcePath[Length - 1] == L'\\'))
+ // Length--;
+ Entry->TargetDirectory = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
+ if (Entry->TargetDirectory == NULL)
{
- Entry->Prev = QueueHeader->CopyTail;
- Entry->Next = NULL;
- QueueHeader->CopyTail->Next = Entry;
- QueueHeader->CopyTail = Entry;
+ RtlFreeHeap(ProcessHeap, 0, Entry);
+ return FALSE;
+ }
+ RtlStringCchCopyW(Entry->TargetDirectory, Length + 1, PathPart1);
+
+ /* Copy optional second part of path */
+ if (PathPart2 != NULL)
+ {
+ Length = wcslen(PathPart2);
+ Entry->TargetFileName = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
+ if (Entry->TargetFileName == NULL)
+ {
+ RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
+ RtlFreeHeap(ProcessHeap, 0, Entry);
+ return FALSE;
+ }
+ RtlStringCchCopyW(Entry->TargetFileName, Length + 1, PathPart2);
}
- QueueHeader->CopyCount++;
+ /* Append the queue entry */
+ InsertTailList(&QueueHeader->DeleteQueue, &Entry->ListEntry);
+ ++QueueHeader->DeleteCount;
return TRUE;
}
+BOOL
+WINAPI
+SetupQueueRenameW(
+ IN HSPFILEQ QueueHandle,
+ IN PCWSTR SourcePath,
+ IN PCWSTR SourceFileName OPTIONAL,
+ IN PCWSTR TargetPath OPTIONAL,
+ IN PCWSTR TargetFileName)
+{
+ PFILEQUEUEHEADER QueueHeader;
+ PQUEUEENTRY Entry;
+ ULONG Length;
+
+ if (QueueHandle == NULL ||
+ SourcePath == NULL ||
+ TargetFileName == NULL)
+ {
+ return FALSE;
+ }
+
+ QueueHeader = (PFILEQUEUEHEADER)QueueHandle;
+
+ DPRINT1("SetupQueueRenameW(SrcPath '%S', SrcFN '%S' -->
DstPath '%S', DstFN '%S')\n",
+ SourcePath, SourceFileName, TargetPath, TargetFileName);
+
+ /* Allocate a new queue entry */
+ Entry = RtlAllocateHeap(ProcessHeap, 0, sizeof(QUEUEENTRY));
+ if (Entry == NULL)
+ return FALSE;
+
+ RtlZeroMemory(Entry, sizeof(QUEUEENTRY));
+
+ Entry->SourceCabinet = NULL;
+ Entry->SourceRootPath = NULL;
+
+ /* Copy source path */
+ Length = wcslen(SourcePath);
+ if ((Length > 0) && (SourcePath[Length - 1] == L'\\'))
+ Length--;
+ Entry->SourcePath = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
+ if (Entry->SourcePath == NULL)
+ {
+ RtlFreeHeap(ProcessHeap, 0, Entry);
+ return FALSE;
+ }
+ RtlStringCchCopyW(Entry->SourcePath, Length + 1, SourcePath);
+
+ /* Copy optional source file name */
+ Entry->SourceFileName = NULL;
+ if (SourceFileName != NULL)
+ {
+ Length = wcslen(SourceFileName);
+ Entry->SourceFileName = (WCHAR*)RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
+ if (Entry->SourceFileName == NULL)
+ {
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
+ RtlFreeHeap(ProcessHeap, 0, Entry);
+ return FALSE;
+ }
+ RtlStringCchCopyW(Entry->SourceFileName, Length + 1, SourceFileName);
+ }
+
+ /* Copy optional target directory */
+ Entry->TargetDirectory = NULL;
+ if (TargetPath != NULL)
+ {
+ Length = wcslen(TargetPath);
+ if ((Length > 0) && (TargetPath[Length - 1] == L'\\'))
+ Length--;
+ Entry->TargetDirectory = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
+ if (Entry->TargetDirectory == NULL)
+ {
+ if (Entry->SourceFileName != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
+
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
+ RtlFreeHeap(ProcessHeap, 0, Entry);
+ return FALSE;
+ }
+ RtlStringCchCopyW(Entry->TargetDirectory, Length + 1, TargetPath);
+ }
+
+ /* Copy target filename */
+ Length = wcslen(TargetFileName);
+ Entry->TargetFileName = RtlAllocateHeap(ProcessHeap,
+ 0,
+ (Length + 1) * sizeof(WCHAR));
+ if (Entry->TargetFileName == NULL)
+ {
+ if (Entry->TargetDirectory != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->TargetDirectory);
+
+ if (Entry->SourceFileName != NULL)
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourceFileName);
+
+ RtlFreeHeap(ProcessHeap, 0, Entry->SourcePath);
+ RtlFreeHeap(ProcessHeap, 0, Entry);
+ return FALSE;
+ }
+ RtlStringCchCopyW(Entry->TargetFileName, Length + 1, TargetFileName);
+
+ /* Append the queue entry */
+ InsertTailList(&QueueHeader->RenameQueue, &Entry->ListEntry);
+ ++QueueHeader->RenameCount;
+
+ return TRUE;
+}
BOOL
WINAPI
SetupCommitFileQueueW(
- HWND Owner,
- HSPFILEQ QueueHandle,
- PSP_FILE_CALLBACK_W MsgHandler,
- PVOID Context)
+ IN HWND Owner,
+ IN HSPFILEQ QueueHandle,
+ IN PSP_FILE_CALLBACK_W MsgHandler,
+ IN PVOID Context OPTIONAL)
{
- WCHAR CabinetName[MAX_PATH];
+ BOOL Success = TRUE; // Suppose success
+ NTSTATUS Status;
PFILEQUEUEHEADER QueueHeader;
+ PLIST_ENTRY ListEntry;
PQUEUEENTRY Entry;
- NTSTATUS Status;
- PCWSTR TargetRootPath, TargetPath;
-
+ FILEPATHS_W FilePathInfo;
+ WCHAR CabinetName[MAX_PATH];
WCHAR FileSrcPath[MAX_PATH];
WCHAR FileDstPath[MAX_PATH];
- TargetRootPath = ((PCOPYCONTEXT)Context)->DestinationRootPath;
- TargetPath = ((PCOPYCONTEXT)Context)->InstallPath;
-
if (QueueHandle == NULL)
return FALSE;
@@ -455,74 +630,203 @@ SetupCommitFileQueueW(
MsgHandler(Context,
SPFILENOTIFY_STARTQUEUE,
- 0,
+ (UINT_PTR)Owner,
0);
+
+ /*
+ * Commit the delete queue
+ */
+
MsgHandler(Context,
SPFILENOTIFY_STARTSUBQUEUE,
- FILEOP_COPY,
- QueueHeader->CopyCount);
+ FILEOP_DELETE,
+ QueueHeader->DeleteCount);
- /* Commit copy queue */
- Entry = QueueHeader->CopyHead;
- while (Entry != NULL)
+ ListEntry = QueueHeader->DeleteQueue.Flink;
+ while (ListEntry != &QueueHeader->DeleteQueue)
{
- /* Build the full source path */
- CombinePaths(FileSrcPath, ARRAYSIZE(FileSrcPath), 3,
- Entry->SourceRootPath, Entry->SourcePath,
- Entry->SourceFilename);
+ Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
+ ListEntry = ListEntry->Flink;
/* Build the full target path */
- wcscpy(FileDstPath, TargetRootPath);
- if (Entry->TargetDirectory[0] == UNICODE_NULL)
- {
- /* Installation path */
+ CombinePaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
+ Entry->TargetDirectory, Entry->TargetFileName);
+ // RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
Entry->TargetDirectory);
+ // ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1,
Entry->TargetFileName);
- /* Add the installation path */
- ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1, TargetPath);
- }
- else if (Entry->TargetDirectory[0] == L'\\')
+ DPRINT1(" -----> " "Delete: '%S'\n",
FileDstPath);
+
+ FilePathInfo.Target = FileDstPath;
+ FilePathInfo.Source = NULL;
+ FilePathInfo.Win32Error = STATUS_SUCCESS;
+ FilePathInfo.Flags = 0; // FIXME: Unused yet...
+
+ MsgHandler(Context,
+ SPFILENOTIFY_STARTDELETE,
+ (UINT_PTR)&FilePathInfo,
+ FILEOP_DELETE);
+
+ /* Force-delete the file */
+ Status = SetupDeleteFile(FileDstPath, TRUE);
+ if (!NT_SUCCESS(Status))
{
- /* Absolute path */
- if (Entry->TargetDirectory[1] != UNICODE_NULL)
- ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1,
Entry->TargetDirectory);
+ /* An error happened */
+ FilePathInfo.Win32Error = (UINT)Status;
+ MsgHandler(Context,
+ SPFILENOTIFY_DELETEERROR,
+ (UINT_PTR)&FilePathInfo,
+ 0);
+ Success = FALSE;
}
- else // if (Entry->TargetDirectory[0] != L'\\')
- {
- /* Path relative to the installation path */
- /* Add the installation path */
- ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
- TargetPath, Entry->TargetDirectory);
+ /* This notification is always sent, even in case of error */
+ FilePathInfo.Win32Error = (UINT)Status;
+ MsgHandler(Context,
+ SPFILENOTIFY_ENDDELETE,
+ (UINT_PTR)&FilePathInfo,
+ 0);
+ }
+
+ MsgHandler(Context,
+ SPFILENOTIFY_ENDSUBQUEUE,
+ FILEOP_DELETE,
+ 0);
+
+
+ /*
+ * Commit the rename queue
+ */
+
+ MsgHandler(Context,
+ SPFILENOTIFY_STARTSUBQUEUE,
+ FILEOP_RENAME,
+ QueueHeader->RenameCount);
+
+ ListEntry = QueueHeader->RenameQueue.Flink;
+ while (ListEntry != &QueueHeader->RenameQueue)
+ {
+ Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
+ ListEntry = ListEntry->Flink;
+
+ /* Build the full source path */
+ CombinePaths(FileSrcPath, ARRAYSIZE(FileSrcPath), 2,
+ Entry->SourcePath, Entry->SourceFileName);
+
+ /* Build the full target path */
+ CombinePaths(FileDstPath, ARRAYSIZE(FileDstPath), 2,
+ Entry->TargetDirectory, Entry->TargetFileName);
+ // RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
Entry->TargetDirectory);
+ // ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1,
Entry->TargetFileName);
+
+ DPRINT1(" -----> " "Rename: '%S' ==>
'%S'\n", FileSrcPath, FileDstPath);
+
+ FilePathInfo.Target = FileDstPath;
+ FilePathInfo.Source = FileSrcPath;
+ FilePathInfo.Win32Error = STATUS_SUCCESS;
+ FilePathInfo.Flags = 0; // FIXME: Unused yet...
+
+ MsgHandler(Context,
+ SPFILENOTIFY_STARTRENAME,
+ (UINT_PTR)&FilePathInfo,
+ FILEOP_RENAME);
+
+ /* Move or rename the file */
+ Status = SetupMoveFile(FileSrcPath, FileDstPath,
+ MOVEFILE_REPLACE_EXISTING
+ | MOVEFILE_COPY_ALLOWED
+ | MOVEFILE_WRITE_THROUGH);
+ if (!NT_SUCCESS(Status))
+ {
+ /* An error happened */
+ FilePathInfo.Win32Error = (UINT)Status;
+ MsgHandler(Context,
+ SPFILENOTIFY_RENAMEERROR,
+ (UINT_PTR)&FilePathInfo,
+ 0);
+ Success = FALSE;
}
+ /* This notification is always sent, even in case of error */
+ FilePathInfo.Win32Error = (UINT)Status;
+ MsgHandler(Context,
+ SPFILENOTIFY_ENDRENAME,
+ (UINT_PTR)&FilePathInfo,
+ 0);
+ }
+
+ MsgHandler(Context,
+ SPFILENOTIFY_ENDSUBQUEUE,
+ FILEOP_RENAME,
+ 0);
+
+
+ /*
+ * Commit the copy queue
+ */
+
+ MsgHandler(Context,
+ SPFILENOTIFY_STARTSUBQUEUE,
+ FILEOP_COPY,
+ QueueHeader->CopyCount);
+
+ ListEntry = QueueHeader->CopyQueue.Flink;
+ while (ListEntry != &QueueHeader->CopyQueue)
+ {
+ Entry = CONTAINING_RECORD(ListEntry, QUEUEENTRY, ListEntry);
+ ListEntry = ListEntry->Flink;
+
+ /* Build the full source path */
+ CombinePaths(FileSrcPath, ARRAYSIZE(FileSrcPath), 3,
+ Entry->SourceRootPath, Entry->SourcePath,
+ Entry->SourceFileName);
+
+ /* Build the full target path */
+ RtlStringCchCopyW(FileDstPath, ARRAYSIZE(FileDstPath),
Entry->TargetDirectory);
+
/*
* If the file is in a cabinet, use only the destination path.
* Otherwise possibly use a different target name.
*/
if (Entry->SourceCabinet == NULL)
{
- if (Entry->TargetFilename != NULL)
- ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1,
Entry->TargetFilename);
+ if (Entry->TargetFileName != NULL)
+ ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1,
Entry->TargetFileName);
else
- ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1,
Entry->SourceFilename);
+ ConcatPaths(FileDstPath, ARRAYSIZE(FileDstPath), 1,
Entry->SourceFileName);
}
- /* FIXME: Do it! */
- DPRINT("Copy: '%S' ==> '%S'\n", FileSrcPath,
FileDstPath);
+ DPRINT(" -----> " "Copy: '%S' ==>
'%S'\n", FileSrcPath, FileDstPath);
+
+ //
+ // Technically, here we should create the target directory,
+ // if it does not already exist... before calling the handler!
+ //
+
+ FilePathInfo.Target = FileDstPath;
+ FilePathInfo.Source = FileSrcPath; // when SourceCabinet not NULL, use
CabinetName ...
+ FilePathInfo.Win32Error = STATUS_SUCCESS;
+ FilePathInfo.Flags = 0; // FIXME: Unused yet...
MsgHandler(Context,
SPFILENOTIFY_STARTCOPY,
- (UINT_PTR)Entry->SourceFilename,
+ (UINT_PTR)&FilePathInfo,
FILEOP_COPY);
if (Entry->SourceCabinet != NULL)
{
- /* Extract the file */
+ /*
+ * Extract the file from the cabinet.
+ * The cabinet must be in Entry->SourceRootPath only!
+ * (ignore Entry->SourcePath).
+ */
CombinePaths(CabinetName, ARRAYSIZE(CabinetName), 3,
Entry->SourceRootPath, Entry->SourcePath,
Entry->SourceCabinet);
- Status = SetupExtractFile(CabinetName, Entry->SourceFilename,
FileDstPath);
+ Status = SetupExtractFile(QueueHeader,
+ CabinetName,
+ Entry->SourceFileName,
+ FileDstPath);
}
else
{
@@ -532,20 +836,21 @@ SetupCommitFileQueueW(
if (!NT_SUCCESS(Status))
{
+ /* An error happened */
+ FilePathInfo.Win32Error = (UINT)Status;
MsgHandler(Context,
SPFILENOTIFY_COPYERROR,
- (UINT_PTR)Entry->SourceFilename,
- FILEOP_COPY);
- }
- else
- {
- MsgHandler(Context,
- SPFILENOTIFY_ENDCOPY,
- (UINT_PTR)Entry->SourceFilename,
- FILEOP_COPY);
+ (UINT_PTR)&FilePathInfo,
+ (UINT_PTR)NULL); // FIXME: Unused yet...
+ Success = FALSE;
}
- Entry = Entry->Next;
+ /* This notification is always sent, even in case of error */
+ FilePathInfo.Win32Error = (UINT)Status;
+ MsgHandler(Context,
+ SPFILENOTIFY_ENDCOPY,
+ (UINT_PTR)&FilePathInfo,
+ 0);
}
MsgHandler(Context,
@@ -553,12 +858,14 @@ SetupCommitFileQueueW(
FILEOP_COPY,
0);
+
+ /* All the queues have been committed */
MsgHandler(Context,
SPFILENOTIFY_ENDQUEUE,
- 0,
+ (UINT_PTR)Success,
0);
- return TRUE;
+ return Success;
}
/* EOF */
diff --git a/base/setup/usetup/filequeue.h b/base/setup/usetup/filequeue.h
index 1623440035..cf608377e1 100644
--- a/base/setup/usetup/filequeue.h
+++ b/base/setup/usetup/filequeue.h
@@ -26,55 +26,59 @@
#pragma once
-#define SPFILENOTIFY_STARTQUEUE 0x1
-#define SPFILENOTIFY_ENDQUEUE 0x2
-#define SPFILENOTIFY_STARTSUBQUEUE 0x3
-#define SPFILENOTIFY_ENDSUBQUEUE 0x4
+#define SPFILENOTIFY_STARTQUEUE 0x00000001
+#define SPFILENOTIFY_ENDQUEUE 0x00000002
+#define SPFILENOTIFY_STARTSUBQUEUE 0x00000003
+#define SPFILENOTIFY_ENDSUBQUEUE 0x00000004
-#define SPFILENOTIFY_STARTCOPY 0xb
-#define SPFILENOTIFY_ENDCOPY 0xc
-#define SPFILENOTIFY_COPYERROR 0xd
+#define SPFILENOTIFY_STARTDELETE 0x00000005
+#define SPFILENOTIFY_ENDDELETE 0x00000006
+#define SPFILENOTIFY_DELETEERROR 0x00000007
-#define FILEOP_COPY 0x0
-#define FILEOP_RENAME 0x1
-#define FILEOP_DELETE 0x2
-#define FILEOP_BACKUP 0x3
+#define SPFILENOTIFY_STARTRENAME 0x00000008
+#define SPFILENOTIFY_ENDRENAME 0x00000009
+#define SPFILENOTIFY_RENAMEERROR 0x0000000a
-#define FILEOP_ABORT 0x0
-#define FILEOP_DOIT 0x1
-#define FILEOP_SKIP 0x2
-#define FILEOP_RETRY FILEOP_DOIT
-#define FILEOP_NEWPATH 0x4
+#define SPFILENOTIFY_STARTCOPY 0x0000000b
+#define SPFILENOTIFY_ENDCOPY 0x0000000c
+#define SPFILENOTIFY_COPYERROR 0x0000000d
+
+#define SPFILENOTIFY_NEEDMEDIA 0x0000000e
+#define SPFILENOTIFY_QUEUESCAN 0x0000000f
+
+#define FILEOP_COPY 0
+#define FILEOP_RENAME 1
+#define FILEOP_DELETE 2
+#define FILEOP_BACKUP 3
+
+#define FILEOP_ABORT 0
+#define FILEOP_DOIT 1
+#define FILEOP_SKIP 2
+#define FILEOP_RETRY FILEOP_DOIT
+#define FILEOP_NEWPATH 4
/* TYPES ********************************************************************/
typedef PVOID HSPFILEQ;
+typedef struct _FILEPATHS_W
+{
+ PCWSTR Target;
+ PCWSTR Source;
+ UINT Win32Error;
+ ULONG Flags;
+} FILEPATHS_W, *PFILEPATHS_W;
+
typedef UINT (CALLBACK* PSP_FILE_CALLBACK_W)(
- PVOID Context,
- UINT Notification,
- UINT_PTR Param1,
- UINT_PTR Param2);
+ IN PVOID Context,
+ IN UINT Notification,
+ IN UINT_PTR Param1,
+ IN UINT_PTR Param2);
-typedef struct _COPYCONTEXT
-{
- LPCWSTR DestinationRootPath; /* Not owned by this structure */
- LPCWSTR InstallPath; /* Not owned by this structure */
- ULONG TotalOperations;
- ULONG CompletedOperations;
- PPROGRESSBAR ProgressBar;
- PPROGRESSBAR MemoryBars[4];
-} COPYCONTEXT, *PCOPYCONTEXT;
/* FUNCTIONS ****************************************************************/
-NTSTATUS
-SetupExtractFile(
- PWCHAR CabinetFileName,
- PWCHAR SourceFileName,
- PWCHAR DestinationFileName);
-
HSPFILEQ
WINAPI
SetupOpenFileQueue(VOID);
@@ -99,22 +103,40 @@ SetupQueueCopyWNew(
IN DWORD CopyStyle);
#endif
+/* A simplified version of SetupQueueCopyW that wraps Cabinet support around */
+BOOL
+WINAPI
+SetupQueueCopyWithCab( // SetupQueueCopyW
+ IN HSPFILEQ QueueHandle,
+ IN PCWSTR SourceCabinet OPTIONAL,
+ IN PCWSTR SourceRootPath,
+ IN PCWSTR SourcePath OPTIONAL,
+ IN PCWSTR SourceFileName,
+ IN PCWSTR TargetDirectory,
+ IN PCWSTR TargetFileName OPTIONAL);
+
BOOL
-SetupQueueCopy(
- HSPFILEQ QueueHandle,
- PCWSTR SourceCabinet,
- PCWSTR SourceRootPath,
- PCWSTR SourcePath,
- PCWSTR SourceFilename,
- PCWSTR TargetDirectory,
- PCWSTR TargetFilename);
+WINAPI
+SetupQueueDeleteW(
+ IN HSPFILEQ QueueHandle,
+ IN PCWSTR PathPart1,
+ IN PCWSTR PathPart2 OPTIONAL);
+
+BOOL
+WINAPI
+SetupQueueRenameW(
+ IN HSPFILEQ QueueHandle,
+ IN PCWSTR SourcePath,
+ IN PCWSTR SourceFileName OPTIONAL,
+ IN PCWSTR TargetPath OPTIONAL,
+ IN PCWSTR TargetFileName);
BOOL
WINAPI
SetupCommitFileQueueW(
- HWND Owner,
- HSPFILEQ QueueHandle,
- PSP_FILE_CALLBACK_W MsgHandler,
- PVOID Context);
+ IN HWND Owner,
+ IN HSPFILEQ QueueHandle,
+ IN PSP_FILE_CALLBACK_W MsgHandler,
+ IN PVOID Context OPTIONAL);
/* EOF */
diff --git a/base/setup/usetup/usetup.c b/base/setup/usetup/usetup.c
index edd98fd654..929a4dca9a 100644
--- a/base/setup/usetup/usetup.c
+++ b/base/setup/usetup/usetup.c
@@ -71,6 +71,8 @@ static PGENERIC_LIST NtOsInstallsList = NULL;
// HACK: Temporary compatibility code.
#if 1
+ #define SetupQueueCopy SetupQueueCopyWithCab
+
static CABINET_CONTEXT CabinetContext;
#define CabinetInitialize() (CabinetInitialize(&CabinetContext))
#define CabinetSetEventHandlers(a,b,c)
(CabinetSetEventHandlers(&CabinetContext,(a),(b),(c)))
@@ -3494,6 +3496,7 @@ AddSectionToCopyQueueCab(HINF InfFile,
PWCHAR FileKeyValue;
PWCHAR DirKeyValue;
PWCHAR TargetFileName;
+ WCHAR FileDstPath[MAX_PATH];
/*
* This code enumerates the list of files in reactos.dff / reactos.inf
@@ -3549,12 +3552,46 @@ AddSectionToCopyQueueCab(HINF InfFile,
break;
}
+#if 1 // HACK moved! (r66604)
+ {
+ ULONG Length = wcslen(DirKeyValue);
+ if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
+ Length--;
+ 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 (!SetupQueueCopy(USetupData.SetupFileQueue,
SourceCabinet,
USetupData.SourceRootPath.Buffer,
USetupData.SourceRootDir.Buffer,
FileKeyName,
- DirKeyValue,
+ FileDstPath,
TargetFileName))
{
/* FIXME: Handle error! */
@@ -3584,6 +3621,7 @@ AddSectionToCopyQueue(HINF InfFile,
PWCHAR DirKeyValue;
PWCHAR TargetFileName;
WCHAR CompleteOrigDirName[512]; // FIXME: MAX_PATH is not enough?
+ WCHAR FileDstPath[MAX_PATH];
if (SourceCabinet)
return AddSectionToCopyQueueCab(InfFile, L"SourceFiles", SourceCabinet,
DestinationPath, Ir);
@@ -3683,12 +3721,46 @@ AddSectionToCopyQueue(HINF InfFile,
DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName);
}
+#if 1 // HACK moved! (r66604)
+ {
+ ULONG Length = wcslen(DirKeyValue);
+ if ((Length > 0) && (DirKeyValue[Length - 1] == L'\\'))
+ Length--;
+ 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 (!SetupQueueCopy(USetupData.SetupFileQueue,
SourceCabinet,
USetupData.SourceRootPath.Buffer,
CompleteOrigDirName,
FileKeyName,
- DirKeyValue,
+ FileDstPath,
TargetFileName))
{
/* FIXME: Handle error! */
@@ -3938,9 +4010,15 @@ PrepareCopyPage(PINPUT_RECORD Ir)
return FILE_COPY_PAGE;
}
+typedef struct _COPYCONTEXT
+{
+ ULONG TotalOperations;
+ ULONG CompletedOperations;
+ PPROGRESSBAR ProgressBar;
+ PPROGRESSBAR MemoryBars[4];
+} COPYCONTEXT, *PCOPYCONTEXT;
-VOID
-NTAPI
+static VOID
SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext,
IN BOOLEAN First)
{
@@ -3967,7 +4045,6 @@ SetupUpdateMemoryInfo(IN PCOPYCONTEXT CopyContext,
ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
}
-
static UINT
CALLBACK
FileCopyCallback(PVOID Context,
@@ -3975,26 +4052,78 @@ FileCopyCallback(PVOID Context,
UINT_PTR Param1,
UINT_PTR Param2)
{
- PCOPYCONTEXT CopyContext;
-
- CopyContext = (PCOPYCONTEXT)Context;
+ PCOPYCONTEXT CopyContext = (PCOPYCONTEXT)Context;
+ PFILEPATHS_W FilePathInfo;
+ PCWSTR SrcFileName, DstFileName;
switch (Notification)
{
case SPFILENOTIFY_STARTSUBQUEUE:
+ {
CopyContext->TotalOperations = (ULONG)Param2;
+ CopyContext->CompletedOperations = 0;
ProgressSetStepCount(CopyContext->ProgressBar,
CopyContext->TotalOperations);
SetupUpdateMemoryInfo(CopyContext, TRUE);
break;
+ }
+ case SPFILENOTIFY_STARTDELETE:
+ case SPFILENOTIFY_STARTRENAME:
case SPFILENOTIFY_STARTCOPY:
- /* Display copy message */
- CONSOLE_SetStatusText(MUIGetString(STRING_COPYING), (PWSTR)Param1);
+ {
+ FilePathInfo = (PFILEPATHS_W)Param1;
+
+ if (Notification == SPFILENOTIFY_STARTDELETE)
+ {
+ /* Display delete message */
+ ASSERT(Param2 == FILEOP_DELETE);
+
+ DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
+ if (DstFileName) ++DstFileName;
+ else DstFileName = FilePathInfo->Target;
+
+ CONSOLE_SetStatusText(MUIGetString(STRING_DELETING),
+ DstFileName);
+ }
+ else if (Notification == SPFILENOTIFY_STARTRENAME)
+ {
+ /* Display move/rename message */
+ ASSERT(Param2 == FILEOP_RENAME);
+
+ SrcFileName = wcsrchr(FilePathInfo->Source, L'\\');
+ if (SrcFileName) ++SrcFileName;
+ else SrcFileName = FilePathInfo->Source;
+
+ DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
+ if (DstFileName) ++DstFileName;
+ else DstFileName = FilePathInfo->Target;
+
+ // TODO: Determine whether using STRING_RENAMING or STRING_MOVING
+ CONSOLE_SetStatusText(MUIGetString(STRING_MOVING),
+ SrcFileName, DstFileName);
+ }
+ else if (Notification == SPFILENOTIFY_STARTCOPY)
+ {
+ /* Display copy message */
+ ASSERT(Param2 == FILEOP_COPY);
+
+ SrcFileName = wcsrchr(FilePathInfo->Source, L'\\');
+ if (SrcFileName) ++SrcFileName;
+ else SrcFileName = FilePathInfo->Source;
+
+ CONSOLE_SetStatusText(MUIGetString(STRING_COPYING),
+ SrcFileName);
+ }
+
SetupUpdateMemoryInfo(CopyContext, FALSE);
break;
+ }
+ case SPFILENOTIFY_ENDDELETE:
+ case SPFILENOTIFY_ENDRENAME:
case SPFILENOTIFY_ENDCOPY:
+ {
CopyContext->CompletedOperations++;
/* SYSREG checkpoint */
@@ -4004,9 +4133,10 @@ FileCopyCallback(PVOID Context,
ProgressNextStep(CopyContext->ProgressBar);
SetupUpdateMemoryInfo(CopyContext, FALSE);
break;
+ }
}
- return 0;
+ return FILEOP_DOIT;
}
@@ -4027,13 +4157,11 @@ static PAGE_NUMBER
FileCopyPage(PINPUT_RECORD Ir)
{
COPYCONTEXT CopyContext;
- unsigned int mem_bar_width;
+ UINT MemBarWidth;
MUIDisplayPage(FILE_COPY_PAGE);
/* Create context for the copy process */
- CopyContext.DestinationRootPath = USetupData.DestinationRootPath.Buffer;
- CopyContext.InstallPath = USetupData.InstallPath.Buffer;
CopyContext.TotalOperations = 0;
CopyContext.CompletedOperations = 0;
@@ -4048,13 +4176,13 @@ FileCopyPage(PINPUT_RECORD Ir)
MUIGetString(STRING_SETUPCOPYINGFILES));
// fit memory bars to screen width, distribute them uniform
- mem_bar_width = (xScreen - 26) / 5;
- mem_bar_width -= mem_bar_width % 2; // make even
+ MemBarWidth = (xScreen - 26) / 5;
+ MemBarWidth -= MemBarWidth % 2; // make even
/* ATTENTION: The following progress bars are debug stuff, which should not be
translated!! */
/* Create the paged pool progress bar */
CopyContext.MemoryBars[0] = CreateProgressBar(13,
40,
- 13 + mem_bar_width,
+ 13 + MemBarWidth,
43,
13,
44,
@@ -4062,21 +4190,21 @@ FileCopyPage(PINPUT_RECORD Ir)
"Kernel Pool");
/* Create the non paged pool progress bar */
- CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (mem_bar_width / 2),
+ CopyContext.MemoryBars[1] = CreateProgressBar((xScreen / 2)- (MemBarWidth / 2),
40,
- (xScreen / 2) + (mem_bar_width / 2),
+ (xScreen / 2) + (MemBarWidth / 2),
43,
- (xScreen / 2)- (mem_bar_width / 2),
+ (xScreen / 2)- (MemBarWidth / 2),
44,
FALSE,
"Kernel Cache");
/* Create the global memory progress bar */
- CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - mem_bar_width,
+ CopyContext.MemoryBars[2] = CreateProgressBar(xScreen - 13 - MemBarWidth,
40,
xScreen - 13,
43,
- xScreen - 13 - mem_bar_width,
+ xScreen - 13 - MemBarWidth,
44,
FALSE,
"Free Memory");