diff --git a/CHANGES.md b/CHANGES.md index 6ccfaaf5..be87a63e 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,5 @@ +## Changes in v10.x compared to v10.x (????? 202x) +1. UNC Path support via CTRL-G. Shows up as 'digit drive' 0: - 9:. Select it either via CTRL-0 ... CTRL-9 or from drive drop-down. Remove UNC digit drive with CTRL-W ## Changes in v10.3 compared to v10.2 (March 2024) diff --git a/src/lang/res_de-DE.rc b/src/lang/res_de-DE.rc index cbec8b65..0f83e59f 100644 --- a/src/lang/res_de-DE.rc +++ b/src/lang/res_de-DE.rc @@ -283,7 +283,7 @@ BEGIN IDS_STATUSMSG, "%d Datei(en) (%s)" /* 128 */ IDS_STATUSMSG2, "%d Datei(en) (%s) ausgewählt" /* 128 */ - IDS_DRIVEFREE, "%c: %s von %s frei" /* 128 */ + IDS_DRIVEFREE, "%s %s von %s frei" /* 128 */ IDS_TREEABORT, "Unvollständiger Verzeichnisbaum wird angezeigt" /* 128 */ IDS_DIRSREAD, "%d Verzeichnisse gelesen" /* 32 */ IDS_SEARCHMSG, "%d Datei(en) gefunden" diff --git a/src/lang/res_en-US.rc b/src/lang/res_en-US.rc index 0ddbb952..b6ed5a59 100644 --- a/src/lang/res_en-US.rc +++ b/src/lang/res_en-US.rc @@ -285,7 +285,7 @@ BEGIN IDS_STATUSMSG, "Total %d file(s) (%s)" /* 128 */ IDS_STATUSMSG2, "Selected %d file(s) (%s)" /* 128 */ - IDS_DRIVEFREE, "%c: %s free, %s total" /* 128 */ + IDS_DRIVEFREE, "%s %s free, %s total" /* 128 */ IDS_TREEABORT, "Incomplete directory tree displayed" /* 128 */ IDS_DIRSREAD, "Directories read: %d " /* 32 */ IDS_SEARCHMSG, "%d file(s) found" diff --git a/src/lang/res_he-IL.rc b/src/lang/res_he-IL.rc index b3c91442..ec35adb0 100644 --- a/src/lang/res_he-IL.rc +++ b/src/lang/res_he-IL.rc @@ -285,7 +285,7 @@ BEGIN IDS_STATUSMSG, "סך הכל %d קבצים (%s)" /* 128 */ IDS_STATUSMSG2, "%d קבצים נבחרו (%s)" /* 128 */ - IDS_DRIVEFREE, "%c: %s פנוי, %s סך הכל" /* 128 */ + IDS_DRIVEFREE, "%s %s פנוי, %s סך הכל" /* 128 */ IDS_TREEABORT, "עץ התיקיות לא מוצג במלואו" /* 128 */ IDS_DIRSREAD, "תיקיות נקראו: %d " /* 32 */ IDS_SEARCHMSG, "%d קבצים נמצאו" diff --git a/src/lang/res_ja-JP.rc b/src/lang/res_ja-JP.rc index d0246ef4..58180df5 100644 --- a/src/lang/res_ja-JP.rc +++ b/src/lang/res_ja-JP.rc @@ -91,8 +91,8 @@ BEGIN MENUITEM "フォント(&F)...", IDM_FONT MENUITEM "ツール バーのカスタマイズ(&B)...", IDM_TOOLBARCUST MENUITEM "追加の設定(&P)...", IDM_PREF - MENUITEM SEPARATOR - MENUITEM "ツール バー(&T)", IDM_TOOLBAR + MENUITEM SEPARATOR + MENUITEM "ツール バー(&T)", IDM_TOOLBAR MENUITEM "ドライブ バー(&D)", IDM_DRIVEBAR MENUITEM "ステータス バー(&S)", IDM_STATUSBAR MENUITEM SEPARATOR @@ -284,7 +284,7 @@ BEGIN IDS_STATUSMSG, "合計 %d 個のファイル (%s)" /* 128 */ IDS_STATUSMSG2, "%d 個のファイルを選択 (%s)" /* 128 */ - IDS_DRIVEFREE, "%c: %s 使用可能(合計 %s)" /* 128 */ + IDS_DRIVEFREE, "%s %s 使用可能(合計 %s)" /* 128 */ IDS_TREEABORT, "ディレクトリ ツリーの表示が不完全" /* 128 */ IDS_DIRSREAD, "ディレクトリの読み込み: %d" /* 32 */ IDS_SEARCHMSG, "%d 個のファイルが見つかりました" diff --git a/src/lang/res_pl-PL.rc b/src/lang/res_pl-PL.rc index 670bc958..f6eed885 100644 --- a/src/lang/res_pl-PL.rc +++ b/src/lang/res_pl-PL.rc @@ -285,7 +285,7 @@ BEGIN IDS_STATUSMSG, "Razem plików: %d (%s)" /* 128 */ IDS_STATUSMSG2, "Wybrano: %d plik(ów) (%s)" /* 128 */ - IDS_DRIVEFREE, "Wolne: %c:%s: razem: %s" /* 128 */ + IDS_DRIVEFREE, "Wolne: %s %s: razem: %s" /* 128 */ IDS_TREEABORT, "Wyświetlono niepełne drzewo katalogów" /* 128 */ IDS_DIRSREAD, "Katalogi przeczytane: %d " /* 32 */ IDS_SEARCHMSG, "Znaleziono: %d plik(ów)" diff --git a/src/lang/res_tr-TR.rc b/src/lang/res_tr-TR.rc index 4f0bb17b..b667593f 100644 --- a/src/lang/res_tr-TR.rc +++ b/src/lang/res_tr-TR.rc @@ -270,7 +270,7 @@ BEGIN IDS_UNFORMATTED, "%c sürücüsündeki disk biçimlendirilmemiş.\n\nŞimdi biçimlendirmek istiyor musunuz?" IDS_STATUSMSG, "Toplam %d dosya (%s bayt)" IDS_STATUSMSG2, "%d dosya seçili (%s bayt)" - IDS_DRIVEFREE, "%c: %s boş, toplam %s" + IDS_DRIVEFREE, "%s %s boş, toplam %s" IDS_TREEABORT, "Görüntülenen dizin ağacı eksik." IDS_DIRSREAD, "Okunan dizin sayısı: %d " IDS_SEARCHMSG, "%d dosya bulundu." diff --git a/src/lang/res_zh-CN.rc b/src/lang/res_zh-CN.rc index 6c775417..9c4095c9 100644 --- a/src/lang/res_zh-CN.rc +++ b/src/lang/res_zh-CN.rc @@ -282,7 +282,7 @@ BEGIN IDS_STATUSMSG, "共 %d 个文件 (%s)" /* 128 */ IDS_STATUSMSG2, "选择了 %d 个文件 (%s)" /* 128 */ - IDS_DRIVEFREE, "%c: %s 可用空间,%s 全部空间" /* 128 */ + IDS_DRIVEFREE, "%s %s 可用空间,%s 全部空间" /* 128 */ IDS_TREEABORT, "目录树未完整显示" /* 128 */ IDS_DIRSREAD, "目录读取: %d" /* 32 */ IDS_SEARCHMSG, "找到 %d 个文件" diff --git a/src/lang/winfile_de-DE.dlg b/src/lang/winfile_de-DE.dlg index eac8843c..c9b644d2 100644 --- a/src/lang/winfile_de-DE.dlg +++ b/src/lang/winfile_de-DE.dlg @@ -91,7 +91,7 @@ BEGIN DIALOGRESIZE { 0, 0 } CONTROL "&Datenträger:", IDD_DRIVE1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 5, 41, 10 DIALOGRESIZECONTROL { 0, 0, 100, 100 } - CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 + CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 6, 40, 14 DIALOGRESIZECONTROL { 100, 10, 0, 0 } diff --git a/src/lang/winfile_he-IL.dlg b/src/lang/winfile_he-IL.dlg index 36cdb3bb..91a7ed69 100644 --- a/src/lang/winfile_he-IL.dlg +++ b/src/lang/winfile_he-IL.dlg @@ -98,7 +98,7 @@ BEGIN DIALOGRESIZE { 0, 0 } CONTROL "&כוננים:", IDD_DRIVE1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 5, 41, 10 DIALOGRESIZECONTROL { 0, 0, 100, 100 } - CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 + CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "אישור", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 6, 40, 14 DIALOGRESIZECONTROL { 100, 10, 0, 0 } diff --git a/src/lang/winfile_ja-JP.dlg b/src/lang/winfile_ja-JP.dlg index 6f9d2ed5..6735ac36 100644 --- a/src/lang/winfile_ja-JP.dlg +++ b/src/lang/winfile_ja-JP.dlg @@ -89,18 +89,18 @@ END DRIVEDLG DIALOGEX 11, 31, 201, 86 CAPTION "ドライブの選択" FONT 8, "MS Shell Dlg" -STYLE WS_BORDER | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU | DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN +STYLE WS_BORDER | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU | DS_MODALFRAME | WS_POPUP | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 0 } + DIALOGRESIZE { 0, 0 } CONTROL "ドライブ(&D):", IDD_DRIVE1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 5, 41, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 100 } - CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 - - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 100 } + CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 + + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } CONTROL "キャンセル", IDCANCEL, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 44, 40, 14 END @@ -109,23 +109,23 @@ CAPTION "実行" FONT 8, "MS Shell Dlg" STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 125 } - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZE { 0, 125 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_DIR, "static", SS_SIMPLE | SS_NOPREFIX | WS_CHILD, 3, 6, 162, 10 - DIALOGRESIZECONTROL { 0, 10, 100, 0 } + DIALOGRESIZECONTROL { 0, 10, 100, 0 } CONTROL "コマンド ライン(&C):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_GROUP | WS_CHILD, 3, 18, 60, 10 - DIALOGRESIZECONTROL { 0, 20, 100, 0 } + DIALOGRESIZECONTROL { 0, 20, 100, 0 } CONTROL "", IDD_NAME, "edit", ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD, 3, 29, 134, 12 - DIALOGRESIZECONTROL { 0, 100, 0, 0 } + DIALOGRESIZECONTROL { 0, 100, 0, 0 } CONTROL "実行時に最小化(&M)", IDD_LOAD, "button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 3, 45, 91, 12 - DIALOGRESIZECONTROL { 50, 100, 0, 0 } + DIALOGRESIZECONTROL { 50, 100, 0, 0 } CONTROL "管理者として実行(&A)", IDD_RUNAS, "button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 84, 45, 91, 12 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 165, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } CONTROL "キャンセル", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 165, 23, 40, 14 // CONTROL "ブラウズ(&B)...", IDD_BROWSE, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 165, 40, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 165, 43, 40, 14 END @@ -134,17 +134,17 @@ CAPTION "ファイルを選択" FONT 8, "MS Shell Dlg" STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 125 } + DIALOGRESIZE { 0, 125 } CONTROL "ファイル(&F):", -1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 16, 60, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_NAME, "edit", ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD, 5, 29, 60, 12 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "選択(&S)", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 70, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } CONTROL "解除(&D)", IDYES, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 70, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 20, 0, 0 } + DIALOGRESIZECONTROL { 100, 20, 0, 0 } CONTROL "キャンセル", IDCANCEL, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 70, 40, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 70, 63, 40, 14 END @@ -276,20 +276,20 @@ CAPTION "印刷" FONT 8, "MS Shell Dlg" STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 125 } - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZE { 0, 125 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_DIR, "static", SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_CHILD, 3, 6, 193, 10 - DIALOGRESIZECONTROL { 0, 0, 0, 0 } + DIALOGRESIZECONTROL { 0, 0, 0, 0 } CONTROL "印刷(&P):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 3, 20, 26, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_FROM, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | ES_AUTOHSCROLL, 38, 18, 150, 12 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "",IDD_STATUS, "static", WS_CHILD | SS_LEFTNOWORDWRAP | SS_NOPREFIX, 3, 36, 190, 10 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 197, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } CONTROL "キャンセル", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 197, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 197, 43, 40, 14 END @@ -299,28 +299,28 @@ CAPTION "検索" FONT 8, "MS Shell Dlg" STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 125 } - DIALOGRESIZECONTROL { 0, 0, 0, 0 } - CONTROL "検索対象(&S):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 6, 50, 12 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZE { 0, 125 } + DIALOGRESIZECONTROL { 0, 0, 0, 0 } + CONTROL "検索対象(&S):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 6, 50, 12 + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_NAME, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | ES_AUTOHSCROLL, 62, 5, 170, 12 - DIALOGRESIZECONTROL { 0, 33, 0, 0 } + DIALOGRESIZECONTROL { 0, 33, 0, 0 } CONTROL "更新日時(&C):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 21, 50, 12 - DIALOGRESIZECONTROL { 0, 33, 100, 0 } + DIALOGRESIZECONTROL { 0, 33, 100, 0 } CONTROL "", IDD_DATE, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | ES_AUTOHSCROLL, 62, 20, 170, 12 - DIALOGRESIZECONTROL { 0, 67, 0, 0 } + DIALOGRESIZECONTROL { 0, 67, 0, 0 } CONTROL "検索の開始(&F):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 36, 50, 12 - DIALOGRESIZECONTROL { 0, 67, 100, 0 } + DIALOGRESIZECONTROL { 0, 67, 100, 0 } CONTROL "", IDD_DIR, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | ES_AUTOHSCROLL, 62, 35, 170, 12 - DIALOGRESIZECONTROL { 0, 100, 0, 0 } + DIALOGRESIZECONTROL { 0, 100, 0, 0 } CONTROL "全てのサブディレクトリを検索(&E)", IDD_SEARCHALL, "button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 15, 49, 110, 12 - DIALOGRESIZECONTROL { 50, 100, 0, 0 } + DIALOGRESIZECONTROL { 50, 100, 0, 0 } CONTROL "結果にディレクトリを含む(&U)", IDD_INCLUDEDIRS, "button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 132, 49, 100, 12 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 237, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 25, 0, 0 } + DIALOGRESIZECONTROL { 100, 25, 0, 0 } CONTROL "キャンセル", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 237, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 237, 43, 40, 14 END @@ -330,35 +330,35 @@ STYLE WS_BORDER | WS_THICKFRAME | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYS CAPTION "移動" FONT 8, "MS Shell Dlg" BEGIN - DIALOGRESIZE { 0, 125 } - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZE { 0, 125 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "現在のディレクトリ: N", IDD_DIR, "Static", SS_SIMPLE | SS_NOPREFIX, 3, 6, 332, 10 - DIALOGRESIZECONTROL { 0, 25, 0, 0 } + DIALOGRESIZECONTROL { 0, 25, 0, 0 } CONTROL "移動先(&T):", IDD_KK_TEXTTO, "Static", SS_LEFTNOWORDWRAP, 3, 33, 70, 10 - DIALOGRESIZECONTROL { 0, 25, 100, 0} + DIALOGRESIZECONTROL { 0, 25, 100, 0} EDITTEXT IDD_TO, 77, 32, 248, 12, ES_AUTOHSCROLL - DIALOGRESIZECONTROL { 0, 0, 0, 0 } + DIALOGRESIZECONTROL { 0, 0, 0, 0 } CONTROL "", IDD_STATUS, "Static", SS_SIMPLE | SS_NOPREFIX, 3, 49, 40, 10 - - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_NAME, "Static", SS_SIMPLE | SS_NOPREFIX, 45, 49, 290, 10 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } DEFPUSHBUTTON "OK", IDOK, 335, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } PUSHBUTTON "キャンセル", IDCANCEL, 335, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } PUSHBUTTON "ヘルプ(&H)", IDD_HELP, 335, 40, 40, 14 - DIALOGRESIZECONTROL { 0, 0, 0, 0 } + DIALOGRESIZECONTROL { 0, 0, 0, 0 } CONTROL "移動元(&F):", IDD_KK_TEXTFROM, "Static", SS_LEFTNOWORDWRAP, 3, 19, 70, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } EDITTEXT IDD_FROM, 77, 18, 248, 12, ES_AUTOHSCROLL - DIALOGRESIZECONTROL { 0, 50, 0, 0 } + DIALOGRESIZECONTROL { 0, 50, 0, 0 } CONTROL "", IDD_DIRS, "Static", SS_LEFTNOWORDWRAP, 3, 49, 330, 10 END @@ -369,21 +369,21 @@ CAPTION "削除" FONT 8, "MS Shell Dlg" STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 125 } - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZE { 0, 125 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "現在のディレクトリ: C", IDD_DIR, "static", SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_CHILD, 3, 5, 193, 10 CONTROL "削除(&L):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 3, 20, 35, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_FROM, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | ES_AUTOHSCROLL, 40, 19, 155, 12 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_STATUS, "static", WS_CHILD | SS_SIMPLE | SS_NOPREFIX, 3, 35, 35, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_NAME, "static", WS_CHILD | SS_SIMPLE | SS_NOPREFIX, 40, 35, 155, 10 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 200, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } CONTROL "キャンセル", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 200, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 200, 40, 40, 14 END @@ -525,19 +525,19 @@ CAPTION "ディレクトリを作成" FONT 8, "MS Shell Dlg" STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 125 } - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZE { 0, 125 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_DIR, "static", SS_LEFTNOWORDWRAP | SS_NOPREFIX | WS_CHILD, 3, 6, 154, 10 CONTROL "名称(&N):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 3, 23, 25, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_NAME, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | ES_AUTOHSCROLL, 35, 22, 90, 12 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "",IDD_STATUS, "static", WS_CHILD | SS_NOPREFIX | SS_LEFTNOWORDWRAP, 3, 46, 150, 10 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 157, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } CONTROL "キャンセル", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 157, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 157, 43, 40, 14 END @@ -573,15 +573,15 @@ CAPTION "ディスクのボリューム ラベル" FONT 8, "MS Shell Dlg" STYLE WS_BORDER | DS_MODALFRAME | WS_CAPTION | WS_THICKFRAME | WS_POPUP | WS_SYSMENU | WS_CLIPCHILDREN BEGIN - DIALOGRESIZE { 0, 125 } + DIALOGRESIZE { 0, 125 } CONTROL "ラベル(&L):", IDD_TEXT, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 15, 30, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } CONTROL "", IDD_NAME, "edit", ES_LEFT | WS_BORDER | WS_TABSTOP | WS_CHILD | ES_AUTOHSCROLL, 5, 26, 100, 12 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", 1, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 115, 6, 40, 14 - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } CONTROL "キャンセル", 2, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 115, 23, 40, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } CONTROL "ヘルプ(&H)", IDD_HELP, "button", BS_PUSHBUTTON | WS_TABSTOP | WS_CHILD, 115, 43, 40, 14 END @@ -819,36 +819,36 @@ CAPTION "関連付け" STYLE WS_BORDER | WS_THICKFRAME | DS_MODALFRAME | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU | WS_CLIPCHILDREN FONT 8, "MS Shell Dlg" BEGIN - DIALOGRESIZE { 0, 0 } + DIALOGRESIZE { 0, 0 } LTEXT "ファイルの拡張子(&F):", -1, 6, 7, 68, 8 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } COMBOBOX IDD_EXT, 76, 5, 44, 55, CBS_DROPDOWN | CBS_SORT | CBS_HASSTRINGS | WS_VSCROLL | WS_TABSTOP LTEXT "関連付け(&A):", -1, 6, 30, 92, 10 - DIALOGRESIZECONTROL { 0, 0, 100, 0 } + DIALOGRESIZECONTROL { 0, 0, 100, 0 } EDITTEXT IDD_COMMAND, 6, 42, 172, 12, ES_AUTOHSCROLL - DIALOGRESIZECONTROL { 0, 0, 100, 100 } + DIALOGRESIZECONTROL { 0, 0, 100, 100 } LISTBOX IDD_CLASSLIST, 11, 54, 167, 62, LBS_SORT | WS_VSCROLL | WS_TABSTOP #ifdef ASSOC #ifdef ASSOCHEAD | LBS_OWNERDRAWFIXED | LBS_HASSTRINGS #endif #endif - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } PUSHBUTTON "ブラウズ(&B)...", IDD_BROWSE, 130, 24, 47, 14 - DIALOGRESIZECONTROL { 100, 0, 0, 0 } + DIALOGRESIZECONTROL { 100, 0, 0, 0 } DEFPUSHBUTTON "OK", IDOK, 187, 6, 62, 14, WS_GROUP - DIALOGRESIZECONTROL { 100, 10, 0, 0 } + DIALOGRESIZECONTROL { 100, 10, 0, 0 } PUSHBUTTON "キャンセル", IDCANCEL, 187, 23, 62, 14 - DIALOGRESIZECONTROL { 100, 30, 0, 0 } + DIALOGRESIZECONTROL { 100, 30, 0, 0 } PUSHBUTTON "新しい種別(&N)...", IDD_NEW, 187, 42, 62, 14 - DIALOGRESIZECONTROL { 100, 40, 0, 0 } + DIALOGRESIZECONTROL { 100, 40, 0, 0 } PUSHBUTTON "種別を変更(&C)...", IDD_CONFIG, 187, 59, 62, 14 - DIALOGRESIZECONTROL { 100, 50, 0, 0 } + DIALOGRESIZECONTROL { 100, 50, 0, 0 } PUSHBUTTON "種別を削除(&D)", IDD_DELETE, 187, 76, 62, 14 - DIALOGRESIZECONTROL { 100, 100, 0, 0 } + DIALOGRESIZECONTROL { 100, 100, 0, 0 } PUSHBUTTON "ヘルプ(&H)", IDD_HELP, 187, 95, 62, 14 #ifdef ASSOC diff --git a/src/lang/winfile_pl-PL.dlg b/src/lang/winfile_pl-PL.dlg index f0cfe857..45e5657b 100644 --- a/src/lang/winfile_pl-PL.dlg +++ b/src/lang/winfile_pl-PL.dlg @@ -94,7 +94,7 @@ BEGIN DIALOGRESIZE { 0, 0 } CONTROL "&Dyski:", IDD_DRIVE1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 5, 41, 10 DIALOGRESIZECONTROL { 0, 0, 100, 100 } - CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 + CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "OK", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 6, 40, 14 DIALOGRESIZECONTROL { 100, 10, 0, 0 } @@ -116,7 +116,7 @@ BEGIN DIALOGRESIZECONTROL { 0, 20, 100, 0 } CONTROL "", IDD_NAME, "edit", ES_LEFT | ES_AUTOHSCROLL | WS_BORDER | WS_TABSTOP | WS_CHILD, 3, 29, 134, 12 DIALOGRESIZECONTROL { 0, 90, 0, 0 } - CONTROL "&Uruchom zminimalizowane", IDD_LOAD, "button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 3, 45, 134, 12 + CONTROL "&Uruchom zminimalizowane", IDD_LOAD, "button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 3, 45, 134, 12 DIALOGRESIZECONTROL { 0, 100, 0, 0 } CONTROL "Uruchom z uprawnieniami &administracyjnymi", IDD_RUNAS, "button", BS_AUTOCHECKBOX | WS_TABSTOP | WS_CHILD, 3, 60, 155, 12 DIALOGRESIZECONTROL { 100, 0, 0, 0 } diff --git a/src/lang/winfile_tr-TR.dlg b/src/lang/winfile_tr-TR.dlg index aa512e67..72cfacad 100644 --- a/src/lang/winfile_tr-TR.dlg +++ b/src/lang/winfile_tr-TR.dlg @@ -94,7 +94,7 @@ BEGIN DIALOGRESIZE { 0, 0 } CONTROL "&Sürücüler:", IDD_DRIVE1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 5, 41, 10 DIALOGRESIZECONTROL { 0, 0, 100, 100 } - CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 + CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "Tamam", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 6, 40, 14 DIALOGRESIZECONTROL { 100, 10, 0, 0 } diff --git a/src/lang/winfile_zh-CN.dlg b/src/lang/winfile_zh-CN.dlg index 61ff217a..3abf4a37 100644 --- a/src/lang/winfile_zh-CN.dlg +++ b/src/lang/winfile_zh-CN.dlg @@ -94,7 +94,7 @@ BEGIN DIALOGRESIZE { 0, 0 } CONTROL "驱动器(&D):", IDD_DRIVE1, "static", SS_LEFTNOWORDWRAP | WS_CHILD, 5, 5, 41, 10 DIALOGRESIZECONTROL { 0, 0, 100, 100 } - CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_SORT | LBS_STANDARD | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 + CONTROL "", IDD_DRIVE, "listbox", LBS_NOTIFY | LBS_USETABSTOPS | WS_BORDER | WS_VSCROLL | WS_CHILD | WS_TABSTOP, 5, 16, 140, 60 DIALOGRESIZECONTROL { 100, 0, 0, 0 } CONTROL "确定", IDOK, "button", BS_DEFPUSHBUTTON | WS_TABSTOP | WS_CHILD, 155, 6, 40, 14 DIALOGRESIZECONTROL { 100, 10, 0, 0 } diff --git a/src/treectl.c b/src/treectl.c index 52948ae0..68003a51 100644 --- a/src/treectl.c +++ b/src/treectl.c @@ -804,6 +804,7 @@ ReadDirLevel( iNode, dwAttribs, bFullyExpand, szAutoExpand, bPartialSort); } + BOOL bCasePreserved = IsCasePreservedDrive(DRIVEID(szPath)); while (bFound) { if (uYieldCount & (1<pParent == *ppPreviousNode) { + if (!lstrcmpi(lpszElement, pNode->szName)) { + // We've found the element, but we are not at the end of the path + *dwPreviousNode = *dwIndex; + *ppPreviousNode = pNode; + break; + } + } + (*dwIndex)++; + } + + return bReturn; +} + // // FindItemFromPath() // @@ -1333,116 +1388,100 @@ FindItemFromPath( HWND hwndLB, LPTSTR lpszPath, BOOL bReturnParent, - DWORD *pIndex, - PDNODE *ppNode) + DWORD* pIndex, + PDNODE* ppNode) { - DWORD i; - LPTSTR p; - PDNODE pNode; - DWORD iPreviousNode; - PDNODE pPreviousNode; - TCHAR szElement[1+MAXFILENAMELEN+1]; - - if (pIndex) - { + DWORD dwIndex; + LPTSTR p; + PDNODE pNode; + DWORD iPreviousNode; + PDNODE pPreviousNode; + TCHAR szElement[1 + MAXFILENAMELEN + 1]; + BOOL bReturn = TRUE; + + if (pIndex) { *pIndex = (DWORD)-1; - } - if (ppNode) - { + } + if (ppNode) { *ppNode = NULL; - } + } - if (!lpszPath || lstrlen(lpszPath) < 3 || lpszPath[1] != CHAR_COLON) - { + if (!lpszPath || lstrlen(lpszPath) < 3 || !((lpszPath[1] == CHAR_COLON) || lpszPath[1] == CHAR_BACKSLASH)) { return FALSE; - } - - i = 0; - iPreviousNode = (DWORD)-1; - pPreviousNode = NULL; - - while (*lpszPath) - { - /* NULL out szElement[1] so the backslash hack isn't repeated with - * a first level directory of length 1. - */ - szElement[1] = CHAR_NULL; - - /* Copy the next section of the path into 'szElement' */ - p = szElement; + } - while (*lpszPath && *lpszPath != CHAR_BACKSLASH) - *p++ = *lpszPath++; + dwIndex = 0; + iPreviousNode = (DWORD)-1; + pPreviousNode = NULL; - /* Add a backslash for the Root directory. */ + // Retrieve the name of the root, which is always on index 0 + if (SendMessage(hwndLB, LB_GETTEXT, 0, (LPARAM)&pNode) != LB_ERR) { - if (szElement[1] == CHAR_COLON) - *p++ = CHAR_BACKSLASH; + // Is the root node a subnode of lpszPath + if (StrStrI(lpszPath, pNode->szName)) { + lstrcpy(szElement, pNode->szName); + // move lpszPath at the end of the + lpszPath += lstrlen(szElement); - /* NULL terminate 'szElement' */ - *p = CHAR_NULL; + do { + bReturn = MatchNode(hwndLB, szElement, &dwIndex, &iPreviousNode, &pPreviousNode); + + /* NULL out szElement[1] so the backslash hack isn't repeated with + * a first level directory of length 1. + */ + szElement[1] = CHAR_NULL; + + // Copy the next section of the path into 'szElement' and terminate it + p = szElement; + while (*lpszPath && *lpszPath != CHAR_BACKSLASH) + *p++ = *lpszPath++; + *p = CHAR_NULL; + + // Skip over the path's next Backslash. + if (*lpszPath) + lpszPath++; + else + if (bReturnParent) { + /* We're at the end of a path which includes a filename. Return + * the previously found parent. + */ + if (pIndex) { + *pIndex = iPreviousNode; + } + if (ppNode) { + *ppNode = pPreviousNode; + } + return TRUE; + } - /* Skip over the path's next Backslash. */ + // Break through the loops + if (!bReturn) + break; - if (*lpszPath) - lpszPath++; + } while (*lpszPath); - else if (bReturnParent) - { - /* We're at the end of a path which includes a filename. Return - * the previously found parent. - */ - if (pIndex) { - *pIndex = iPreviousNode; - } - if (ppNode) { - *ppNode = pPreviousNode; - } - return TRUE; - } - - while (TRUE) - { - /* Out of LB items? Not found. */ - if (SendMessage(hwndLB, LB_GETTEXT, i, (LPARAM)&pNode) == LB_ERR) - { - if (pIndex) - { - *pIndex = iPreviousNode; - } - if (ppNode) - { - *ppNode = pPreviousNode; - } - return FALSE; - } + if (*szElement) + bReturn = MatchNode(hwndLB, szElement, &dwIndex, &iPreviousNode, &pPreviousNode); + } + else { + // e.g. drive change, when root node is different than lpszPath + bReturn = FALSE; + } + } + else + // uuups no root node. We should never get there + bReturn = FALSE; - if (pNode->pParent == pPreviousNode) - { - if (!lstrcmpi(szElement, pNode->szName)) - { - /* We've found the element... */ - iPreviousNode = i; - pPreviousNode = pNode; - break; - } - } - i++; - } - } - if (pIndex) - { + if (pIndex) { *pIndex = iPreviousNode; - } - if (ppNode) - { + } + if (ppNode) { *ppNode = pPreviousNode; - } + } - return TRUE; + return bReturn; } - /*--------------------------------------------------------------------------*/ /* */ /* RectTreeItem() - */ @@ -2123,7 +2162,7 @@ TreeControlWndProc( switch (uMsg) { case FS_GETDRIVE: - return (GetWindowLongPtr(hwndParent, GWL_TYPE) + L'A'); + return GetWindowLongPtr(hwndParent, GWL_TYPE) + CHAR_A; case TC_COLLAPSELEVEL: { @@ -2248,10 +2287,10 @@ TreeControlWndProc( case TC_SETDRIVE: { -#define fFullyExpand LOBYTE(wParam) -#define fDontSteal HIBYTE(wParam) -#define fDontSelChange HIWORD(wParam) -#define szDir (LPTSTR)lParam // NULL -> default == window text. + INT fFullyExpand = LOBYTE(wParam); + INT fDontSteal = HIBYTE(wParam); + INT fDontSelChange = HIWORD(wParam); + LPTSTR szDir = (LPTSTR)lParam; // NULL -> default == window text. // // Don't do anything while the tree is being built. @@ -2294,10 +2333,8 @@ TreeControlWndProc( (LPARAM)szPath); StripBackslash(szPath); } - - CharUpperBuff(szPath, 1); // make sure - - SetWindowLongPtr(hwndParent, GWL_TYPE, szPath[0] - TEXT('A')); + + SetWindowLongPtr(hwndParent, GWL_TYPE, DRIVEID(szPath)); // // resize for new vol label @@ -2324,10 +2361,6 @@ TreeControlWndProc( LBN_SELCHANGE)); } break; -#undef fFullyExpand -#undef fDontSteal -#undef fDontSelChange -#undef szDir } case WM_CHARTOITEM: @@ -3307,10 +3340,13 @@ TreeControlWndProc( INT BuildTreeName(LPTSTR lpszPath, INT iLen, INT iSize) { - DRIVE drive = DRIVEID(lpszPath); + // Check for \\ aka UNC + if (!ISUNCPATH(lpszPath)) + // Check for X:\ + if (3 != iLen || CHAR_BACKSLASH != lpszPath[2]) + return iLen; - if (3 != iLen || CHAR_BACKSLASH != lpszPath[2]) - return iLen; + DRIVE drive = DRIVEID(lpszPath); lstrcat(lpszPath, SZ_FILESYSNAMESEP); iLen = lstrlen(lpszPath); diff --git a/src/wfchgnot.c b/src/wfchgnot.c index 16405469..9d06c2bb 100644 --- a/src/wfchgnot.c +++ b/src/wfchgnot.c @@ -179,7 +179,7 @@ NotifyReset() // // INC -- drive -2 == ALL // -1 == All of type uType -// 0 < drive < 26 is the drive to stop +// 0 < drive < MAX_DRIVES is the drive to stop // INC -- uType Type of drive to stop notification on // // @@ -239,7 +239,7 @@ NotifyPause(DRIVE drive, UINT uType) // Synopsis: Resume all notifications // // INC -- drive -1 == ALL -// 0 < drive < 26 is the drive to stop +// 0 < drive < MAX_DRIVES is the drive to stop // INC -- uType Type of drive to stop notification on // // Return: VOID diff --git a/src/wfcomman.c b/src/wfcomman.c index d885adce..c265084a 100644 --- a/src/wfcomman.c +++ b/src/wfcomman.c @@ -41,8 +41,7 @@ NotifySearchFSC( if (!hwndSearch) return; - if (DRIVEID(pszPath) == - SendMessage(hwndSearch, FS_GETDRIVE, 0, 0L) - CHAR_A) { + if (DRIVEID(pszPath) == SendMessage(hwndSearch, FS_GETDRIVE, 0, 0L) - CHAR_A) { SendMessage(hwndSearch, WM_FSC, dwFunction, 0L); } @@ -533,7 +532,6 @@ CreateDirWindow( { HWND hwndT; INT dxSplit; - BOOLEAN bDriveChanged; if (hwndActive == hwndSearch) { bReplaceOpen = FALSE; @@ -553,25 +551,17 @@ CreateDirWindow( return hwndT; } - bDriveChanged = FALSE; + BOOLEAN bDriveChanged = FALSE; // // Are we replacing the contents of the currently active child? // if (bReplaceOpen) { - DRIVE drive; - INT i; - - CharUpperBuff(szPath, 1); // make sure - - drive = DRIVEID(szPath); - for (i = 0; i= CHAR_A && pOrig[0] <= CHAR_Z) && - !(pOrig[0] >= CHAR_a && pOrig[0] <= TEXT('z')) ) { + !(pOrig[0] >= CHAR_a && pOrig[0] <= CHAR_z) ) { // // Invalid drive string; return FALSE! @@ -357,7 +355,7 @@ JAPANEND DRIVESET(szDrive,drive); - flfn = IsLFNDrive(szDrive); + flfn = IsLFNDrive(szDrive) || ISDIGIT_DRIVE(szDrive); // // on FAT _AND_ lfn devices, replace any illegal chars with underscores @@ -375,7 +373,7 @@ JAPANEND } if (CHAR_BACKSLASH == pOrig[0]) { - lpszPath[0] = (TCHAR)drive + (TCHAR)'A'; + lpszPath[0] = (TCHAR)drive + CHAR_A; lpszPath[1] = CHAR_COLON; lpszPath[2] = CHAR_BACKSLASH; lpszPath[3] = CHAR_NULL; @@ -475,6 +473,8 @@ JAPANEND } else { + LPSTR pOrigA = NULL; + CHAR szOrigA[11 * 2]; if (bJAPAN) { if (!WideCharToMultiByte(CP_ACP, 0, @@ -704,7 +704,7 @@ IsTheDiskReallyThere( STKCHK(); - if (pPath[1]==CHAR_COLON) + if (pPath[1] == CHAR_COLON || ISUNCPATH(pPath)) drive = DRIVEID(pPath); else return 1; @@ -717,7 +717,7 @@ IsTheDiskReallyThere( LoadString(hAppInstance, IDS_COPYERROR + FUNC_SETDRIVE, szTitle, COUNTOF(szTitle)); - wsprintf(szMessage, szTemp, drive + CHAR_A); + wsprintf(szMessage, szTemp, DRIVESET_UC(drive)); MessageBox(hwnd, szMessage, szTitle, MB_ICONHAND); return 0; @@ -794,7 +794,7 @@ IsTheDiskReallyThere( // LoadString(hAppInstance, IDS_COPYERROR + dwFunc, szTitle, COUNTOF(szTitle)); LoadString(hAppInstance, IDS_DRIVENOTREADY, szTemp, COUNTOF(szTemp)); - wsprintf(szMessage, szTemp, drive + CHAR_A); + wsprintf(szMessage, szTemp, DRIVESET_UC(drive)); if (MessageBox(hwnd, szMessage, szTitle, MB_ICONEXCLAMATION | MB_RETRYCANCEL) == IDRETRY) goto Retry; else @@ -815,7 +815,7 @@ IsTheDiskReallyThere( if (!CancelInfo.hCancelDlg && IsRemovableDrive(drive)) { LoadString(hAppInstance, IDS_UNFORMATTED, szTemp, COUNTOF(szTemp)); - wsprintf(szMessage, szTemp, drive + CHAR_A); + wsprintf(szMessage, szTemp, DRIVESET_UC(drive)); if (MessageBox(hwnd, szMessage, szTitle, MB_ICONEXCLAMATION| MB_YESNO) == IDYES) { @@ -2715,9 +2715,7 @@ WFMoveCopyDriverThread(LPVOID lpParameter) #endif #ifdef FASTMOVE - if ((CHAR_COLON == pcr->sz[1]) && - (CHAR_COLON == szDest[1]) && - (DRIVEID(pcr->sz) == DRIVEID(szDest))) { + if (DRIVEID(pcr->sz) == DRIVEID(szDest)) { // // Warning: This will not work on winball drives! diff --git a/src/wfcopy.h b/src/wfcopy.h index 21a4f79c..061575e4 100644 --- a/src/wfcopy.h +++ b/src/wfcopy.h @@ -39,7 +39,7 @@ typedef struct _copyroot { WORD cDepth; LPTSTR pSource; LPTSTR pRoot; - TCHAR cIsDiskThereCheck[26]; + TCHAR cIsDiskThereCheck[MAX_DRIVES]; TCHAR sz[MAXPATHLEN]; TCHAR szDest[MAXPATHLEN]; LFNDTA rgDTA[MAXDIRDEPTH]; diff --git a/src/wfdir.c b/src/wfdir.c index 2616c734..9a4e39e1 100644 --- a/src/wfdir.c +++ b/src/wfdir.c @@ -377,10 +377,10 @@ CreateLBLine(DWORD dwLineFormat, LPXDTA lpxdta, LPWSTR szBuffer) } else { - pch += PutSize(&lpxdta->qFileSize, pch); - } + pch += PutSize(&lpxdta->qFileSize, pch); } } + } // // Should we show the date? @@ -1434,9 +1434,7 @@ ChangeDisplay( // FS_CHANGEDISPLAY (CD_PATH) directory reset // - CharUpperBuff(szPath, 1); // make sure - - SetWindowLongPtr(hwndListParms, GWL_TYPE, szPath[0] - TEXT('A')); + SetWindowLongPtr(hwndListParms, GWL_TYPE, DRIVEID(szPath)); SetMDIWindowText(hwndListParms, szPath); @@ -3182,15 +3180,22 @@ UpdateStatus(HWND hwnd) } U_Space(drive); - } qFreeSpace=aDriveInfo[drive].qFreeSpace; qTotalSpace=aDriveInfo[drive].qTotalSpace; + WCHAR szRoot[MAXPATHLEN] = { 0 }; + if (drive < OFFSET_UNC) { + lstrcpy(szRoot, SZ_ACOLON); + DRIVESET(szRoot, drive); + } else { + lstrcpy(szRoot, aDriveInfo[drive].szRoot); + } + SetStatusText(0, SST_RESOURCE|SST_FORMAT, (LPWSTR) MAKEINTRESOURCE(IDS_DRIVEFREE), - L'A' + drive, + szRoot, ShortSizeFormatInternal(szNumBuf1, qFreeSpace), ShortSizeFormatInternal(szNumBuf2, qTotalSpace)); } diff --git a/src/wfdirrd.c b/src/wfdirrd.c index f8a0f46c..fb59762b 100644 --- a/src/wfdirrd.c +++ b/src/wfdirrd.c @@ -780,7 +780,15 @@ CreateDTABlockWorker( } } - lstrcpy(szPath+3, lpTemp+1); + // Go back to the root + if (drive < OFFSET_UNC) { + // Easy for drives + lstrcpy(szPath + 3, lpTemp + 1); + } else { + // for UNC one needs to know the UNC root + lstrcpy(szPath, aDriveInfo[drive].szRootBackslash); + lstrcat(szPath, lpTemp + 1); + } SendMessage(hwndDir, FS_CHANGEDISPLAY, @@ -845,10 +853,21 @@ CreateDTABlockWorker( if (!(lpTemp=StrRChr(szPath, NULL, CHAR_BACKSLASH))) goto CDBDiskGone; + // Check if we are at the root of a drive + BOOL bShowDotDot; + if (drive < OFFSET_UNC) + bShowDotDot = (lpTemp - szPath) > 3; + else { + WCHAR szRoot[MAXPATHLEN] = { 0 }; + lstrcpy(szRoot, aDriveInfo[drive].szRootBackslash); + lstrcat(szRoot, szStarDotStar); + bShowDotDot = lstrcmpi(szPath, szRoot); + } + // // Always show .. if this is not the root directory. // - if ((lpTemp - szPath > 3) && (dwAttribs & ATTR_DIR)) { + if (bShowDotDot && (dwAttribs & ATTR_DIR)) { // // Add a DTA to the list. diff --git a/src/wfdlgs.c b/src/wfdlgs.c index e939c570..b970c8a4 100644 --- a/src/wfdlgs.c +++ b/src/wfdlgs.c @@ -90,20 +90,36 @@ SaveWindows(HWND hwndMain) wsprintf(key, szDirKeyFormat, dir_num--); - // format: - // x_win, y_win, - // x_win, y_win, - // x_icon, y_icon, - // show_window, view, sort, attribs, split, directory - - // NOTE: MDI child windows are in child coordinats; no translation is done. - wsprintf(buf2, TEXT("%ld,%ld,%ld,%ld,%ld,%ld,%u,%lu,%lu,%lu,%d,%s"), - wp.rcNormalPosition.left, wp.rcNormalPosition.top, - wp.rcNormalPosition.right, wp.rcNormalPosition.bottom, - wp.ptMinPosition.x, wp.ptMinPosition.y, - wp.showCmd, view, sort, attribs, - GetSplit(hwnd), - szPath); + INT drive = DRIVEID(szPath); + if (drive < OFFSET_UNC) { + // format: + // x_win, y_win, + // x_win, y_win, + // x_icon, y_icon, + // show_window, view, sort, attribs, split, directory + + // NOTE: MDI child windows are in child coordinats; no translation is done. + wsprintf(buf2, TEXT("%ld,%ld,%ld,%ld,%ld,%ld,%u,%lu,%lu,%lu,%d,%s"), + wp.rcNormalPosition.left, wp.rcNormalPosition.top, + wp.rcNormalPosition.right, wp.rcNormalPosition.bottom, + wp.ptMinPosition.x, wp.ptMinPosition.y, + wp.showCmd, view, sort, attribs, + GetSplit(hwnd), + szPath); + } else { + // For UNC path we need to save the name of the root and the drive id too + wsprintf(buf2, TEXT("%ld,%ld,%ld,%ld,%ld,%ld,%u,%lu,%lu,%lu,%d,%s\"%s\"%d"), + wp.rcNormalPosition.left, wp.rcNormalPosition.top, + wp.rcNormalPosition.right, wp.rcNormalPosition.bottom, + wp.ptMinPosition.x, wp.ptMinPosition.y, + wp.showCmd, view, sort, attribs, + GetSplit(hwnd), + szPath, + aDriveInfo[drive].szRoot, + drive - OFFSET_UNC); + + aDriveInfo[drive].bDirtyPersist = TRUE; + } // the dir is an ANSI string (?) @@ -123,6 +139,8 @@ SaveWindows(HWND hwndMain) goto DO_AGAIN; } + SaveUNCDrives(); + // Save CachedPath and GotoCachePunctuation WritePrivateProfileString(szSettings, szCachedPath, szCachedPathIni, szTheINIFile); WritePrivateProfileString(szSettings, szGotoCachePunctuation, szPunctuation, szTheINIFile); diff --git a/src/wfdlgs3.c b/src/wfdlgs3.c index 8f290659..af924041 100644 --- a/src/wfdlgs3.c +++ b/src/wfdlgs3.c @@ -584,7 +584,7 @@ FormatDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) { nItemIndex++; - wsprintf(szMessage, szBuf, (TCHAR)(CHAR_A+rgiDrive[i]), CHAR_SPACE); + wsprintf(szMessage, szBuf, (TCHAR)(DRIVESET_UC(rgiDrive[i])), CHAR_SPACE); SendDlgItemMessage(hDlg, IDD_DRIVE, CB_INSERTSTRING, count, (LPARAM)szMessage); SendDlgItemMessage(hDlg, IDD_DRIVE, CB_SETITEMDATA, count++, MAKELONG(rgiDrive[i], 0)); @@ -692,7 +692,7 @@ FormatDlgProc(HWND hDlg, UINT wMsg, WPARAM wParam, LPARAM lParam) if (bConfirmFormat) { LoadString(hAppInstance, IDS_FORMATCONFIRMTITLE, szTitle, COUNTOF(szTitle)); LoadString(hAppInstance, IDS_FORMATCONFIRM, szBuf, COUNTOF(szBuf)); - wsprintf(szMessage, szBuf, (TCHAR)(CHAR_A+CancelInfo.Info.Format.iFormatDrive)); + wsprintf(szMessage, szBuf, (TCHAR)(DRIVESET_UC(CancelInfo.Info.Format.iFormatDrive))); if (MessageBox(hDlg, szMessage, szTitle, MB_ICONEXCLAMATION | MB_YESNO | MB_DEFBUTTON1) != IDYES) break; @@ -888,7 +888,7 @@ FormatDrive( IN PVOID ThreadParameter ) WCHAR wszDrive[3]; WCHAR wszFileSystem[4] = L"FAT"; - wszDrive[0] = (WCHAR)(CancelInfo.Info.Format.iFormatDrive + CHAR_A); + wszDrive[0] = (WCHAR)(DRIVESET_UC(CancelInfo.Info.Format.iFormatDrive)); wszDrive[1] = CHAR_COLON; wszDrive[2] = CHAR_NULL; @@ -919,11 +919,11 @@ CopyDiskette( IN PVOID ThreadParameter ) WCHAR wszSrcDrive[3]; WCHAR wszDestDrive[3]; - wszSrcDrive[0] = (WCHAR)(CancelInfo.Info.Copy.iSourceDrive + CHAR_A); + wszSrcDrive[0] = (WCHAR)(DRIVESET_UC(CancelInfo.Info.Copy.iSourceDrive)); wszSrcDrive[1] = CHAR_COLON; wszSrcDrive[2] = CHAR_NULL; - wszDestDrive[0] = (WCHAR)(CancelInfo.Info.Copy.iDestDrive + CHAR_A); + wszDestDrive[0] = (WCHAR)(DRIVESET_UC(CancelInfo.Info.Copy.iDestDrive)); wszDestDrive[1] = CHAR_COLON; wszDestDrive[2] = CHAR_NULL; diff --git a/src/wfdos.c b/src/wfdos.c index c6dbb901..3bd2b50a 100644 --- a/src/wfdos.c +++ b/src/wfdos.c @@ -22,7 +22,7 @@ GetDiskSpace(DRIVE drive, DRIVESET(szDriveRoot, drive); - if (!GetDiskFreeSpaceEx(szDriveRoot, + if (!GetDiskFreeSpaceEx(drive < OFFSET_UNC ? szDriveRoot : aDriveInfo[drive].szRoot, &qBytesAvailableToCaller, pqTotalSpace, pqFreeSpace)) { @@ -82,14 +82,14 @@ FillVolumeInfo(DRIVE drive, LPTSTR lpszVolName, PDWORD pdwVolumeSerialNumber, TCHAR szDrive[] = SZ_ACOLONSLASH; PDRIVEINFO pDriveInfo = &aDriveInfo[drive]; - DRIVESET(szDrive,drive); + DRIVESET(szDrive, drive); - if (!(GetVolumeInformation(szDrive, - lpszVolName, COUNTOF(pDriveInfo->szVolNameMinusFour)-4, + if (!GetVolumeInformation(drive < OFFSET_UNC ? szDrive : pDriveInfo->szRootBackslash, + lpszVolName, COUNTOF(pDriveInfo->szVolNameMinusFour) - 4, pdwVolumeSerialNumber, pdwMaximumComponentLength, pdwFileSystemFlags, - lpszFileSysName, COUNTOF(pDriveInfo->szFileSysName)))) { + lpszFileSysName, COUNTOF(pDriveInfo->szFileSysName))) { lpszVolName[0] = CHAR_NULL; diff --git a/src/wfdrives.c b/src/wfdrives.c index 93805aea..05a13c6e 100644 --- a/src/wfdrives.c +++ b/src/wfdrives.c @@ -339,7 +339,7 @@ DrawDrive(HDC hdc, INT x, INT y, DRIVEIND driveInd, BOOL bCurrent, BOOL bFocus) if (bFocus) DrawFocusRect(hdc, &rc); - szTemp[0] = (TCHAR)(chFirstDrive + rgiDrive[driveInd]); + szTemp[0] = DRIVESET_LC(rgiDrive[driveInd]); SetBkMode(hdc, TRANSPARENT); rgb = SetTextColor(hdc, rgb); @@ -363,7 +363,7 @@ CheckDrive(HWND hwnd, DRIVE drive, DWORD dwFunc) DWORD err; DRIVEIND driveInd; HCURSOR hCursor; - WCHAR szDrive[] = SZ_ACOLON; + WCHAR szDrive[MAXPATHLEN] = SZ_ACOLON; // Put up the hourglass cursor since this // could take a long time @@ -382,7 +382,13 @@ CheckDrive(HWND hwnd, DRIVE drive, DWORD dwFunc) while ((driveInd < cDrives) && (rgiDrive[driveInd] != drive)) driveInd++; - switch (IsNetDrive(drive)) { + INT iNetDrive; + if (drive < OFFSET_UNC) + iNetDrive = IsNetDrive(drive); + else + iNetDrive = 2; + + switch (iNetDrive) { case 2: @@ -456,6 +462,8 @@ CheckDrive(HWND hwnd, DRIVE drive, DWORD dwFunc) SetCursor(hCursor); ShowCursor(FALSE); + if (drive >= OFFSET_UNC) + lstrcpy(szDrive, aDriveInfo[drive].szRoot); return IsTheDiskReallyThere(hwnd, szDrive, dwFunc, FALSE); } @@ -827,6 +835,7 @@ DrivesWndProc(HWND hWnd, UINT wMsg, WPARAM wParam, LPARAM lParam) InvalidateRect(hWnd, &rc, TRUE); GetDriveRect(nDrive, &rc); InvalidateRect(hWnd, &rc, TRUE); + // UNC How to get there ??? } else if ((wParam >= CHAR_A) && (wParam <= CHAR_Z)) KeyToItem(hWnd, (WORD)wParam); @@ -1118,10 +1127,15 @@ KeyToItem(HWND hWnd, WORD nDriveLetter) { INT nDrive; - if (nDriveLetter > CHAR_Z) - nDriveLetter -= CHAR_a; - else - nDriveLetter -= CHAR_A; + if (ISDIGIT(nDriveLetter)) { + nDriveLetter -= CHAR_ZERO; + nDriveLetter += OFFSET_UNC; + } else { + if (nDriveLetter > CHAR_Z) + nDriveLetter -= CHAR_a; + else + nDriveLetter -= CHAR_A; + } for (nDrive = 0; nDrive < cDrives; nDrive++) { if (rgiDrive[nDrive] == (int)nDriveLetter) { diff --git a/src/wfgoto.cpp b/src/wfgoto.cpp index 01938447..e61ae5fe 100644 --- a/src/wfgoto.cpp +++ b/src/wfgoto.cpp @@ -299,8 +299,6 @@ BOOL BuildDirectoryBagOValues(BagOValues *pbov, vector *pNodes, LFNDTA lfndta; WCHAR szPath[MAXPATHLEN]; LPWSTR szEndPath; - BOOL bFound; - DWORD dwAttr; lstrcpy(szPath, szRoot); if (lstrlen(szPath) + 1 >= COUNTOF(szPath)) @@ -336,13 +334,7 @@ BOOL BuildDirectoryBagOValues(BagOValues *pbov, vector *pNodes, // add *.* to end of path lstrcat(szPath, szStarDotStar); - dwAttr = ATTR_DIR; - if (bIndexHiddenSystem) - { - dwAttr = dwAttr | ATTR_HS; - } - - bFound = WFFindFirst(&lfndta, szPath, dwAttr); + BOOL bFound = WFFindFirst(&lfndta, szPath, bIndexHiddenSystem ? ATTR_DIR | ATTR_HS : ATTR_DIR); while (bFound) { @@ -609,27 +601,51 @@ LRESULT APIENTRY GotoEditSubclassProc( VOID SetCurrentPathOfWindow(LPWSTR szPath) { - TCHAR szFullPath[MAXPATHLEN]; - LPTSTR szFilePart; - DWORD result; - HWND hwndActive; - HWND hwndNew; - HWND hwndTree; - - result = GetFullPathName(szPath, COUNTOF(szFullPath), szFullPath, &szFilePart); - if (result == 0 || result >= COUNTOF(szFullPath) || ISUNCPATH(szFullPath)) - { - return; - } - - hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L); - hwndNew = CreateDirWindow(szFullPath, TRUE, hwndActive); - hwndTree = HasTreeWindow(hwndNew); - - if (hwndTree) - { - SetFocus(hwndTree); - } + HWND hwndActive = (HWND)SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L); + + HWND hwndNew = nullptr; + if (ISUNCPATH(szPath)) + { + // For UNC path this is the place of opening a new UNC window. + // Use CTRL+W to remove the number-drive mapping and close it + DRIVE freeDriveFound = AddUNCDrive(szPath); + switch (freeDriveFound) + { + case -1: + // UNC Loop found. e.g. \\foo\bar for existing drive \\foo\bar\share + // Throw your favourite messagebox here + break; + + case 0: + // Out of free UNC Slots. Throw your favourite messagebox here + break; + + // drive slot found > 0 + default: + hwndNew = CreateDirWindow(szPath, FALSE, hwndActive); + if (hwndNew) + RefreshWindow(hwndNew, TRUE, TRUE); + } + } + else + { + TCHAR szFullPath[MAXPATHLEN]; + LPTSTR szFilePart; + + DWORD result = GetFullPathName(szPath, COUNTOF(szFullPath), szFullPath, &szFilePart); + if (result == 0 || result >= COUNTOF(szFullPath)) + { + return; + } + + hwndNew = CreateDirWindow(szFullPath, TRUE, hwndActive); + } + + HWND hwndTree = HasTreeWindow(hwndNew); + if (hwndTree) + { + SetFocus(hwndTree); + } } INT_PTR diff --git a/src/wfinfo.c b/src/wfinfo.c index f4a2a97a..ab1bd169 100644 --- a/src/wfinfo.c +++ b/src/wfinfo.c @@ -89,7 +89,15 @@ U_HEAD(Type) DRIVESET(szDrive, drive); IF_READ(Type) - uType = GetDriveType(szDrive); + if (drive < OFFSET_UNC) + uType = GetDriveType(szDrive); + else + { + if (pDriveInfo->szRootBackslash[0]) + uType = GetDriveType(pDriveInfo->szRootBackslash); + else + uType = DRIVE_UNKNOWN; + } ENTER_MODIFY(Type) @@ -269,7 +277,20 @@ U_HEAD(NetCon) pDriveInfo->dwConnectInfoMax = dwSize; - dwRetVal = WNetGetConnection2(szDrive, lpConnectInfo, &dwSize); + if (drive < OFFSET_UNC) + dwRetVal = WNetGetConnection2(szDrive, lpConnectInfo, &dwSize); + else + { + // Mimic WNetGetConnection2() + lpConnectInfo->lpRemoteName = LocalAlloc(LPTR, lstrlen(aDriveInfo[drive].szRoot) * 2 + 2); + lstrcpy(lpConnectInfo->lpRemoteName, aDriveInfo[drive].szRoot); + + #define NetWorkProvider L"Microsoft Windows Network" + lpConnectInfo->lpProvider = LocalAlloc(LPTR, sizeof(NetWorkProvider) + 2); + lstrcpy(lpConnectInfo->lpProvider, NetWorkProvider); + + dwRetVal = ERROR_SUCCESS; + } if (ERROR_MORE_DATA == dwRetVal) { @@ -1557,6 +1578,14 @@ UpdateDriveListComplete(VOID) if (IsRemoteDrive(drive)) { + // UNC drives always need a refresh + if (drive >= OFFSET_UNC) + { + RefreshWindow(hwnd, FALSE, FALSE); + continue; + } + + // Network drives might need a refresh if the share has changed if (!WFGetConnection(drive, &lpszVol, FALSE, ALTNAME_REG)) { lpszOldVol = (LPTSTR) GetWindowLongPtr(hwnd, GWL_VOLNAME); diff --git a/src/wfinit.c b/src/wfinit.c index f3ddd0c4..b8bb16b8 100644 --- a/src/wfinit.c +++ b/src/wfinit.c @@ -702,7 +702,35 @@ GetSavedWindow( count++; } - lstrcpy(pwin->szDir, szBuf); // this is the directory + // Search for an optional name of the root, which seperated by " from the directory + // and a drive number also seperated with " + // e.g. + // dir1==....,\\unc\path1\*.*"\\unc\path1\aurea\prima"2 + // It is " because is must be a character, which is not allowed in pathnames + LPTSTR szDir = szBuf; + while (*szBuf && *szBuf != CHAR_DQUOTE) + szBuf++; + if (*szBuf) { + *szBuf = CHAR_NULL; + LPCTSTR szRoot = ++szBuf; + + // Search on for the next quote + while (*szBuf && *szBuf != CHAR_DQUOTE) + szBuf++; + if (*szBuf) { + *szBuf = CHAR_NULL; + ++szBuf; // number of drive + if (*szBuf) + pwin->dwDriveNumber = atoi(szBuf); + } else + pwin->dwDriveNumber = -1; + + lstrcpy(pwin->szRoot, szRoot); // name of the root + + } else { + pwin->szRoot[0] = CHAR_NULL; + } + lstrcpy(pwin->szDir, szDir); // this is the directory } @@ -712,13 +740,19 @@ CheckDirExists( { BOOL bRet = FALSE; - if (IsNetDrive(DRIVEID(szDir)) == 2) { + DRIVE drive = DRIVEID(szDir); + + // Immediatley give up on not existing UNC Drives. They will not reconnect at some time + if (drive >= OFFSET_UNC && INVALID_FILE_ATTRIBUTES == GetFileAttributes(szDir)) + return FALSE; + + if (IsNetDrive(drive) == 2 || drive >= OFFSET_UNC) { - CheckDrive(hwndFrame, DRIVEID(szDir), FUNC_SETDRIVE); + CheckDrive(hwndFrame, drive, FUNC_SETDRIVE); return TRUE; } - if (IsValidDisk(DRIVEID(szDir))) + if (IsValidDisk(drive)) bRet = SetCurrentDirectory(szDir); return bRet; @@ -727,23 +761,17 @@ CheckDirExists( BOOL CreateSavedWindows( - LPCWSTR pszInitialDir - ) + LPCWSTR pszInitialDir +) { - WCHAR buf[2*MAXPATHLEN+7*7], key[10]; + WCHAR buf[2 * MAXPATHLEN + 7 * 7], key[10]; WINDOW win; - LPTSTR FilePart; - DWORD SizeAvailable; - DWORD CharsCopied; - // // since win.szDir is bigger. // - WCHAR szDir[2*MAXPATHLEN]; + WCHAR szDir[2 * MAXPATHLEN]; - INT nDirNum; HWND hwnd; - INT iNumTrees; // // Initialize window geometry to use system default @@ -762,8 +790,8 @@ CreateSavedWindows( // make sure this thing exists so we don't hit drives that don't // exist any more // - nDirNum = 1; - iNumTrees = 0; + INT nDirNum = 1; + INT iNumTrees = 0; do { @@ -771,44 +799,61 @@ CreateSavedWindows( GetPrivateProfileString(szSettings, key, szNULL, buf, COUNTOF(buf), szTheINIFile); - if (*buf) - { + if (*buf) { + GetSavedWindow(buf, &win); if (pszInitialDir == NULL) { - // - // Winfile won't retain any relative paths in the INI file, but if - // one was provided externally, convert it into a full path - // - - SizeAvailable = COUNTOF(szDir); - CharsCopied = GetFullPathName(win.szDir, SizeAvailable, szDir, &FilePart); - if (CharsCopied == 0 || CharsCopied >= SizeAvailable || ISUNCPATH(szDir)) { - continue; - } - lstrcpy(win.szDir, szDir); + lstrcpy(szDir, win.szDir); - // // clean off some junk so we can do this test - // StripFilespec(szDir); StripBackslash(szDir); + if (win.szRoot[0]) { + // UNC Drive + if (win.dwDriveNumber > -1 && win.dwDriveNumber < MAX_UNC) + SetUNCDrive(win.szRoot, OFFSET_UNC + win.dwDriveNumber); + else + AddUNCDrive(win.szRoot); + } + else { + // In case of broken .ini file and UNC + if (ISUNCPATH(szDir)) + AddUNCDrive(szDir); + else { + // + // Winfile won't retain any relative paths in the INI file, but if + // one was provided externally, convert it into a full path + // + LPTSTR FilePart; + DWORD SizeAvailable = COUNTOF(win.szDir); + DWORD CharsCopied = GetFullPathName(szDir, SizeAvailable, win.szDir, &FilePart); + if (CharsCopied == 0 || CharsCopied >= SizeAvailable) { + continue; + } + lstrcpy(szDir, win.szDir); + } + } + if (!CheckDirExists(szDir)) { continue; } + AddBackslash(szDir); + lstrcat(szDir, szStarDotStar); + dwNewView = win.dwView; dwNewSort = win.dwSort; dwNewAttribs = win.dwAttribs; - hwnd = CreateTreeWindow(win.szDir, - win.rc.left, - win.rc.top, - win.rc.right - win.rc.left, - win.rc.bottom - win.rc.top, - win.nSplit); + hwnd = CreateTreeWindow(szDir, + win.rc.left, + win.rc.top, + win.rc.right - win.rc.left, + win.rc.bottom - win.rc.top, + win.nSplit); if (!hwnd) { continue; @@ -826,7 +871,6 @@ CreateSavedWindows( ShowWindow(hwnd, win.sw); } } - } while (*buf); // @@ -836,12 +880,12 @@ CreateSavedWindows( if (pszInitialDir != NULL) { - SizeAvailable = COUNTOF(buf) - (DWORD)wcslen(szStarDotStar) - 1; - CharsCopied = GetFullPathName(pszInitialDir, SizeAvailable, buf, &FilePart); + LPTSTR FilePart; + DWORD SizeAvailable = COUNTOF(buf) - (DWORD)wcslen(szStarDotStar) - 1; + DWORD CharsCopied = GetFullPathName(pszInitialDir, SizeAvailable, buf, &FilePart); if (CharsCopied > 0 && - CharsCopied < SizeAvailable && - !ISUNCPATH(buf) && - CheckDirExists(buf)) + CharsCopied < SizeAvailable && + CheckDirExists(buf)) { AddBackslash(buf); lstrcat(buf, szStarDotStar); @@ -855,11 +899,11 @@ CreateSavedWindows( dwNewAttribs = win.dwAttribs; hwnd = CreateTreeWindow(buf, - win.rc.left, - win.rc.top, - win.rc.right - win.rc.left, - win.rc.bottom - win.rc.top, - win.nSplit); + win.rc.left, + win.rc.top, + win.rc.right - win.rc.left, + win.rc.bottom - win.rc.top, + win.nSplit); if (!hwnd) { return FALSE; @@ -875,6 +919,8 @@ CreateSavedWindows( } } + LoadUNCDrives(); + // // if nothing was saved or specified, create a tree for the current drive // @@ -1105,7 +1151,7 @@ JAPANEND // SetErrorMode(1); - for (i=0; i<26;i++) { + for (i = 0; i < MAX_DRIVES; i++) { I_Space(i); } @@ -1177,8 +1223,6 @@ JAPANEND hicoTreeDir = LoadIcon(hAppInstance, (LPTSTR) MAKEINTRESOURCE(TREEDIRICON)); hicoDir = LoadIcon(hAppInstance, (LPTSTR) MAKEINTRESOURCE(DIRICON)); - chFirstDrive = CHAR_a; - // now build the parameters based on the font we will be using hdcScreen = GetDC(NULL); diff --git a/src/wftree.c b/src/wftree.c index 2367fb9d..a8c3ca17 100644 --- a/src/wftree.c +++ b/src/wftree.c @@ -530,8 +530,8 @@ TreeWndProc( case WM_CREATE: { -#define lpcs ((LPCREATESTRUCT)lParam) -#define lpmdics ((LPMDICREATESTRUCT)(lpcs->lpCreateParams)) + LPCREATESTRUCT lpcs = (LPCREATESTRUCT)lParam; + LPMDICREATESTRUCT lpmdics = (LPMDICREATESTRUCT)(lpcs->lpCreateParams); INT dxSplit; DRIVE drive; @@ -590,8 +590,6 @@ TreeWndProc( SetMDIWindowText(hwnd, szPath); break; -#undef lpcs -#undef lpmdics } case WM_CLOSE: diff --git a/src/wfutil.c b/src/wfutil.c index b34d8ca9..8d7c8b4f 100644 --- a/src/wfutil.c +++ b/src/wfutil.c @@ -14,7 +14,7 @@ #include #include -LPTSTR CurDirCache[26]; +LPTSTR CurDirCache[MAX_DRIVES]; #define MAXHISTORY 32 DWORD historyCur = 0; @@ -249,9 +249,11 @@ GetSelectedDirectory(DRIVE drive, LPTSTR pszDir) BOOL GetDriveDirectory(INT iDrive, LPTSTR pszDir) { - TCHAR drvstr[4]; DWORD ret; + WCHAR drvstr[MAXPATHLEN]; + if (iDrive - 1 < OFFSET_UNC) + { pszDir[0] = '\0'; if(iDrive!=0) @@ -266,13 +268,15 @@ BOOL GetDriveDirectory(INT iDrive, LPTSTR pszDir) drvstr[0] = ('.'); drvstr[1] = ('\0'); } + } + else + { + lstrcpy(drvstr, aDriveInfo[iDrive - 1].szRoot); + } if (GetFileAttributes(drvstr) == INVALID_FILE_ATTRIBUTES) return FALSE; -// if (!CheckDirExists(drvstr)) -// return FALSE; - ret = GetFullPathName( drvstr, MAXPATHLEN, pszDir, NULL); return ret != 0; @@ -789,8 +793,6 @@ SetMDIWindowText( SaveHistoryDir(hwnd, szTitle); } -#define ISDIGIT(c) ((c) >= TEXT('0') && (c) <= TEXT('9')) - INT atoiW(LPTSTR sz) { @@ -1791,3 +1793,178 @@ HMODULE LoadSystemLibrary(LPCTSTR FileName) LocalFree(FullPath); return Module; } + +// Search the list of slots if path would be parent of already existing drive == circularity +BOOL FindUNCLoop(LPCTSTR path) +{ + for (DWORD dwDriveIndex = OFFSET_UNC; dwDriveIndex < MAX_DRIVES; ++dwDriveIndex) { + if (aDriveInfo[dwDriveIndex].szRoot[0] && StrStrIW(aDriveInfo[dwDriveIndex].szRoot, path)) { + + if (_wcsicmp(path, aDriveInfo[dwDriveIndex].szRoot)) + // path a was a parent of an existing drive, e.g. \\foo\bar for \\foo\bar\share + // This is a loop, which can't be handled + return TRUE; + // else + // path is the same as an existing drive, e.g. \\foo\bar for \\foo\bar + // This is o ok + } + } + return FALSE; +} + +DRIVE FindUNCDrive(LPCTSTR path, PDWORD pdwFreeDriveSlot) +{ + // Search the list of slots if drive is already there + for (DWORD dwDriveIndex = OFFSET_UNC; dwDriveIndex < MAX_DRIVES; ++dwDriveIndex) { + // Found existing slot + if (aDriveInfo[dwDriveIndex].szRoot[0] && StrStrIW(path, aDriveInfo[dwDriveIndex].szRoot)) + // Added an UNC drive which already existed + return dwDriveIndex; + + // If we come across an empty one, remember the first one + if (!aDriveInfo[dwDriveIndex].szRoot[0] && !(*pdwFreeDriveSlot)) + *pdwFreeDriveSlot = dwDriveIndex; + } + return 0; +} + +VOID SaveUNCDrives() +{ + TCHAR szUNCBuf[MAXPATHLEN]; + for (DWORD dwDriveIndex = OFFSET_UNC; dwDriveIndex < MAX_DRIVES; ++dwDriveIndex) { + + TCHAR szUNCKey[MAXPATHLEN]; + wsprintf(szUNCKey, szUNCKeyFormat, dwDriveIndex - OFFSET_UNC); + + if (aDriveInfo[dwDriveIndex].bDirtyPersist == FALSE && aDriveInfo[dwDriveIndex].szRoot[0] && IsValidDisk(dwDriveIndex)) + { + // For UNC path we need to save the name of the root and the drive id too + wsprintf(szUNCBuf, TEXT("%s"), + aDriveInfo[dwDriveIndex].szRoot); + + WritePrivateProfileString(szSettings, szUNCKey, szUNCBuf, szTheINIFile); + } else { + WritePrivateProfileString(szSettings, szUNCKey, NULL, szTheINIFile); + aDriveInfo[dwDriveIndex].bDirtyPersist = FALSE; + } + + } +} + +VOID LoadUNCDrives() +{ + TCHAR szUNCBuf[MAXPATHLEN]; + for (DWORD dwDriveIndex = OFFSET_UNC; dwDriveIndex < MAX_DRIVES; ++dwDriveIndex) { + + TCHAR szUNCKey[MAXPATHLEN]; + wsprintf(szUNCKey, szUNCKeyFormat, dwDriveIndex - OFFSET_UNC); + + GetPrivateProfileString(szSettings, szUNCKey, szNULL, szUNCBuf, COUNTOF(szUNCBuf), szTheINIFile); + if (szUNCBuf[0]) + SetUNCDrive(szUNCBuf, dwDriveIndex); + } +} + +VOID SetUNCDrive(LPCTSTR path, DWORD aFreeDriveSlot) +{ + lstrcpy(aDriveInfo[aFreeDriveSlot].szRoot, path); + lstrcpy(aDriveInfo[aFreeDriveSlot].szRootBackslash, path); + + // Force drive to be network drive + aDriveInfo[aFreeDriveSlot].uType = DRIVE_REMOTE; + aDriveInfo[aFreeDriveSlot].iOffset = GetDriveOffset(aFreeDriveSlot); + + AddBackslash(aDriveInfo[aFreeDriveSlot].szRootBackslash); +} + +// Returns drive-id if possible. If not returns 0 +// Possible failure reasons: Exceeded number of free numbered drives or UNC cirularity +DRIVE AddUNCDrive(LPTSTR path) +{ + StripBackslash(path); + if (FindUNCLoop(path)) + return -1; + + DWORD dwFreeDriveSlot = 0; + DRIVE drive = FindUNCDrive(path, &dwFreeDriveSlot); + if (!drive && dwFreeDriveSlot) { + // Havent't found an existing slot, so add new to first free found + SetUNCDrive(path, dwFreeDriveSlot); + drive = dwFreeDriveSlot; + } + + return drive; +} + +DRIVE RemoveUNCDrive(LPCTSTR path) +{ + DWORD dwFreeDriveSlot = 0; + DRIVE drive = FindUNCDrive(path, &dwFreeDriveSlot); + if (drive) { + // Found an empty slot so mark it free + aDriveInfo[drive].szRoot[0] = '\0'; + aDriveInfo[drive].szRootBackslash[0] = '\0'; + I_Space(drive); + } + + return dwFreeDriveSlot; +} + +PTCHAR GetUNCDrivePath(const DRIVE aDrive) +{ + return aDriveInfo[aDrive].szRootBackslash; +} + +// Closes the UNC mapping and all the windows showing instances of this UNC mapping +// if all instances of the UNC drive are not the last open windows +VOID CloseUNCDrive(LPCTSTR aPath) +{ + HWND hUNCSave[MAX_DRIVES] = { 0 }; + INT iWndCount = 0; + INT iUNCWndCount = 0; + INT iUNCSaveCount = 0; + + PTCHAR szUNCPath = GetUNCDrivePath(DRIVEID(aPath)); + + // Go through all non title/search windows to find instances of aPath windows + for (HWND hwnd = GetWindow(hwndMDIClient, GW_CHILD); hwnd; hwnd = GetWindow(hwnd, GW_HWNDNEXT)) { + if (!GetWindow(hwnd, GW_OWNER) && ((INT)GetWindowLongPtr(hwnd, GWL_TYPE) >= 0)) { + + TCHAR szUNCWndPath[MAX_PATH]; + SendMessage(hwnd, FS_GETDIRECTORY, COUNTOF(szUNCWndPath), (LPARAM)szUNCWndPath); + + // Check if this is an instance of the active UNC windows + if (StrStrIW(szUNCWndPath, szUNCPath)) { + iUNCWndCount++; + hUNCSave[iUNCSaveCount++] = hwnd; + } + + iWndCount++; + } + } + + // If there are more windows open than instances of the active UNC windows, we + // can close the windows and then unmap the UNC drive + if (iWndCount > iUNCWndCount) { + for (INT i = 0; i < iUNCSaveCount; ++i) + PostMessage(hUNCSave[i], WM_CLOSE, 0, 0L); + + RemoveUNCDrive(aPath); + } +} + + +DRIVE DRIVEID(LPCTSTR path) +{ + DRIVE drive = toupper(path[0]); + if (drive >= CHAR_A && drive <= CHAR_Z) + // regular drive + return drive - CHAR_A; + + DWORD dwFreeDriveSlot = 0; + drive = FindUNCDrive(path, &dwFreeDriveSlot); + if (drive) + return drive; + + return MAX_DRIVES; +} diff --git a/src/winfile.h b/src/winfile.h index bf27d9e9..9eb57235 100644 --- a/src/winfile.h +++ b/src/winfile.h @@ -130,7 +130,9 @@ INT atoiW(LPWSTR sz); #define MAXMESSAGELEN (MAXPATHLEN * 2 + MAXSUGGESTLEN) #define MAX_WINDOWS 27 -#define MAX_DRIVES 26 +#define MAX_UNC 10 +#define OFFSET_UNC ('Z' - 'A' + 1) +#define MAX_DRIVES OFFSET_UNC + MAX_UNC // struct for volume info @@ -210,6 +212,7 @@ INT atoiW(LPWSTR sz); #define CHAR_A TEXT('A') #define CHAR_a TEXT('a') #define CHAR_Z TEXT('Z') +#define CHAR_z TEXT('z') // Default char for untranslatable unicode // MUST NOT BE an acceptable char for file systems!! @@ -225,13 +228,15 @@ INT atoiW(LPWSTR sz); #define DwordAlign(cb) (((cb) + 3) & ~3) #define ISDOTDIR(x) (x[0]==CHAR_DOT && (!x[1] || (x[1] == CHAR_DOT && !x[2]))) #define ISUNCPATH(x) (CHAR_BACKSLASH == x[0] && CHAR_BACKSLASH == x[1]) -#define DRIVESET(str, drive) (str[0] = CHAR_A + (drive)) +#define DRIVESET_LC(drive) ((drive < OFFSET_UNC ? CHAR_a : CHAR_Z - CHAR_A - 3) + drive) +#define DRIVESET_UC(drive) ((drive < OFFSET_UNC ? CHAR_A : CHAR_Z - CHAR_A - 3) + drive) +#define DRIVESET(str, drive) (str[0] = DRIVESET_UC(drive)) +#define ISDIGIT(c) ((c) >= TEXT('0') && (c) <= TEXT('9')) +#define ISDIGIT_DRIVE(str) (CHAR_COLON == str[1] && ISDIGIT(str[0])) #define COUNTOF(x) (sizeof(x)/sizeof(*x)) #define ByteCountOf(x) ((x)*sizeof(TCHAR)) #define abs(x) (((x) < 0) ? -(x) : (x)) -#define DRIVEID(path) ((path[0] - CHAR_A)&31) - #define IsDocument(lpszPath) IsBucketFile(lpszPath, ppDocBucket) #define IsProgramFile(lpszPath) IsBucketFile(lpszPath, ppProgBucket) #define IsProgramIconFile(lpszPath) IsBucketFile(lpszPath, ppProgIconBucket) @@ -329,7 +334,9 @@ typedef struct { // // *2 since may have huge filter // - WCHAR szDir[2*MAXPATHLEN]; + TCHAR szDir[2*MAXPATHLEN]; + TCHAR szRoot[MAXPATHLEN]; + INT dwDriveNumber; // // Next block of fields must be together (11 DWORDS) @@ -454,6 +461,17 @@ BOOL TypeAheadString(WCHAR ch, LPWSTR szT); VOID SaveHistoryDir(HWND hwnd, LPWSTR szDir); BOOL GetPrevHistoryDir(BOOL forward, HWND *phwnd, LPWSTR szDir); +DRIVE DRIVEID(LPCTSTR path); +DRIVE AddUNCDrive(LPTSTR path); +DRIVE RemoveUNCDrive(LPCTSTR path); +DRIVE FindUNCDrive(LPCTSTR path, PDWORD pdwFreeDriveSlot); +BOOL FindUNCLoop(LPCTSTR path); +VOID SetUNCDrive(LPCTSTR path, DWORD aFreeDriveSlot); +VOID SaveUNCDrives(); +VOID LoadUNCDrives(); +PTCHAR GetUNCDrivePath(const DRIVE aDrive); +VOID CloseUNCDrive(LPCTSTR aPath); + // WFDIR.C VOID UpdateStatus(HWND hWnd); @@ -972,6 +990,10 @@ typedef struct _DRIVE_INFO { STATUSNAME(Space); LARGE_INTEGER qFreeSpace; LARGE_INTEGER qTotalSpace; + + TCHAR szRoot[MAXPATHLEN]; + TCHAR szRootBackslash[MAXPATHLEN]; + BOOL bDirtyPersist; } DRIVEINFO, *PDRIVEINFO; #define SC_SPLIT 100 @@ -1190,8 +1212,9 @@ Extern DWORD gdwMachineId EQ( MACHINEID_MICROSOFT ); #define rgiDrive rgiDriveReal[iUpdateReal] Extern INT iUpdateReal EQ( 0 ); -Extern DRIVE rgiDriveReal[2][26]; -Extern DRIVEINFO aDriveInfo[26]; + +Extern DRIVE rgiDriveReal[2][MAX_DRIVES]; +Extern DRIVEINFO aDriveInfo[MAX_DRIVES]; Extern UINT uMenuID; Extern HMENU hMenu; @@ -1237,8 +1260,6 @@ Extern BOOL bConnectable EQ( FALSE ); Extern INT iShowSourceBitmaps EQ( 1 ); Extern BOOL bFSCTimerSet EQ( FALSE ); -Extern TCHAR chFirstDrive; // 'A' or 'a' - Extern TCHAR szExtensions[] EQ( TEXT("Extensions") ); Extern TCHAR szFrameClass[] EQ( TEXT("WFS_Frame") ); Extern TCHAR szTreeClass[] EQ( TEXT("WFS_Tree") ); @@ -1279,6 +1300,7 @@ Extern TCHAR szChangeNotifyTime[] EQ( TEXT("ChangeNotifyTime") ); Extern UINT uChangeNotifyTime EQ( 3000 ); Extern TCHAR szDirKeyFormat[] EQ( TEXT("dir%d") ); +Extern TCHAR szUNCKeyFormat[] EQ(TEXT("unc%d")); Extern TCHAR szWindow[] EQ( TEXT("Window") ); Extern TCHAR szWindows[] EQ( TEXT("Windows") );