From: Toni Wilen Date: Mon, 8 Jan 2018 18:19:37 +0000 (+0200) Subject: CHS-only IDE drive imaging support. X-Git-Tag: 3600~6 X-Git-Url: https://git.unchartedbackwaters.co.uk/w/?a=commitdiff_plain;h=f88faf34c00c4f5dc6091edd67a0963bf5f14ea2;p=francis%2Fwinuae.git CHS-only IDE drive imaging support. --- diff --git a/od-win32/hardfile_win32.cpp b/od-win32/hardfile_win32.cpp index aa6c1ee4..9cc5d19e 100644 --- a/od-win32/hardfile_win32.cpp +++ b/od-win32/hardfile_win32.cpp @@ -754,10 +754,11 @@ static bool hd_get_meta_hack(HWND hDlg, HANDLE h, uae_u8 *data, uae_u8 *inq) return false; } -static bool do_scsi_read10_chs(HANDLE handle, uae_u32 lba, int c, int h, int s, uae_u8 *data) +static bool do_scsi_read10_chs(HANDLE handle, uae_u32 lba, int c, int h, int s, uae_u8 *data, int cnt, bool log) { uae_u8 cmd[10] = { 0 }; +#if 0 cmd[0] = 0x28; cmd[2] = 0; cmd[3] = 0; @@ -765,6 +766,8 @@ static bool do_scsi_read10_chs(HANDLE handle, uae_u32 lba, int c, int h, int s, cmd[5] = 1; cmd[8] = 1; do_scsi_in(handle, cmd, 10, data, 512); +#endif + memset(data, 0, 512 * cnt); cmd[0] = 0x28; if (lba != 0xffffffff) { @@ -778,9 +781,9 @@ static bool do_scsi_read10_chs(HANDLE handle, uae_u32 lba, int c, int h, int s, cmd[4] = c; cmd[5] = s; } - cmd[8] = 1; - bool r = do_scsi_in(handle, cmd, 10, data, 512) > 0; - if (r) { + cmd[8] = cnt; + bool r = do_scsi_in(handle, cmd, 10, data, 512 * cnt) > 0; + if (r && log) { int s = 32; int o = 0; for (int i = 0; i < 512; i += s) { @@ -981,19 +984,19 @@ static bool hd_get_meta_satl(HWND hDlg, HANDLE h, uae_u8 *data, TCHAR *text, str } if (invalidcapacity) { - bool chs0 = do_scsi_read10_chs(h, 0xffffffff, 0, 0, 0, data); - bool chs1 = do_scsi_read10_chs(h, 0xffffffff, 0, 0, 1, data); + bool chs0 = do_scsi_read10_chs(h, 0xffffffff, 0, 0, 0, data, 1, true); + bool chs1 = do_scsi_read10_chs(h, 0xffffffff, 0, 0, 1, data, 1, true); write_log(_T("CHS0=%d CHS1=%d\n"), chs0, chs1); int hh, ss; for (ss = 1; ss < 256; ss++) { - if (!do_scsi_read10_chs(h, 0xffffffff, 0, 0, ss, data)) { + if (!do_scsi_read10_chs(h, 0xffffffff, 0, 0, ss, data, 1, true)) { ss--; break; } } write_log(_T("Sectors=%d\n"), ss); for (hh = 0; hh < 16; hh++) { - if (!do_scsi_read10_chs(h, 0xffffffff, 0, hh, 1, data)) { + if (!do_scsi_read10_chs(h, 0xffffffff, 0, hh, 1, data, 1, true)) { break; } } @@ -1025,6 +1028,125 @@ end:; return ret; } +static int chsdialogactive, chs_secs, chs_cyls, chs_heads; +static INT_PTR CALLBACK CHSDialogProc(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam) +{ + switch (msg) + { + case WM_DESTROY: + PostQuitMessage(0); + return TRUE; + case WM_CLOSE: + chsdialogactive = 0; + DestroyWindow(hDlg); + return TRUE; + case WM_INITDIALOG: + chs_secs = chs_cyls = chs_heads = 0; + return TRUE; + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDC_CHS_SECTORS: + chs_secs = GetDlgItemInt(hDlg, IDC_CHS_SECTORS, NULL, FALSE); + break; + case IDC_CHS_CYLINDERS: + chs_cyls = GetDlgItemInt(hDlg, IDC_CHS_CYLINDERS, NULL, FALSE); + break; + case IDC_CHS_HEADS: + chs_heads = GetDlgItemInt(hDlg, IDC_CHS_HEADS, NULL, FALSE); + break; + case IDOK: + chsdialogactive = -1; + DestroyWindow(hDlg); + return TRUE; + case IDCANCEL: + chsdialogactive = 0; + DestroyWindow(hDlg); + return TRUE; + } + break; + } + return FALSE; +} + + +static int gethdfchs(HWND hDlg, HANDLE h, int *cylsp, int *headsp, int *secsp) +{ + uae_u8 cmd[10]; + int cyls = 0, heads = 0, secs = 0; + uae_u8 *data = (uae_u8*)VirtualAlloc(NULL, 65536, MEM_COMMIT, PAGE_READWRITE); + DWORD err = 0; + + memset(data, 0, 512); + memset(cmd, 0, sizeof(cmd)); + cmd[0] = 0x25; + if (do_scsi_in(h, cmd, 10, data, 8) == 8) { +#if 1 + if (data[0] != 0xff || data[1] != 0xff || data[2] != 0xff || data[3] != 0xff) { + err = -11; + goto end; + } + if (data[4] != 0x00 || data[5] != 0x00 || data[6] != 0x02 || data[7] != 0x00) { + err = -12; + goto end; + } +#endif + } else { + write_log(_T("READ_CAPACITY FAILED\n")); + err = -10; + } + if (!cylsp || !headsp || !secsp) + return err; + chsdialogactive = 1; + HWND hwnd = CustomCreateDialog(IDD_CHSQUERY, hDlg, CHSDialogProc); + if (hwnd == NULL) { + err = -15; + goto end; + } + HFONT font = CreateFont(getscaledfontsize(-1), 0, 0, 0, 0, 0, 0, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, _T("Lucida Console")); + if (font) + SendMessage(GetDlgItem(hwnd, IDD_CHSQUERY), WM_SETFONT, WPARAM(font), FALSE); + while (chsdialogactive == 1) { + MSG msg; + int ret; + WaitMessage(); + while ((ret = GetMessage(&msg, NULL, 0, 0))) { + if (ret == -1) + break; + if (!IsWindow(hwnd) || !IsDialogMessage(hwnd, &msg)) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + } + DeleteObject(font); + if (chsdialogactive == 0) { + err = -100; + goto end; + } + secs = chs_secs; + heads = chs_heads; + cyls = chs_cyls; + if (secs <= 0 || heads <= 0 || cyls <= 0) { + err = -13; + goto end; + } + if (secs >= 256 || heads >= 16 || cyls > 2048) { + err = -14; + goto end; + } +end: + VirtualFree(data, 0, MEM_RELEASE); + if (cylsp) + *cylsp = cyls; + if (headsp) + *headsp = heads; + if (secsp) + *secsp = secs; + return err; +} + + static int stringboxdialogactive; static TCHAR geometry_file[MAX_DPATH]; static struct ini_data *hdini; @@ -2940,15 +3062,43 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx) MSG msg; int pct, cnt; DWORD r; + bool chsmode = false; + DWORD erc = 0; + int cyls = 0, heads = 0, secs = 0; + int cyl = 0, head = 0; cache = VirtualAlloc (NULL, COPY_CACHE_SIZE, MEM_COMMIT, PAGE_READWRITE); if (!cache) goto err; - h = CreateFile (uae_drives[idx].device_path, GENERIC_READ, FILE_SHARE_READ, NULL, - OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_NO_BUFFERING, NULL); + + // Direct scsi for CHS check requires both READ and WRITE access. + h = CreateFile(uae_drives[idx].device_path, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h != INVALID_HANDLE_VALUE) { + if (!gethdfchs(hDlg, h, NULL, NULL, NULL)) { + chsmode = true; + erc = gethdfchs(hDlg, h, &cyls, &heads, &secs); + if (erc == -100) { + chsmode = false; + CloseHandle(h); + h = INVALID_HANDLE_VALUE; + } else if (erc) { + goto err; + } else { + size = (uae_u64)cyls * heads * secs * 512; + } + } else { + CloseHandle(h); + } + } + erc = 0; + if (!chsmode) { + size = uae_drives[idx].size; + h = CreateFile(uae_drives[idx].device_path, GENERIC_READ, FILE_SHARE_READ, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | FILE_FLAG_NO_BUFFERING, NULL); + } if (h == INVALID_HANDLE_VALUE) goto err; - size = uae_drives[idx].size; path[0] = 0; DiskSelection (hDlg, IDC_PATH_NAME, 3, p, NULL, NULL); GetDlgItemText (hDlg, IDC_PATH_NAME, path, MAX_DPATH); @@ -2991,7 +3141,12 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx) break; if (cnt > 0) { SendMessage (hwndprogress, PBM_SETPOS, (WPARAM)pct, 0); - _stprintf (tmp, _T("%dM / %dM (%d%%)"), (int)(written >> 20), (int)(size >> 20), pct); + if (chsmode) { + _stprintf(tmp2, _T("Cyl %d/%d Head %d/%d"), cyl, cyls, head, heads); + } else { + _stprintf(tmp2, _T("LBA %lld/%lld"), written / 512, size / 512); + } + _stprintf (tmp, _T("%s %dM/%dM (%d%%)"), tmp2, (int)(written >> 20), (int)(size >> 20), pct); SendMessage (hwndprogresstxt, WM_SETTEXT, 0, (LPARAM)tmp); while (PeekMessage (&msg, hwnd, 0, 0, PM_REMOVE)) { if (!IsDialogMessage (hwnd, &msg)) { @@ -3010,12 +3165,23 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx) break; } } - get = COPY_CACHE_SIZE; - if (sizecnt + get > size) - get = size - sizecnt; - if (!ReadFile (h, cache, get, &got, NULL)) { - progressdialogreturn = 4; - break; + if (chsmode) { + do_scsi_read10_chs(h, -1, cyl, head, 1, (uae_u8*)cache, secs, false); + get = 512 * secs; + got = 512 * secs; + head++; + if (head >= heads) { + head = 0; + cyl++; + } + } else { + get = COPY_CACHE_SIZE; + if (sizecnt + get > size) + get = size - sizecnt; + if (!ReadFile(h, cache, get, &got, NULL)) { + progressdialogreturn = 4; + break; + } } if (get != got) { progressdialogreturn = 5; @@ -3032,7 +3198,7 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx) if (written == size) break; } - if (got != COPY_CACHE_SIZE) { + if (got != COPY_CACHE_SIZE && !chsmode) { progressdialogreturn = 1; break; } @@ -3059,12 +3225,13 @@ int harddrive_to_hdf (HWND hDlg, struct uae_prefs *p, int idx) goto ok; err: - DWORD err = GetLastError (); + if (!erc) + erc = GetLastError (); LPWSTR pBuffer = NULL; WIN32GUI_LoadUIString (IDS_HDCLONE_FAIL, tmp, MAX_DPATH); - if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&pBuffer, 0, NULL)) + if (!FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, erc, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&pBuffer, 0, NULL)) pBuffer = NULL; - _stprintf (tmp2, tmp, progressdialogreturn, err, pBuffer ? _T("") : pBuffer); + _stprintf (tmp2, tmp, progressdialogreturn, erc, pBuffer ? _T("") : pBuffer); gui_message (tmp2); LocalFree (pBuffer); diff --git a/od-win32/resources/resource.h b/od-win32/resources/resource.h index f5ba452c..4f25a83c 100644 --- a/od-win32/resources/resource.h +++ b/od-win32/resources/resource.h @@ -393,6 +393,7 @@ #define IDS_SLIRP_INBOUND 399 #define IDD_BOARDS 399 #define IDS_FILTER_PAL_EXTRA 400 +#define IDD_CHSQUERY 400 #define IDS_FILTER_3D_EXTRA 401 #define IDS_ALWAYS_ON 402 #define IDS_DISPLAY_ATTRIBUTES 403 @@ -1284,6 +1285,9 @@ #define IDC_EDIT1 1857 #define IDC_EXPANSIONBOARDSTRINGBOX 1857 #define IDC_CS_UNMAPPED 1858 +#define IDC_CHS_CYLINDERS 1859 +#define IDC_CHS_HEADS 1860 +#define IDC_CHS_SECTORS 1861 #define ID__FLOPPYDRIVES 40004 #define ID_FLOPPYDRIVES_DF0 40005 #define ID_ST_CONFIGURATION 40010 @@ -1335,7 +1339,7 @@ #define _APS_3D_CONTROLS 1 #define _APS_NEXT_RESOURCE_VALUE 407 #define _APS_NEXT_COMMAND_VALUE 40050 -#define _APS_NEXT_CONTROL_VALUE 1859 +#define _APS_NEXT_CONTROL_VALUE 1860 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif diff --git a/od-win32/resources/winuae.rc b/od-win32/resources/winuae.rc index 457e39ea..7907bf06 100644 --- a/od-win32/resources/winuae.rc +++ b/od-win32/resources/winuae.rc @@ -1344,6 +1344,22 @@ BEGIN CONTROL "Enabled",IDC_SCSIROMSELECTED,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,202,43,99,12 END +IDD_CHSQUERY DIALOGEX 0, 0, 396, 85 +STYLE DS_LOCALEDIT | DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | DS_CENTERMOUSE | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +CAPTION "CHS Geometry" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + PUSHBUTTON "OK",IDOK,59,57,135,15 + PUSHBUTTON "Cancel",IDCANCEL,201,57,135,15 + EDITTEXT IDC_CHS_CYLINDERS,86,32,45,13,ES_AUTOHSCROLL + EDITTEXT IDC_CHS_HEADS,204,32,45,13,ES_AUTOHSCROLL + EDITTEXT IDC_CHS_SECTORS,322,32,45,13,ES_AUTOHSCROLL + RTEXT "Cylinders:",IDC_STATIC,27,33,45,9 + RTEXT "Heads:",IDC_STATIC,145,33,45,9 + RTEXT "Sectors:",IDC_STATIC,263,33,45,9 + CTEXT "Imaging CHS-only IDE drive requires correct geometry. Check drive label.",IDC_STATIC,39,10,330,9 +END + ///////////////////////////////////////////////////////////////////////////// // @@ -1679,6 +1695,10 @@ BEGIN IDD_EXPANSION2, DIALOG BEGIN END + + IDD_CHSQUERY, DIALOG + BEGIN + END END #endif // APSTUDIO_INVOKED