* PROJECT: ReactOS text-mode setup
* FILE: base/setup/usetup/usetup.c
* PURPOSE: Text-mode setup
- * PROGRAMMER: Casper S. Hornstrup (chorns@users.sourceforge.net)
+ * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
* Hervé Poussineau (hpoussin@reactos.org)
*/
}
+// PSETUP_ERROR_ROUTINE
+static VOID
+__cdecl
+USetupErrorRoutine(
+ IN PUSETUP_DATA pSetupData,
+ ...)
+{
+ INPUT_RECORD Ir;
+ va_list arg_ptr;
+
+ va_start(arg_ptr, pSetupData);
+
+ if (pSetupData->LastErrorNumber >= ERROR_SUCCESS &&
+ pSetupData->LastErrorNumber < ERROR_LAST_ERROR_CODE)
+ {
+ // Note: the "POPUP_WAIT_ENTER" actually depends on the LastErrorNumber...
+ MUIDisplayErrorV(pSetupData->LastErrorNumber, &Ir, POPUP_WAIT_ENTER, arg_ptr);
+ }
+
+ va_end(arg_ptr);
+}
+
+
static BOOLEAN
AddSectionToCopyQueueCab(HINF InfFile,
- PWCHAR SectionName,
- PWCHAR SourceCabinet,
+ PCWSTR SectionName,
+ PCWSTR SourceCabinet,
PCUNICODE_STRING DestinationPath,
PINPUT_RECORD Ir)
{
INFCONTEXT FilesContext;
INFCONTEXT DirContext;
- PWCHAR FileKeyName;
- PWCHAR FileKeyValue;
- PWCHAR DirKeyValue;
- PWCHAR TargetFileName;
+ PCWSTR FileKeyName;
+ PCWSTR FileKeyValue;
+ PCWSTR DirKeyValue;
+ PCWSTR TargetFileName;
+ WCHAR FileDstPath[MAX_PATH];
/*
* This code enumerates the list of files in reactos.dff / reactos.inf
*/
/* Search for the SectionName section */
- if (!SetupFindFirstLineW(InfFile, SectionName, NULL, &FilesContext))
+ if (!SpInfFindFirstLine(InfFile, SectionName, NULL, &FilesContext))
{
MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, SectionName);
return FALSE;
DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
/* Lookup target directory */
- if (!SetupFindFirstLineW(InfFile, L"Directories", FileKeyValue, &DirContext))
+ if (!SpInfFindFirstLine(InfFile, L"Directories", FileKeyValue, &DirContext))
{
/* FIXME: Handle error! */
DPRINT1("SetupFindFirstLine() failed\n");
break;
}
- if (!SetupQueueCopy(USetupData.SetupFileQueue,
- SourceCabinet,
- USetupData.SourceRootPath.Buffer,
- USetupData.SourceRootDir.Buffer,
- FileKeyName,
- DirKeyValue,
- TargetFileName))
+#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("SetupQueueCopy() failed\n");
+ DPRINT1("SpFileQueueCopy() failed\n");
}
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
INF_FreeData(DirKeyValue);
- } while (SetupFindNextLine(&FilesContext, &FilesContext));
+ } while (SpInfFindNextLine(&FilesContext, &FilesContext));
return TRUE;
}
static BOOLEAN
AddSectionToCopyQueue(HINF InfFile,
- PWCHAR SectionName,
- PWCHAR SourceCabinet,
+ PCWSTR SectionName,
+ PCWSTR SourceCabinet,
PCUNICODE_STRING DestinationPath,
PINPUT_RECORD Ir)
{
INFCONTEXT FilesContext;
INFCONTEXT DirContext;
- PWCHAR FileKeyName;
- PWCHAR FileKeyValue;
- PWCHAR DirKeyValue;
- PWCHAR TargetFileName;
+ 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);
*/
/* Search for the SectionName section */
- if (!SetupFindFirstLineW(InfFile, SectionName, NULL, &FilesContext))
+ if (!SpInfFindFirstLine(InfFile, SectionName, NULL, &FilesContext))
{
MUIDisplayError(ERROR_TXTSETUP_SECTION, Ir, POPUP_WAIT_ENTER, SectionName);
return FALSE;
DPRINT("FileKeyName: '%S' FileKeyValue: '%S'\n", FileKeyName, FileKeyValue);
/* Lookup target directory */
- if (!SetupFindFirstLineW(InfFile, L"Directories", FileKeyValue, &DirContext))
+ if (!SpInfFindFirstLine(InfFile, L"Directories", FileKeyValue, &DirContext))
{
/* FIXME: Handle error! */
DPRINT1("SetupFindFirstLine() failed\n");
DPRINT("RelativePath(2): '%S'\n", CompleteOrigDirName);
}
- if (!SetupQueueCopy(USetupData.SetupFileQueue,
- SourceCabinet,
- USetupData.SourceRootPath.Buffer,
- CompleteOrigDirName,
- FileKeyName,
- DirKeyValue,
- TargetFileName))
+#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("SetupQueueCopy() failed\n");
+ DPRINT1("SpFileQueueCopy() failed\n");
}
INF_FreeData(FileKeyName);
INF_FreeData(TargetFileName);
INF_FreeData(DirKeyValue);
- } while (SetupFindNextLine(&FilesContext, &FilesContext));
+ } while (SpInfFindNextLine(&FilesContext, &FilesContext));
return TRUE;
}
static BOOLEAN
PrepareCopyPageInfFile(HINF InfFile,
- PWCHAR SourceCabinet,
+ PCWSTR SourceCabinet,
PINPUT_RECORD Ir)
{
NTSTATUS Status;
INFCONTEXT DirContext;
PWCHAR AdditionalSectionName = NULL;
- PWCHAR DirKeyValue;
+ PCWSTR DirKeyValue;
WCHAR PathBuffer[MAX_PATH];
/* Add common files */
}
/* Search for the 'Directories' section */
- if (!SetupFindFirstLineW(InfFile, L"Directories", NULL, &DirContext))
+ if (!SpInfFindFirstLine(InfFile, L"Directories", NULL, &DirContext))
{
if (SourceCabinet)
MUIDisplayError(ERROR_CABINET_SECTION, Ir, POPUP_WAIT_ENTER, L"Directories");
}
INF_FreeData(DirKeyValue);
- } while (SetupFindNextLine(&DirContext, &DirContext));
+ } while (SpInfFindNextLine(&DirContext, &DirContext));
return TRUE;
}
WCHAR PathBuffer[MAX_PATH];
INFCONTEXT CabinetsContext;
ULONG InfFileSize;
- PWCHAR KeyValue;
+ PCWSTR KeyValue;
UINT ErrorLine;
PVOID InfFileData;
MUIDisplayPage(PREPARE_COPY_PAGE);
/* Create the file queue */
- USetupData.SetupFileQueue = SetupOpenFileQueue();
+ USetupData.SetupFileQueue = SpFileQueueOpen();
if (USetupData.SetupFileQueue == NULL)
{
MUIDisplayError(ERROR_COPY_QUEUE, Ir, POPUP_WAIT_ENTER);
}
/* Search for the 'Cabinets' section */
- if (!SetupFindFirstLineW(USetupData.SetupInf, L"Cabinets", NULL, &CabinetsContext))
+ if (!SpInfFindFirstLine(USetupData.SetupInf, L"Cabinets", NULL, &CabinetsContext))
{
return FILE_COPY_PAGE;
}
/* FIXME: show an error dialog */
return QUIT_PAGE;
}
- } while (SetupFindNextLine(&CabinetsContext, &CabinetsContext));
+ } while (SpInfFindNextLine(&CabinetsContext, &CabinetsContext));
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)
{
ProgressSetStep(CopyContext->MemoryBars[2], PerfInfo.AvailablePages);
}
-
static UINT
CALLBACK
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;
+
+ if (!wcsicmp(SrcFileName, DstFileName))
+ Param2 = STRING_MOVING;
+ else
+ Param2 = STRING_RENAMING;
+
+ CONSOLE_SetStatusText(MUIGetString(Param2),
+ SrcFileName, DstFileName);
+ }
+ else if (Notification == SPFILENOTIFY_STARTCOPY)
+ {
+ /* Display copy message */
+ ASSERT(Param2 == FILEOP_COPY);
+
+ /* NOTE: When extracting from CABs the Source is the CAB name */
+ DstFileName = wcsrchr(FilePathInfo->Target, L'\\');
+ if (DstFileName) ++DstFileName;
+ else DstFileName = FilePathInfo->Target;
+
+ CONSOLE_SetStatusText(MUIGetString(STRING_COPYING),
+ DstFileName);
+ }
+
SetupUpdateMemoryInfo(CopyContext, FALSE);
break;
+ }
+
+ case SPFILENOTIFY_COPYERROR:
+ {
+ FilePathInfo = (PFILEPATHS_W)Param1;
+
+ DPRINT1("An error happened while trying to copy file '%S' (error 0x%08lx), skipping it...\n",
+ FilePathInfo->Target, FilePathInfo->Win32Error);
+ return FILEOP_SKIP;
+ }
+ case SPFILENOTIFY_ENDDELETE:
+ case SPFILENOTIFY_ENDRENAME:
case SPFILENOTIFY_ENDCOPY:
+ {
CopyContext->CompletedOperations++;
/* SYSREG checkpoint */
ProgressNextStep(CopyContext->ProgressBar);
SetupUpdateMemoryInfo(CopyContext, FALSE);
break;
+ }
}
- return 0;
+ return FILEOP_DOIT;
}
*
* SIDEEFFECTS
* Calls SetupCommitFileQueueW
- * Calls SetupCloseFileQueue
+ * Calls SpFileQueueClose
*
* RETURNS
* Number of the next page.
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;
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,
"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");
/* Do the file copying */
- SetupCommitFileQueueW(NULL,
- USetupData.SetupFileQueue,
- FileCopyCallback,
- &CopyContext);
+ SpFileQueueCommit(NULL,
+ USetupData.SetupFileQueue,
+ FileCopyCallback,
+ &CopyContext);
/* If we get here, we're done, so cleanup the queue and progress bar */
- SetupCloseFileQueue(USetupData.SetupFileQueue);
+ SpFileQueueClose(USetupData.SetupFileQueue);
DestroyProgressBar(CopyContext.ProgressBar);
DestroyProgressBar(CopyContext.MemoryBars[0]);
DestroyProgressBar(CopyContext.MemoryBars[1]);
MUIDisplayPage(REGISTRY_PAGE);
- Error = UpdateRegistry(USetupData.SetupInf,
- &USetupData,
+ Error = UpdateRegistry(&USetupData,
RepairUpdateFlag,
PartitionList,
DestinationDriveLetter,
SelectedLanguageId,
- USetupData.DisplayList,
- USetupData.LayoutList,
- USetupData.LanguageList,
RegistryStatus);
if (Error != ERROR_SUCCESS)
{
/* Initialize Setup, phase 0 */
InitializeSetup(&USetupData, 0);
+ USetupData.ErrorRoutine = USetupErrorRoutine;
/* Hide the cursor */
CONSOLE_SetCursorType(TRUE, FALSE);