diff --git a/reactos/base/setup/usetup/filequeue.c b/reactos/base/setup/usetup/filequeue.c index 4f1bc3b33c6..f3abf7047b9 100644 --- a/reactos/base/setup/usetup/filequeue.c +++ b/reactos/base/setup/usetup/filequeue.c @@ -38,7 +38,7 @@ typedef struct _QUEUEENTRY struct _QUEUEENTRY *Prev; struct _QUEUEENTRY *Next; - PWSTR SourceCabinet; /* May be NULL if file is not in a cabinet */ + PWSTR SourceCabinet; /* May be NULL if the file is not in a cabinet */ PWSTR SourceRootPath; PWSTR SourcePath; PWSTR SourceFilename; @@ -215,6 +215,8 @@ SetupQueueCopy( if (SourcePath != NULL) { Length = wcslen(SourcePath); + if ((Length > 0) && (SourcePath[Length - 1] == L'\\')) + Length--; Entry->SourcePath = (WCHAR*)RtlAllocateHeap(ProcessHeap, 0, (Length + 1) * sizeof(WCHAR)); @@ -257,7 +259,7 @@ SetupQueueCopy( /* Copy target directory */ Length = wcslen(TargetDirectory); - if (TargetDirectory[Length] == '\\') + if ((Length > 0) && (TargetDirectory[Length - 1] == L'\\')) Length--; Entry->TargetDirectory = (WCHAR*)RtlAllocateHeap(ProcessHeap, 0, @@ -366,6 +368,7 @@ SetupCommitFileQueueW( Entry = QueueHeader->CopyHead; while (Entry != NULL) { + /* Build the full source path */ wcscpy(FileSrcPath, Entry->SourceRootPath); if (Entry->SourcePath != NULL) wcscat(FileSrcPath, Entry->SourcePath); @@ -374,12 +377,29 @@ SetupCommitFileQueueW( /* Build the full target path */ wcscpy(FileDstPath, TargetRootPath); - if (Entry->TargetDirectory[0] == L'\\') + if (Entry->TargetDirectory[0] == 0) { - wcscat(FileDstPath, Entry->TargetDirectory); + /* Installation path */ + + /* Add the installation path */ + if (TargetPath != NULL) + { + if (TargetPath[0] != L'\\') + wcscat(FileDstPath, L"\\"); + wcscat(FileDstPath, TargetPath); + } } - else + else if (Entry->TargetDirectory[0] == L'\\') { + /* Absolute path */ + if (Entry->TargetDirectory[1] != 0) + wcscat(FileDstPath, Entry->TargetDirectory); + } + else // if (Entry->TargetDirectory[0] != L'\\') + { + /* Path relative to the installation path */ + + /* Add the installation path */ if (TargetPath != NULL) { if (TargetPath[0] != L'\\') @@ -391,7 +411,10 @@ SetupCommitFileQueueW( wcscat(FileDstPath, Entry->TargetDirectory); } - /* Use only the destination path if the file is in a cabinet */ + /* + * If the file is in a cabinet, use only the destination path. + * Otherwise possibly use a different target name. + */ if (Entry->SourceCabinet == NULL) { wcscat(FileDstPath, L"\\"); @@ -402,7 +425,7 @@ SetupCommitFileQueueW( } /* FIXME: Do it! */ - DPRINT("'%S' ==> '%S'\n", FileSrcPath, FileDstPath); + DPRINT("Copy: '%S' ==> '%S'\n", FileSrcPath, FileDstPath); MsgHandler(Context, SPFILENOTIFY_STARTCOPY, diff --git a/reactos/base/setup/usetup/filesup.c b/reactos/base/setup/usetup/filesup.c index 2fe323a5497..b8461e6ad0d 100644 --- a/reactos/base/setup/usetup/filesup.c +++ b/reactos/base/setup/usetup/filesup.c @@ -327,7 +327,7 @@ SetupCopyFile( 0); if (!NT_SUCCESS(Status)) { - DPRINT1("NtCreateFile failed: %x\n", Status); + DPRINT1("NtCreateFile failed: %x, %wZ\n", Status, &FileName); goto unmapsrcsec; } diff --git a/reactos/base/setup/usetup/interface/usetup.c b/reactos/base/setup/usetup/interface/usetup.c index 5789b5ba09f..84e0e04de30 100644 --- a/reactos/base/setup/usetup/interface/usetup.c +++ b/reactos/base/setup/usetup/interface/usetup.c @@ -3121,7 +3121,8 @@ AddSectionToCopyQueue(HINF InfFile, PWCHAR FileKeyValue; PWCHAR DirKeyValue; PWCHAR TargetFileName; - WCHAR CompleteOrigFileName[512]; + ULONG Length; + WCHAR CompleteOrigDirName[512]; if (SourceCabinet) return AddSectionToCopyQueueCab(InfFile, L"SourceFiles", SourceCabinet, DestinationPath, Ir); @@ -3180,14 +3181,35 @@ AddSectionToCopyQueue(HINF InfFile, break; } - wcscpy(CompleteOrigFileName, SourceRootDir.Buffer); - wcscat(CompleteOrigFileName, L"\\"); - wcscat(CompleteOrigFileName, DirKeyValue); + if ((DirKeyValue[0] == 0) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == 0)) + { + /* Installation path */ + wcscpy(CompleteOrigDirName, SourceRootDir.Buffer); + } + else if (DirKeyValue[0] == L'\\') + { + /* Absolute path */ + wcscpy(CompleteOrigDirName, DirKeyValue); + } + else // if (DirKeyValue[0] != L'\\') + { + /* Path relative to the installation path */ + wcscpy(CompleteOrigDirName, SourceRootDir.Buffer); + wcscat(CompleteOrigDirName, L"\\"); + wcscat(CompleteOrigDirName, DirKeyValue); + } + + /* Remove trailing backslash */ + Length = wcslen(CompleteOrigDirName); + if ((Length > 0) && (CompleteOrigDirName[Length - 1] == L'\\')) + { + CompleteOrigDirName[Length - 1] = 0; + } if (!SetupQueueCopy(SetupFileQueue, SourceCabinet, SourceRootPath.Buffer, - CompleteOrigFileName, + CompleteOrigDirName, FileKeyName, DirKeyValue, TargetFileName)) @@ -3209,7 +3231,7 @@ PrepareCopyPageInfFile(HINF InfFile, WCHAR PathBuffer[MAX_PATH]; INFCONTEXT DirContext; PWCHAR AdditionalSectionName = NULL; - PWCHAR KeyValue; + PWCHAR DirKeyValue; ULONG Length; NTSTATUS Status; @@ -3233,16 +3255,20 @@ PrepareCopyPageInfFile(HINF InfFile, /* Create directories */ /* - * FIXME: - * Install directories like '\reactos\test' are not handled yet. - */ + * FIXME: + * - Install directories like '\reactos\test' are not handled yet. + * - Copying files to 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 DestinationPath specify just '\' . + */ /* Get destination path */ wcscpy(PathBuffer, DestinationPath.Buffer); /* Remove trailing backslash */ Length = wcslen(PathBuffer); - if ((Length > 0) && (PathBuffer[Length - 1] == '\\')) + if ((Length > 0) && (PathBuffer[Length - 1] == L'\\')) { PathBuffer[Length - 1] = 0; } @@ -3274,27 +3300,35 @@ PrepareCopyPageInfFile(HINF InfFile, /* Enumerate the directory values and create the subdirectories */ do { - if (!INF_GetData(&DirContext, NULL, &KeyValue)) + if (!INF_GetData(&DirContext, NULL, &DirKeyValue)) { DPRINT1("break\n"); break; } - if (KeyValue[0] == L'\\' && KeyValue[1] != 0) + if ((DirKeyValue[0] == 0) || (DirKeyValue[0] == L'\\' && DirKeyValue[1] == 0)) { - DPRINT("Absolute Path: '%S'\n", KeyValue); + /* Installation path */ + DPRINT("InstallationPath: '%S'\n", DirKeyValue); - wcscpy(PathBuffer, DestinationRootPath.Buffer); - wcscat(PathBuffer, KeyValue); + wcscpy(PathBuffer, DestinationPath.Buffer); DPRINT("FullPath: '%S'\n", PathBuffer); } - else if (KeyValue[0] != L'\\') + else if (DirKeyValue[0] == L'\\') { - DPRINT("RelativePath: '%S'\n", KeyValue); - wcscpy(PathBuffer, DestinationPath.Buffer); - wcscat(PathBuffer, L"\\"); - wcscat(PathBuffer, KeyValue); + /* Absolute path */ + DPRINT("Absolute Path: '%S'\n", DirKeyValue); + + wcscpy(PathBuffer, DestinationRootPath.Buffer); + wcscat(PathBuffer, DirKeyValue); + + /* Remove trailing backslash */ + Length = wcslen(PathBuffer); + if ((Length > 0) && (PathBuffer[Length - 1] == L'\\')) + { + PathBuffer[Length - 1] = 0; + } DPRINT("FullPath: '%S'\n", PathBuffer); @@ -3306,7 +3340,33 @@ PrepareCopyPageInfFile(HINF InfFile, return FALSE; } } - } while (SetupFindNextLine (&DirContext, &DirContext)); + else // if (DirKeyValue[0] != L'\\') + { + /* Path relative to the installation path */ + DPRINT("RelativePath: '%S'\n", DirKeyValue); + + wcscpy(PathBuffer, DestinationPath.Buffer); + wcscat(PathBuffer, L"\\"); + wcscat(PathBuffer, DirKeyValue); + + /* Remove trailing backslash */ + Length = wcslen(PathBuffer); + if ((Length > 0) && (PathBuffer[Length - 1] == L'\\')) + { + PathBuffer[Length - 1] = 0; + } + + DPRINT("FullPath: '%S'\n", PathBuffer); + + Status = SetupCreateDirectory(PathBuffer); + if (!NT_SUCCESS(Status) && Status != STATUS_OBJECT_NAME_COLLISION) + { + DPRINT("Creating directory '%S' failed: Status = 0x%08lx", PathBuffer, Status); + MUIDisplayError(ERROR_CREATE_DIR, Ir, POPUP_WAIT_ENTER); + return FALSE; + } + } + } while (SetupFindNextLine(&DirContext, &DirContext)); return TRUE; } diff --git a/reactos/boot/bootdata/packages/reactos.dff.in b/reactos/boot/bootdata/packages/reactos.dff.in index ddd6cb30246..00362dd1ffb 100644 --- a/reactos/boot/bootdata/packages/reactos.dff.in +++ b/reactos/boot/bootdata/packages/reactos.dff.in @@ -13,11 +13,14 @@ [Version] Signature = "$ReactOS$" +; Directories relative to the installation directory. +; For specifying absolute directories, use the SystemPartitionFiles section, +; or use names starting with \. [Directories] 1 = system32 2 = system32\drivers 3 = Fonts -4 = +4 = "\" 5 = system32\drivers\etc 6 = inf 7 = bin diff --git a/reactos/boot/bootdata/txtsetup.sif b/reactos/boot/bootdata/txtsetup.sif index fbf8217b627..134c7dbc373 100644 --- a/reactos/boot/bootdata/txtsetup.sif +++ b/reactos/boot/bootdata/txtsetup.sif @@ -1,6 +1,9 @@ [Version] Signature = "$ReactOS$" +; Directories relative to the installation directory. +; For specifying absolute directories, use the SystemPartitionFiles section, +; or use names starting with \. [Directories] ; = 1 = "\" @@ -22,6 +25,7 @@ sacdrv.sys=,,,,,,x,,,,,,4 uniata.sys=,,,,,,x,,,,,,4 buslogic.sys=,,,,,,x,,,,,,4 blue.sys=,,,,,,x,,,,,,4 +vgafonts.cab=,,,,,,,,,,,,1 bootvid.dll=,,,,,,,,,,,,2 c_437.nls=,,,,,,,,,,,,2 c_1252.nls=,,,,,,,,,,,,2 @@ -64,6 +68,8 @@ wmilib.sys=,,,,,,,,,,,,4 ksecdd.sys=,,,,,,,,,,,,4 mountmgr.sys=,,,,,,x,,,,,,4 +[SystemPartitionFiles] + [HardwareIdsDatabase] ;*PNP0A00 = isapnp *PNP0A03 = pci