https://git.reactos.org/?p=reactos.git;a=commitdiff;h=c16f93c5f39d3f469b3fa24cbe6afcd12184cacb

commit c16f93c5f39d3f469b3fa24cbe6afcd12184cacb
Author:     Katayama Hirofumi MZ <katayama.hirofumi...@gmail.com>
AuthorDate: Wed Aug 30 21:43:09 2023 +0900
Commit:     GitHub <nore...@github.com>
CommitDate: Wed Aug 30 21:43:09 2023 +0900

    [REGEDIT] Support exporting registry to text file (#5619)
    
    - Add txtproc.c source file.
    - Add some resource strings.
    - Add *.txt filter to export on a text file.
    CORE-16910
---
 base/applications/regedit/CMakeLists.txt |   1 +
 base/applications/regedit/framewnd.c     |  58 +++--
 base/applications/regedit/lang/bg-BG.rc  |  16 ++
 base/applications/regedit/lang/cs-CZ.rc  |  16 ++
 base/applications/regedit/lang/de-DE.rc  |  16 ++
 base/applications/regedit/lang/el-GR.rc  |  16 ++
 base/applications/regedit/lang/en-US.rc  |  16 ++
 base/applications/regedit/lang/es-ES.rc  |  16 ++
 base/applications/regedit/lang/fr-FR.rc  |  16 ++
 base/applications/regedit/lang/he-IL.rc  |  16 ++
 base/applications/regedit/lang/hu-HU.rc  |  16 ++
 base/applications/regedit/lang/id-ID.rc  |  16 ++
 base/applications/regedit/lang/it-IT.rc  |  16 ++
 base/applications/regedit/lang/ja-JP.rc  |  16 ++
 base/applications/regedit/lang/ko-KR.rc  |  16 ++
 base/applications/regedit/lang/nl-NL.rc  |  16 ++
 base/applications/regedit/lang/no-NO.rc  |  16 ++
 base/applications/regedit/lang/pl-PL.rc  |  16 ++
 base/applications/regedit/lang/pt-BR.rc  |  16 ++
 base/applications/regedit/lang/pt-PT.rc  |  16 ++
 base/applications/regedit/lang/ro-RO.rc  |  16 ++
 base/applications/regedit/lang/ru-RU.rc  |  16 ++
 base/applications/regedit/lang/sk-SK.rc  |  16 ++
 base/applications/regedit/lang/sl-SI.rc  |  16 ++
 base/applications/regedit/lang/sq-AL.rc  |  16 ++
 base/applications/regedit/lang/sv-SE.rc  |  16 ++
 base/applications/regedit/lang/th-TH.rc  |  16 ++
 base/applications/regedit/lang/tr-TR.rc  |  16 ++
 base/applications/regedit/lang/uk-UA.rc  |  16 ++
 base/applications/regedit/lang/zh-CN.rc  |  16 ++
 base/applications/regedit/lang/zh-HK.rc  |  16 ++
 base/applications/regedit/lang/zh-TW.rc  |  16 ++
 base/applications/regedit/main.h         |   3 +
 base/applications/regedit/resource.h     |  13 +
 base/applications/regedit/txtproc.c      | 406 +++++++++++++++++++++++++++++++
 35 files changed, 945 insertions(+), 16 deletions(-)

diff --git a/base/applications/regedit/CMakeLists.txt 
b/base/applications/regedit/CMakeLists.txt
index 351a4696f11..a1d2ffc7349 100644
--- a/base/applications/regedit/CMakeLists.txt
+++ b/base/applications/regedit/CMakeLists.txt
@@ -20,6 +20,7 @@ list(APPEND SOURCE
     security.c
     settings.c
     treeview.c
+    txtproc.c
     regedit.h)
 
 file(GLOB regedit_rc_deps res/*.*)
diff --git a/base/applications/regedit/framewnd.c 
b/base/applications/regedit/framewnd.c
index 852d38feb02..6b5b1c28cfb 100644
--- a/base/applications/regedit/framewnd.c
+++ b/base/applications/regedit/framewnd.c
@@ -230,8 +230,7 @@ static BOOL CheckCommDlgError(HWND hWnd)
     return TRUE;
 }
 
-WCHAR FileNameBuffer[_MAX_PATH];
-WCHAR FileTitleBuffer[_MAX_PATH];
+WCHAR FileNameBuffer[MAX_PATH];
 
 typedef struct
 {
@@ -255,9 +254,9 @@ BuildFilterStrings(WCHAR *Filter, PFILTERPAIR Pairs, int 
PairCount)
     Filter[++c] = L'\0';
 }
 
-static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
+static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn, BOOL bSave)
 {
-    FILTERPAIR FilterPairs[4];
+    FILTERPAIR FilterPairs[5];
     static WCHAR Filter[1024];
 
     memset(pofn, 0, sizeof(OPENFILENAME));
@@ -272,17 +271,31 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* 
pofn)
     FilterPairs[1].FilterID = IDS_FLT_HIVFILES_FLT;
     FilterPairs[2].DisplayID = IDS_FLT_REGEDIT4;
     FilterPairs[2].FilterID = IDS_FLT_REGEDIT4_FLT;
-    FilterPairs[3].DisplayID = IDS_FLT_ALLFILES;
-    FilterPairs[3].FilterID = IDS_FLT_ALLFILES_FLT;
-    BuildFilterStrings(Filter, FilterPairs, ARRAY_SIZE(FilterPairs));
+    if (bSave)
+    {
+        FilterPairs[3].DisplayID = IDS_FLT_TXTFILES;
+        FilterPairs[3].FilterID = IDS_FLT_TXTFILES_FLT;
+        FilterPairs[4].DisplayID = IDS_FLT_ALLFILES;
+        FilterPairs[4].FilterID = IDS_FLT_ALLFILES_FLT;
+    }
+    else
+    {
+        FilterPairs[3].DisplayID = IDS_FLT_ALLFILES;
+        FilterPairs[3].FilterID = IDS_FLT_ALLFILES_FLT;
+    }
+
+    BuildFilterStrings(Filter, FilterPairs, ARRAY_SIZE(FilterPairs) - !bSave);
 
     pofn->lpstrFilter = Filter;
     pofn->lpstrFile = FileNameBuffer;
-    pofn->nMaxFile = _MAX_PATH;
-    pofn->lpstrFileTitle = FileTitleBuffer;
-    pofn->nMaxFileTitle = _MAX_PATH;
+    pofn->nMaxFile = _countof(FileNameBuffer);
     pofn->Flags = OFN_EXPLORER | OFN_HIDEREADONLY;
     pofn->lpstrDefExt = L"reg";
+    if (bSave)
+        pofn->Flags |= OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST;
+    else
+        pofn->Flags |= OFN_FILEMUSTEXIST;
+
     return TRUE;
 }
 
@@ -354,7 +367,7 @@ static BOOL LoadHive(HWND hWnd)
     /* get the item key to load the hive in */
     pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
     /* initialize the "open file" dialog */
-    InitOpenFileName(hWnd, &ofn);
+    InitOpenFileName(hWnd, &ofn, FALSE);
     /* build the "All Files" filter up */
     filter.DisplayID = IDS_FLT_ALLFILES;
     filter.FilterID = IDS_FLT_ALLFILES_FLT;
@@ -364,7 +377,7 @@ static BOOL LoadHive(HWND hWnd)
     LoadStringW(hInst, IDS_LOAD_HIVE, Caption, ARRAY_SIZE(Caption));
     ofn.lpstrTitle = Caption;
     ofn.Flags |= OFN_ENABLESIZING;
-    /*    ofn.lCustData = ;*/
+
     /* now load the hive */
     if (GetOpenFileName(&ofn))
     {
@@ -442,11 +455,11 @@ static BOOL ImportRegistryFile(HWND hWnd)
     /* Figure out in which key path we are importing */
     pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
 
-    InitOpenFileName(hWnd, &ofn);
+    InitOpenFileName(hWnd, &ofn, FALSE);
     LoadStringW(hInst, IDS_IMPORT_REG_FILE, Caption, ARRAY_SIZE(Caption));
     ofn.lpstrTitle = Caption;
     ofn.Flags |= OFN_ENABLESIZING;
-    /*    ofn.lCustData = ;*/
+
     if (GetOpenFileName(&ofn))
     {
         /* Look at the extension of the file to determine its type */
@@ -590,7 +603,7 @@ BOOL ExportRegistryFile(HWND hWnd)
     pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
     GetKeyName(ExportKeyPath, ARRAY_SIZE(ExportKeyPath), hKeyRoot, pszKeyPath);
 
-    InitOpenFileName(hWnd, &ofn);
+    InitOpenFileName(hWnd, &ofn, TRUE);
     LoadStringW(hInst, IDS_EXPORT_REG_FILE, Caption, ARRAY_SIZE(Caption));
     ofn.lpstrTitle = Caption;
 
@@ -599,7 +612,7 @@ BOOL ExportRegistryFile(HWND hWnd)
     {
         ofn.lCustData = (LPARAM) ExportKeyPath;
     }
-    ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK | 
OFN_OVERWRITEPROMPT;
+    ofn.Flags |= OFN_ENABLETEMPLATE | OFN_ENABLEHOOK;
     ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
     ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORTRANGE);
     if (GetSaveFileName(&ofn))
@@ -677,6 +690,19 @@ BOOL ExportRegistryFile(HWND hWnd)
 
                 break;
             }
+
+            case 4:  /* Text File */
+            {
+                bRet = txt_export_registry_key(ofn.lpstrFile, ExportKeyPath);
+                if (!bRet)
+                {
+                    /* Error creating the file */
+                    LoadStringW(hInst, IDS_APP_TITLE, szTitle, 
ARRAY_SIZE(szTitle));
+                    LoadStringW(hInst, IDS_EXPORT_ERROR, szText, 
ARRAY_SIZE(szText));
+                    InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, 
szText, ofn.lpstrFile);
+                }
+                break;
+            }
         }
     }
     else
diff --git a/base/applications/regedit/lang/bg-BG.rc 
b/base/applications/regedit/lang/bg-BG.rc
index d3fb06924a5..6e7395ce1e2 100644
--- a/base/applications/regedit/lang/bg-BG.rc
+++ b/base/applications/regedit/lang/bg-BG.rc
@@ -426,6 +426,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Всички файлове (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -521,6 +523,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Неизвестен вид интерфейс"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/cs-CZ.rc 
b/base/applications/regedit/lang/cs-CZ.rc
index 477a5e00d9c..b5c1966561b 100644
--- a/base/applications/regedit/lang/cs-CZ.rc
+++ b/base/applications/regedit/lang/cs-CZ.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Všechny soubory (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Neznámý typ rozhraní"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/de-DE.rc 
b/base/applications/regedit/lang/de-DE.rc
index 6394f18e3ae..f097213567b 100644
--- a/base/applications/regedit/lang/de-DE.rc
+++ b/base/applications/regedit/lang/de-DE.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Alle Dateien (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unbekannter Schnittstellentyp"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/el-GR.rc 
b/base/applications/regedit/lang/el-GR.rc
index 5fdb8ff7a26..72b420111ba 100644
--- a/base/applications/regedit/lang/el-GR.rc
+++ b/base/applications/regedit/lang/el-GR.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Όλα τα αρχεία (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/en-US.rc 
b/base/applications/regedit/lang/en-US.rc
index c733468f1fc..2b3cc3137b5 100644
--- a/base/applications/regedit/lang/en-US.rc
+++ b/base/applications/regedit/lang/en-US.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "All Files (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/es-ES.rc 
b/base/applications/regedit/lang/es-ES.rc
index ab8ed5c0afd..703f821d72d 100644
--- a/base/applications/regedit/lang/es-ES.rc
+++ b/base/applications/regedit/lang/es-ES.rc
@@ -424,6 +424,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Todos los archivos (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -519,6 +521,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Tipo de interfaz desconocido"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/fr-FR.rc 
b/base/applications/regedit/lang/fr-FR.rc
index 9db8d8ab118..4c049612b61 100644
--- a/base/applications/regedit/lang/fr-FR.rc
+++ b/base/applications/regedit/lang/fr-FR.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Tous les fichiers (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/he-IL.rc 
b/base/applications/regedit/lang/he-IL.rc
index 31fbda0e42c..1f1e50a0abd 100644
--- a/base/applications/regedit/lang/he-IL.rc
+++ b/base/applications/regedit/lang/he-IL.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "כל הקבצים (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/hu-HU.rc 
b/base/applications/regedit/lang/hu-HU.rc
index 923cf80e9ff..49a5bf8a5ba 100644
--- a/base/applications/regedit/lang/hu-HU.rc
+++ b/base/applications/regedit/lang/hu-HU.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "All Files (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/id-ID.rc 
b/base/applications/regedit/lang/id-ID.rc
index 0d2ab2c0a1d..0c6c516d995 100644
--- a/base/applications/regedit/lang/id-ID.rc
+++ b/base/applications/regedit/lang/id-ID.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Semua Berkas (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/it-IT.rc 
b/base/applications/regedit/lang/it-IT.rc
index 6f7fd072280..5226bad09d8 100644
--- a/base/applications/regedit/lang/it-IT.rc
+++ b/base/applications/regedit/lang/it-IT.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Tutti i file (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Tipologia interfaccia sconosciuta"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/ja-JP.rc 
b/base/applications/regedit/lang/ja-JP.rc
index e49b42a0d00..68f820f9ccb 100644
--- a/base/applications/regedit/lang/ja-JP.rc
+++ b/base/applications/regedit/lang/ja-JP.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "すべてのファイル (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/ko-KR.rc 
b/base/applications/regedit/lang/ko-KR.rc
index d68d0ab9d84..08807796261 100644
--- a/base/applications/regedit/lang/ko-KR.rc
+++ b/base/applications/regedit/lang/ko-KR.rc
@@ -423,6 +423,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "모든 파일 (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -518,6 +520,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/nl-NL.rc 
b/base/applications/regedit/lang/nl-NL.rc
index 455a615b57e..96b94f9227e 100644
--- a/base/applications/regedit/lang/nl-NL.rc
+++ b/base/applications/regedit/lang/nl-NL.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "All Files (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/no-NO.rc 
b/base/applications/regedit/lang/no-NO.rc
index 4f946548851..94e748de214 100644
--- a/base/applications/regedit/lang/no-NO.rc
+++ b/base/applications/regedit/lang/no-NO.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Alle Filer (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/pl-PL.rc 
b/base/applications/regedit/lang/pl-PL.rc
index 456e1abf8ba..23b94db9ede 100644
--- a/base/applications/regedit/lang/pl-PL.rc
+++ b/base/applications/regedit/lang/pl-PL.rc
@@ -431,6 +431,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Wszystkie pliki (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -526,6 +528,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Nieznany typ interfejsu"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/pt-BR.rc 
b/base/applications/regedit/lang/pt-BR.rc
index 41e9bf0551d..eed2f74ffec 100644
--- a/base/applications/regedit/lang/pt-BR.rc
+++ b/base/applications/regedit/lang/pt-BR.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Todos os arquivos (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/pt-PT.rc 
b/base/applications/regedit/lang/pt-PT.rc
index fddef2f9c3e..790ef64cb5a 100644
--- a/base/applications/regedit/lang/pt-PT.rc
+++ b/base/applications/regedit/lang/pt-PT.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Todos os ficheiros (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/ro-RO.rc 
b/base/applications/regedit/lang/ro-RO.rc
index 3dc4fe0b3be..b3b0899923d 100644
--- a/base/applications/regedit/lang/ro-RO.rc
+++ b/base/applications/regedit/lang/ro-RO.rc
@@ -431,6 +431,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Orice fișier (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -526,6 +528,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Nespecificat"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/ru-RU.rc 
b/base/applications/regedit/lang/ru-RU.rc
index 6a13e2b0577..5e7f89dbca8 100644
--- a/base/applications/regedit/lang/ru-RU.rc
+++ b/base/applications/regedit/lang/ru-RU.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Все файлы (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Неизвестный тип интерфейса"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/sk-SK.rc 
b/base/applications/regedit/lang/sk-SK.rc
index 5f453c80f5c..1b5b3878aeb 100644
--- a/base/applications/regedit/lang/sk-SK.rc
+++ b/base/applications/regedit/lang/sk-SK.rc
@@ -426,6 +426,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Všetky súbory (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -521,6 +523,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/sl-SI.rc 
b/base/applications/regedit/lang/sl-SI.rc
index 345b80f37cc..27862c037e2 100644
--- a/base/applications/regedit/lang/sl-SI.rc
+++ b/base/applications/regedit/lang/sl-SI.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "All Files (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/sq-AL.rc 
b/base/applications/regedit/lang/sq-AL.rc
index 280814c024e..5890b9771f5 100644
--- a/base/applications/regedit/lang/sq-AL.rc
+++ b/base/applications/regedit/lang/sq-AL.rc
@@ -425,6 +425,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Gjith Dokumentat (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -520,6 +522,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/sv-SE.rc 
b/base/applications/regedit/lang/sv-SE.rc
index 7df2fca17b6..1b573768e40 100644
--- a/base/applications/regedit/lang/sv-SE.rc
+++ b/base/applications/regedit/lang/sv-SE.rc
@@ -421,6 +421,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Alla filer (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -516,6 +518,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/th-TH.rc 
b/base/applications/regedit/lang/th-TH.rc
index 2b7d63f609f..518846fe433 100644
--- a/base/applications/regedit/lang/th-TH.rc
+++ b/base/applications/regedit/lang/th-TH.rc
@@ -423,6 +423,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "All Files (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -518,6 +520,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/tr-TR.rc 
b/base/applications/regedit/lang/tr-TR.rc
index df6b6ce4e01..d1a63326a99 100644
--- a/base/applications/regedit/lang/tr-TR.rc
+++ b/base/applications/regedit/lang/tr-TR.rc
@@ -423,6 +423,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Tüm Dosyalar (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -518,6 +520,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Bilinmeyen Arayüz Türü"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/uk-UA.rc 
b/base/applications/regedit/lang/uk-UA.rc
index 1ec8de53702..dfcd70543e0 100644
--- a/base/applications/regedit/lang/uk-UA.rc
+++ b/base/applications/regedit/lang/uk-UA.rc
@@ -423,6 +423,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "Усі файли (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -518,6 +520,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "Unknown Interface Type"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/zh-CN.rc 
b/base/applications/regedit/lang/zh-CN.rc
index 3250830dc0e..b3e911b060f 100644
--- a/base/applications/regedit/lang/zh-CN.rc
+++ b/base/applications/regedit/lang/zh-CN.rc
@@ -431,6 +431,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "所有文件 (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -526,6 +528,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "未知的接口类型"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/zh-HK.rc 
b/base/applications/regedit/lang/zh-HK.rc
index 0ec044875ae..ccb5f7385f6 100644
--- a/base/applications/regedit/lang/zh-HK.rc
+++ b/base/applications/regedit/lang/zh-HK.rc
@@ -429,6 +429,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "所有檔案 (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -524,6 +526,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "不明介面類型"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/lang/zh-TW.rc 
b/base/applications/regedit/lang/zh-TW.rc
index db2d11e39a5..4b4b3a2d1c7 100644
--- a/base/applications/regedit/lang/zh-TW.rc
+++ b/base/applications/regedit/lang/zh-TW.rc
@@ -430,6 +430,8 @@ BEGIN
     IDS_FLT_REGEDIT4_FLT "*.reg"
     IDS_FLT_ALLFILES "所有檔案 (*.*)"
     IDS_FLT_ALLFILES_FLT "*.*"
+    IDS_FLT_TXTFILES "Text Files (*.txt)"
+    IDS_FLT_TXTFILES_FLT "*.txt"
 END
 
 STRINGTABLE
@@ -525,6 +527,20 @@ BEGIN
     IDS_BUS_UNKNOWNTYPE "不明介面類型"
 END
 
+STRINGTABLE
+BEGIN
+    IDS_FIELD_KEY_NAME "Key Name:"
+    IDS_FIELD_CLASS_NAME "Class Name:"
+    IDS_NO_CLASS_NAME "<NO CLASS>"
+    IDS_NULL_TIMESTAMP "<NULL>"
+    IDS_FIELD_NAME "  Name:"
+    IDS_FIELD_TYPE "  Type:"
+    IDS_FIELD_DATA "  Data:"
+    IDS_FIELD_LASTWRITE "Last Write Time:"
+    IDS_UNKNOWN "<UNKNOWN>"
+    IDS_VALUE_INDEX "Value %d"
+END
+
 /*****************************************************************/
 
 /* Dialogs */
diff --git a/base/applications/regedit/main.h b/base/applications/regedit/main.h
index bb257e792cc..bb3a07dbd27 100644
--- a/base/applications/regedit/main.h
+++ b/base/applications/regedit/main.h
@@ -163,4 +163,7 @@ void DestroyTreeView(HWND hwndTV);
 void DestroyListView(HWND hwndLV);
 void DestroyMainMenu(void);
 
+/* txtproc.c */
+BOOL txt_export_registry_key(LPCWSTR file_name, LPCWSTR path);
+
 /* EOF */
diff --git a/base/applications/regedit/resource.h 
b/base/applications/regedit/resource.h
index 933a8a03420..c4cc3955273 100644
--- a/base/applications/regedit/resource.h
+++ b/base/applications/regedit/resource.h
@@ -168,6 +168,8 @@
 #define IDS_FLT_REGEDIT4_FLT 31006
 #define IDS_FLT_ALLFILES     31007
 #define IDS_FLT_ALLFILES_FLT 31008
+#define IDS_FLT_TXTFILES     31009
+#define IDS_FLT_TXTFILES_FLT 31010
 
 #define IDS_ACCESS_FULLCONTROL      31100
 #define IDS_ACCESS_READ             31101
@@ -244,6 +246,17 @@
 #define IDS_BUS_PNPBUS            31546
 #define IDS_BUS_UNKNOWNTYPE       31547
 
+#define IDS_FIELD_KEY_NAME      31600
+#define IDS_FIELD_CLASS_NAME    31601
+#define IDS_NO_CLASS_NAME       31602
+#define IDS_NULL_TIMESTAMP      31603
+#define IDS_FIELD_NAME          31604
+#define IDS_FIELD_TYPE          31605
+#define IDS_FIELD_DATA          31606
+#define IDS_FIELD_LASTWRITE     31607
+#define IDS_UNKNOWN             31608
+#define IDS_VALUE_INDEX         31609
+
 #define IDD_EDIT_STRING 2000
 #define IDC_VALUE_NAME  2001
 #define IDC_VALUE_DATA  2002
diff --git a/base/applications/regedit/txtproc.c 
b/base/applications/regedit/txtproc.c
new file mode 100644
index 00000000000..f5e3ea041c2
--- /dev/null
+++ b/base/applications/regedit/txtproc.c
@@ -0,0 +1,406 @@
+/*
+ * PROJECT:     ReactOS Registry Editor
+ * LICENSE:     LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
+ * PURPOSE:     Exporting registry data to a text file
+ * COPYRIGHT:   Copyright 2023 Katayama Hirofumi MZ 
<katayama.hirofumi...@gmail.com>
+ */
+
+#include "regedit.h"
+
+static HKEY reg_class_keys[] =
+{
+    HKEY_LOCAL_MACHINE, HKEY_USERS, HKEY_CLASSES_ROOT,
+    HKEY_CURRENT_CONFIG, HKEY_CURRENT_USER, HKEY_DYN_DATA
+};
+
+static LPWSTR load_str(INT id)
+{
+    /* Use rotation buffer */
+    static WCHAR s_asz[3][MAX_PATH];
+    static INT s_index = 0;
+    LPWSTR psz;
+    LoadStringW(hInst, id, s_asz[s_index], MAX_PATH);
+    psz = s_asz[s_index];
+    s_index = (s_index + 1) % _countof(s_asz);
+    return psz;
+}
+
+static void txt_fputs(FILE *fp, LPCWSTR str)
+{
+    fwrite(str, lstrlenW(str) * sizeof(WCHAR), 1, fp);
+}
+
+static void txt_newline(FILE *fp)
+{
+    txt_fputs(fp, L"\r\n");
+}
+
+static void txt_fprintf(FILE *fp, LPCWSTR format, ...)
+{
+    WCHAR line[1024];
+    va_list va;
+    va_start(va, format);
+    StringCchVPrintfW(line, _countof(line), format, va);
+    txt_fputs(fp, line);
+    va_end(va);
+}
+
+static HKEY txt_parse_key_name(LPCWSTR key_name, WCHAR **key_path)
+{
+    unsigned int i;
+
+    if (!key_name) return 0;
+
+    *key_path = wcschr(key_name, '\\');
+    if (*key_path)
+        (*key_path)++;
+
+    for (i = 0; i < _countof(reg_class_keys); i++)
+    {
+        int len = lstrlenW(reg_class_namesW[i]);
+        if (!_wcsnicmp(key_name, reg_class_namesW[i], len) &&
+            (key_name[len] == 0 || key_name[len] == '\\'))
+        {
+            return reg_class_keys[i];
+        }
+    }
+
+    return 0;
+}
+
+static void txt_export_binary(FILE *fp, const void *data, size_t size)
+{
+    const BYTE *pb = data;
+    for (DWORD addr = 0; addr < size; addr += 0x10)
+    {
+        txt_fprintf(fp, L"%08X  ", addr);
+        for (size_t column = 0; column < 16; ++column)
+        {
+            if (addr + column >= size)
+            {
+                if (column == 8)
+                    txt_fputs(fp, L"  ");
+                txt_fputs(fp, L"   ");
+            }
+            else
+            {
+                if (column == 8)
+                    txt_fputs(fp, L" -");
+                txt_fprintf(fp, L" %02x", (pb[addr + column] & 0xFF));
+            }
+        }
+        txt_fputs(fp, L"  ");
+        for (size_t column = 0; column < 16; ++column)
+        {
+            if (addr + column >= size)
+            {
+                break;
+            }
+            else
+            {
+                BYTE b = pb[addr + column];
+                if (isprint(b) || IsCharAlphaNumericW(b))
+                    txt_fprintf(fp, L"%c", b);
+                else
+                    txt_fputs(fp, L".");
+            }
+        }
+        txt_newline(fp);
+    }
+}
+
+static void txt_export_field(FILE *fp, LPCWSTR label, LPCWSTR value)
+{
+    txt_fprintf(fp, L"%-19s%s\r\n", label, value);
+}
+
+static void txt_export_multi_sz(FILE *fp, const void *data, size_t size)
+{
+    LPCWSTR pch;
+    for (pch = data; *pch; pch += lstrlenW(pch) + 1)
+    {
+        if (pch == data)
+            txt_export_field(fp, load_str(IDS_FIELD_DATA), pch);
+        else
+            txt_export_field(fp, L"", pch);
+    }
+}
+
+static void txt_export_type(FILE *fp, LPCWSTR type)
+{
+    txt_export_field(fp, load_str(IDS_FIELD_TYPE), type);
+}
+
+static void txt_export_name(FILE *fp, LPCWSTR name)
+{
+    txt_export_field(fp, load_str(IDS_FIELD_NAME), name);
+}
+
+static void
+txt_export_data(FILE *fp, INT i, LPCWSTR value_name, DWORD value_len, DWORD 
type,
+                const void *data, size_t size)
+{
+    LPCWSTR pszType;
+
+    txt_fprintf(fp, load_str(IDS_VALUE_INDEX), i);
+    txt_newline(fp);
+    txt_export_name(fp, value_name);
+
+    switch (type)
+    {
+        case REG_SZ:
+            txt_export_type(fp, L"REG_SZ");
+            txt_export_field(fp, load_str(IDS_FIELD_DATA), data);
+            break;
+
+        case REG_DWORD:
+            txt_export_type(fp, L"REG_DWORD");
+            txt_fprintf(fp, L"%-19s0x%lx\r\n", load_str(IDS_FIELD_DATA), 
*(DWORD*)data);
+            break;
+
+        case REG_EXPAND_SZ:
+            txt_export_type(fp, L"REG_EXPAND_SZ");
+            txt_export_field(fp, load_str(IDS_FIELD_DATA), data);
+            break;
+
+        case REG_MULTI_SZ:
+            txt_export_type(fp, L"REG_MULTI_SZ");
+            txt_export_multi_sz(fp, data, size);
+            break;
+
+        case REG_BINARY:
+        case REG_QWORD:
+        case REG_NONE:
+        default:
+            if (type == REG_BINARY)
+                pszType = L"REG_BINARY";
+            else if (type == REG_QWORD)
+                pszType = L"REG_QWORD";
+            else if (type == REG_NONE)
+                pszType = L"REG_NONE";
+            else
+                pszType = load_str(IDS_UNKNOWN);
+
+            txt_export_type(fp, pszType);
+            txt_export_field(fp, load_str(IDS_FIELD_DATA), L"");
+            txt_export_binary(fp, data, size);
+            break;
+    }
+
+    txt_newline(fp);
+}
+
+static WCHAR *
+txt_build_subkey_path(LPCWSTR path, DWORD path_len, LPCWSTR subkey_name, DWORD 
subkey_len)
+{
+    WCHAR *subkey_path;
+    subkey_path = malloc((path_len + subkey_len + 2) * sizeof(WCHAR));
+    swprintf(subkey_path, L"%s\\%s", path, subkey_name);
+    return subkey_path;
+}
+
+static void txt_export_key_name(FILE *fp, LPCWSTR name)
+{
+    txt_export_field(fp, load_str(IDS_FIELD_KEY_NAME), name);
+}
+
+static void txt_export_class_and_last_write(FILE *fp, HKEY key)
+{
+    WCHAR szClassName[MAX_PATH];
+    DWORD cchClassName = _countof(szClassName);
+    FILETIME ftLastWrite, ftLocal, ftNull = { 0 };
+    SYSTEMTIME stLastWrite;
+    WCHAR sz1[64], sz2[64];
+    LONG error;
+
+    error = RegQueryInfoKeyW(key, szClassName, &cchClassName, NULL, NULL, 
NULL, NULL, NULL, NULL,
+                             NULL, NULL, &ftLastWrite);
+    if (error != ERROR_SUCCESS)
+    {
+        cchClassName = 0;
+        ftLastWrite = ftNull;
+    }
+
+    szClassName[_countof(szClassName) - 1] = UNICODE_NULL;
+
+    if (cchClassName > 0)
+        txt_export_field(fp, load_str(IDS_FIELD_CLASS_NAME), szClassName);
+    else
+        txt_export_field(fp, load_str(IDS_FIELD_CLASS_NAME), 
load_str(IDS_NO_CLASS_NAME));
+
+    if (memcmp(&ftLastWrite, &ftNull, sizeof(ftNull)) == 0)
+    {
+        txt_export_field(fp, load_str(IDS_FIELD_LASTWRITE), 
load_str(IDS_NULL_TIMESTAMP));
+        return;
+    }
+
+    FileTimeToLocalFileTime(&ftLastWrite, &ftLocal);
+    FileTimeToSystemTime(&ftLocal, &stLastWrite);
+    GetDateFormatW(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stLastWrite, NULL, 
sz1, _countof(sz1));
+    GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_NOSECONDS, &stLastWrite, NULL, 
sz2, _countof(sz2));
+    txt_fprintf(fp, L"%-19s%s - %s\r\n", load_str(IDS_FIELD_LASTWRITE), sz1, 
sz2);
+}
+
+static void txt_export_registry_data(FILE *fp, HKEY key, LPCWSTR path)
+{
+    LONG rc;
+    DWORD max_value_len = MAX_PATH, value_len;
+    DWORD max_data_bytes = 2048, data_size;
+    DWORD subkey_len;
+    DWORD i, type, path_len;
+    WCHAR *value_name, *subkey_name, *subkey_path;
+    BYTE *data;
+    HKEY subkey;
+
+    txt_export_key_name(fp, path);
+    txt_export_class_and_last_write(fp, key);
+
+    value_name = malloc(max_value_len * sizeof(WCHAR));
+    data = malloc(max_data_bytes);
+
+    i = 0;
+    for (;;)
+    {
+        value_len = max_value_len;
+        data_size = max_data_bytes;
+        rc = RegEnumValueW(key, i, value_name, &value_len, NULL, &type, data, 
&data_size);
+        if (rc == ERROR_SUCCESS)
+        {
+            txt_export_data(fp, i, value_name, value_len, type, data, 
data_size);
+            i++;
+        }
+        else if (rc == ERROR_MORE_DATA)
+        {
+            if (data_size > max_data_bytes)
+            {
+                max_data_bytes = data_size;
+                data = realloc(data, max_data_bytes);
+            }
+            else
+            {
+                max_value_len *= 2;
+                value_name = realloc(value_name, max_value_len * 
sizeof(WCHAR));
+            }
+        }
+        else break;
+    }
+
+    free(data);
+    free(value_name);
+
+    subkey_name = malloc(MAX_PATH * sizeof(WCHAR));
+
+    path_len = lstrlenW(path);
+
+    i = 0;
+    for (;;)
+    {
+        subkey_len = MAX_PATH;
+        rc = RegEnumKeyExW(key, i, subkey_name, &subkey_len, NULL, NULL, NULL, 
NULL);
+        if (rc == ERROR_SUCCESS)
+        {
+            if (i == 0)
+                txt_newline(fp);
+
+            subkey_path = txt_build_subkey_path(path, path_len, subkey_name, 
subkey_len);
+            if (!RegOpenKeyExW(key, subkey_name, 0, KEY_READ, &subkey))
+            {
+                txt_newline(fp);
+                txt_export_registry_data(fp, subkey, subkey_path);
+                RegCloseKey(subkey);
+            }
+            free(subkey_path);
+            i++;
+        }
+        else break;
+    }
+
+    free(subkey_name);
+}
+
+static FILE *txt_open_export_file(LPCWSTR file_name)
+{
+    FILE *file = _wfopen(file_name, L"wb");
+    if (file)
+        fwrite("\xFF\xFE", 2, 1, file);
+    return file;
+}
+
+static HKEY txt_open_export_key(HKEY key_class, LPCWSTR subkey, LPCWSTR path)
+{
+    HKEY key;
+
+    if (RegOpenKeyExW(key_class, subkey, 0, KEY_READ, &key) != ERROR_SUCCESS)
+        return NULL;
+
+    return key;
+}
+
+static BOOL txt_export_key(LPCWSTR file_name, LPCWSTR path)
+{
+    HKEY key_class, key;
+    WCHAR *subkey;
+    FILE *fp;
+
+    if (!(key_class = txt_parse_key_name(path, &subkey)))
+    {
+        if (subkey) *(subkey - 1) = 0;
+        return FALSE;
+    }
+
+    if (!(key = txt_open_export_key(key_class, subkey, path)))
+        return FALSE;
+
+    fp = txt_open_export_file(file_name);
+    if (fp)
+    {
+        txt_export_registry_data(fp, key, path);
+        txt_newline(fp);
+        fclose(fp);
+    }
+
+    RegCloseKey(key);
+    return fp != NULL;
+}
+
+static BOOL txt_export_all(LPCWSTR file_name, LPCWSTR path)
+{
+    FILE *fp;
+    int i;
+    HKEY classes[] = {HKEY_LOCAL_MACHINE, HKEY_USERS}, key;
+    WCHAR *class_name;
+
+    fp = txt_open_export_file(file_name);
+    if (!fp)
+        return FALSE;
+
+    for (i = 0; i < _countof(classes); i++)
+    {
+        if (!(key = txt_open_export_key(classes[i], NULL, path)))
+        {
+            fclose(fp);
+            return FALSE;
+        }
+
+        class_name = malloc((lstrlenW(reg_class_namesW[i]) + 1) * 
sizeof(WCHAR));
+        lstrcpyW(class_name, reg_class_namesW[i]);
+
+        txt_export_registry_data(fp, classes[i], class_name);
+
+        free(class_name);
+        RegCloseKey(key);
+    }
+
+    txt_newline(fp);
+    fclose(fp);
+
+    return TRUE;
+}
+
+BOOL txt_export_registry_key(LPCWSTR file_name, LPCWSTR path)
+{
+    if (path && *path)
+        return txt_export_key(file_name, path);
+    else
+        return txt_export_all(file_name, path);
+}

Reply via email to