PCACHE_BLOCK CacheInternalAddBlockToCache(PCACHE_DRIVE CacheDrive, ULONG BlockNumber) { PCACHE_BLOCK CacheBlock = NULL; TRACE("CacheInternalAddBlockToCache() BlockNumber = %d\n", BlockNumber); // Check the size of the cache so we don't exceed our limits CacheInternalCheckCacheSizeLimits(CacheDrive); // We will need to add the block to the // drive's list of cached blocks. So allocate // the block memory. CacheBlock = FrLdrTempAlloc(sizeof(CACHE_BLOCK), TAG_CACHE_BLOCK); if (CacheBlock == NULL) { return NULL; } // Now initialize the structure and // allocate room for the block data RtlZeroMemory(CacheBlock, sizeof(CACHE_BLOCK)); CacheBlock->BlockNumber = BlockNumber; CacheBlock->BlockData = FrLdrTempAlloc(CacheDrive->BlockSize * CacheDrive->BytesPerSector, TAG_CACHE_DATA); if (CacheBlock->BlockData ==NULL) { FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK); return NULL; } // Now try to read in the block if (!MachDiskReadLogicalSectors(CacheDrive->DriveNumber, (BlockNumber * CacheDrive->BlockSize), CacheDrive->BlockSize, DiskReadBuffer)) { FrLdrTempFree(CacheBlock->BlockData, TAG_CACHE_DATA); FrLdrTempFree(CacheBlock, TAG_CACHE_BLOCK); return NULL; } RtlCopyMemory(CacheBlock->BlockData, DiskReadBuffer, CacheDrive->BlockSize * CacheDrive->BytesPerSector); // Add it to our list of blocks managed by the cache InsertTailList(&CacheDrive->CacheBlockHead, &CacheBlock->ListEntry); // Update the cache data CacheBlockCount++; CacheSizeCurrent = CacheBlockCount * (CacheDrive->BlockSize * CacheDrive->BytesPerSector); CacheInternalDumpBlockList(CacheDrive); return CacheBlock; }
static PVOID InfpAddFieldToLine( PINFCACHELINE Line, PCHAR Data) { PINFCACHEFIELD Field; SIZE_T Size; Size = sizeof(INFCACHEFIELD) + strlen(Data); Field = (PINFCACHEFIELD)FrLdrTempAlloc(Size, TAG_INF_FIELD); if (Field == NULL) { return NULL; } memset(Field, 0, Size); strcpy(Field->Data, Data); /* Append key */ if (Line->FirstField == NULL) { Line->FirstField = Field; Line->LastField = Field; } else { Line->LastField->Next = Field; Field->Prev = Line->LastField; Line->LastField = Field; } Line->FieldCount++; return (PVOID)Field; }
VOID UiShowMessageBoxesInSection(PCSTR SectionName) { ULONG Idx; CHAR SettingName[80]; CHAR SettingValue[80]; PCHAR MessageBoxText; ULONG MessageBoxTextSize; ULONG_PTR SectionId; if (!IniOpenSection(SectionName, &SectionId)) { return; } // // Find all the message box settings and run them // for (Idx=0; Idx<IniGetNumSectionItems(SectionId); Idx++) { IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), SettingValue, sizeof(SettingValue)); if (_stricmp(SettingName, "MessageBox") == 0) { // Get the real length of the MessageBox text MessageBoxTextSize = IniGetSectionSettingValueSize(SectionId, Idx); //if (MessageBoxTextSize > 0) { // Allocate enough memory to hold the text MessageBoxText = FrLdrTempAlloc(MessageBoxTextSize, TAG_UI_TEXT); if (MessageBoxText) { // Get the MessageBox text IniReadSettingByNumber(SectionId, Idx, SettingName, sizeof(SettingName), MessageBoxText, MessageBoxTextSize); // Fix it up UiEscapeString(MessageBoxText); // Display it UiMessageBox(MessageBoxText); // Free the memory FrLdrTempFree(MessageBoxText, TAG_UI_TEXT); } } } } }
static PINFCACHESECTION InfpCacheAddSection( PINFCACHE Cache, PCHAR Name) { PINFCACHESECTION Section = NULL; SIZE_T Size; if ((Cache == NULL) || (Name == NULL)) { // DPRINT("Invalid parameter\n"); return NULL; } /* Allocate and initialize the new section */ Size = sizeof(INFCACHESECTION) + strlen(Name); Section = (PINFCACHESECTION)FrLdrTempAlloc(Size, TAG_INF_SECTION); if (Section == NULL) { // DPRINT("RtlAllocateHeap() failed\n"); return NULL; } memset(Section, 0, Size); /* Copy section name */ strcpy(Section->Name, Name); /* Append section */ if (Cache->FirstSection == NULL) { Cache->FirstSection = Section; Cache->LastSection = Section; } else { Cache->LastSection->Next = Section; Section->Prev = Cache->LastSection; Cache->LastSection = Section; } return Section; }
static PVOID InfpAddKeyToLine( PINFCACHELINE Line, PCHAR Key) { if (Line == NULL) return NULL; if (Line->Key != NULL) return NULL; Line->Key = FrLdrTempAlloc(strlen(Key) + 1, TAG_INF_KEY); if (Line->Key == NULL) return NULL; strcpy(Line->Key, Key); return (PVOID)Line->Key; }
static PINFCACHELINE InfpCacheAddLine(PINFCACHESECTION Section) { PINFCACHELINE Line; if (Section == NULL) { // DPRINT("Invalid parameter\n"); return NULL; } Line = (PINFCACHELINE)FrLdrTempAlloc(sizeof(INFCACHELINE), TAG_INF_LINE); if (Line == NULL) { // DPRINT("RtlAllocateHeap() failed\n"); return NULL; } memset(Line, 0, sizeof(INFCACHELINE)); /* Append line */ if (Section->FirstLine == NULL) { Section->FirstLine = Line; Section->LastLine = Line; } else { Section->LastLine->Next = Line; Line->Prev = Section->LastLine; Section->LastLine = Line; } Section->LineCount++; return Line; }
static ARC_STATUS PxeOpen(CHAR* Path, OPENMODE OpenMode, ULONG* FileId) { t_PXENV_TFTP_GET_FSIZE sizeData; t_PXENV_TFTP_OPEN openData; SIZE_T PathLen, i; if (_OpenFile != NO_FILE) return EIO; if (OpenMode != OpenReadOnly) return EACCES; /* Retrieve the path length without NULL terminator */ PathLen = (Path ? min(strlen(Path), sizeof(_OpenFileName) - 1) : 0); /* Lowercase the path and always use slashes as separators */ for (i = 0; i < PathLen; i++) { if (Path[i] == '\\') _OpenFileName[i] = '/'; else _OpenFileName[i] = tolower(Path[i]); } /* Zero out rest of the file name */ RtlZeroMemory(_OpenFileName + PathLen, sizeof(_OpenFileName) - PathLen); RtlZeroMemory(&sizeData, sizeof(sizeData)); sizeData.ServerIPAddress = _ServerIP; RtlCopyMemory(sizeData.FileName, _OpenFileName, sizeof(_OpenFileName)); if (!CallPxe(PXENV_TFTP_GET_FSIZE, &sizeData)) { ERR("Failed to get '%s' size\n", Path); return EIO; } _FileSize = sizeData.FileSize; if (_FileSize < 1024 * 1024) { _CachedFile = FrLdrTempAlloc(_FileSize, TAG_PXE_FILE); // Don't check for allocation failure, we support _CachedFile == NULL } _CachedLength = 0; RtlZeroMemory(&openData, sizeof(openData)); openData.ServerIPAddress = _ServerIP; RtlCopyMemory(openData.FileName, _OpenFileName, sizeof(_OpenFileName)); openData.PacketSize = sizeof(_Packet); if (!CallPxe(PXENV_TFTP_OPEN, &openData)) { if (_CachedFile) { FrLdrTempFree(_CachedFile, TAG_PXE_FILE); _CachedFile = NULL; } return ENOENT; } _FilePosition = 0; _PacketPosition = 0; _OpenFile = *FileId; return ESUCCESS; }
VOID RunLoader(VOID) { ULONG_PTR SectionId; ULONG OperatingSystemCount; OperatingSystemItem* OperatingSystemList; PCSTR* OperatingSystemDisplayNames; ULONG DefaultOperatingSystem; LONG TimeOut; ULONG SelectedOperatingSystem; ULONG i; if (!MachInitializeBootDevices()) { UiMessageBoxCritical("Error when detecting hardware."); return; } #ifdef _M_IX86 /* Load additional SCSI driver (if any) */ if (LoadBootDeviceDriver() != ESUCCESS) { UiMessageBoxCritical("Unable to load additional boot device drivers."); } #endif if (!IniFileInitialize()) { UiMessageBoxCritical("Error initializing .ini file."); return; } /* Debugger main initialization */ DebugInit(TRUE); if (!IniOpenSection("FreeLoader", &SectionId)) { UiMessageBoxCritical("Section [FreeLoader] not found in freeldr.ini."); return; } TimeOut = GetTimeOut(); /* UI main initialization */ if (!UiInitialize(TRUE)) { UiMessageBoxCritical("Unable to initialize UI."); return; } OperatingSystemList = InitOperatingSystemList(&OperatingSystemCount); if (!OperatingSystemList) { UiMessageBox("Unable to read operating systems section in freeldr.ini.\nPress ENTER to reboot."); goto Reboot; } if (OperatingSystemCount == 0) { UiMessageBox("There were no operating systems listed in freeldr.ini.\nPress ENTER to reboot."); goto Reboot; } DefaultOperatingSystem = GetDefaultOperatingSystem(OperatingSystemList, OperatingSystemCount); /* Create list of display names */ OperatingSystemDisplayNames = FrLdrTempAlloc(sizeof(PCSTR) * OperatingSystemCount, 'mNSO'); if (!OperatingSystemDisplayNames) goto Reboot; for (i = 0; i < OperatingSystemCount; i++) { OperatingSystemDisplayNames[i] = OperatingSystemList[i].LoadIdentifier; } /* Find all the message box settings and run them */ UiShowMessageBoxesInSection("FreeLoader"); for (;;) { /* Redraw the backdrop */ UiDrawBackdrop(); /* Show the operating system list menu */ if (!UiDisplayMenu("Please select the operating system to start:", "For troubleshooting and advanced startup options for " "ReactOS, press F8.", TRUE, OperatingSystemDisplayNames, OperatingSystemCount, DefaultOperatingSystem, TimeOut, &SelectedOperatingSystem, FALSE, MainBootMenuKeyPressFilter)) { UiMessageBox("Press ENTER to reboot."); goto Reboot; } TimeOut = -1; /* Load the chosen operating system */ LoadOperatingSystem(&OperatingSystemList[SelectedOperatingSystem]); } Reboot: UiUnInitialize("Rebooting..."); return; }
VOID LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem, IN USHORT OperatingSystemVersion) { ULONG_PTR SectionId; PCSTR SectionName = OperatingSystem->SystemPartition; CHAR SettingsValue[80]; BOOLEAN HasSection; CHAR BootOptions2[256]; PCHAR File; CHAR FileName[512]; CHAR BootPath[512]; LPCSTR LoadOptions; LPSTR BootOptions; BOOLEAN BootFromFloppy; ULONG i, ErrorLine; HINF InfHandle; INFCONTEXT InfContext; PLOADER_PARAMETER_BLOCK LoaderBlock; PSETUP_LOADER_BLOCK SetupBlock; LPCSTR SystemPath; LPCSTR SourcePaths[] = { "", /* Only for floppy boot */ #if defined(_M_IX86) "I386\\", #elif defined(_M_MPPC) "PPC\\", #elif defined(_M_MRX000) "MIPS\\", #endif "reactos\\", NULL }; /* Get OS setting value */ SettingsValue[0] = ANSI_NULL; IniOpenSection("Operating Systems", &SectionId); IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue)); /* Open the operating system section specified in the .ini file */ HasSection = IniOpenSection(SectionName, &SectionId); UiDrawBackdrop(); UiDrawProgressBarCenter(1, 100, "Loading NT..."); /* Read the system path is set in the .ini file */ if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath))) { MachDiskGetBootPath(BootPath, sizeof(BootPath)); } /* Append a backslash */ if ((strlen(BootPath)==0) || BootPath[strlen(BootPath)] != '\\') strcat(BootPath, "\\"); /* Read booting options */ if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions2, sizeof(BootOptions2))) { /* Get options after the title */ PCSTR p = SettingsValue; while (*p == ' ' || *p == '"') p++; while (*p != '\0' && *p != '"') p++; strcpy(BootOptions2, p); TRACE("BootOptions: '%s'\n", BootOptions2); } /* Check if a ramdisk file was given */ File = strstr(BootOptions2, "/RDPATH="); if (File) { /* Copy the file name and everything else after it */ strcpy(FileName, File + 8); /* Null-terminate */ *strstr(FileName, " ") = ANSI_NULL; /* Load the ramdisk */ RamDiskLoadVirtualFile(FileName); } TRACE("BootPath: '%s'\n", BootPath); /* And check if we booted from floppy */ BootFromFloppy = strstr(BootPath, "fdisk") != NULL; /* Open 'txtsetup.sif' from any of source paths */ File = BootPath + strlen(BootPath); for (i = BootFromFloppy ? 0 : 1; ; i++) { SystemPath = SourcePaths[i]; if (!SystemPath) { ERR("Failed to open txtsetup.sif\n"); return; } sprintf(File, "%stxtsetup.sif", SystemPath); if (InfOpenFile (&InfHandle, BootPath, &ErrorLine)) { sprintf(File, "%s", SystemPath); break; } } TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath); /* Get Load options - debug and non-debug */ if (!InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions", &InfContext)) { ERR("Failed to find 'SetupData/OsLoadOptions'\n"); return; } if (!InfGetDataField(&InfContext, 1, &LoadOptions)) { ERR("Failed to get load options\n"); return; } #if DBG /* Get debug load options and use them */ if (InfFindFirstLine(InfHandle, "SetupData", "DbgOsLoadOptions", &InfContext)) { LPCSTR DbgLoadOptions; if (InfGetDataField(&InfContext, 1, &DbgLoadOptions)) LoadOptions = DbgLoadOptions; } #endif /* Copy loadoptions (original string will be freed) */ BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS); strcpy(BootOptions, LoadOptions); TRACE("BootOptions: '%s'\n", BootOptions); UiDrawStatusText("Setup is loading..."); /* Allocate and minimalistic-initialize LPB */ AllocateAndInitLPB(&LoaderBlock); /* Allocate and initialize setup loader block */ SetupBlock = &WinLdrSystemBlock->SetupBlock; LoaderBlock->SetupLdrBlock = SetupBlock; /* Set textmode setup flag */ SetupBlock->Flags = SETUPLDR_TEXT_MODE; /* Load NLS data, they are in system32 */ strcpy(FileName, BootPath); strcat(FileName, "system32\\"); SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName); /* Get a list of boot drivers */ SetupLdrScanBootDrivers(&LoaderBlock->BootDriverListHead, InfHandle, BootPath); /* Close the inf file */ InfCloseFile(InfHandle); /* Load ReactOS */ LoadAndBootWindowsCommon(_WIN32_WINNT_WS03, LoaderBlock, BootOptions, BootPath, TRUE); }
BOOLEAN InfOpenFile( PHINF InfHandle, PCSTR FileName, PULONG ErrorLine) { FILEINFORMATION Information; ULONG FileId; PCHAR FileBuffer; ULONG FileSize, Count; PINFCACHE Cache; BOOLEAN Success; ARC_STATUS Status; *InfHandle = NULL; *ErrorLine = (ULONG) - 1; // // Open the .inf file // Status = ArcOpen((PCHAR)FileName, OpenReadOnly, &FileId); if (Status != ESUCCESS) { return FALSE; } // // Query file size // Status = ArcGetFileInformation(FileId, &Information); if ((Status != ESUCCESS) || (Information.EndingAddress.HighPart != 0)) { ArcClose(FileId); return FALSE; } FileSize = Information.EndingAddress.LowPart; // // Allocate buffer to cache the file // FileBuffer = FrLdrTempAlloc(FileSize + 1, TAG_INF_FILE); if (!FileBuffer) { ArcClose(FileId); return FALSE; } // // Read file into memory // Status = ArcRead(FileId, FileBuffer, FileSize, &Count); if ((Status != ESUCCESS) || (Count != FileSize)) { ArcClose(FileId); FrLdrTempFree(FileBuffer, TAG_INF_FILE); return FALSE; } // // We don't need the file anymore. Close it // ArcClose(FileId); // // Append string terminator // FileBuffer[FileSize] = 0; // // Allocate infcache header // Cache = (PINFCACHE)FrLdrTempAlloc(sizeof(INFCACHE), TAG_INF_CACHE); if (!Cache) { FrLdrTempFree(FileBuffer, TAG_INF_FILE); return FALSE; } // // Initialize inicache header // RtlZeroMemory(Cache, sizeof(INFCACHE)); // // Parse the inf buffer // Success = InfpParseBuffer(Cache, FileBuffer, FileBuffer + FileSize, ErrorLine); if (!Success) { FrLdrTempFree(Cache, TAG_INF_CACHE); Cache = NULL; } // // Free file buffer, as it has been parsed // FrLdrTempFree(FileBuffer, TAG_INF_FILE); // // Return .inf parsed contents // *InfHandle = (HINF)Cache; return Success; }
static BOOLEAN RegImportValue ( PHHIVE Hive, PCM_KEY_VALUE ValueCell, FRLDRHKEY Key) { PVOID DataCell; PWCHAR wName; LONG Error; ULONG DataLength; ULONG i; if (ValueCell->Signature != CM_KEY_VALUE_SIGNATURE) { ERR("Invalid key cell!\n"); return FALSE; } if (ValueCell->Flags & VALUE_COMP_NAME) { wName = FrLdrTempAlloc((ValueCell->NameLength + 1) * sizeof(WCHAR), TAG_REG_NAME); for (i = 0; i < ValueCell->NameLength; i++) { wName[i] = ((PCHAR)ValueCell->Name)[i]; } wName[ValueCell->NameLength] = 0; } else { wName = FrLdrTempAlloc(ValueCell->NameLength + sizeof(WCHAR), TAG_REG_NAME); memcpy(wName, ValueCell->Name, ValueCell->NameLength); wName[ValueCell->NameLength / sizeof(WCHAR)] = 0; } DataLength = ValueCell->DataLength & REG_DATA_SIZE_MASK; TRACE("ValueName: '%S'\n", wName); TRACE("DataLength: %u\n", DataLength); if (DataLength <= sizeof(HCELL_INDEX) && (ValueCell->DataLength & REG_DATA_IN_OFFSET)) { Error = RegSetValue(Key, wName, ValueCell->Type, (PCHAR)&ValueCell->Data, DataLength); if (Error != ERROR_SUCCESS) { ERR("RegSetValue() failed!\n"); FrLdrTempFree(wName, TAG_REG_NAME); return FALSE; } } else { DataCell = (PVOID)HvGetCell(Hive, ValueCell->Data); TRACE("DataCell: %x\n", DataCell); Error = RegSetValue(Key, wName, ValueCell->Type, DataCell, DataLength); if (Error != ERROR_SUCCESS) { ERR("RegSetValue() failed!\n"); FrLdrTempFree(wName, TAG_REG_NAME); return FALSE; } } FrLdrTempFree(wName, TAG_REG_NAME); return TRUE; }
static BOOLEAN RegImportSubKey( PHHIVE Hive, PCM_KEY_NODE KeyCell, FRLDRHKEY ParentKey) { PCM_KEY_INDEX IndexCell; PVALUE_LIST_CELL ValueListCell; PCM_KEY_VALUE ValueCell = NULL; PWCHAR wName; FRLDRHKEY SubKey; LONG Error; ULONG i; TRACE("KeyCell: %x\n", KeyCell); TRACE("KeyCell->Signature: %x\n", KeyCell->Signature); if (KeyCell->Signature != CM_KEY_NODE_SIGNATURE) { ERR("Invalid key cell Signature!\n"); return FALSE; } if (KeyCell->Flags & KEY_COMP_NAME) { wName = FrLdrTempAlloc((KeyCell->NameLength + 1) * sizeof(WCHAR), TAG_REG_NAME); for (i = 0; i < KeyCell->NameLength; i++) { wName[i] = ((PCHAR)KeyCell->Name)[i]; } wName[KeyCell->NameLength] = 0; } else { wName = FrLdrTempAlloc(KeyCell->NameLength + sizeof(WCHAR), TAG_REG_NAME); memcpy(wName, KeyCell->Name, KeyCell->NameLength); wName[KeyCell->NameLength / sizeof(WCHAR)] = 0; } TRACE("KeyName: '%S'\n", wName); /* Create new sub key */ Error = RegCreateKey(ParentKey, wName, &SubKey); FrLdrTempFree(wName, TAG_REG_NAME); if (Error != ERROR_SUCCESS) { ERR("RegCreateKey() failed!\n"); return FALSE; } TRACE("Subkeys: %u\n", KeyCell->SubKeyCounts); TRACE("Values: %u\n", KeyCell->ValueList.Count); /* Enumerate and add values */ if (KeyCell->ValueList.Count > 0) { ValueListCell = (PVALUE_LIST_CELL)HvGetCell(Hive, KeyCell->ValueList.List); TRACE("ValueListCell: %x\n", ValueListCell); for (i = 0; i < KeyCell->ValueList.Count; i++) { TRACE("ValueOffset[%d]: %x\n", i, ValueListCell->ValueOffset[i]); ValueCell = (PCM_KEY_VALUE) HvGetCell (Hive, ValueListCell->ValueOffset[i]); TRACE("ValueCell[%d]: %x\n", i, ValueCell); if (!RegImportValue(Hive, ValueCell, SubKey)) return FALSE; } } /* Enumerate and add subkeys */ if (KeyCell->SubKeyCounts[Stable] > 0) { IndexCell = HvGetCell (Hive, KeyCell->SubKeyLists[Stable]); if (!RegImportIndexSubKey(Hive, IndexCell, SubKey)) return FALSE; } return TRUE; }
VOID LoadReactOSSetup(IN OperatingSystemItem* OperatingSystem, IN USHORT OperatingSystemVersion) { ULONG_PTR SectionId; PCSTR SectionName = OperatingSystem->SystemPartition; CHAR SettingsValue[80]; BOOLEAN HasSection; CHAR BootOptions2[256]; PCHAR File; CHAR FileName[512]; CHAR BootPath[512]; LPCSTR LoadOptions; LPSTR BootOptions; BOOLEAN BootFromFloppy; ULONG i, ErrorLine; HINF InfHandle; INFCONTEXT InfContext; PLOADER_PARAMETER_BLOCK LoaderBlock; PSETUP_LOADER_BLOCK SetupBlock; LPCSTR SystemPath; LPCSTR SourcePaths[] = { "", /* Only for floppy boot */ #if defined(_M_IX86) "I386\\", #elif defined(_M_MPPC) "PPC\\", #elif defined(_M_MRX000) "MIPS\\", #endif "reactos\\", NULL }; /* Get OS setting value */ SettingsValue[0] = ANSI_NULL; IniOpenSection("Operating Systems", &SectionId); IniReadSettingByName(SectionId, SectionName, SettingsValue, sizeof(SettingsValue)); /* Open the operating system section specified in the .ini file */ HasSection = IniOpenSection(SectionName, &SectionId); UiDrawBackdrop(); UiDrawProgressBarCenter(1, 100, "Loading ReactOS Setup..."); /* Read the system path is set in the .ini file */ if (!HasSection || !IniReadSettingByName(SectionId, "SystemPath", BootPath, sizeof(BootPath))) { /* * IMPROVE: I don't want to call MachDiskGetBootPath here as a * default choice because I can call it after (see few lines below). * Also doing the strcpy call as it is done in winldr.c is not * really what we want. Instead I reset BootPath here so that * we can build the full path using the general code from below. */ // MachDiskGetBootPath(BootPath, sizeof(BootPath)); // strcpy(BootPath, SectionName); BootPath[0] = '\0'; } /* * Check whether BootPath is a full path * and if not, create a full boot path. * * See FsOpenFile for the technique used. */ if (strrchr(BootPath, ')') == NULL) { /* Temporarily save the boot path */ strcpy(FileName, BootPath); /* This is not a full path. Use the current (i.e. boot) device. */ MachDiskGetBootPath(BootPath, sizeof(BootPath)); /* Append a path separator if needed */ if (FileName[0] != '\\' && FileName[0] != '/') strcat(BootPath, "\\"); /* Append the remaining path */ strcat(BootPath, FileName); } /* Append a backslash if needed */ if ((strlen(BootPath) == 0) || BootPath[strlen(BootPath) - 1] != '\\') strcat(BootPath, "\\"); /* Read booting options */ if (!HasSection || !IniReadSettingByName(SectionId, "Options", BootOptions2, sizeof(BootOptions2))) { /* Get options after the title */ PCSTR p = SettingsValue; while (*p == ' ' || *p == '"') p++; while (*p != '\0' && *p != '"') p++; strcpy(BootOptions2, p); TRACE("BootOptions: '%s'\n", BootOptions2); } /* Check if a ramdisk file was given */ File = strstr(BootOptions2, "/RDPATH="); if (File) { /* Copy the file name and everything else after it */ strcpy(FileName, File + 8); /* Null-terminate */ *strstr(FileName, " ") = ANSI_NULL; /* Load the ramdisk */ if (!RamDiskLoadVirtualFile(FileName)) { UiMessageBox("Failed to load RAM disk file %s", FileName); return; } } TRACE("BootPath: '%s'\n", BootPath); /* And check if we booted from floppy */ BootFromFloppy = strstr(BootPath, "fdisk") != NULL; /* Open 'txtsetup.sif' from any of source paths */ File = BootPath + strlen(BootPath); for (i = BootFromFloppy ? 0 : 1; ; i++) { SystemPath = SourcePaths[i]; if (!SystemPath) { UiMessageBox("Failed to open txtsetup.sif"); return; } strcpy(File, SystemPath); strcpy(FileName, BootPath); strcat(FileName, "txtsetup.sif"); if (InfOpenFile(&InfHandle, FileName, &ErrorLine)) { break; } } TRACE("BootPath: '%s', SystemPath: '%s'\n", BootPath, SystemPath); /* Get Load options - debug and non-debug */ if (!InfFindFirstLine(InfHandle, "SetupData", "OsLoadOptions", &InfContext)) { ERR("Failed to find 'SetupData/OsLoadOptions'\n"); return; } if (!InfGetDataField(&InfContext, 1, &LoadOptions)) { ERR("Failed to get load options\n"); return; } #if DBG /* Get debug load options and use them */ if (InfFindFirstLine(InfHandle, "SetupData", "DbgOsLoadOptions", &InfContext)) { LPCSTR DbgLoadOptions; if (InfGetDataField(&InfContext, 1, &DbgLoadOptions)) LoadOptions = DbgLoadOptions; } #endif /* Copy loadoptions (original string will be freed) */ BootOptions = FrLdrTempAlloc(strlen(LoadOptions) + 1, TAG_BOOT_OPTIONS); strcpy(BootOptions, LoadOptions); TRACE("BootOptions: '%s'\n", BootOptions); UiDrawStatusText("Setup is loading..."); /* Allocate and minimalistic-initialize LPB */ AllocateAndInitLPB(&LoaderBlock); /* Allocate and initialize setup loader block */ SetupBlock = &WinLdrSystemBlock->SetupBlock; LoaderBlock->SetupLdrBlock = SetupBlock; /* Set textmode setup flag */ SetupBlock->Flags = SETUPLDR_TEXT_MODE; /* Load NLS data, they are in system32 */ strcpy(FileName, BootPath); strcat(FileName, "system32\\"); SetupLdrLoadNlsData(LoaderBlock, InfHandle, FileName); /* Get a list of boot drivers */ SetupLdrScanBootDrivers(&LoaderBlock->BootDriverListHead, InfHandle, BootPath); /* Close the inf file */ InfCloseFile(InfHandle); /* Load ReactOS Setup */ LoadAndBootWindowsCommon(_WIN32_WINNT_WS03, LoaderBlock, BootOptions, BootPath, TRUE); }