Added clipboard and common dialog references as well as build improvements.
authorRobert Dickenson <robd@reactos.org>
Tue, 7 Jan 2003 18:06:16 +0000 (18:06 +0000)
committerRobert Dickenson <robd@reactos.org>
Tue, 7 Jan 2003 18:06:16 +0000 (18:06 +0000)
svn path=/trunk/; revision=3956

rosapps/regedit/Makefile
rosapps/regedit/childwnd.c
rosapps/regedit/dbg.h [new file with mode: 0644]
rosapps/regedit/framewnd.c
rosapps/regedit/listview.c
rosapps/regedit/main.c
rosapps/regedit/regcmds.c
rosapps/regedit/regedit.rc
rosapps/regedit/regproc.c
rosapps/regedit/regproc.h
rosapps/regedit/resource.h

index b2a8fd3..acb97fc 100644 (file)
@@ -24,23 +24,22 @@ PATH_TO_TOP = ..
 
 TARGET = regedit
 
-BASE_CFLAGS = -DGCC -D_WIN32_IE=0x0400
+BASE_CFLAGS = -D_WIN32_IE=0x0400
 
-RCFLAGS = -DGCC -D_WIN32_IE=0x0400
+RCFLAGS = -D_WIN32_IE=0x0400
 
-
-OBJS = framewnd.o \
+OBJS = about.o \
         childwnd.o \
-        listview.o \
-        treeview.o \
-        about.o \
-        trace.o \
+        framewnd.o \
         hex_str.o \
+        listview.o \
+        main.o \
        regcmds.o \
        regproc.o \
-        main.o
+        treeview.o \
+        trace.o
 
-LIBS = -lgdi32 -luser32 -lkernel32 -lcomctl32
+LIBS = -lgdi32 -luser32 -lkernel32 -lcomctl32 -lcomdlg32
 
 all:   $(TARGET).exe
 
index 32f08d1..d3f6f8d 100644 (file)
 
 #define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
 #include <windows.h>
-#include <commctrl.h>
-#include <stdlib.h>
 #include <tchar.h>
-#include <process.h>
-#include <stdio.h>
-    
+#include <commctrl.h>
 #include <assert.h>
 #define ASSERT assert
 
diff --git a/rosapps/regedit/dbg.h b/rosapps/regedit/dbg.h
new file mode 100644 (file)
index 0000000..b531bb7
--- /dev/null
@@ -0,0 +1,33 @@
+#ifndef __DBG_H__
+#define __DBG_H__
+
+/*
+void Assert(void* assert, const char* file, int line, void* msg);
+#define ASSERT Assert(void* assert, const char* file, int line, void* msg)
+#define D(_x_) \
+        printf("(%hS:%d)(%hS) ", __FILE__, __LINE__, __FUNCTION__); \
+           printf _x_;
+ */
+
+#ifdef ASSERT
+#undef ASSERT
+#endif
+
+#ifdef NASSERT
+#define ASSERT(x)
+#else /* NASSERT */
+//#define ASSERT(x) if (!(x)) { printf("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__); assert(0); }
+#define ASSERT(x) if (!(x)) { printf("Assertion "#x" failed at %s:%d\n", __FILE__, __LINE__); }
+#endif /* NASSERT */
+
+
+#ifdef __GNUC__
+
+#else
+
+//#define __FUNCTION__ "unknown"
+
+#endif /*__GNUC__*/
+
+
+#endif /*__DBG_H__*/
index 30f3b66..df03f56 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
+//#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
 #include <windows.h>
+#include <tchar.h>
 #include <commctrl.h>
+#include <commdlg.h>
 #include <stdlib.h>
-#include <malloc.h>
-#include <tchar.h>
-#include <process.h>
 #include <stdio.h>
     
 #include "main.h"
@@ -36,6 +35,7 @@
 #include "listview.h"
 #include <shellapi.h>
 
+#include "regproc.h"
 
 ////////////////////////////////////////////////////////////////////////////////
 // Global and Local Variables:
@@ -150,6 +150,285 @@ static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
        resize_frame_client(hWnd);
 }
 
+static BOOL CheckCommDlgError(HWND hWnd)
+{
+        DWORD dwErrorCode = CommDlgExtendedError();
+        switch (dwErrorCode) {
+        case CDERR_DIALOGFAILURE:
+            break;
+        case CDERR_FINDRESFAILURE:
+            break;
+        case CDERR_NOHINSTANCE:
+            break;
+        case CDERR_INITIALIZATION:
+            break;
+        case CDERR_NOHOOK:
+            break;
+        case CDERR_LOCKRESFAILURE:
+            break;
+        case CDERR_NOTEMPLATE:
+            break;
+        case CDERR_LOADRESFAILURE:
+            break;
+        case CDERR_STRUCTSIZE:
+            break;
+        case CDERR_LOADSTRFAILURE:
+            break;
+        case FNERR_BUFFERTOOSMALL:
+            break;
+        case CDERR_MEMALLOCFAILURE:
+            break;
+        case FNERR_INVALIDFILENAME:
+            break;
+        case CDERR_MEMLOCKFAILURE:
+            break;
+        case FNERR_SUBCLASSFAILURE:
+            break;
+        default:
+            break;
+        }
+       return TRUE;
+}
+
+UINT_PTR CALLBACK ImportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
+{
+    OPENFILENAME* pOpenFileName;
+    OFNOTIFY* pOfNotify;
+
+    switch (uiMsg) {
+    case WM_INITDIALOG:
+        pOpenFileName = (OPENFILENAME*)lParam;
+        break;
+    case WM_NOTIFY:
+        pOfNotify = (OFNOTIFY*)lParam;
+        if (pOfNotify->hdr.code == CDN_INITDONE) {
+        }
+        break;
+    default:
+        break;
+    }
+    return 0L;
+}
+
+#define MAX_CUSTOM_FILTER_SIZE 50
+TCHAR CustomFilterBuffer[MAX_CUSTOM_FILTER_SIZE];
+TCHAR FileNameBuffer[_MAX_PATH];
+TCHAR FileTitleBuffer[_MAX_PATH];
+
+static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
+{
+    memset(pofn, 0, sizeof(OPENFILENAME));
+    pofn->lStructSize = sizeof(OPENFILENAME);
+    pofn->hwndOwner = hWnd;
+    pofn->hInstance = hInst;
+
+    pofn->lpstrFilter = _T("Registration Files\0*.reg\0Win9x/NT4 Registration Files (REGEDIT4)\0*.reg\0All Files (*.*)\0*.*\0\0");
+    pofn->lpstrCustomFilter = CustomFilterBuffer;
+    pofn->nMaxCustFilter = MAX_CUSTOM_FILTER_SIZE;
+    pofn->nFilterIndex = 0;
+    pofn->lpstrFile = FileNameBuffer;
+    pofn->nMaxFile = _MAX_PATH;
+    pofn->lpstrFileTitle = FileTitleBuffer;
+    pofn->nMaxFileTitle = _MAX_PATH;
+//    pofn->lpstrInitialDir = _T("");
+//    pofn->lpstrTitle = _T("Import Registry File");
+//    pofn->Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER + OFN_ENABLESIZING;
+    pofn->Flags = OFN_HIDEREADONLY;
+//    pofn->nFileOffset = ;
+//    pofn->nFileExtension = ;
+//    pofn->lpstrDefExt = _T("");
+//    pofn->lCustData = ;
+//    pofn->lpfnHook = ImportRegistryFile_OFNHookProc;
+//    pofn->lpTemplateName = _T("ID_DLG_IMPORT_REGFILE");
+//    pofn->lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);
+//    pofn->FlagsEx = ;
+       return TRUE;
+}
+
+static BOOL ImportRegistryFile(HWND hWnd)
+{
+    OPENFILENAME ofn;
+
+    InitOpenFileName(hWnd, &ofn);
+    ofn.lpstrTitle = _T("Import Registry File");
+//    ofn.lCustData = ;
+    if (GetOpenFileName(&ofn)) {
+        if (!import_registry_file(ofn.lpstrFile)) {
+            //printf("Can't open file \"%s\"\n", ofn.lpstrFile);
+            return FALSE;
+        }
+/*
+        get_file_name(&s, filename, MAX_PATH);
+        if (!filename[0]) {
+            printf("No file name is specified\n%s", usage);
+            return FALSE;
+            //exit(1);
+        }
+        while (filename[0]) {
+            if (!import_registry_file(filename)) {
+                perror("");
+                printf("Can't open file \"%s\"\n", filename);
+                return FALSE;
+                //exit(1);
+            }
+            get_file_name(&s, filename, MAX_PATH);
+        }
+ */
+    } else {
+        CheckCommDlgError(hWnd);
+    }
+       return TRUE;
+}
+
+
+static BOOL ExportRegistryFile(HWND hWnd)
+{
+    OPENFILENAME ofn;
+    TCHAR ExportKeyPath[_MAX_PATH];
+
+    ExportKeyPath[0] = _T('\0');
+    InitOpenFileName(hWnd, &ofn);
+    ofn.lpstrTitle = _T("Export Registry File");
+//    ofn.lCustData = ;
+    ofn.Flags = OFN_ENABLETEMPLATE + OFN_EXPLORER;
+    ofn.lpfnHook = ImportRegistryFile_OFNHookProc;
+    ofn.lpTemplateName = MAKEINTRESOURCE(IDD_DIALOG1);
+    if (GetSaveFileName(&ofn)) {
+        BOOL result;
+        result = export_registry_key(ofn.lpstrFile, ExportKeyPath);
+        //result = export_registry_key(ofn.lpstrFile, NULL);
+        //if (!export_registry_key(ofn.lpstrFile, NULL)) {
+        if (!result) {
+            //printf("Can't open file \"%s\"\n", ofn.lpstrFile);
+            return FALSE;
+        }
+/*
+        TCHAR filename[MAX_PATH];
+        filename[0] = '\0';
+        get_file_name(&s, filename, MAX_PATH);
+        if (!filename[0]) {
+            printf("No file name is specified\n%s", usage);
+            return FALSE;
+            //exit(1);
+        }
+        if (s[0]) {
+            TCHAR reg_key_name[KEY_MAX_LEN];
+            get_file_name(&s, reg_key_name, KEY_MAX_LEN);
+            export_registry_key(filename, reg_key_name);
+        } else {
+            export_registry_key(filename, NULL);
+        }
+ */
+    } else {
+        CheckCommDlgError(hWnd);
+    }
+       return TRUE;
+}
+
+BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
+{
+#if 1
+    PRINTDLG pd;
+
+    ZeroMemory(&pd, sizeof(PRINTDLG));
+    pd.lStructSize = sizeof(PRINTDLG);
+    pd.hwndOwner   = hWnd;
+    pd.hDevMode    = NULL;     // Don't forget to free or store hDevMode
+    pd.hDevNames   = NULL;     // Don't forget to free or store hDevNames
+    pd.Flags       = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; 
+    pd.nCopies     = 1;
+    pd.nFromPage   = 0xFFFF; 
+    pd.nToPage     = 0xFFFF; 
+    pd.nMinPage    = 1; 
+    pd.nMaxPage    = 0xFFFF; 
+    if (PrintDlg(&pd) == TRUE) {
+        // GDI calls to render output. 
+        DeleteDC(pd.hDC); // Delete DC when done.
+    }
+#else    
+    HRESULT hResult;
+    PRINTDLGEX pd;
+
+    hResult = PrintDlgEx(&pd);
+    if (hResult == S_OK) {
+        switch (pd.dwResultAction) {
+        case PD_RESULT_APPLY:
+            //The user clicked the Apply button and later clicked the Cancel button. This indicates that the user wants to apply the changes made in the property sheet, but does not yet want to print. The PRINTDLGEX structure contains the information specified by the user at the time the Apply button was clicked. 
+            break;
+        case PD_RESULT_CANCEL:
+            //The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. 
+            break;
+        case PD_RESULT_PRINT:
+            //The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. 
+            break;
+        default:
+            break;
+        }
+    } else {
+        switch (hResult) {
+        case E_OUTOFMEMORY:
+            //Insufficient memory. 
+            break;
+        case E_INVALIDARG:
+            // One or more arguments are invalid. 
+            break;
+        case E_POINTER:
+            //Invalid pointer. 
+            break;
+        case E_HANDLE:
+            //Invalid handle. 
+            break;
+        case E_FAIL:
+            //Unspecified error. 
+            break;
+        default:
+            break;
+        }
+        return FALSE;
+    }
+#endif
+    return TRUE;
+}
+
+BOOL CopyKeyName(HWND hWnd, LPTSTR keyName)
+{
+    BOOL result;
+    
+    result = OpenClipboard(hWnd);
+    if (result) {
+        result = EmptyClipboard();
+        if (result) {
+
+            //HANDLE hClipData;
+            //hClipData = SetClipboardData(UINT uFormat, HANDLE hMem);
+
+        } else {
+            // error emptying clipboard
+            DWORD dwError = GetLastError();
+        }
+        if (!CloseClipboard()) {
+            // error closing clipboard
+            DWORD dwError = GetLastError();
+        }
+    } else {
+        // error opening clipboard
+        DWORD dwError = GetLastError();
+    }
+    return result;
+}
+
+BOOL RefreshView(HWND hWnd)
+{
+    // TODO:
+    MessageBeep(-1);
+    MessageBeep(MB_ICONASTERISK);
+    MessageBeep(MB_ICONEXCLAMATION);
+    MessageBeep(MB_ICONHAND);
+    MessageBeep(MB_ICONQUESTION);
+    MessageBeep(MB_OK);
+    return TRUE;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 //  FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG)
@@ -157,11 +436,26 @@ static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
 //  PURPOSE:  Processes WM_COMMAND messages for the main frame window.
 //
 //
-
 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
        switch (LOWORD(wParam)) {
     // Parse the menu selections:
+    case ID_REGISTRY_IMPORTREGISTRYFILE:
+        ImportRegistryFile(hWnd);
+        break;
+    case ID_REGISTRY_EXPORTREGISTRYFILE:
+        ExportRegistryFile(hWnd);
+        break;
+    case ID_REGISTRY_CONNECTNETWORKREGISTRY:
+        break;
+    case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
+        break;
+    case ID_REGISTRY_PRINT:
+        PrintRegistryHive(hWnd, _T(""));
+        break;
+    case ID_EDIT_COPYKEYNAME:
+        CopyKeyName(hWnd, _T(""));
+        break;
     case ID_REGISTRY_PRINTERSETUP:
         //PRINTDLG pd;
         //PrintDlg(&pd);
@@ -174,7 +468,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         DestroyWindow(hWnd);
         break;
     case ID_VIEW_REFRESH:
-        // TODO:
+        RefreshView(hWnd);
         break;
 //     case ID_OPTIONS_TOOLBAR:
 //             toggle_child(hWnd, LOWORD(wParam), hToolBar);
@@ -217,7 +511,7 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
     switch (message) {
     case WM_CREATE:
         {
-        pChildWnd = malloc(sizeof(ChildWnd));
+        pChildWnd = HeapAlloc(GetProcessHeap(), 0, sizeof(ChildWnd));
         _tcsncpy(pChildWnd->szPath, _T("My Computer"), MAX_PATH);
         hChildWnd = CreateWindowEx(0, szChildClass, _T("regedit child window"),
 //                    WS_CHILD|WS_CLIPCHILDREN|WS_VISIBLE|WS_BORDER,
@@ -247,7 +541,7 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
         break;
     case WM_DESTROY:
         if (pChildWnd) {
-            free(pChildWnd);
+            HeapFree(GetProcessHeap(), 0, pChildWnd);
             pChildWnd = NULL;
         }
                WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
index 5d19151..fba22f8 100644 (file)
@@ -24,7 +24,6 @@
 #include <windows.h>
 #include <commctrl.h>
 #include <stdlib.h>
-#include <malloc.h>
 #include <tchar.h>
 #include <process.h>
 #include <stdio.h>
@@ -93,7 +92,7 @@ static void AddEntryToList(HWND hwndLV, LPTSTR Name, DWORD dwValType, void* ValB
             {
                 unsigned int i;
                 LPTSTR pData = (LPTSTR)ValBuf;
-                LPTSTR strBinary = malloc(dwCount * sizeof(TCHAR) * 3 + 1);
+                LPTSTR strBinary = HeapAlloc(GetProcessHeap(), 0, dwCount * sizeof(TCHAR) * 3 + 1);
                 memset(strBinary, _T(' '), dwCount * sizeof(TCHAR) * 3);
                 strBinary[dwCount * sizeof(TCHAR) * 3] = _T('\0');
                 for (i = 0; i < dwCount; i++) {
@@ -104,7 +103,7 @@ static void AddEntryToList(HWND hwndLV, LPTSTR Name, DWORD dwValType, void* ValB
                     *pShort = Byte2Hex(*(pData+i));
                 }
                 ListView_SetItemText(hwndLV, index, 2, strBinary);
-                free(strBinary);
+                HeapFree(GetProcessHeap(), 0, strBinary);
             }
             break;
         default:
@@ -353,9 +352,9 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPTSTR keyPath)
 #define BUF_HEAD_SPACE 2 // TODO: check why this is required with ROS ???
 
             if (errCode == ERROR_SUCCESS) {
-                TCHAR* ValName = malloc(++max_val_name_len * sizeof(TCHAR) + BUF_HEAD_SPACE);
+                TCHAR* ValName = HeapAlloc(GetProcessHeap(), 0, ++max_val_name_len * sizeof(TCHAR) + BUF_HEAD_SPACE);
                 DWORD dwValNameLen = max_val_name_len;
-                BYTE* ValBuf = malloc(++max_val_size/* + BUF_HEAD_SPACE*/);
+                BYTE* ValBuf = HeapAlloc(GetProcessHeap(), 0, ++max_val_size/* + BUF_HEAD_SPACE*/);
                 DWORD dwValSize = max_val_size;
                 DWORD dwIndex = 0L;
                 DWORD dwValType;
@@ -371,10 +370,8 @@ BOOL RefreshListView(HWND hwndLV, HKEY hKey, LPTSTR keyPath)
                     dwValType = 0L;
                     ++dwIndex;
                 }
-
-                free(ValBuf);
-                free(ValName);
-
+                HeapFree(GetProcessHeap(), 0, ValBuf);
+                HeapFree(GetProcessHeap(), 0, ValName);
             }
             //ListView_SortItemsEx(hwndLV, CompareFunc, hwndLV);
 //            SendMessage(hwndLV, LVM_SORTITEMSEX, (WPARAM)CompareFunc, (LPARAM)hwndLV);
index 7efca1d..ac544a2 100644 (file)
@@ -45,6 +45,9 @@ HINSTANCE hInst;
 HWND hFrameWnd;
 HWND hStatusBar;
 HMENU hMenuFrame;
+UINT nClipboardFormat;
+LPCTSTR strClipboardFormat = _T("TODO: SET CORRECT FORMAT");
+
 
 TCHAR szTitle[MAX_LOADSTRING];
 TCHAR szFrameClass[MAX_LOADSTRING];
@@ -107,6 +110,11 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
     // Initialize the Windows Common Controls DLL
     InitCommonControls();
 
+    nClipboardFormat = RegisterClipboardFormat(strClipboardFormat);
+    if (nClipboardFormat == 0) {
+        DWORD dwError = GetLastError();
+    }
+
     hFrameWnd = CreateWindowEx(0, (LPCTSTR)(int)hFrameWndClass, szTitle,
                     WS_OVERLAPPEDWINDOW | WS_EX_CLIENTEDGE,
                     CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
index ea71432..e67be71 100644 (file)
@@ -1,4 +1,5 @@
-/*
+/* $Id: regcmds.c,v 1.4 2003/01/07 18:06:16 robd Exp $
+ *
  *  ReactOS regedit
  *
  *  regcmds.c
 
 #define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
 #include <windows.h>
-#ifndef WIN32_REGDBG
-#include <tchar.h>
-#else
-#ifndef __GNUC__
 #include <tchar.h>
-#endif
-#define _tfopen     _wfopen
-#include <memory.h>
-#endif
 #include <stdio.h>
+
+#ifdef WIN32_REGDBG
+#else
 #include <ctype.h>
+#endif
 
 #include "regproc.h"
 
@@ -58,6 +55,7 @@ static char *usage =
 "Switches:\n"
 "    /E - exports contents of the specified registry key to the specified\n"
 "      file. Exports the whole registry if no key is specified.\n"
+"    /P - same as /E (export) however prints output to console.\n"
 "    /D - deletes specified registry key\n"
 "    /S - silent execution, can be used with any other switch.\n"
 "      The only existing mode, exists for compatibility with Windows regedit.\n"
@@ -76,7 +74,7 @@ static char *usage =
 "command-line interface only.\n";
 
 typedef enum {
-    ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE
+    ACTION_UNDEF, ACTION_ADD, ACTION_EXPORT, ACTION_DELETE, ACTION_PRINT
 } REGEDIT_ACTION;
 
 /**
@@ -97,6 +95,68 @@ void error_unknown_switch(char chu, char *s)
     //exit(1);
 }
 
+BOOL PerformRegAction(REGEDIT_ACTION action, LPSTR s)
+{
+    TCHAR filename[MAX_PATH];
+    TCHAR reg_key_name[KEY_MAX_LEN];
+
+    switch (action) {
+    case ACTION_ADD:
+        get_file_name(&s, filename, MAX_PATH);
+        if (!filename[0]) {
+            printf("No file name is specified\n%s", usage);
+            return FALSE;
+            //exit(1);
+        }
+        while (filename[0]) {
+            if (!import_registry_file(filename)) {
+                perror("");
+                printf("Can't open file \"%s\"\n", filename);
+                return FALSE;
+                //exit(1);
+            }
+            get_file_name(&s, filename, MAX_PATH);
+        }
+        break;
+    case ACTION_DELETE:
+        get_file_name(&s, reg_key_name, KEY_MAX_LEN);
+        if (!reg_key_name[0]) {
+            printf("No registry key is specified for removal\n%s", usage);
+            return FALSE;
+            //exit(1);
+        }
+        delete_registry_key(reg_key_name);
+        break;
+    case ACTION_EXPORT:
+        filename[0] = '\0';
+        get_file_name(&s, filename, MAX_PATH);
+        if (!filename[0]) {
+            printf("No file name is specified\n%s", usage);
+            return FALSE;
+            //exit(1);
+        }
+        if (s[0]) {
+            get_file_name(&s, reg_key_name, KEY_MAX_LEN);
+            export_registry_key(filename, reg_key_name);
+        } else {
+            export_registry_key(filename, NULL);
+        }
+        break;
+    case ACTION_PRINT:
+        if (s[0]) {
+            get_file_name(&s, reg_key_name, KEY_MAX_LEN);
+            export_registry_key(NULL, reg_key_name);
+        } else {
+            export_registry_key(NULL, NULL);
+        }
+        break;
+    default:
+        printf("Unhandled action!\n");
+        return FALSE;
+    }
+    return TRUE;
+}
+
 BOOL ProcessCmdLine(LPSTR lpCmdLine)
 {
     REGEDIT_ACTION action = ACTION_UNDEF;
@@ -122,6 +182,9 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
                 case 'E':
                     action = ACTION_EXPORT;
                     break;
+                case 'P':
+                    action = ACTION_PRINT;
+                    break;
                 case '?':
                     printf(usage);
                     return FALSE;
@@ -166,66 +229,5 @@ BOOL ProcessCmdLine(LPSTR lpCmdLine)
     if (action == ACTION_UNDEF) {
         action = ACTION_ADD;
     }
-
-    switch (action) {
-    case ACTION_ADD:
-    {
-        TCHAR filename[MAX_PATH];
-        FILE *reg_file;
-        get_file_name(&s, filename, MAX_PATH);
-        if (!filename[0]) {
-            printf("No file name is specified\n%s", usage);
-            return FALSE;
-            //exit(1);
-        }
-        while (filename[0]) {
-            reg_file = _tfopen(filename, _T("r"));
-            if (reg_file) {
-                processRegLines(reg_file, doSetValue);
-            } else {
-                perror("");
-                printf("Can't open file \"%s\"\n", filename);
-                return FALSE;
-                //exit(1);
-            }
-            get_file_name(&s, filename, MAX_PATH);
-        }
-        break;
-    }
-    case ACTION_DELETE:
-    {
-        TCHAR reg_key_name[KEY_MAX_LEN];
-        get_file_name(&s, reg_key_name, KEY_MAX_LEN);
-        if (!reg_key_name[0]) {
-            printf("No registry key is specified for removal\n%s", usage);
-            return FALSE;
-            //exit(1);
-        }
-        delete_registry_key(reg_key_name);
-        break;
-    }
-    case ACTION_EXPORT:
-    {
-        TCHAR filename[MAX_PATH];
-        filename[0] = '\0';
-        get_file_name(&s, filename, MAX_PATH);
-        if (!filename[0]) {
-            printf("No file name is specified\n%s", usage);
-            return FALSE;
-            //exit(1);
-        }
-        if (s[0]) {
-            TCHAR reg_key_name[KEY_MAX_LEN];
-            get_file_name(&s, reg_key_name, KEY_MAX_LEN);
-            export_registry_key(filename, reg_key_name);
-        } else {
-            export_registry_key(filename, NULL);
-        }
-        break;
-    }
-    default:
-        printf("Unhandled action!\n");
-        return FALSE;
-    }
-    return TRUE;
+    return PerformRegAction(action, s);
 }
index a2e5391..8f20c33 100644 (file)
@@ -1,6 +1,5 @@
-#include <windows.h>
-#include <reactos/resource.h>
-
+//Microsoft Developer Studio generated resource script.
+//
 #include "resource.h"
 
 #define APSTUDIO_READONLY_SYMBOLS
@@ -66,9 +65,9 @@ BEGIN
     POPUP "&Registry"
     BEGIN
         MENUITEM "&Import Registry File...",    ID_REGISTRY_IMPORTREGISTRYFILE
-        , GRAYED
+
         MENUITEM "&Export Registry File...",    ID_REGISTRY_EXPORTREGISTRYFILE
-        , GRAYED
+
         MENUITEM SEPARATOR
         MENUITEM "&Connect Network Registry...", 
                                                 ID_REGISTRY_CONNECTNETWORKREGISTRY
@@ -168,14 +167,15 @@ END
 #endif    // APSTUDIO_INVOKED
 
 
+#ifndef _MAC
 /////////////////////////////////////////////////////////////////////////////
 //
 // Version
 //
 
-VS_VERSION_INFO VERSIONINFO
-       FILEVERSION     RES_UINT_FV_MAJOR,RES_UINT_FV_MINOR,RES_UINT_FV_REVISION,RES_UINT_FV_BUILD
-       PRODUCTVERSION  RES_UINT_PV_MAJOR,RES_UINT_PV_MINOR,RES_UINT_PV_REVISION,RES_UINT_PV_BUILD
+(1) VERSIONINFO
+ FILEVERSION 0,0,21,3
+ PRODUCTVERSION 0,0,21,0
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -191,7 +191,7 @@ BEGIN
         BLOCK "040904b0"
         BEGIN
             VALUE "Comments", "Absolutely no warranties whatsoever - Use at your own risk\0"
-            VALUE "CompanyName", RES_STR_COMPANY_NAME
+            VALUE "CompanyName", "ReactOS Development Team\0"
             VALUE "FileDescription", "ReactOS Registry Editor by Robert Dickenson\0"
             VALUE "FileVersion", "1, 0, 0, 1\0"
             VALUE "InternalName", "regedit\0"
@@ -199,8 +199,8 @@ BEGIN
             VALUE "LegalTrademarks", "\0"
             VALUE "OriginalFilename", "regedit.exe\0"
             VALUE "PrivateBuild", "\0"
-            VALUE "ProductName",       RES_STR_PRODUCT_NAME
-            VALUE "ProductVersion",    RES_STR_PRODUCT_VERSION
+            VALUE "ProductName", "ReactOS Operating System\0"
+            VALUE "ProductVersion", "0.0.21\0"
             VALUE "SpecialBuild", "Non-versioned Development Beta Release\0"
         END
     END
@@ -210,6 +210,8 @@ BEGIN
     END
 END
 
+#endif    // !_MAC
+
 
 /////////////////////////////////////////////////////////////////////////////
 //
@@ -255,13 +257,13 @@ BEGIN
     ID_REGISTRY_DISCONNECTNETWORKREGISTRY 
                             "Disconnects from a remote computer's registry"
     ID_REGISTRY_PRINT       "Prints all or part of the registry"
+    ID_HELP_HELPTOPICS      "Opens registry editor help"
     ID_HELP_ABOUT           "Displays program information, version number and copyright"
 END
 
 STRINGTABLE DISCARDABLE 
 BEGIN
     ID_REGISTRY_EXIT        "Quits the registry editor"
-    ID_HELP_HELPTOPICS      "Opens registry editor help"
     ID_FAVOURITES_ADDTOFAVOURITES "Adds keys to the favourites list"
     ID_FAVOURITES_REMOVEFAVOURITE "Removes keys from the favourites list"
     ID_VIEW_STATUSBAR       "Shows or hides the status bar"
@@ -292,13 +294,20 @@ LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_AUS
 // Dialog
 //
 
-IDD_DIALOG1 DIALOG DISCARDABLE  0, 0, 186, 95
+IDD_DIALOG1 DIALOG DISCARDABLE  50, 50, 268, 98
+STYLE DS_3DLOOK | DS_CONTROL | WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | 
+    WS_BORDER
+FONT 8, "MS Sans Serif"
+BEGIN
+END
+
+IDD_DIALOG2 DIALOG DISCARDABLE  0, 0, 187, 95
 STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
 CAPTION "Dialog"
 FONT 8, "MS Sans Serif"
 BEGIN
-    DEFPUSHBUTTON   "OK",IDOK,129,7,50,14
-    PUSHBUTTON      "Cancel",IDCANCEL,129,24,50,14
+    DEFPUSHBUTTON   "OK",IDOK,130,7,50,14
+    PUSHBUTTON      "Cancel",IDCANCEL,130,24,50,14
 END
 
 
@@ -327,7 +336,15 @@ BEGIN
     IDD_DIALOG1, DIALOG
     BEGIN
         LEFTMARGIN, 7
-        RIGHTMARGIN, 179
+        RIGHTMARGIN, 261
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 91
+    END
+
+    IDD_DIALOG2, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 180
         TOPMARGIN, 7
         BOTTOMMARGIN, 88
     END
index 312e282..0544841 100644 (file)
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifdef WIN32_REGDBG
+#include <windows.h>
+#include <tchar.h>
+#ifndef __GNUC__
+#include <ntsecapi.h>
+#else
+#include <ctype.h>
+#endif
+#include <limits.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <assert.h>
+//#include <winreg.h>
+#include "regdump.h"
+#else
+
 #define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers
 #include <windows.h>
 #include <commctrl.h>
 #include <stdlib.h>
-#include <malloc.h>
-#include <memory.h>
 #include <tchar.h>
 #include <process.h>
 #include <stdio.h>
+#include <wchar.h>
     
 #include <ctype.h>
 #include <limits.h>
 #include <winreg.h>
 #include <assert.h>
 
+#endif
+
 #include "regproc.h"
+#include "dbg.h"
 
+#ifdef WIN32_REGDBG
+#define HeapAlloc RegHeapAlloc
+#define HeapReAlloc RegHeapReAlloc
+#define HeapFree RegHeapFree
+#endif /*WIN32_REGDBG*/
 
 #define REG_VAL_BUF_SIZE        4096
 
 #define REG_FILE_HEX_LINE_LEN   76
 
 /* Globals used by the api setValue, queryValue */
-static LPSTR currentKeyName   = NULL;
+static LPTSTR currentKeyName   = NULL;
 static HKEY  currentKeyClass  = 0;
 static HKEY  currentKeyHandle = 0;
 static BOOL  bTheKeyIsOpen    = FALSE;
 
-static CHAR *app_name = "UNKNOWN";
-
-static CHAR *reg_class_names[] = {
-    "HKEY_LOCAL_MACHINE", "HKEY_USERS", "HKEY_CLASSES_ROOT",
-    "HKEY_CURRENT_CONFIG", "HKEY_CURRENT_USER"
+static TCHAR *reg_class_names[] = {
+    _T("HKEY_LOCAL_MACHINE"),
+    _T("HKEY_USERS"),
+    _T("HKEY_CLASSES_ROOT"),
+    _T("HKEY_CURRENT_CONFIG"),
+    _T("HKEY_CURRENT_USER")
 };
 
 #define REG_CLASS_NUMBER (sizeof(reg_class_names) / sizeof(reg_class_names[0]))
@@ -75,13 +99,29 @@ static HKEY reg_class_keys[REG_CLASS_NUMBER] = {
 /* processing macros */
 
 /* common check of memory allocation results */
+#ifdef UNICODE
 #define CHECK_ENOUGH_MEMORY(p) \
     if (!(p)) \
     { \
-        printf("%s: file %s, line %d: Not enough memory", \
-               getAppName(), __FILE__, __LINE__); \
+        _tprintf(_T("file %S, line %d: Not enough memory"), __FILE__, __LINE__); \
+        assert(0);\
         exit(NOT_ENOUGH_MEMORY); \
     }
+#else
+#define CHECK_ENOUGH_MEMORY(p) \
+    if (!(p)) \
+    { \
+        _tprintf(_T("file %s, line %d: Not enough memory"), __FILE__, __LINE__); \
+        assert(0);\
+        exit(NOT_ENOUGH_MEMORY); \
+    }
+#endif
+
+#ifdef UNICODE
+#define _TEOF WEOF 
+#else
+#define _TEOF EOF 
+#endif
 
 /******************************************************************************
  * This is a replacement for strsep which is not portable (missing on Solaris).
@@ -123,7 +163,7 @@ char* getToken(char** str, const char* delims)
  *      where *s[0] is the first symbol of the file name.
  * file_name - buffer to write the file name to.
  */
-void get_file_name(CHAR **command_line, CHAR *file_name)
+void get_file_nameA(CHAR **command_line, CHAR *file_name, int max_filename)
 {
     CHAR *s = *command_line;
     int pos = 0;                /* position of pointer "s" in *command_line */
@@ -137,8 +177,9 @@ void get_file_name(CHAR **command_line, CHAR *file_name)
         (*command_line)++;
         while (s[0] != '"') {
             if (!s[0]) {
-                printf("%s: Unexpected end of file name!\n", getAppName());
-                exit(1);
+                _tprintf(_T("Unexpected end of file name!\n"));
+                assert(0);
+                //exit(1);
             }
             s++;
             pos++;
@@ -167,18 +208,40 @@ void get_file_name(CHAR **command_line, CHAR *file_name)
     (*command_line) += pos;
 }
 
+void get_file_nameW(CHAR** command_line, WCHAR* filename, int max_filename)
+{
+    CHAR filenameA[_MAX_PATH];
+    int len;
+
+    get_file_nameA(command_line, filenameA, _MAX_PATH);
+    len = strlen(filenameA);
+    OemToCharBuffW(filenameA, filename, max_filename);
+    filename[len] = _T('\0');
+/*
+    UNICODE_STRING UnicodeString;
+    ANSI_STRING AnsiString;
+    CHAR filenameA[_MAX_PATH];
+
+    get_file_nameA(command_line, filenameA, _MAX_PATH);
+
+    //RtlInitAnsiString(&AnsiString, filenameA);
+    UnicodeString.Buffer = filename;
+    UnicodeString.MaximumLength = max_filename;//MAX_PATH;
+    RtlAnsiStringToUnicodeString(&UnicodeString, &AnsiString, FALSE);
+ */
+}
 
 /******************************************************************************
  * Converts a hex representation of a DWORD into a DWORD.
  */
-DWORD convertHexToDWord(char* str, BYTE* buf)
+DWORD convertHexToDWord(TCHAR* str, BYTE* buf)
 {
     DWORD dw;
-    char xbuf[9];
+    TCHAR xbuf[9];
 
-    memcpy(xbuf, str, 8);
-    xbuf[8] = '\0';
-    sscanf(xbuf, "%08lx", &dw);
+    memcpy(xbuf, str, 8 * sizeof(TCHAR));
+    xbuf[88 * sizeof(TCHAR)] = '\0';
+    _stscanf(xbuf, _T("%08lx"), &dw);
     memcpy(buf, &dw, sizeof(DWORD));
     return sizeof(DWORD);
 }
@@ -186,41 +249,41 @@ DWORD convertHexToDWord(char* str, BYTE* buf)
 /******************************************************************************
  * Converts a hex buffer into a hex comma separated values
  */
-char* convertHexToHexCSV(BYTE* buf, ULONG bufLen)
+TCHAR* convertHexToHexCSV(BYTE* buf, ULONG bufLen)
 {
-    char* str;
-    char* ptrStr;
+    TCHAR* str;
+    TCHAR* ptrStr;
     BYTE* ptrBuf;
 
     ULONG current = 0;
-    str = HeapAlloc(GetProcessHeap(), 0, (bufLen+1)*2);
+    str = HeapAlloc(GetProcessHeap(), 0, (bufLen+1)*2*sizeof(TCHAR));
     memset(str, 0, (bufLen+1)*2);
     ptrStr = str;  /* Pointer to result  */
     ptrBuf = buf;  /* Pointer to current */
     while (current < bufLen) {
         BYTE bCur = ptrBuf[current++];
-        char res[3];
-        sprintf(res, "%02x", (unsigned int)*&bCur);
-        strcat(str, res);
-        strcat(str, ",");
+        TCHAR res[3];
+        _stprintf(res, _T("%02x"), (unsigned int)*&bCur);
+        _tcscat(str, res);
+        _tcscat(str, _T(","));
     }
     /* Get rid of the last comma */
-    str[strlen(str)-1] = '\0';
+    str[_tcslen(str)-1] = _T('\0');
     return str;
 }
 
 /******************************************************************************
  * Converts a hex buffer into a DWORD string
  */
-char* convertHexToDWORDStr(BYTE* buf, ULONG bufLen)
+TCHAR* convertHexToDWORDStr(BYTE* buf, ULONG bufLen)
 {
-    char* str;
+    TCHAR* str;
     DWORD dw;
 
     if (bufLen != sizeof(DWORD)) return NULL;
-    str = HeapAlloc(GetProcessHeap(), 0, (bufLen*2)+1);
+    str = HeapAlloc(GetProcessHeap(), 0, ((bufLen*2)+1)*sizeof(TCHAR));
     memcpy(&dw, buf, sizeof(DWORD));
-    sprintf(str, "%08lx", dw);
+    _stprintf(str, _T("%08lx"), dw);
     /* Get rid of the last comma */
     return str;
 }
@@ -229,11 +292,11 @@ char* convertHexToDWORDStr(BYTE* buf, ULONG bufLen)
  * Converts a hex comma separated values list into a hex list.
  * The Hex input string must be in exactly the correct form.
  */
-DWORD convertHexCSVToHex(char* str, BYTE* buf, ULONG bufLen)
+DWORD convertHexCSVToHex(TCHAR* str, BYTE* buf, ULONG bufLen)
 {
-    char* s = str;  /* Pointer to current */
-    char* b = buf;  /* Pointer to result  */
-    ULONG strLen    = strlen(str);
+    TCHAR* s = str;  /* Pointer to current */
+    CHAR* b = buf;  /* Pointer to result  */
+    ULONG strLen    = _tcslen(str);
     ULONG strPos    = 0;
     DWORD byteCount = 0;
 
@@ -242,17 +305,19 @@ DWORD convertHexCSVToHex(char* str, BYTE* buf, ULONG bufLen)
      * warn the user if we are here with a string longer than 2 bytes that does
      * not contains ",".  It is more likely because the data is invalid.
      */
-    if ((strLen > 2) && (strchr(str, ',') == NULL))
-        printf("%s: WARNING converting CSV hex stream with no comma, "
-               "input data seems invalid.\n", getAppName());
-    if (strLen > 3*bufLen)
-        printf ("%s: ERROR converting CSV hex stream.  Too long\n", getAppName());
+    if ((strLen > 2) && (_tcschr(str, _T(',')) == NULL)) {
+        _tprintf(_T("WARNING converting CSV hex stream with no comma, ") \
+                 _T("input data seems invalid.\n"));
+    }
+    if (strLen > 3*bufLen) {
+        _tprintf(_T("ERROR converting CSV hex stream.  Too long\n"));
+    }
     while (strPos < strLen) {
-        char xbuf[3];
-        char wc;
+        TCHAR xbuf[3];
+        TCHAR wc;
         memcpy(xbuf, s, 2);
-        xbuf[3] = '\0';
-        sscanf(xbuf, "%02x", (UINT*)&wc);
+        xbuf[3] = _T('\0');
+        _stscanf(xbuf, _T("%02x"), (UINT*)&wc);
         if (byteCount < bufLen)
             *b++ = (unsigned char)wc;
         s += 3;
@@ -269,19 +334,20 @@ DWORD convertHexCSVToHex(char* str, BYTE* buf, ULONG bufLen)
  *
  * Note: Updated based on the algorithm used in 'server/registry.c'
  */
-DWORD getDataType(LPSTR* lpValue, DWORD* parse_type)
+DWORD getDataType(LPTSTR* lpValue, DWORD* parse_type)
 {
-    struct data_type { const char *tag; int len; int type; int parse_type; };
+    struct data_type { const TCHAR *tag; int len; int type; int parse_type; };
 
     static const struct data_type data_types[] =
     {                   /* actual type */  /* type to assume for parsing */
-        { "\"",        1,   REG_SZ,              REG_SZ },
-        { "str:\"",    5,   REG_SZ,              REG_SZ },
-        { "str(2):\"", 8,   REG_EXPAND_SZ,       REG_SZ },
-        { "hex:",      4,   REG_BINARY,          REG_BINARY },
-        { "dword:",    6,   REG_DWORD,           REG_DWORD },
-        { "hex(",      4,   -1,                  REG_BINARY },
-        { NULL,        0,    0,                  0 }
+        { _T("\""),        1,   REG_SZ,              REG_SZ },
+        { _T("str:\""),    5,   REG_SZ,              REG_SZ },
+//        { _T("str(2):\""), 8,   REG_EXPAND_SZ,       REG_SZ },
+        { _T("expand:\""), 8,   REG_EXPAND_SZ,       REG_EXPAND_SZ },
+        { _T("hex:"),      4,   REG_BINARY,          REG_BINARY },
+        { _T("dword:"),    6,   REG_DWORD,           REG_DWORD },
+        { _T("hex("),      4,   -1,                  REG_BINARY },
+        { NULL,            0,    0,                  0 }
     };
 
     const struct data_type *ptr;
@@ -296,10 +362,10 @@ DWORD getDataType(LPSTR* lpValue, DWORD* parse_type)
         type = ptr->type;
         *lpValue += ptr->len;
         if (type == -1) {
-            char* end;
+            TCHAR* end;
             /* "hex(xx):" is special */
-            type = (int)strtoul(*lpValue , &end, 16);
-            if (**lpValue=='\0' || *end!=')' || *(end+1)!=':') {
+            type = (int)_tcstoul(*lpValue , &end, 16);
+            if (**lpValue == _T('\0') || *end != _T(')') || *(end+1) != _T(':')) {
                 type = REG_NONE;
             } else {
                 *lpValue = end + 2;
@@ -307,50 +373,50 @@ DWORD getDataType(LPSTR* lpValue, DWORD* parse_type)
         }
         return type;
     }
-    return (**lpValue == '\0'?REG_SZ:REG_NONE);
+    return (**lpValue == _T('\0') ? REG_SZ : REG_NONE);
 }
 
 /******************************************************************************
  * Returns an allocated buffer with a cleaned copy (removed the surrounding
  * dbl quotes) of the passed value.
  */
-LPSTR getArg( LPSTR arg)
+LPTSTR getArg(LPTSTR arg)
 {
-  LPSTR tmp = NULL;
+  LPTSTR tmp = NULL;
   ULONG len;
 
   if (arg == NULL) return NULL;
 
   // Get rid of surrounding quotes
-  len = strlen(arg);
-  if (arg[len-1] == '\"') arg[len-1] = '\0';
-  if (arg[0]     == '\"') arg++;
-  tmp = HeapAlloc(GetProcessHeap(), 0, strlen(arg)+1);
-  strcpy(tmp, arg);
+  len = _tcslen(arg);
+  if (arg[len-1] == _T('\"')) arg[len-1] = _T('\0');
+  if (arg[0]     == _T('\"')) arg++;
+  tmp = HeapAlloc(GetProcessHeap(), 0, (_tcslen(arg)+1) * sizeof(TCHAR));
+  _tcscpy(tmp, arg);
   return tmp;
 }
 
 /******************************************************************************
  * Replaces escape sequences with the characters.
  */
-void REGPROC_unescape_string(LPSTR str)
+void REGPROC_unescape_string(LPTSTR str)
 {
     int str_idx = 0;            /* current character under analysis */
     int val_idx = 0;            /* the last character of the unescaped string */
-    int len = strlen(str);
+    int len = _tcslen(str);
     for (str_idx = 0; str_idx < len; str_idx++, val_idx++) {
-        if (str[str_idx] == '\\') {
+        if (str[str_idx] == _T('\\')) {
             str_idx++;
             switch (str[str_idx]) {
-            case 'n':
-                str[val_idx] = '\n';
+            case _T('n'):
+                str[val_idx] = _T('\n');
                 break;
-            case '\\':
-            case '"':
+            case _T('\\'):
+            case _T('"'):
                 str[val_idx] = str[str_idx];
                 break;
             default:
-                printf("Warning! Unrecognized escape sequence: \\%c'\n", str[str_idx]);
+                _tprintf(_T("Warning! Unrecognized escape sequence: \\%c'\n"), str[str_idx]);
                 str[val_idx] = str[str_idx];
                 break;
             }
@@ -358,7 +424,7 @@ void REGPROC_unescape_string(LPSTR str)
             str[val_idx] = str[str_idx];
         }
     }
-    str[val_idx] = '\0';
+    str[val_idx] = _T('\0');
 }
 
 /******************************************************************************
@@ -369,7 +435,7 @@ void REGPROC_unescape_string(LPSTR str)
  * val_name - name of the registry value
  * val_data - registry value data
  */
-HRESULT setValue(LPSTR val_name, LPSTR val_data)
+HRESULT setValue(LPTSTR val_name, LPTSTR val_data)
 {
   HRESULT hRes;
   DWORD   dwDataType, dwParseType;
@@ -384,22 +450,30 @@ HRESULT setValue(LPSTR val_name, LPSTR val_data)
   /* Get the data type stored into the value field */
   dwDataType = getDataType(&val_data, &dwParseType);
 
+//  if (dwParseType == REG_EXPAND_SZ) {
+//  }
+//  if (dwParseType == REG_SZ || dwParseType == REG_EXPAND_SZ) { /* no conversion for string */
+
   if (dwParseType == REG_SZ) {       /* no conversion for string */
-    dwLen = strlen(val_data);
-    if (dwLen>0 && val_data[dwLen-1]=='"') {
+    dwLen = _tcslen(val_data);
+    if (dwLen > 0 && val_data[dwLen-1] == _T('"')) {
       dwLen--;
-      val_data[dwLen]='\0';
+      val_data[dwLen] = _T('\0');
     }
     dwLen++;
+    dwLen *= sizeof(TCHAR);
     REGPROC_unescape_string(val_data);
     lpbData = val_data;
   } else if (dwParseType == REG_DWORD) { /* Convert the dword types */
     dwLen   = convertHexToDWord(val_data, convert);
     lpbData = convert;
   } else {                               /* Convert the hexadecimal types */
-    int b_len = strlen (val_data)+2/3;
+    int b_len = _tcslen(val_data)+2/3;
     if (b_len > KEY_MAX_LEN) {
-      bBigBuffer = HeapAlloc (GetProcessHeap(), 0, b_len);
+      bBigBuffer = HeapAlloc(GetProcessHeap(), 0, b_len * sizeof(TCHAR));
+      if (bBigBuffer == NULL) {
+          return ERROR_REGISTRY_IO_FAILED;
+      }
       CHECK_ENOUGH_MEMORY(bBigBuffer);
       dwLen = convertHexCSVToHex(val_data, bBigBuffer, b_len);
       lpbData = bBigBuffer;
@@ -408,9 +482,12 @@ HRESULT setValue(LPSTR val_name, LPSTR val_data)
       lpbData = convert;
     }
   }
-  hRes = RegSetValueExA(currentKeyHandle, val_name,
+  hRes = RegSetValueEx(currentKeyHandle, val_name,
           0, /* Reserved */dwDataType, lpbData, dwLen);
 
+    //_tprintf(_T("  Value: %s, Data: %s\n"), val_name, lpbData);
+
+
   if (bBigBuffer)
       HeapFree(GetProcessHeap(), 0, bBigBuffer);
   return hRes;
@@ -420,7 +497,7 @@ HRESULT setValue(LPSTR val_name, LPSTR val_data)
 /******************************************************************************
  * Open the key
  */
-HRESULT openKey( LPSTR stdInput)
+HRESULT openKey(LPTSTR stdInput)
 {
   DWORD   dwDisp;
   HRESULT hRes;
@@ -439,7 +516,7 @@ HRESULT openKey( LPSTR stdInput)
   if (currentKeyName == NULL)
     return ERROR_INVALID_PARAMETER;
 
-  hRes = RegCreateKeyExA(
+  hRes = RegCreateKeyEx(
           currentKeyClass,          /* Class     */
           currentKeyName,           /* Sub Key   */
           0,                        /* MUST BE 0 */
@@ -462,65 +539,65 @@ HRESULT openKey( LPSTR stdInput)
  * Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line
  * the key name (what starts after the first '\')
  */
-LPSTR getRegKeyName(LPSTR lpLine)
+LPTSTR getRegKeyName(LPTSTR lpLine)
 {
-  LPSTR keyNameBeg;
-  char  lpLineCopy[KEY_MAX_LEN];
+  LPTSTR keyNameBeg;
+  TCHAR  lpLineCopy[KEY_MAX_LEN];
 
   if (lpLine == NULL)
     return NULL;
 
-  strcpy(lpLineCopy, lpLine);
-  keyNameBeg = strchr(lpLineCopy, '\\');    /* The key name start by '\' */
+  _tcscpy(lpLineCopy, lpLine);
+  keyNameBeg = _tcschr(lpLineCopy, _T('\\'));    /* The key name start by '\' */
   if (keyNameBeg) {
-      LPSTR keyNameEnd;
+      LPTSTR keyNameEnd;
 
       keyNameBeg++;                             /* is not part of the name */
-      keyNameEnd = strchr(lpLineCopy, ']');
+      keyNameEnd = _tcschr(lpLineCopy, _T(']'));
       if (keyNameEnd) {
-          *keyNameEnd = '\0';               /* remove ']' from the key name */
+          *keyNameEnd = _T('\0');               /* remove ']' from the key name */
       }
   } else {
-      keyNameBeg = lpLineCopy + strlen(lpLineCopy); /* branch - empty string */
+      keyNameBeg = lpLineCopy + _tcslen(lpLineCopy); /* branch - empty string */
   }
-  currentKeyName = HeapAlloc(GetProcessHeap(), 0, strlen(keyNameBeg) + 1);
+  currentKeyName = HeapAlloc(GetProcessHeap(), 0, (_tcslen(keyNameBeg)+1)*sizeof(TCHAR));
   CHECK_ENOUGH_MEMORY(currentKeyName);
-  strcpy(currentKeyName, keyNameBeg);
-   return currentKeyName;
+  _tcscpy(currentKeyName, keyNameBeg);
+  return currentKeyName;
 }
 
 /******************************************************************************
  * Extracts from [HKEY\some\key\path] or HKEY\some\key\path types of line
  * the key class (what ends before the first '\')
  */
-HKEY getRegClass(LPSTR lpClass)
+HKEY getRegClass(LPTSTR lpClass)
 {
-  LPSTR classNameEnd;
-  LPSTR classNameBeg;
+  LPTSTR classNameEnd;
+  LPTSTR classNameBeg;
   int i;
 
-  char  lpClassCopy[KEY_MAX_LEN];
+  TCHAR lpClassCopy[KEY_MAX_LEN];
 
   if (lpClass == NULL)
     return (HKEY)ERROR_INVALID_PARAMETER;
 
-  strncpy(lpClassCopy, lpClass, KEY_MAX_LEN);
+  _tcsncpy(lpClassCopy, lpClass, KEY_MAX_LEN);
 
-  classNameEnd  = strchr(lpClassCopy, '\\');    /* The class name ends by '\' */
+  classNameEnd  = _tcschr(lpClassCopy, _T('\\'));    /* The class name ends by '\' */
   if (!classNameEnd) {                          /* or the whole string */
-      classNameEnd = lpClassCopy + strlen(lpClassCopy);
-      if (classNameEnd[-1] == ']') {
+      classNameEnd = lpClassCopy + _tcslen(lpClassCopy);
+      if (classNameEnd[-1] == _T(']')) {
           classNameEnd--;
       }
   }
-  *classNameEnd = '\0';                       /* Isolate the class name */
-  if (lpClassCopy[0] == '[') {
+  *classNameEnd = _T('\0');                       /* Isolate the class name */
+  if (lpClassCopy[0] == _T('[')) {
       classNameBeg = lpClassCopy + 1;
   } else {
       classNameBeg = lpClassCopy;
   }
   for (i = 0; i < REG_CLASS_NUMBER; i++) {
-      if (!strcmp(classNameBeg, reg_class_names[i])) {
+      if (!_tcscmp(classNameBeg, reg_class_names[i])) {
           return reg_class_keys[i];
       }
   }
@@ -545,10 +622,10 @@ void closeKey(VOID)
  * receives the currently read line and dispatch the work depending on the
  * context.
  */
-void doSetValue(LPSTR stdInput)
+void doSetValue(LPTSTR stdInput)
 {
   /*
-   * We encoutered the end of the file, make sure we
+   * We encountered the end of the file, make sure we
    * close the opened key and exit
    */
   if (stdInput == NULL) {
@@ -557,14 +634,16 @@ void doSetValue(LPSTR stdInput)
     return;
   }
 
-  if ( stdInput[0] == '[') {     /* We are reading a new key */
-    if ( bTheKeyIsOpen != FALSE )
-      closeKey();                    /* Close the previous key before */
-    if ( openKey(stdInput) != ERROR_SUCCESS )
-      printf ("%s: doSetValue failed to open key %s\n", getAppName(), stdInput);
-  } else if (( bTheKeyIsOpen ) &&
-            (( stdInput[0] == '@') || /* reading a default @=data pair */
-             ( stdInput[0] == '\"'))) { /* reading a new value=data pair */
+  if (stdInput[0] == _T('[')) {     /* We are reading a new key */
+      if (bTheKeyIsOpen != FALSE) {
+          closeKey();                    /* Close the previous key before */
+      }
+      if (openKey(stdInput) != ERROR_SUCCESS) {
+          _tprintf(_T("doSetValue failed to open key %s\n"), stdInput);
+      }
+  } else if ((bTheKeyIsOpen) &&
+            ((stdInput[0] == _T('@')) || /* reading a default @=data pair */
+             (stdInput[0] == _T('\"')))) { /* reading a new value=data pair */
     processSetValue(stdInput);
   } else {             /* since we are assuming that the file format is */
     if (bTheKeyIsOpen) /* valid we must be reading a blank line which  */
@@ -577,7 +656,7 @@ void doSetValue(LPSTR stdInput)
  * receives the currently read line and dispatch the work depending on the
  * context.
  */
-void doQueryValue(LPSTR stdInput) {
+void doQueryValue(LPTSTR stdInput) {
   /*
    * We encoutered the end of the file, make sure we
    * close the opened key and exit
@@ -588,18 +667,19 @@ void doQueryValue(LPSTR stdInput) {
     return;
   }
 
-  if (stdInput[0] == '[') {     /* We are reading a new key */
-    if ( bTheKeyIsOpen != FALSE )
+  if (stdInput[0] == _T('[')) {     /* We are reading a new key */
+    if (bTheKeyIsOpen != FALSE)
       closeKey();                    /* Close the previous key before */
-    if ( openKey(stdInput) != ERROR_SUCCESS )
-      printf ("%s: doSetValue failed to open key %s\n", getAppName(), stdInput);
+    if (openKey(stdInput) != ERROR_SUCCESS ) {
+      _tprintf(_T("doQueryValue failed to open key %s\n"), stdInput);
+    }
   }
-  else if( ( bTheKeyIsOpen ) &&
-           (( stdInput[0] == '@') || /* reading a default @=data pair */
-           ( stdInput[0] == '\"'))) { /* reading a new value=data pair */
+  else if( (bTheKeyIsOpen) &&
+           ((stdInput[0] == _T('@')) || /* reading a default @=data pair */
+           (stdInput[0] == _T('\"')))) { /* reading a new value=data pair */
     processQueryValue(stdInput);
   } else {                /* since we are assuming that the file format is */
-    if ( bTheKeyIsOpen )  /* valid we must be reading a blank line which  */
+    if (bTheKeyIsOpen)    /* valid we must be reading a blank line which  */
       closeKey();         /* indicate end of this key processing */
   }
 }
@@ -609,8 +689,8 @@ void doQueryValue(LPSTR stdInput) {
  * receives the currently read line and dispatch the work depending on the
  * context.
  */
-void doDeleteValue(LPSTR line) {
-  printf ("%s: deleteValue not yet implemented\n", getAppName());
+void doDeleteValue(LPTSTR line) {
+  _tprintf(_T("deleteValue not yet implemented\n"));
 }
 
 /******************************************************************************
@@ -618,8 +698,8 @@ void doDeleteValue(LPSTR line) {
  * receives the currently read line and dispatch the work depending on the
  * context.
  */
-void doDeleteKey(LPSTR line)   {
-  printf ("%s: deleteKey not yet implemented\n", getAppName());
+void doDeleteKey(LPTSTR line)   {
+  _tprintf(_T("deleteKey not yet implemented\n"));
 }
 
 /******************************************************************************
@@ -627,8 +707,8 @@ void doDeleteKey(LPSTR line)   {
  * receives the currently read line and dispatch the work depending on the
  * context.
  */
-void doCreateKey(LPSTR line)   {
-  printf ("%s: createKey not yet implemented\n", getAppName());
+void doCreateKey(LPTSTR line)   {
+  _tprintf(_T("createKey not yet implemented\n"));
 }
 
 /******************************************************************************
@@ -639,28 +719,28 @@ void doCreateKey(LPSTR line)   {
  * line - registry file unwrapped line. Should have the registry value name and
  *      complete registry value data.
  */
-void processSetValue(LPSTR line)
+void processSetValue(LPTSTR line)
 {
-  LPSTR val_name;                   /* registry value name   */
-  LPSTR val_data;                   /* registry value data   */
+  LPTSTR val_name;                   /* registry value name   */
+  LPTSTR val_data;                   /* registry value data   */
 
   int line_idx = 0;                 /* current character under analysis */
   HRESULT hRes = 0;
 
   /* get value name */
-  if (line[line_idx] == '@' && line[line_idx + 1] == '=') {
-      line[line_idx] = '\0';
+  if (line[line_idx] == _T('@') && line[line_idx + 1] == _T('=')) {
+      line[line_idx] = _T('\0');
       val_name = line;
       line_idx++;
-  } else if (line[line_idx] == '\"') {
+  } else if (line[line_idx] == _T('\"')) {
       line_idx++;
       val_name = line + line_idx;
       while (TRUE) {
-          if (line[line_idx] == '\\') {  /* skip escaped character */
+          if (line[line_idx] == _T('\\')) {  /* skip escaped character */
               line_idx += 2;
           } else {
-              if (line[line_idx] == '\"') {
-                  line[line_idx] = '\0';
+              if (line[line_idx] == _T('\"')) {
+                  line[line_idx] = _T('\0');
                   line_idx++;
                   break;
               } else {
@@ -668,32 +748,36 @@ void processSetValue(LPSTR line)
               }
           }
       }
-      if (line[line_idx] != '=') {
-          line[line_idx] = '\"';
-          printf("Warning! uncrecognized line:\n%s\n", line);
+      if (line[line_idx] != _T('=')) {
+          line[line_idx] = _T('\"');
+          _tprintf(_T("Warning! uncrecognized line:\n%s\n"), line);
           return;
       }
   } else {
-      printf("Warning! uncrecognized line:\n%s\n", line);
+      _tprintf(_T("Warning! unrecognized line:\n%s\n"), line);
       return;
   }
   line_idx++;                   /* skip the '=' character */
   val_data = line + line_idx;
   REGPROC_unescape_string(val_name);
+
+    _tprintf(_T("Key: %s, Value: %s, Data: %s\n"), currentKeyName, val_name, val_data);
+
   hRes = setValue(val_name, val_data);
-  if ( hRes != ERROR_SUCCESS )
-    printf("%s: ERROR Key %s not created. Value: %s, Data: %s\n",
-           getAppName(), currentKeyName, val_name, val_data);
+  if (hRes != ERROR_SUCCESS) {
+    _tprintf(_T("ERROR Key %s not created. Value: %s, Data: %s\n"), currentKeyName, val_name, val_data);
+  }
 }
 
 /******************************************************************************
  * This function is a wrapper for the queryValue function.  It prepares the
  * land and clean the area once completed.
  */
-void processQueryValue(LPSTR cmdline)
+void processQueryValue(LPTSTR cmdline)
 {
-  printf("ERROR!!! - temporary disabled");
-  exit(1);
+  _tprintf(_T("ERROR!!! - temporary disabled"));
+  //exit(1);
+  return;
 #if 0
   LPSTR   argv[QUERY_VALUE_MAX_ARGS];/* args storage    */
   LPSTR   token      = NULL;         /* current token analized */
@@ -721,9 +805,9 @@ void processQueryValue(LPSTR cmdline)
   else
     keyValue = argv[0];
 
-  if ((keyValue[0] == '@') && (strlen(keyValue) == 1)) {
+  if ((keyValue[0] == '@') && (_tcslen(keyValue) == 1)) {
     LONG lLen = KEY_MAX_LEN;
-    CHAR* lpsData = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,KEY_MAX_LEN);
+    TCHAR* lpsData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, KEY_MAX_LEN * sizeof(TCHAR));
     /*
      * We need to query the key default value
      */
@@ -753,7 +837,7 @@ void processQueryValue(LPSTR cmdline)
              &dwLen);
 
     if (hRes == ERROR_MORE_DATA) {
-        lpbData = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpbData, dwLen);
+        lpbData = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpbData, dwLen * sizeof(TCHAR));
         hRes = RegQueryValueEx(currentKeyHandle, keyValue, NULL, &dwType, (LPBYTE)lpbData, &dwLen);
     }
 
@@ -764,7 +848,7 @@ void processQueryValue(LPSTR cmdline)
       switch (dwType) {
         case REG_SZ:
         case REG_EXPAND_SZ:
-          lpsRes = HeapAlloc(GetProcessHeap(), 0, dwLen);
+          lpsRes = HeapAlloc(GetProcessHeap(), 0, dwLen * sizeof(TCHAR));
           strncpy(lpsRes, lpbData, dwLen);
           lpsRes[dwLen-1] = '\0';
           break;
@@ -779,13 +863,12 @@ void processQueryValue(LPSTR cmdline)
 
     HeapFree(GetProcessHeap(), 0, lpbData);
   }
-  if (hRes == ERROR_SUCCESS)
-    printf("%s: Value \"%s\" = \"%s\" in key [%s]\n",
-      getAppName(), keyValue, lpsRes, currentKeyName);
+  if (hRes == ERROR_SUCCESS) {
+    _tprintf(_T("Value \"%s\" = \"%s\" in key [%s]\n"), keyValue, lpsRes, currentKeyName);
 
-  else
-    printf("%s: ERROR Value \"%s\" not found. for key \"%s\"\n",
-      getAppName(), keyValue, currentKeyName);
+  } else {
+    _tprintf(_T("ERROR Value \"%s\" not found. for key \"%s\"\n"), keyValue, currentKeyName);
+  }
 
   /*
    * Do some cleanup
@@ -809,28 +892,28 @@ void processQueryValue(LPSTR cmdline)
  */
 void processRegLines(FILE *in, CommandAPI command)
 {
-    LPSTR line     = NULL;  /* line read from input stream */
+    LPTSTR line     = NULL;  /* line read from input stream */
     ULONG lineSize = REG_VAL_BUF_SIZE;
 
-    line = HeapAlloc(GetProcessHeap(), 0, lineSize);
+    line = HeapAlloc(GetProcessHeap(), 0, lineSize * sizeof(TCHAR));
     CHECK_ENOUGH_MEMORY(line);
 
     while (!feof(in)) {
-        LPSTR s; /* The pointer into line for where the current fgets should read */
+        LPTSTR s; /* The pointer into line for where the current fgets should read */
         s = line;
         for (;;) {
             size_t size_remaining;
             int size_to_get;
-            char *s_eol; /* various local uses */
+            TCHAR *s_eol; /* various local uses */
 
             /* Do we need to expand the buffer ? */
             assert (s >= line && s <= line + lineSize);
             size_remaining = lineSize - (s-line);
             if (size_remaining < 2) { /* room for 1 character and the \0 */
-                char *new_buffer;
+                TCHAR *new_buffer;
                 size_t new_size = lineSize + REG_VAL_BUF_SIZE;
                 if (new_size > lineSize) /* no arithmetic overflow */
-                    new_buffer = HeapReAlloc (GetProcessHeap(), 0, line, new_size);
+                    new_buffer = HeapReAlloc (GetProcessHeap(), 0, line, new_size * sizeof(TCHAR));
                 else
                     new_buffer = NULL;
                 CHECK_ENOUGH_MEMORY(new_buffer);
@@ -844,13 +927,15 @@ void processRegLines(FILE *in, CommandAPI command)
              * eof, error, eol or getting the maximum amount.  Abort on error.
              */
             size_to_get = (size_remaining > INT_MAX ? INT_MAX : size_remaining);
-            if (NULL == fgets (s, size_to_get, in)) {
+            if (NULL == _fgetts(s, size_to_get, in)) {
                 if (ferror(in)) {
-                    perror ("While reading input");
-                    exit (IO_ERROR);
+                    //_tperror(_T("While reading input"));
+                    perror("While reading input");
+                    //exit(IO_ERROR);
+                    return;
                 } else {
-                    assert (feof(in));
-                    *s = '\0';
+                    assert(feof(in));
+                    *s = _T('\0');
                     /* It is not clear to me from the definition that the
                      * contents of the buffer are well defined on detecting
                      * an eof without managing to read anything.
@@ -859,44 +944,42 @@ void processRegLines(FILE *in, CommandAPI command)
             }
 
             /* If we didn't read the eol nor the eof go around for the rest */
-            s_eol = strchr (s, '\n');
-            if (!feof (in) && !s_eol) {
-                s = strchr (s, '\0');
+            s_eol = _tcschr (s, _T('\n'));
+            if (!feof(in) && !s_eol) {
+                s = _tcschr (s, _T('\0'));
                 /* It should be s + size_to_get - 1 but this is safer */
                 continue;
             }
 
             /* If it is a comment line then discard it and go around again */
-            if (line [0] == '#') {
+            if (line [0] == _T('#')) {
                 s = line;
                 continue;
             }
 
             /* Remove any line feed.  Leave s_eol on the \0 */
             if (s_eol) {
-                *s_eol = '\0';
-                if (s_eol > line && *(s_eol-1) == '\r')
-                    *--s_eol = '\0';
+                *s_eol = _T('\0');
+                if (s_eol > line && *(s_eol-1) == _T('\r'))
+                    *--s_eol = _T('\0');
+            } else {
+                s_eol = _tcschr (s, _T('\0'));
             }
-            else
-                s_eol = strchr (s, '\0');
-
             /* If there is a concatenating \\ then go around again */
-            if (s_eol > line && *(s_eol-1) == '\\') {
+            if (s_eol > line && *(s_eol-1) == _T('\\')) {
                 int c;
                 s = s_eol-1;
                 /* The following error protection could be made more self-
                  * correcting but I thought it not worth trying.
                  */
-                if ((c = fgetc (in)) == EOF || c != ' ' ||
-                    (c = fgetc (in)) == EOF || c != ' ')
-                    printf ("%s: ERROR - invalid continuation.\n", getAppName());
+
+                if ((c = _fgettc(in)) == _TEOF || c != _T(' ') ||
+                    (c = _fgettc(in)) == _TEOF || c != _T(' '))
+                    _tprintf(_T("ERROR - invalid continuation.\n"));
                 continue;
             }
-
             break; /* That is the full virtual line */
         }
-
         command(line);
     }
     command(NULL);
@@ -907,7 +990,7 @@ void processRegLines(FILE *in, CommandAPI command)
  * This funtion is the main entry point to the registerDLL action.  It
  * receives the currently read line, then loads and registers the requested DLLs
  */
-void doRegisterDLL(LPSTR stdInput)
+void doRegisterDLL(LPTSTR stdInput)
 {
     HMODULE theLib = 0;
     UINT retVal = 0;
@@ -916,18 +999,20 @@ void doRegisterDLL(LPSTR stdInput)
     if (stdInput == NULL) return;
 
     /* Load and register the library, then free it */
-    theLib = LoadLibraryA(stdInput);
+    theLib = LoadLibrary(stdInput);
     if (theLib) {
         FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllRegisterServer");
-        if (lpfnDLLRegProc)
+        if (lpfnDLLRegProc) {
             retVal = (*lpfnDLLRegProc)();
-        else
-            printf("%s: Couldn't find DllRegisterServer proc in '%s'.\n", getAppName(), stdInput);
-        if (retVal != S_OK)
-            printf("%s: DLLRegisterServer error 0x%x in '%s'.\n", getAppName(), retVal, stdInput);
+        } else {
+            _tprintf(_T("Couldn't find DllRegisterServer proc in '%s'.\n"), stdInput);
+        }
+        if (retVal != S_OK) {
+            _tprintf(_T("Couldn't find DllRegisterServer proc in '%s'.\n"), stdInput);
+        }
         FreeLibrary(theLib);
     } else {
-        printf("%s: Could not load DLL '%s'.\n", getAppName(), stdInput);
+        _tprintf(_T("Could not load DLL '%s'.\n"), stdInput);
     }
 }
 
@@ -935,7 +1020,7 @@ void doRegisterDLL(LPSTR stdInput)
  * This funtion is the main entry point to the unregisterDLL action.  It
  * receives the currently read line, then loads and unregisters the requested DLLs
  */
-void doUnregisterDLL(LPSTR stdInput)
+void doUnregisterDLL(LPTSTR stdInput)
 {
     HMODULE theLib = 0;
     UINT retVal = 0;
@@ -944,18 +1029,20 @@ void doUnregisterDLL(LPSTR stdInput)
     if (stdInput == NULL) return;
 
     /* Load and unregister the library, then free it */
-    theLib = LoadLibraryA(stdInput);
+    theLib = LoadLibrary(stdInput);
     if (theLib) {
         FARPROC lpfnDLLRegProc = GetProcAddress(theLib, "DllUnregisterServer");
-        if (lpfnDLLRegProc)
+        if (lpfnDLLRegProc) {
             retVal = (*lpfnDLLRegProc)();
-        else
-            printf("%s: Couldn't find DllUnregisterServer proc in '%s'.\n", getAppName(), stdInput);
-        if (retVal != S_OK)
-            printf("%s: DLLUnregisterServer error 0x%x in '%s'.\n", getAppName(), retVal, stdInput);
+        } else {
+            _tprintf(_T("Couldn't find DllUnregisterServer proc in '%s'.\n"), stdInput);
+        }
+        if (retVal != S_OK) {
+            _tprintf(_T("DLLUnregisterServer error 0x%x in '%s'.\n"), retVal, stdInput);
+        }
         FreeLibrary(theLib);
     } else {
-        printf("%s: Could not load DLL '%s'.\n", getAppName(), stdInput);
+        _tprintf(_T("Could not load DLL '%s'.\n"), stdInput);
     }
 }
 
@@ -972,16 +1059,15 @@ void REGPROC_print_error(VOID)
     int status;
 
     error_code = GetLastError ();
-    status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
-                           NULL, error_code, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
+    status = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                           NULL, error_code, 0, (LPSTR) &lpMsgBuf, 0, NULL);
     if (!status) {
-        printf("%s: Cannot display message for error %ld, status %ld\n",
-               getAppName(), error_code, GetLastError());
-        exit(1);
+        _tprintf(_T("Cannot display message for error %ld, status %ld\n"), error_code, GetLastError());
+    } else {
+        puts(lpMsgBuf);
+        LocalFree((HLOCAL)lpMsgBuf);
     }
-    puts(lpMsgBuf);
-    LocalFree((HLOCAL)lpMsgBuf);
-    exit(1);
+    //exit(1);
 }
 
 /******************************************************************************
@@ -994,12 +1080,12 @@ void REGPROC_print_error(VOID)
  * required_len - length of the string to place to the buffer in characters.
  *   The length does not include the terminating null character.
  */
-void REGPROC_resize_char_buffer(CHAR **buffer, DWORD *len, DWORD required_len)
+void REGPROC_resize_char_buffer(TCHAR **buffer, DWORD *len, DWORD required_len)
 {
     required_len++;
     if (required_len > *len) {
         *len = required_len;
-        *buffer = HeapReAlloc(GetProcessHeap(), 0, *buffer, *len * sizeof(**buffer));
+        *buffer = HeapReAlloc(GetProcessHeap(), 0, *buffer, *len * sizeof(**buffer) * sizeof(TCHAR));
         CHECK_ENOUGH_MEMORY(*buffer);
     }
 }
@@ -1007,19 +1093,19 @@ void REGPROC_resize_char_buffer(CHAR **buffer, DWORD *len, DWORD required_len)
 /******************************************************************************
  * Prints string str to file
  */
-void REGPROC_export_string(FILE *file, CHAR *str)
+void REGPROC_export_string(FILE *file, TCHAR *str)
 {
-    size_t len = strlen(str);
+    size_t len = _tcslen(str);
     size_t i;
 
     /* escaping characters */
     for (i = 0; i < len; i++) {
-        CHAR c = str[i];
+        TCHAR c = str[i];
         switch (c) {
-        case '\\': fputs("\\\\", file); break;
-        case '\"': fputs("\\\"", file); break;
-        case '\n': fputs("\\\n", file); break;
-        default:   fputc(c, file);      break;
+        //case _T('\\'): _fputts(_T("\\\\"), file); break;
+        case _T('\"'): _fputts(_T("\\\""), file); break;
+        case _T('\n'): _fputts(_T("\\\n"), file); break;
+        default:       _fputtc(c, file);          break;
         }
     }
 }
@@ -1041,8 +1127,8 @@ void REGPROC_export_string(FILE *file, CHAR *str)
  * val_size - size of the buffer for storing values in bytes.
  */
 void export_hkey(FILE *file, HKEY key,
-                 CHAR **reg_key_name_buf, DWORD *reg_key_name_len,
-                 CHAR **val_name_buf, DWORD *val_name_len,
+                 TCHAR **reg_key_name_buf, DWORD *reg_key_name_len,
+                 TCHAR **val_name_buf, DWORD *val_name_len,
                  BYTE **val_buf, DWORD *val_size)
 {
     DWORD max_sub_key_len;
@@ -1058,19 +1144,18 @@ void export_hkey(FILE *file, HKEY key,
                         NULL, &max_val_name_len, &max_val_size, NULL, NULL) != ERROR_SUCCESS) {
         REGPROC_print_error();
     }
-    curr_len = strlen(*reg_key_name_buf);
+    curr_len = _tcslen(*reg_key_name_buf);
     REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len, max_sub_key_len + curr_len + 1);
     REGPROC_resize_char_buffer(val_name_buf, val_name_len, max_val_name_len);
     if (max_val_size > *val_size) {
         *val_size = max_val_size;
-        *val_buf = HeapReAlloc(GetProcessHeap(), 0, *val_buf, *val_size);
+        *val_buf = HeapReAlloc(GetProcessHeap(), 0, *val_buf, *val_size * sizeof(TCHAR));
         CHECK_ENOUGH_MEMORY(val_buf);
     }
-
     /* output data for the current key */
-    fputs("\n[", file);
-    fputs(*reg_key_name_buf, file);
-    fputs("]\n", file);
+    _fputts(_T("\n["), file);
+    _fputts(*reg_key_name_buf, file);
+    _fputts(_T("]\n"), file);
     /* print all the values */
     i = 0;
     more_data = TRUE;
@@ -1078,7 +1163,7 @@ void export_hkey(FILE *file, HKEY key,
         DWORD value_type;
         DWORD val_name_len1 = *val_name_len;
         DWORD val_size1 = *val_size;
-        ret = RegEnumValueA(key, i, *val_name_buf, &val_name_len1, NULL, &value_type, *val_buf, &val_size1);
+        ret = RegEnumValue(key, i, *val_name_buf, &val_name_len1, NULL, &value_type, *val_buf, &val_size1);
         if (ret != ERROR_SUCCESS) {
             more_data = FALSE;
             if (ret != ERROR_NO_MORE_ITEMS) {
@@ -1087,78 +1172,73 @@ void export_hkey(FILE *file, HKEY key,
         } else {
             i++;
             if ((*val_name_buf)[0]) {
-                fputs("\"", file);
+                _fputts(_T("\""), file);
                 REGPROC_export_string(file, *val_name_buf);
-                fputs("\"=", file);
+                _fputts(_T("\"="), file);
             } else {
-                fputs("@=", file);
+                _fputts(_T("@="), file);
             }
-
             switch (value_type) {
-            case REG_SZ:
             case REG_EXPAND_SZ:
-                fputs("\"", file);
+                _fputts(_T("expand:"), file);
+            case REG_SZ:
+                _fputts(_T("\""), file);
                 REGPROC_export_string(file, *val_buf);
-                fputs("\"\n", file);
+                _fputts(_T("\"\n"), file);
                 break;
             case REG_DWORD:
-                fprintf(file, "dword:%08lx\n", *((DWORD *)*val_buf));
+                _ftprintf(file, _T("dword:%08lx\n"), *((DWORD *)*val_buf));
                 break;
             default:
-                printf("%s: warning - unsupported registry format '%ld', "
-                       "treat as binary\n", getAppName(), value_type);
-                printf("key name: \"%s\"\n", *reg_key_name_buf);
-                printf("value name:\"%s\"\n\n", *val_name_buf);
+                _tprintf(_T("warning - unsupported registry format '%ld', ") \
+                         _T("treating as binary\n"), value_type);
+                _tprintf(_T("key name: \"%s\"\n"), *reg_key_name_buf);
+                _tprintf(_T("value name:\"%s\"\n\n"), *val_name_buf);
                 /* falls through */
             case REG_MULTI_SZ:
                 /* falls through */
             case REG_BINARY:
             {
                 DWORD i1;
-                CHAR *hex_prefix;
-                CHAR buf[20];
+                TCHAR *hex_prefix;
+                TCHAR buf[20];
                 int cur_pos;
 
                 if (value_type == REG_BINARY) {
-                    hex_prefix = "hex:";
+                    hex_prefix = _T("hex:");
                 } else {
                     hex_prefix = buf;
-                    sprintf(buf, "hex(%ld):", value_type);
+                    _stprintf(buf, _T("hex(%ld):"), value_type);
                 }
-
                 /* position of where the next character will be printed */
-                /* NOTE: yes, strlen("hex:") is used even for hex(x): */
-                cur_pos = strlen("\"\"=") + strlen("hex:") +
-                    strlen(*val_name_buf);
-
-                fputs(hex_prefix, file);
+                /* NOTE: yes, _tcslen("hex:") is used even for hex(x): */
+                cur_pos = _tcslen(_T("\"\"=")) + _tcslen(_T("hex:")) +
+                    _tcslen(*val_name_buf);
+                _fputts(hex_prefix, file);
                 for (i1 = 0; i1 < val_size1; i1++) {
-                    fprintf(file, "%02x", (unsigned int)(*val_buf)[i1]);
+                    _ftprintf(file, _T("%02x"), (unsigned int)(*val_buf)[i1]);
                     if (i1 + 1 < val_size1) {
-                        fputs(",", file);
+                        _fputts(_T(","), file);
                     }
                     cur_pos += 3;
-
                     /* wrap the line */
                     if (cur_pos > REG_FILE_HEX_LINE_LEN) {
-                        fputs("\\\n  ", file);
+                        _fputts(_T("\\\n  "), file);
                         cur_pos = 2;
                     }
                 }
-                fputs("\n", file);
+                _fputts(_T("\n"), file);
                 break;
             }
             }
         }
     }
-
     i = 0;
     more_data = TRUE;
-    (*reg_key_name_buf)[curr_len] = '\\';
+    (*reg_key_name_buf)[curr_len] = _T('\\');
     while (more_data) {
         DWORD buf_len = *reg_key_name_len - curr_len;
-
-        ret = RegEnumKeyExA(key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL);
+        ret = RegEnumKeyEx(key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL);
         if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA) {
             more_data = FALSE;
             if (ret != ERROR_NO_MORE_ITEMS) {
@@ -1168,7 +1248,7 @@ void export_hkey(FILE *file, HKEY key,
             HKEY subkey;
 
             i++;
-            if (RegOpenKeyA(key, *reg_key_name_buf + curr_len + 1, &subkey) == ERROR_SUCCESS) {
+            if (RegOpenKey(key, *reg_key_name_buf + curr_len + 1, &subkey) == ERROR_SUCCESS) {
                 export_hkey(file, subkey, reg_key_name_buf, reg_key_name_len, val_name_buf, val_name_len, val_buf, val_size);
                 RegCloseKey(subkey);
             } else {
@@ -1176,21 +1256,27 @@ void export_hkey(FILE *file, HKEY key,
             }
         }
     }
-    (*reg_key_name_buf)[curr_len] = '\0';
+    (*reg_key_name_buf)[curr_len] = _T('\0');
 }
 
 /******************************************************************************
  * Open file for export.
  */
-FILE *REGPROC_open_export_file(CHAR *file_name)
+FILE* REGPROC_open_export_file(TCHAR* file_name)
 {
-    FILE *file = fopen(file_name, "w");
-    if (!file) {
-        perror("");
-        printf("%s: Can't open file \"%s\"\n", getAppName(), file_name);
-        exit(1);
+    FILE* file;
+
+    if (!file_name) {
+        file = stdout;
+    } else {
+        file = _tfopen(file_name, _T("w"));
+        if (!file) {
+            //perror("");
+            _tprintf(_T("REGPROC_open_export_file(%s) - Can't open file.\n"), file_name);
+        } else {
+            _fputts(_T("REGEDIT4\n"), file);
+        }
     }
-    fputs("REGEDIT4\n", file);
     return file;
 }
 
@@ -1202,37 +1288,39 @@ FILE *REGPROC_open_export_file(CHAR *file_name)
  * reg_key_name - registry branch to export. The whole registry is exported if
  *      reg_key_name is NULL or contains an empty string.
  */
-void export_registry_key(CHAR* file_name, CHAR* reg_key_name)
+BOOL export_registry_key(TCHAR* file_name, TCHAR* reg_key_name)
 {
     HKEY reg_key_class;
 
-    CHAR *reg_key_name_buf;
-    CHAR *val_name_buf;
+    TCHAR *reg_key_name_buf;
+    TCHAR *val_name_buf;
     BYTE *val_buf;
     DWORD reg_key_name_len = KEY_MAX_LEN;
     DWORD val_name_len = KEY_MAX_LEN;
     DWORD val_size = REG_VAL_BUF_SIZE;
     FILE *file = NULL;
 
-    reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0, reg_key_name_len * sizeof(*reg_key_name_buf));
-    val_name_buf = HeapAlloc(GetProcessHeap(), 0, val_name_len * sizeof(*val_name_buf));
-    val_buf = HeapAlloc(GetProcessHeap(), 0, val_size);
+    _tprintf(_T("export_registry_key(%s, %s)\n"), reg_key_name, file_name);
+
+    reg_key_name_buf = HeapAlloc(GetProcessHeap(), 0, reg_key_name_len * sizeof(*reg_key_name_buf) * sizeof(TCHAR));
+    val_name_buf = HeapAlloc(GetProcessHeap(), 0, val_name_len * sizeof(*val_name_buf) * sizeof(TCHAR));
+    val_buf = HeapAlloc(GetProcessHeap(), 0, val_size * sizeof(TCHAR));
     CHECK_ENOUGH_MEMORY(reg_key_name_buf && val_name_buf && val_buf);
 
     if (reg_key_name && reg_key_name[0]) {
-        CHAR *branch_name;
+        TCHAR *branch_name;
         HKEY key;
 
         REGPROC_resize_char_buffer(&reg_key_name_buf, &reg_key_name_len,
-                                   strlen(reg_key_name));
-        strcpy(reg_key_name_buf, reg_key_name);
+                                   _tcslen(reg_key_name));
+        _tcscpy(reg_key_name_buf, reg_key_name);
 
         /* open the specified key */
         reg_key_class = getRegClass(reg_key_name);
         if (reg_key_class == (HKEY)ERROR_INVALID_PARAMETER) {
-            printf("%s: Incorrect registry class specification in '%s'\n",
-                   getAppName(), reg_key_name);
-            exit(1);
+            _tprintf(_T("Incorrect registry class specification in '%s\n"), reg_key_name);
+            //exit(1);
+            return FALSE;
         }
         branch_name = getRegKeyName(reg_key_name);
         CHECK_ENOUGH_MEMORY(branch_name);
@@ -1243,7 +1331,7 @@ void export_registry_key(CHAR* file_name, CHAR* reg_key_name)
                         &reg_key_name_buf, &reg_key_name_len,
                         &val_name_buf, &val_name_len,
                         &val_buf, &val_size);
-        } else if (RegOpenKeyA(reg_key_class, branch_name, &key) == ERROR_SUCCESS) {
+        } else if (RegOpenKey(reg_key_class, branch_name, &key) == ERROR_SUCCESS) {
             file = REGPROC_open_export_file(file_name);
             export_hkey(file, key,
                         &reg_key_name_buf, &reg_key_name_len,
@@ -1251,8 +1339,7 @@ void export_registry_key(CHAR* file_name, CHAR* reg_key_name)
                         &val_buf, &val_size);
             RegCloseKey(key);
         } else {
-            printf("%s: Can't export. Registry key '%s' does not exist!\n",
-                   getAppName(), reg_key_name);
+            _tprintf(_T("Can't export. Registry key '%s does not exist!\n"), reg_key_name);
             REGPROC_print_error();
         }
         HeapFree(GetProcessHeap(), 0, branch_name);
@@ -1266,7 +1353,7 @@ void export_registry_key(CHAR* file_name, CHAR* reg_key_name)
             if (reg_class_keys[i] != HKEY_CLASSES_ROOT &&
                 reg_class_keys[i] != HKEY_CURRENT_USER &&
                 reg_class_keys[i] != HKEY_CURRENT_CONFIG) {
-                strcpy(reg_key_name_buf, reg_class_names[i]);
+                _tcscpy(reg_key_name_buf, reg_class_names[i]);
                 export_hkey(file, reg_class_keys[i],
                             &reg_key_name_buf, &reg_key_name_len,
                             &val_name_buf, &val_name_len,
@@ -1274,17 +1361,34 @@ void export_registry_key(CHAR* file_name, CHAR* reg_key_name)
             }
         }
     }
-    if (file) {
+    if (file_name && file) {
         fclose(file);
     }
-    HeapFree(GetProcessHeap(), 0, reg_key_name);
+//    HeapFree(GetProcessHeap(), 0, reg_key_name);
     HeapFree(GetProcessHeap(), 0, val_buf);
+    HeapFree(GetProcessHeap(), 0, val_name_buf);
+    HeapFree(GetProcessHeap(), 0, reg_key_name_buf);
+    return TRUE;
+}
+
+/******************************************************************************
+ * Reads contents of the specified file into the registry.
+ */
+BOOL import_registry_file(LPTSTR filename)
+{
+    FILE* reg_file = _tfopen(filename, _T("r"));
+
+    if (reg_file) {
+        processRegLines(reg_file, doSetValue);
+        return TRUE;
+    }
+    return FALSE;
 }
 
 /******************************************************************************
  * Recursive function which removes the registry key with all subkeys.
  */
-void delete_branch(HKEY key, CHAR** reg_key_name_buf, DWORD* reg_key_name_len)
+BOOL delete_branch(HKEY key, TCHAR** reg_key_name_buf, DWORD* reg_key_name_len)
 {
     HKEY branch_key;
     DWORD max_sub_key_len;
@@ -1293,31 +1397,37 @@ void delete_branch(HKEY key, CHAR** reg_key_name_buf, DWORD* reg_key_name_len)
     LONG ret;
     long int i;
 
-    if (RegOpenKeyA(key, *reg_key_name_buf, &branch_key) != ERROR_SUCCESS) {
+    if (RegOpenKey(key, *reg_key_name_buf, &branch_key) != ERROR_SUCCESS) {
         REGPROC_print_error();
+        return FALSE;
     }
 
     /* get size information and resize the buffers if necessary */
     if (RegQueryInfoKey(branch_key, NULL, NULL, NULL, &subkeys, &max_sub_key_len,
                         NULL, NULL, NULL, NULL, NULL, NULL) != ERROR_SUCCESS) {
         REGPROC_print_error();
+        RegCloseKey(branch_key);
+        return FALSE;
     }
-    curr_len = strlen(*reg_key_name_buf);
+    curr_len = _tcslen(*reg_key_name_buf);
     REGPROC_resize_char_buffer(reg_key_name_buf, reg_key_name_len, max_sub_key_len + curr_len + 1);
 
     (*reg_key_name_buf)[curr_len] = '\\';
     for (i = subkeys - 1; i >= 0; i--) {
         DWORD buf_len = *reg_key_name_len - curr_len;
-        ret = RegEnumKeyExA(branch_key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL);
+        ret = RegEnumKeyEx(branch_key, i, *reg_key_name_buf + curr_len + 1, &buf_len, NULL, NULL, NULL, NULL);
         if (ret != ERROR_SUCCESS && ret != ERROR_MORE_DATA && ret != ERROR_NO_MORE_ITEMS) {
             REGPROC_print_error();
+            RegCloseKey(branch_key);
+            return FALSE;
         } else {
             delete_branch(key, reg_key_name_buf, reg_key_name_len);
         }
     }
     (*reg_key_name_buf)[curr_len] = '\0';
     RegCloseKey(branch_key);
-    RegDeleteKeyA(key, *reg_key_name_buf);
+    RegDeleteKey(key, *reg_key_name_buf);
+    return TRUE;
 }
 
 /******************************************************************************
@@ -1327,29 +1437,32 @@ void delete_branch(HKEY key, CHAR** reg_key_name_buf, DWORD* reg_key_name_len)
  * reg_key_name - full name of registry branch to delete. Ignored if is NULL,
  *      empty, points to register key class, does not exist.
  */
-void delete_registry_key(CHAR* reg_key_name)
+void delete_registry_key(TCHAR* reg_key_name)
 {
-    CHAR* branch_name;
+    TCHAR* branch_name;
     DWORD branch_name_len;
     HKEY reg_key_class;
     HKEY branch_key;
 
-    if (!reg_key_name || !reg_key_name[0])
+    if (!reg_key_name || !reg_key_name[0]) {
         return;
+    }
     /* open the specified key */
     reg_key_class = getRegClass(reg_key_name);
     if (reg_key_class == (HKEY)ERROR_INVALID_PARAMETER) {
-        printf("%s: Incorrect registry class specification in '%s'\n", getAppName(), reg_key_name);
-        exit(1);
+        _tprintf(_T("Incorrect registry class specification in '%s'\n"), reg_key_name);
+        //exit(1);
+        return;
     }
     branch_name = getRegKeyName(reg_key_name);
     CHECK_ENOUGH_MEMORY(branch_name);
-    branch_name_len = strlen(branch_name);
+    branch_name_len = _tcslen(branch_name);
     if (!branch_name[0]) {
-        printf("%s: Can't delete registry class '%s'\n", getAppName(), reg_key_name);
-        exit(1);
+        _tprintf(_T("Can't delete registry class '%s'\n"), reg_key_name);
+        //exit(1);
+        return;
     }
-    if (RegOpenKeyA(reg_key_class, branch_name, &branch_key) == ERROR_SUCCESS) {
+    if (RegOpenKey(reg_key_class, branch_name, &branch_key) == ERROR_SUCCESS) {
         /* check whether the key exists */
         RegCloseKey(branch_key);
         delete_branch(reg_key_class, &branch_name, &branch_name_len);
@@ -1357,17 +1470,64 @@ void delete_registry_key(CHAR* reg_key_name)
     HeapFree(GetProcessHeap(), 0, branch_name);
 }
 
-/******************************************************************************
- * Sets the application name. Then application name is used in the error
- * reporting.
- */
-void setAppName(CHAR* name)
+////////////////////////////////////////////////////////////////////////////////
+//#ifdef __GNUC__
+#ifdef WIN32_REGDBG
+
+int nHeapAllocCalls = 0;
+int nHeapReAllocCalls = 0;
+int nHeapFreeCalls = 0;
+int nHeapBuffersOutstanding = 0;
+
+//extern LONG  APIENTRY RegCloseKey(LONG hKey);
+
+#ifdef __GNUC__
+extern PVOID STDCALL AquireMemory(HANDLE PoolType, ULONG NumberOfBytes, ULONG Tag);
+extern PVOID STDCALL ReAquireMemory(HANDLE PoolType, LPVOID lpMem, ULONG NumberOfBytes, ULONG Tag);
+extern BOOL STDCALL FreeMemory(PVOID buf);
+#else
+extern PVOID __cdecl AquireMemory(HANDLE PoolType, ULONG NumberOfBytes, ULONG Tag);
+extern PVOID __cdecl ReAquireMemory(HANDLE PoolType, LPVOID lpMem, ULONG NumberOfBytes, ULONG Tag);
+extern BOOL __cdecl FreeMemory(PVOID buf);
+#endif
+
+LPVOID RegHeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes)
 {
-    app_name = name;
+    LPVOID result;
+//    result = HeapAlloc(hHeap, dwFlags, dwBytes);
+    result = AquireMemory(hHeap, dwBytes, 0);
+    ASSERT(result);
+    if (result) {
+        ++nHeapBuffersOutstanding;
+        ++nHeapAllocCalls;
+    }
+    return result;
 }
 
-CHAR* getAppName(VOID)
+LPVOID RegHeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes)
 {
-    return app_name;
+    LPVOID result;
+//    result = HeapReAlloc(hHeap, dwFlags, lpMem, dwBytes);
+    result = ReAquireMemory(hHeap, lpMem, dwBytes, 0);
+    assert(result);
+    if (result) {
+        ++nHeapReAllocCalls;
+    }
+    return result;
+}
+
+BOOL RegHeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem)
+{
+    BOOL result = TRUE;
+//    result = HeapFree(hHeap, dwFlags, lpMem);
+    result = FreeMemory(lpMem);
+    assert(result);
+    if (result) {
+        --nHeapBuffersOutstanding;
+        ++nHeapFreeCalls;
+    }
+    return result;
 }
 
+#endif /*WIN32_REGDBG*/
+//#endif /*__GNUC__*/
index 2dda8c5..70215a1 100644 (file)
 #define SUCCESS               0
 #define KEY_VALUE_ALREADY_SET 2
 
-typedef void (*CommandAPI)(LPSTR lpsLine);
+typedef void (*CommandAPI)(LPTSTR lpsLine);
 
-void doSetValue(LPSTR lpsLine);
-void doDeleteValue(LPSTR lpsLine);
-void doCreateKey(LPSTR lpsLine);
-void doDeleteKey(LPSTR lpsLine);
-void doQueryValue(LPSTR lpsLine);
-void doRegisterDLL(LPSTR lpsLine);
-void doUnregisterDLL(LPSTR lpsLine);
+void doSetValue(LPTSTR lpsLine);
+void doDeleteValue(LPTSTR lpsLine);
+void doCreateKey(LPTSTR lpsLine);
+void doDeleteKey(LPTSTR lpsLine);
+void doQueryValue(LPTSTR lpsLine);
+void doRegisterDLL(LPTSTR lpsLine);
+void doUnregisterDLL(LPTSTR lpsLine);
 
-void export_registry_key(CHAR* file_name, CHAR* reg_key_name);
-void delete_registry_key(CHAR* reg_key_name);
-
-void setAppName(CHAR* name);
-CHAR* getAppName(VOID);
+BOOL export_registry_key(TCHAR* file_name, TCHAR* reg_key_name);
+BOOL import_registry_file(LPTSTR filename);
+void delete_registry_key(TCHAR* reg_key_name);
 
 void processRegLines(FILE* in, CommandAPI command);
 
 /*
  * Generic prototypes
  */
+#ifdef _UNICODE
+#define get_file_name get_file_nameW
+#else
+#define get_file_name get_file_nameA
+#endif
+
 char*   getToken(char** str, const char* delims);
-void    get_file_name(CHAR** command_line, CHAR* filename);
-DWORD   convertHexToDWord(char* str, BYTE* buf);
-DWORD   convertHexCSVToHex(char* str, BYTE* buf, ULONG bufLen);
-LPSTR   convertHexToHexCSV(BYTE* buf, ULONG len);
-LPSTR   convertHexToDWORDStr(BYTE* buf, ULONG len);
-LPSTR   getRegKeyName(LPSTR lpLine);
-HKEY    getRegClass(LPSTR lpLine);
-DWORD   getDataType(LPSTR* lpValue, DWORD* parse_type);
-LPSTR   getArg(LPSTR arg);
-HRESULT openKey(LPSTR stdInput);
+void    get_file_nameA(CHAR** command_line, CHAR* filename, int max_filename);
+void    get_file_nameW(CHAR** command_line, WCHAR* filename, int max_filename);
+DWORD   convertHexToDWord(TCHAR* str, BYTE* buf);
+DWORD   convertHexCSVToHex(TCHAR* str, BYTE* buf, ULONG bufLen);
+LPTSTR  convertHexToHexCSV(BYTE* buf, ULONG len);
+LPTSTR  convertHexToDWORDStr(BYTE* buf, ULONG len);
+LPTSTR  getRegKeyName(LPTSTR lpLine);
+HKEY    getRegClass(LPTSTR lpLine);
+DWORD   getDataType(LPTSTR* lpValue, DWORD* parse_type);
+LPTSTR  getArg(LPTSTR arg);
+HRESULT openKey(LPTSTR stdInput);
 void    closeKey(VOID);
 
 /*
  * api setValue prototypes
  */
-void    processSetValue(LPSTR cmdline);
-HRESULT setValue(LPSTR val_name, LPSTR val_data);
+void    processSetValue(LPTSTR cmdline);
+HRESULT setValue(LPTSTR val_name, LPTSTR val_data);
 
 /*
  * api queryValue prototypes
  */
-void    processQueryValue(LPSTR cmdline);
+void    processQueryValue(LPTSTR cmdline);
+
+#ifdef __GNUC__
+#ifdef WIN32_REGDBG
+//typedef UINT_PTR SIZE_T, *PSIZE_T;
+//#define _MAX_PATH   260 /* max. length of full pathname */
+#endif /*WIN32_REGDBG*/
+
+#ifdef UNICODE
+#define _tfopen     _wfopen
+#else
+#define _tfopen     fopen
+#endif
+
+#endif /*__GNUC__*/
+
+LPVOID RegHeapAlloc(
+  HANDLE hHeap,   // handle to private heap block
+  DWORD dwFlags,  // heap allocation control
+  SIZE_T dwBytes  // number of bytes to allocate
+);
+
+LPVOID RegHeapReAlloc(
+  HANDLE hHeap,   // handle to heap block
+  DWORD dwFlags,  // heap reallocation options
+  LPVOID lpMem,   // pointer to memory to reallocate
+  SIZE_T dwBytes  // number of bytes to reallocate
+);
 
+BOOL RegHeapFree(
+  HANDLE hHeap,  // handle to heap
+  DWORD dwFlags, // heap free options
+  LPVOID lpMem   // pointer to memory
+);
index 8400555..6ef4412 100644 (file)
@@ -2,20 +2,17 @@
 // Microsoft Developer Studio generated include file.
 // Used by regedit.rc
 //
-
 #define ID_REGISTRY_MENU                0
 #define ID_EDIT_MENU                    1
 #define ID_VIEW_MENU                    2
 #define ID_FAVOURITES_MENU              3
 #define ID_HELP_MENU                    4
 #define ID_EDIT_NEW_MENU                5
-
 #define IDS_LIST_COLUMN_FIRST           91
 #define IDS_LIST_COLUMN_NAME            91
 #define IDS_LIST_COLUMN_TYPE            92
 #define IDS_LIST_COLUMN_DATA            93
 #define IDS_LIST_COLUMN_LAST            93
-
 #define IDD_ABOUTBOX                    103
 #define IDS_APP_TITLE                   103
 #define IDI_REGEDIT                     107
 #define IDR_REGEDIT_MENU                130
 #define IDD_DIALOG1                     131
 #define IDB_OPEN_FILE                   132
+#define IDD_DIALOG2                     132
 #define IDB_CLOSED_FILE                 133
 #define IDB_ROOT                        134
-
+#define IDC_LICENSE_EDIT                1029
 #define ID_REGISTRY_EXIT                32770
 #define ID_FAVOURITES_ADDTOFAVOURITES   32772
 #define ID_FAVOURITES_REMOVEFAVOURITE   32773
 #define ID_REGISTRY_PRINTSUBTREE        32832
 #define ID_REGISTRY_PRINTERSETUP        32833
 #define ID_REGISTRY_SAVESUBTREEAS       32834
-
-#define IDC_LICENSE_EDIT                1029
 #define IDS_LICENSE                     32835
-
 #define IDC_STATIC                      -1
 
 // Next default values for new objects
 // 
 #ifdef APSTUDIO_INVOKED
 #ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        132
+#define _APS_NEXT_RESOURCE_VALUE        133
 #define _APS_NEXT_COMMAND_VALUE         32836
 #define _APS_NEXT_CONTROL_VALUE         1000
 #define _APS_NEXT_SYMED_VALUE           110