mirror of
https://github.com/pbatard/rufus.git
synced 2024-08-14 23:57:05 +00:00
[dos] reinstate MS-DOS boot disk creation for Windows 10 and later platforms
* The BlackLotus malware shows that it is possible to download individual executables and DLLs straight from Microsoft's symbol servers, so we use that capability to download the missing Windows 8.1 'diskcopy.dll', that contains the flat floppy disk image with MS-DOS files we need. See: https://randomascii.wordpress.com/2013/03/09/symbols-the-microsoft-way/ * Also reorder entries in the "Boot selection" dropdown. * Also use CreateFileWithTimeout() in GetLogicalName().
This commit is contained in:
parent
3a0f7d3813
commit
3afa139d7a
8 changed files with 71 additions and 60 deletions
|
@ -5,6 +5,9 @@ To edit a translation, please make sure to follow:
|
|||
https://github.com/pbatard/rufus/wiki/Localization#Editing_an_existing_translation
|
||||
Or simply download https://files.akeo.ie/pollock/pollock-1.5.exe and follow its directions.
|
||||
|
||||
o v4.?? (202?.??.??)
|
||||
- *NEW* MSG_337 "An additional file ('diskcopy.dll') must be downloaded from Microsoft to install MS-DOS (...)"
|
||||
|
||||
o v3.22 (2023.??.??)
|
||||
// MSG_144 is aimed the the ISO download feature
|
||||
- *UPDATED* MSG_144 "Temporarily banned by Microsoft for requesting too many downloads (...)" -> "Download of Windows ISOs is unavailable due to Microsoft having altered their website to prevent it."
|
||||
|
|
|
@ -593,6 +593,11 @@ t MSG_333 "Create a local account with username:"
|
|||
t MSG_334 "Set regional options to the same values as this user's"
|
||||
t MSG_335 "Disable BitLocker automatic device encryption"
|
||||
t MSG_336 "Persistent log"
|
||||
t MSG_337 "An additional file ('diskcopy.dll') must be downloaded from Microsoft to install MS-DOS:\n"
|
||||
"- Select 'Yes' to connect to the Internet and download it\n"
|
||||
"- Select 'No' to cancel the operation\n\n"
|
||||
"Note: The file will be downloaded in the current application directory and will be reused "
|
||||
"automatically if present."
|
||||
# The following messages are for the Windows Store listing only and are not used by the application
|
||||
t MSG_900 "Rufus is a utility that helps format and create bootable USB flash drives, such as USB keys/pendrives, memory sticks, etc."
|
||||
t MSG_901 "Official site: %s"
|
||||
|
|
34
src/dos.c
34
src/dos.c
|
@ -33,6 +33,7 @@
|
|||
#include "rufus.h"
|
||||
#include "missing.h"
|
||||
#include "resource.h"
|
||||
#include "msapi_utf8.h"
|
||||
|
||||
#include "dos.h"
|
||||
|
||||
|
@ -289,8 +290,9 @@ static BOOL ExtractMSDOS(const char* path)
|
|||
{
|
||||
int i, j;
|
||||
BOOL r = FALSE;
|
||||
HMODULE hDLL = NULL;
|
||||
uint8_t* diskcopy_buffer = NULL;
|
||||
char locale_path[MAX_PATH];
|
||||
char diskcopy_dll_path[MAX_PATH];
|
||||
char* extractlist[] = { "MSDOS SYS", "COMMAND COM", "IO SYS", "MODE COM",
|
||||
"KEYB COM", "KEYBOARDSYS", "KEYBRD2 SYS", "KEYBRD3 SYS", "KEYBRD4 SYS",
|
||||
"DISPLAY SYS", "EGA CPI", "EGA2 CPI", "EGA3 CPI" };
|
||||
|
@ -298,28 +300,22 @@ static BOOL ExtractMSDOS(const char* path)
|
|||
if (path == NULL)
|
||||
return FALSE;
|
||||
|
||||
// There should be a diskcopy.dll in the user's AppData directory.
|
||||
// Since we're working with a known copy of diskcopy.dll, just load it
|
||||
// in memory and point to the known disk image resource buffer.
|
||||
static_sprintf(diskcopy_dll_path, "%s\\%s\\diskcopy.dll", app_data_dir, FILES_DIR);
|
||||
if (read_file(diskcopy_dll_path, &diskcopy_buffer) != DISKCOPY_SIZE) {
|
||||
uprintf("'diskcopy.dll' was either not found or is invalid");
|
||||
goto out;
|
||||
}
|
||||
DiskImage = &diskcopy_buffer[DISKCOPY_IMAGE_OFFSET];
|
||||
DiskImageSize = DISKCOPY_IMAGE_SIZE;
|
||||
|
||||
// Reduce the visible mess by placing all the locale files into a subdir
|
||||
static_strcpy(locale_path, path);
|
||||
static_strcat(locale_path, "LOCALE\\");
|
||||
CreateDirectoryA(locale_path, NULL);
|
||||
|
||||
hDLL = GetLibraryHandle("diskcopy");
|
||||
if (hDLL == NULL) {
|
||||
uprintf("Unable to open 'diskcopy.dll': %s", WindowsErrorString());
|
||||
goto out;
|
||||
}
|
||||
|
||||
DiskImageSize = 0;
|
||||
DiskImage = (BYTE*)GetResource(hDLL, MAKEINTRESOURCEA(1), "BINFILE", "disk image", &DiskImageSize, TRUE);
|
||||
if (DiskImage == NULL)
|
||||
goto out;
|
||||
|
||||
// Sanity check
|
||||
if (DiskImageSize < 700*KB) {
|
||||
uprintf("MS-DOS disk image is too small (%d bytes)", DiskImageSize);
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0, r = TRUE; r && i < FAT_FN_DIR_ENTRY_LAST; i++) {
|
||||
if (DiskImage[FAT12_ROOTDIR_OFFSET + i * FAT_BYTES_PER_DIRENT] == FAT_DIRENT_DELETED)
|
||||
continue;
|
||||
|
@ -335,7 +331,7 @@ static BOOL ExtractMSDOS(const char* path)
|
|||
r = SetDOSLocale(path, FALSE);
|
||||
|
||||
out:
|
||||
safe_free(DiskImage);
|
||||
safe_free(diskcopy_buffer);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
|
|
@ -307,8 +307,8 @@ char* GetLogicalName(DWORD DriveIndex, uint64_t PartitionOffset, BOOL bKeepTrail
|
|||
continue;
|
||||
}
|
||||
|
||||
hDrive = CreateFileA(volume_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
hDrive = CreateFileWithTimeout(volume_name, GENERIC_READ, FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL, 3000);
|
||||
if (hDrive == INVALID_HANDLE_VALUE) {
|
||||
suprintf("Could not open GUID volume '%s': %s", volume_name, WindowsErrorString());
|
||||
continue;
|
||||
|
|
20
src/net.c
20
src/net.c
|
@ -273,10 +273,10 @@ static __inline BOOL is_WOW64(void)
|
|||
}
|
||||
|
||||
// Open an Internet session
|
||||
static HINTERNET GetInternetSession(BOOL bRetry)
|
||||
static HINTERNET GetInternetSession(const char* user_agent, BOOL bRetry)
|
||||
{
|
||||
int i;
|
||||
char agent[64];
|
||||
char default_agent[64];
|
||||
BOOL decodingSupport = TRUE;
|
||||
VARIANT_BOOL InternetConnection = VARIANT_FALSE;
|
||||
DWORD dwFlags, dwTimeout = NET_SESSION_TIMEOUT, dwProtocolSupport = HTTP_PROTOCOL_FLAG_HTTP2;
|
||||
|
@ -314,10 +314,11 @@ static HINTERNET GetInternetSession(BOOL bRetry)
|
|||
SetLastError(ERROR_INTERNET_DISCONNECTED);
|
||||
goto out;
|
||||
}
|
||||
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %lu.%lu%s)",
|
||||
static_sprintf(default_agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %lu.%lu%s)",
|
||||
rufus_version[0], rufus_version[1], rufus_version[2],
|
||||
WindowsVersion.Major, WindowsVersion.Minor, is_WOW64() ? "; WOW64" : "");
|
||||
hSession = pfInternetOpenA(agent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
hSession = pfInternetOpenA((user_agent == NULL) ? default_agent : user_agent,
|
||||
INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
|
||||
// Set the timeouts
|
||||
pfInternetSetOptionA(hSession, INTERNET_OPTION_CONNECT_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout));
|
||||
pfInternetSetOptionA(hSession, INTERNET_OPTION_SEND_TIMEOUT, (LPVOID)&dwTimeout, sizeof(dwTimeout));
|
||||
|
@ -341,7 +342,8 @@ out:
|
|||
* Note that when a buffer is used, the actual size of the buffer is one more than its reported
|
||||
* size (with the extra byte set to 0) to accommodate for calls that need a NUL-terminated buffer.
|
||||
*/
|
||||
uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress)
|
||||
uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* user_agent,
|
||||
BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress)
|
||||
{
|
||||
const char* accept_types[] = {"*/*\0", NULL};
|
||||
const char* short_name;
|
||||
|
@ -395,7 +397,7 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
|
|||
}
|
||||
hostname[sizeof(hostname)-1] = 0;
|
||||
|
||||
hSession = GetInternetSession(TRUE);
|
||||
hSession = GetInternetSession(user_agent, TRUE);
|
||||
if (hSession == NULL) {
|
||||
uprintf("Could not open Internet session: %s", WinInetErrorString());
|
||||
goto out;
|
||||
|
@ -427,7 +429,7 @@ uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer
|
|||
if (DownloadStatus != 200) {
|
||||
error_code = ERROR_INTERNET_ITEM_NOT_FOUND;
|
||||
SetLastError(ERROR_SEVERITY_ERROR | FAC(FACILITY_HTTP) | error_code);
|
||||
uprintf("Unable to access file: %d", DownloadStatus);
|
||||
uprintf("%s: %d", (DownloadStatus == 404) ? "File not found" : "Unable to access file", DownloadStatus);
|
||||
goto out;
|
||||
}
|
||||
dwSize = sizeof(strsize);
|
||||
|
@ -705,7 +707,7 @@ static DWORD WINAPI CheckForUpdatesThread(LPVOID param)
|
|||
static_sprintf(agent, APPLICATION_NAME "/%d.%d.%d (Windows NT %lu.%lu%s)",
|
||||
rufus_version[0], rufus_version[1], rufus_version[2],
|
||||
WindowsVersion.Major, WindowsVersion.Minor, is_WOW64() ? "; WOW64" : "");
|
||||
hSession = GetInternetSession(FALSE);
|
||||
hSession = GetInternetSession(NULL, FALSE);
|
||||
if (hSession == NULL)
|
||||
goto out;
|
||||
hConnection = pfInternetConnectA(hSession, UrlParts.lpszHostName, UrlParts.nPort,
|
||||
|
@ -1125,7 +1127,7 @@ BOOL IsDownloadable(const char* url)
|
|||
hostname[sizeof(hostname) - 1] = 0;
|
||||
|
||||
// Open an Internet session
|
||||
hSession = GetInternetSession(FALSE);
|
||||
hSession = GetInternetSession(NULL, FALSE);
|
||||
if (hSession == NULL)
|
||||
goto out;
|
||||
|
||||
|
|
45
src/rufus.c
45
src/rufus.c
|
@ -226,12 +226,11 @@ static void SetBootOptions(void)
|
|||
|
||||
IGNORE_RETVAL(ComboBox_ResetContent(hBootType));
|
||||
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, lmprintf(MSG_279)), BT_NON_BOOTABLE));
|
||||
if (WindowsVersion.Version < WINDOWS_10) // The diskcopy.dll along with its MS-DOS floppy image was removed in Windows 10
|
||||
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), BT_MSDOS));
|
||||
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), BT_FREEDOS));
|
||||
image_index = (WindowsVersion.Version < WINDOWS_10) ? 3 : 2;
|
||||
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType,
|
||||
(image_path == NULL) ? lmprintf(MSG_281, lmprintf(MSG_280)) : short_image_path), BT_IMAGE));
|
||||
image_index = 1;
|
||||
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "MS-DOS"), BT_MSDOS));
|
||||
IGNORE_RETVAL(ComboBox_SetItemData(hBootType, ComboBox_AddStringU(hBootType, "FreeDOS"), BT_FREEDOS));
|
||||
|
||||
if (advanced_mode_device) {
|
||||
static_sprintf(tmp, "Syslinux %s", embedded_sl_version_str[0]);
|
||||
|
@ -1824,9 +1823,25 @@ static DWORD WINAPI BootCheckThread(LPVOID param)
|
|||
} else if (boot_type == BT_MSDOS) {
|
||||
if ((size_check) && (ComboBox_GetCurItemData(hClusterSize) >= 65536)) {
|
||||
// MS-DOS cannot boot from a drive using a 64 kilobytes Cluster size
|
||||
MessageBoxExU(hMainDialog, lmprintf(MSG_110), lmprintf(MSG_111), MB_OK|MB_ICONERROR|MB_IS_RTL, selected_langid);
|
||||
MessageBoxExU(hMainDialog, lmprintf(MSG_110), lmprintf(MSG_111), MB_OK | MB_ICONERROR | MB_IS_RTL, selected_langid);
|
||||
goto out;
|
||||
}
|
||||
static_sprintf(tmp, "%s\\%s\\diskcopy.dll", app_data_dir, FILES_DIR);
|
||||
if (_accessU(tmp, 0) != -1) {
|
||||
uprintf("Will reuse '%s' for MS-DOS installation", tmp);
|
||||
} else {
|
||||
r = MessageBoxExU(hMainDialog, lmprintf(MSG_337), lmprintf(MSG_115),
|
||||
MB_YESNOCANCEL | MB_ICONWARNING | MB_IS_RTL, selected_langid);
|
||||
if (r != IDYES)
|
||||
goto out;
|
||||
IGNORE_RETVAL(_chdirU(app_data_dir));
|
||||
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
||||
IGNORE_RETVAL(_chdir(FILES_DIR));
|
||||
if (DownloadToFileOrBufferEx(DISKCOPY_URL, tmp, DISKCOPY_USER_AGENT, NULL, hMainDialog, FALSE) != DISKCOPY_SIZE) {
|
||||
ret = BOOTCHECK_DOWNLOAD_ERROR;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
} else if (boot_type == BT_GRUB4DOS) {
|
||||
IGNORE_RETVAL(_chdirU(app_data_dir));
|
||||
IGNORE_RETVAL(_mkdir(FILES_DIR));
|
||||
|
@ -3823,25 +3838,7 @@ extern int TestChecksum(void);
|
|||
// Ctrl-T => Alternate Test mode that doesn't require a full rebuild
|
||||
if ((ctrl_without_focus || ((GetKeyState(VK_CONTROL) & 0x8000) && (msg.message == WM_KEYDOWN)))
|
||||
&& (msg.wParam == 'T')) {
|
||||
char tmp[256], c;
|
||||
char label[256] = "2.06-blah-bli-ubutnu.23.2.1-blo";
|
||||
size_t i;
|
||||
for (i = strlen(label); i > 0; i--) {
|
||||
c = label[i];
|
||||
if (c != 0 && c != '.' && c != '-')
|
||||
continue;
|
||||
label[i] = 0;
|
||||
static_sprintf(tmp, "%s/%s-%s/core.img", FILES_URL, "grub", label);
|
||||
uprintf(tmp);
|
||||
label[i] = c;
|
||||
}
|
||||
// TestChecksum();
|
||||
//FILE* fd = fopen("D:\\ISOs\\vol.txt", "r");
|
||||
//while (fgets(label, 256, fd) != NULL) {
|
||||
// sanitize_label(label);
|
||||
// uprintf(label);
|
||||
//}
|
||||
//fclose(fd);
|
||||
TestChecksum();
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
|
10
src/rufus.h
10
src/rufus.h
|
@ -120,6 +120,11 @@
|
|||
#define SECURE_BOOT_MORE_INFO_URL "https://github.com/pbatard/rufus/wiki/FAQ#Why_do_I_need_to_disable_Secure_Boot_to_use_UEFINTFS"
|
||||
#define WPPRECORDER_MORE_INFO_URL "https://github.com/pbatard/rufus/wiki/FAQ#BSODs_with_Windows_To_Go_drives_created_from_Windows_10_1809_ISOs"
|
||||
#define SEVENZIP_URL "https://www.7-zip.org"
|
||||
#define DISKCOPY_URL "https://msdl.microsoft.com/download/symbols/diskcopy.dll/54505118173000/diskcopy.dll"
|
||||
#define DISKCOPY_USER_AGENT "Microsoft-Symbol-Server/10.0.22621.755"
|
||||
#define DISKCOPY_SIZE 0x16ee00
|
||||
#define DISKCOPY_IMAGE_OFFSET 0x66d8
|
||||
#define DISKCOPY_IMAGE_SIZE 0x168000
|
||||
#define DEFAULT_ESP_MOUNT_POINT "S:\\"
|
||||
#define IS_POWER_OF_2(x) ((x != 0) && (((x) & ((x) - 1)) == 0))
|
||||
#define IGNORE_RETVAL(expr) do { (void)(expr); } while(0)
|
||||
|
@ -654,7 +659,10 @@ extern BOOL MountRegistryHive(const HKEY key, const char* pszHiveName, const cha
|
|||
extern BOOL UnmountRegistryHive(const HKEY key, const char* pszHiveName);
|
||||
extern BOOL SetLGP(BOOL bRestore, BOOL* bExistingKey, const char* szPath, const char* szPolicy, DWORD dwValue);
|
||||
extern LONG GetEntryWidth(HWND hDropDown, const char* entry);
|
||||
extern uint64_t DownloadToFileOrBuffer(const char* url, const char* file, BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress);
|
||||
extern uint64_t DownloadToFileOrBufferEx(const char* url, const char* file, const char* user_agent,
|
||||
BYTE** buffer, HWND hProgressDialog, BOOL bTaskBarProgress);
|
||||
#define DownloadToFileOrBuffer(url, file, buffer, hProgressDialog, bTaskBarProgress) \
|
||||
DownloadToFileOrBufferEx(url, file, NULL, buffer, hProgressDialog, bTaskBarProgress)
|
||||
extern DWORD DownloadSignedFile(const char* url, const char* file, HWND hProgressDialog, BOOL PromptOnError);
|
||||
extern HANDLE DownloadSignedFileThreaded(const char* url, const char* file, HWND hProgressDialog, BOOL bPromptOnError);
|
||||
extern INT_PTR CALLBACK UpdateCallback(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
|
10
src/rufus.rc
10
src/rufus.rc
|
@ -33,7 +33,7 @@ LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
|||
IDD_DIALOG DIALOGEX 12, 12, 232, 326
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
EXSTYLE WS_EX_ACCEPTFILES
|
||||
CAPTION "Rufus 4.0.2039"
|
||||
CAPTION "Rufus 4.0.2040"
|
||||
FONT 9, "Segoe UI Symbol", 400, 0, 0x0
|
||||
BEGIN
|
||||
LTEXT "Drive Properties",IDS_DRIVE_PROPERTIES_TXT,8,6,53,12,NOT WS_GROUP
|
||||
|
@ -392,8 +392,8 @@ END
|
|||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 4,0,2039,0
|
||||
PRODUCTVERSION 4,0,2039,0
|
||||
FILEVERSION 4,0,2040,0
|
||||
PRODUCTVERSION 4,0,2040,0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
|
@ -411,13 +411,13 @@ BEGIN
|
|||
VALUE "Comments", "https://rufus.ie"
|
||||
VALUE "CompanyName", "Akeo Consulting"
|
||||
VALUE "FileDescription", "Rufus"
|
||||
VALUE "FileVersion", "4.0.2039"
|
||||
VALUE "FileVersion", "4.0.2040"
|
||||
VALUE "InternalName", "Rufus"
|
||||
VALUE "LegalCopyright", "© 2011-2023 Pete Batard (GPL v3)"
|
||||
VALUE "LegalTrademarks", "https://www.gnu.org/licenses/gpl-3.0.html"
|
||||
VALUE "OriginalFilename", "rufus-4.0.exe"
|
||||
VALUE "ProductName", "Rufus"
|
||||
VALUE "ProductVersion", "4.0.2039"
|
||||
VALUE "ProductVersion", "4.0.2040"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
|
|
Loading…
Reference in a new issue