[SNDVOL32] Add the small line dialog
[reactos.git] / base / applications / regedit / framewnd.c
index 79cc3b3..a16019e 100644 (file)
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <regedit.h>
+#include "regedit.h"
+
+#include <commdlg.h>
+#include <cderr.h>
+#include <objsel.h>
 
 /********************************************************************************
  * Global and Local Variables:
@@ -26,7 +30,7 @@
 
 #define FAVORITES_MENU_POSITION 3
 
-static TCHAR s_szFavoritesRegKey[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites");
+static WCHAR s_szFavoritesRegKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites";
 
 static BOOL bInMenuLoop = FALSE;        /* Tells us if we are in the menu loop */
 
@@ -39,7 +43,7 @@ static void resize_frame_rect(HWND hWnd, PRECT prect)
     RECT rt;
     /*
        if (IsWindowVisible(hToolBar)) {
-               SendMessage(hToolBar, WM_SIZE, 0, 0);
+               SendMessageW(hToolBar, WM_SIZE, 0, 0);
                GetClientRect(hToolBar, &rt);
                prect->top = rt.bottom+3;
                prect->bottom -= rt.bottom+3;
@@ -69,7 +73,7 @@ static void OnInitMenu(HWND hWnd)
     LONG lResult;
     HKEY hKey = NULL;
     DWORD dwIndex, cbValueName, cbValueData, dwType;
-    TCHAR szValueName[256];
+    WCHAR szValueName[256];
     BYTE abValueData[256];
     static int s_nFavoriteMenuSubPos = -1;
     HMENU hMenu;
@@ -85,11 +89,10 @@ static void OnInitMenu(HWND hWnd)
     }
     else
     {
-        while(RemoveMenu(hMenu, s_nFavoriteMenuSubPos, MF_BYPOSITION))
-            ;
+        while(RemoveMenu(hMenu, s_nFavoriteMenuSubPos, MF_BYPOSITION)) ;
     }
 
-    lResult = RegOpenKey(HKEY_CURRENT_USER, s_szFavoritesRegKey, &hKey);
+    lResult = RegOpenKeyW(HKEY_CURRENT_USER, s_szFavoritesRegKey, &hKey);
     if (lResult != ERROR_SUCCESS)
         goto done;
 
@@ -98,7 +101,7 @@ static void OnInitMenu(HWND hWnd)
     {
         cbValueName = COUNT_OF(szValueName);
         cbValueData = sizeof(abValueData);
-        lResult = RegEnumValue(hKey, dwIndex, szValueName, &cbValueName, NULL, &dwType, abValueData, &cbValueData);
+        lResult = RegEnumValueW(hKey, dwIndex, szValueName, &cbValueName, NULL, &dwType, abValueData, &cbValueData);
         if ((lResult == ERROR_SUCCESS) && (dwType == REG_SZ))
         {
             if (!bDisplayedAny)
@@ -124,9 +127,9 @@ static void OnEnterMenuLoop(HWND hWnd)
 
     /* Update the status bar pane sizes */
     nParts = -1;
-    SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
+    SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
     bInMenuLoop = TRUE;
-    SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
+    SendMessageW(hStatusBar, SB_SETTEXTW, (WPARAM)0, (LPARAM)L"");
 }
 
 static void OnExitMenuLoop(HWND hWnd)
@@ -139,9 +142,9 @@ static void OnExitMenuLoop(HWND hWnd)
 
 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
 {
-    TCHAR str[100];
+    WCHAR str[100];
 
-    _tcscpy(str, _T(""));
+    wcscpy(str, L"");
     if (nFlags & MF_POPUP)
     {
         if (hSysMenu != GetMenu(hWnd))
@@ -149,16 +152,16 @@ static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu)
             if (nItemID == 2) nItemID = 5;
         }
     }
-    if (LoadString(hInst, nItemID, str, 100))
+    if (LoadStringW(hInst, nItemID, str, 100))
     {
         /* load appropriate string*/
-        LPTSTR lpsz = str;
+        LPWSTR lpsz = str;
         /* first newline terminates actual string*/
-        lpsz = _tcschr(lpsz, _T('\n'));
+        lpsz = wcschr(lpsz, L'\n');
         if (lpsz != NULL)
-            *lpsz = '\0';
+            *lpsz = L'\0';
     }
-    SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)str);
+    SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)str);
 }
 
 void SetupStatusBar(HWND hWnd, BOOL bResize)
@@ -169,16 +172,16 @@ void SetupStatusBar(HWND hWnd, BOOL bResize)
     nParts = rc.right;
     /*    nParts = -1;*/
     if (bResize)
-        SendMessage(hStatusBar, WM_SIZE, 0, 0);
-    SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
+        SendMessageW(hStatusBar, WM_SIZE, 0, 0);
+    SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
 }
 
 void UpdateStatusBar(void)
 {
-    NMHDR nmhdr;
-    ZeroMemory(&nmhdr, sizeof(NMHDR));
-    nmhdr.code = TVN_SELCHANGED;
-    SendMessage(g_pChildWnd->hWnd, WM_NOTIFY, (WPARAM)TREE_WINDOW, (LPARAM)&nmhdr);
+    HKEY hKeyRoot;
+    LPCWSTR pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
+
+    SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)pszKeyPath);
 }
 
 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild)
@@ -197,44 +200,44 @@ static BOOL CheckCommDlgError(HWND hWnd)
     UNREFERENCED_PARAMETER(hWnd);
     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;
+        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;
 }
 
-TCHAR FileNameBuffer[_MAX_PATH];
-TCHAR FileTitleBuffer[_MAX_PATH];
+WCHAR FileNameBuffer[_MAX_PATH];
+WCHAR FileTitleBuffer[_MAX_PATH];
 
 typedef struct
 {
@@ -243,25 +246,25 @@ typedef struct
 } FILTERPAIR, *PFILTERPAIR;
 
 void
-BuildFilterStrings(TCHAR *Filter, PFILTERPAIR Pairs, int PairCount)
+BuildFilterStrings(WCHAR *Filter, PFILTERPAIR Pairs, int PairCount)
 {
     int i, c;
 
     c = 0;
     for(i = 0; i < PairCount; i++)
     {
-        c += LoadString(hInst, Pairs[i].DisplayID, &Filter[c], 255 * sizeof(TCHAR));
-        Filter[++c] = '\0';
-        c += LoadString(hInst, Pairs[i].FilterID, &Filter[c], 255 * sizeof(TCHAR));
-        Filter[++c] = '\0';
+        c += LoadStringW(hInst, Pairs[i].DisplayID, &Filter[c], 255);
+        Filter[++c] = L'\0';
+        c += LoadStringW(hInst, Pairs[i].FilterID, &Filter[c], 255);
+        Filter[++c] = L'\0';
     }
-    Filter[++c] = '\0';
+    Filter[++c] = L'\0';
 }
 
 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
 {
-    FILTERPAIR FilterPairs[3];
-    static TCHAR Filter[1024];
+    FILTERPAIR FilterPairs[4];
+    static WCHAR Filter[1024];
 
     memset(pofn, 0, sizeof(OPENFILENAME));
     pofn->lStructSize = sizeof(OPENFILENAME);
@@ -271,11 +274,13 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
     /* create filter string */
     FilterPairs[0].DisplayID = IDS_FLT_REGFILES;
     FilterPairs[0].FilterID = IDS_FLT_REGFILES_FLT;
-    FilterPairs[1].DisplayID = IDS_FLT_REGEDIT4;
-    FilterPairs[1].FilterID = IDS_FLT_REGEDIT4_FLT;
-    FilterPairs[2].DisplayID = IDS_FLT_ALLFILES;
-    FilterPairs[2].FilterID = IDS_FLT_ALLFILES_FLT;
-    BuildFilterStrings(Filter, FilterPairs, sizeof(FilterPairs) / sizeof(FILTERPAIR));
+    FilterPairs[1].DisplayID = IDS_FLT_HIVFILES;
+    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, COUNT_OF(FilterPairs));
 
     pofn->lpstrFilter = Filter;
     pofn->lpstrFile = FileNameBuffer;
@@ -283,24 +288,25 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
     pofn->lpstrFileTitle = FileTitleBuffer;
     pofn->nMaxFileTitle = _MAX_PATH;
     pofn->Flags = OFN_HIDEREADONLY;
-    pofn->lpstrDefExt = TEXT("reg");
+    pofn->lpstrDefExt = L"reg";
     return TRUE;
 }
 
+#define LOADHIVE_KEYNAMELENGTH 128
+
 static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
 {
-    static LPTSTR sKey = NULL;
-    static INT sLength = 0;
+    static LPWSTR sKey = NULL;
     switch(uMsg)
     {
     case WM_INITDIALOG:
-        sKey = (LPTSTR)lParam;
-        sLength = 128; /* FIXME: Ugly hack! */
+        sKey = (LPWSTR)lParam;
+        break;
     case WM_COMMAND:
         switch(LOWORD(wParam))
         {
         case IDOK:
-            if(GetDlgItemText(hWndDlg, IDC_EDIT_KEY, sKey, sLength))
+            if(GetDlgItemTextW(hWndDlg, IDC_EDIT_KEY, sKey, LOADHIVE_KEYNAMELENGTH))
                 return EndDialog(hWndDlg, -1);
             else
                 return EndDialog(hWndDlg, 0);
@@ -312,14 +318,44 @@ static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPAR
     return FALSE;
 }
 
+static BOOL EnablePrivilege(LPCWSTR lpszPrivilegeName, LPCWSTR lpszSystemName, BOOL bEnablePrivilege)
+{
+    BOOL   bRet   = FALSE;
+    HANDLE hToken = NULL;
+
+    if (OpenProcessToken(GetCurrentProcess(),
+                         TOKEN_ADJUST_PRIVILEGES,
+                         &hToken))
+    {
+        TOKEN_PRIVILEGES tp;
+
+        tp.PrivilegeCount = 1;
+        tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0);
+
+        if (LookupPrivilegeValueW(lpszSystemName,
+                                  lpszPrivilegeName,
+                                  &tp.Privileges[0].Luid))
+        {
+            bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
+
+            if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
+                bRet = FALSE;
+        }
+
+        CloseHandle(hToken);
+    }
+
+    return bRet;
+}
+
 static BOOL LoadHive(HWND hWnd)
 {
     OPENFILENAME ofn;
-    TCHAR Caption[128];
-    LPCTSTR pszKeyPath;
-    TCHAR xPath[128];
+    WCHAR Caption[128];
+    LPCWSTR pszKeyPath;
+    WCHAR xPath[LOADHIVE_KEYNAMELENGTH];
     HKEY hRootKey;
-    TCHAR Filter[1024];
+    WCHAR Filter[1024];
     FILTERPAIR filter;
     /* get the item key to load the hive in */
     pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
@@ -328,19 +364,26 @@ static BOOL LoadHive(HWND hWnd)
     /* build the "All Files" filter up */
     filter.DisplayID = IDS_FLT_ALLFILES;
     filter.FilterID = IDS_FLT_ALLFILES_FLT;
-    BuildFilterStrings(Filter, &filter, sizeof(filter));
+    BuildFilterStrings(Filter, &filter, 1);
     ofn.lpstrFilter = Filter;
     /* load and set the caption and flags for dialog */
-    LoadString(hInst, IDS_LOAD_HIVE, Caption, COUNT_OF(Caption));
+    LoadStringW(hInst, IDS_LOAD_HIVE, Caption, COUNT_OF(Caption));
     ofn.lpstrTitle = Caption;
     ofn.Flags |= OFN_ENABLESIZING;
     /*    ofn.lCustData = ;*/
     /* now load the hive */
     if (GetOpenFileName(&ofn))
     {
-        if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_LOADHIVE), hWnd, &LoadHive_KeyNameInHookProc, (LPARAM)xPath))
+        if (DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_LOADHIVE), hWnd,
+                            &LoadHive_KeyNameInHookProc, (LPARAM)xPath))
         {
-            LONG regLoadResult = RegLoadKey(hRootKey, xPath, ofn.lpstrFile);
+            LONG regLoadResult;
+
+            /* Enable the 'restore' privilege, load the hive, disable the privilege */
+            EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
+            regLoadResult = RegLoadKeyW(hRootKey, xPath, ofn.lpstrFile);
+            EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
+
             if(regLoadResult == ERROR_SUCCESS)
             {
                 /* refresh tree and list views */
@@ -364,17 +407,21 @@ static BOOL LoadHive(HWND hWnd)
 
 static BOOL UnloadHive(HWND hWnd)
 {
-    TCHAR Caption[128];
-    LPCTSTR pszKeyPath;
+    WCHAR Caption[128];
+    LPCWSTR pszKeyPath;
     HKEY hRootKey;
     LONG regUnloadResult;
 
     /* get the item key to unload */
     pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
     /* load and set the caption and flags for dialog */
-    LoadString(hInst, IDS_UNLOAD_HIVE, Caption, COUNT_OF(Caption));
-    /* now unload the hive */
-    regUnloadResult = RegUnLoadKey(hRootKey, pszKeyPath);
+    LoadStringW(hInst, IDS_UNLOAD_HIVE, Caption, COUNT_OF(Caption));
+
+    /* Enable the 'restore' privilege, unload the hive, disable the privilege */
+    EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
+    regUnloadResult = RegUnLoadKeyW(hRootKey, pszKeyPath);
+    EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
+
     if(regUnloadResult == ERROR_SUCCESS)
     {
         /* refresh tree and list views */
@@ -392,44 +439,94 @@ static BOOL UnloadHive(HWND hWnd)
 
 static BOOL ImportRegistryFile(HWND hWnd)
 {
+    BOOL bRet = FALSE;
     OPENFILENAME ofn;
-    TCHAR Caption[128], szTitle[256], szText[256];
-    LPCTSTR pszKeyPath;
-    HKEY hRootKey;
+    WCHAR Caption[128], szTitle[512], szText[512];
+    HKEY hKeyRoot;
+    LPCWSTR pszKeyPath;
+
+    /* Figure out in which key path we are importing */
+    pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
 
     InitOpenFileName(hWnd, &ofn);
-    LoadString(hInst, IDS_IMPORT_REG_FILE, Caption, COUNT_OF(Caption));
+    LoadStringW(hInst, IDS_IMPORT_REG_FILE, Caption, COUNT_OF(Caption));
     ofn.lpstrTitle = Caption;
     ofn.Flags |= OFN_ENABLESIZING;
     /*    ofn.lCustData = ;*/
     if (GetOpenFileName(&ofn))
     {
-        FILE *fp = _wfopen(ofn.lpstrFile, L"r");
-        if (fp == NULL || !import_registry_file(fp))
+        /* Look at the extension of the file to determine its type */
+        if (ofn.nFileExtension >= 1 &&
+            _wcsicmp(ofn.lpstrFile + ofn.nFileExtension, L"reg") == 0) /* REGEDIT4 or Windows Registry Editor Version 5.00 */
+        {
+            /* Open the file */
+            FILE* fp = _wfopen(ofn.lpstrFile, L"r");
+
+            /* Import it */
+            if (fp == NULL || !import_registry_file(fp))
+            {
+                /* Error opening the file */
+                LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
+                LoadStringW(hInst, IDS_IMPORT_ERROR, szText, COUNT_OF(szText));
+                InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile);
+                bRet = FALSE;
+            }
+            else
+            {
+                /* Show successful import */
+                LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
+                LoadStringW(hInst, IDS_IMPORT_OK, szText, COUNT_OF(szText));
+                InfoMessageBox(hWnd, MB_OK | MB_ICONINFORMATION, szTitle, szText, ofn.lpstrFile);
+                bRet = TRUE;
+            }
+
+            /* Close the file */
+            if (fp) fclose(fp);
+        }
+        else /* Registry Hive Files */
         {
-            LPSTR p = GetMultiByteString(ofn.lpstrFile);
-            fprintf(stderr, "Can't open file \"%s\"\n", p);
-            HeapFree(GetProcessHeap(), 0, p);
-            if (fp != NULL)
-                fclose(fp);
-            return FALSE;
+            LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_CAPTION, szTitle, COUNT_OF(szTitle));
+            LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_MSG, szText, COUNT_OF(szText));
+
+            /* Display a confirmation message */
+            if (MessageBoxW(g_pChildWnd->hWnd, szText, szTitle, MB_ICONWARNING | MB_YESNO) == IDYES)
+            {
+                LONG lResult;
+                HKEY hSubKey;
+
+                /* Open the subkey */
+                lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_WRITE, &hSubKey);
+                if (lResult == ERROR_SUCCESS)
+                {
+                    /* Enable the 'restore' privilege, restore the hive then disable the privilege */
+                    EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE);
+                    lResult = RegRestoreKey(hSubKey, ofn.lpstrFile, REG_FORCE_RESTORE);
+                    EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE);
+
+                    /* Flush the subkey and close it */
+                    RegFlushKey(hSubKey);
+                    RegCloseKey(hSubKey);
+                }
+
+                /* Set the return value */
+                bRet = (lResult == ERROR_SUCCESS);
+
+                /* Display error, if any */
+                if (!bRet) ErrorMessageBox(hWnd, Caption, lResult);
+            }
         }
-        LoadString(hInst, IDS_APP_TITLE, szTitle, sizeof(szTitle));
-        LoadString(hInst, IDS_IMPORTED_OK, szText, sizeof(szTitle));
-        /* show successful import */
-        MessageBox(NULL, szText, szTitle, MB_OK);
-        fclose(fp);
     }
     else
     {
         CheckCommDlgError(hWnd);
     }
 
+    /* refresh tree and list views */
     RefreshTreeView(g_pChildWnd->hTreeWnd);
-    pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey);
-    RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
+    pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
+    RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, pszKeyPath);
 
-    return TRUE;
+    return bRet;
 }
 
 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
@@ -439,7 +536,7 @@ static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, W
     HWND hwndExportBranchText;
     UINT_PTR iResult = 0;
     OPENFILENAME *pOfn;
-    LPTSTR pszSelectedKey;
+    LPWSTR pszSelectedKey;
     OFNOTIFY *pOfnNotify;
 
     UNREFERENCED_PARAMETER(wParam);
@@ -448,37 +545,37 @@ static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, W
     {
     case WM_INITDIALOG:
         pOfn = (OPENFILENAME *) lParam;
-        pszSelectedKey = (LPTSTR) pOfn->lCustData;
+        pszSelectedKey = (LPWSTR) pOfn->lCustData;
 
         hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL);
         if (hwndExportAll)
-            SendMessage(hwndExportAll, BM_SETCHECK, pszSelectedKey ? BST_UNCHECKED : BST_CHECKED, 0);
+            SendMessageW(hwndExportAll, BM_SETCHECK, pszSelectedKey ? BST_UNCHECKED : BST_CHECKED, 0);
 
         hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
         if (hwndExportBranch)
-            SendMessage(hwndExportBranch, BM_SETCHECK, pszSelectedKey ? BST_CHECKED : BST_UNCHECKED, 0);
+            SendMessageW(hwndExportBranch, BM_SETCHECK, pszSelectedKey ? BST_CHECKED : BST_UNCHECKED, 0);
 
         hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
         if (hwndExportBranchText)
-            SetWindowText(hwndExportBranchText, pszSelectedKey);
+            SetWindowTextW(hwndExportBranchText, pszSelectedKey);
         break;
 
     case WM_NOTIFY:
         if (((NMHDR *) lParam)->code == CDN_FILEOK)
         {
             pOfnNotify = (OFNOTIFY *) lParam;
-            pszSelectedKey = (LPTSTR) pOfnNotify->lpOFN->lCustData;
+            pszSelectedKey = (LPWSTR) pOfnNotify->lpOFN->lCustData;
 
             hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
             hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
             if (hwndExportBranch && hwndExportBranchText
-                    && (SendMessage(hwndExportBranch, BM_GETCHECK, 0, 0) == BST_CHECKED))
+                    && (SendMessageW(hwndExportBranch, BM_GETCHECK, 0, 0) == BST_CHECKED))
             {
-                GetWindowText(hwndExportBranchText, pszSelectedKey, _MAX_PATH);
+                GetWindowTextW(hwndExportBranchText, pszSelectedKey, _MAX_PATH);
             }
             else
             {
-                pszSelectedKey[0] = '\0';
+                pszSelectedKey[0] = L'\0';
             }
         }
         break;
@@ -488,18 +585,19 @@ static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, W
 
 BOOL ExportRegistryFile(HWND hWnd)
 {
+    BOOL bRet = FALSE;
     OPENFILENAME ofn;
-    TCHAR ExportKeyPath[_MAX_PATH];
-    TCHAR Caption[128];
+    WCHAR ExportKeyPath[_MAX_PATH] = {0};
+    WCHAR Caption[128], szTitle[512], szText[512];
     HKEY hKeyRoot;
-    LPCTSTR pszKeyPath;
+    LPCWSTR pszKeyPath;
 
     /* Figure out which key path we are exporting */
     pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
     GetKeyName(ExportKeyPath, COUNT_OF(ExportKeyPath), hKeyRoot, pszKeyPath);
 
     InitOpenFileName(hWnd, &ofn);
-    LoadString(hInst, IDS_EXPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
+    LoadStringW(hInst, IDS_EXPORT_REG_FILE, Caption, COUNT_OF(Caption));
     ofn.lpstrTitle = Caption;
 
     /* Only set the path if a key (not the root node) is selected */
@@ -509,33 +607,93 @@ BOOL ExportRegistryFile(HWND hWnd)
     }
     ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK | OFN_OVERWRITEPROMPT;
     ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
-    ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORTRANGE);
+    ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORTRANGE);
     if (GetSaveFileName(&ofn))
     {
-        BOOL result;
-        DWORD format;
-
-        if (ofn.nFilterIndex == 1)
-            format = REG_FORMAT_5;
-        else
-            format = REG_FORMAT_4;
-        result = export_registry_key(ofn.lpstrFile, ExportKeyPath, format);
-        if (!result)
+        switch (ofn.nFilterIndex)
         {
-            LPSTR p = GetMultiByteString(ofn.lpstrFile);
-            fprintf(stderr, "Can't open file \"%s\"\n", p);
-            HeapFree(GetProcessHeap(), 0, p);
-            return FALSE;
+            case 2: /* Registry Hive Files */
+            {
+                LONG lResult;
+                HKEY hSubKey;
+
+                /* Open the subkey */
+                lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_READ, &hSubKey);
+                if (lResult == ERROR_SUCCESS)
+                {
+                    /* Enable the 'backup' privilege, save the hive then disable the privilege */
+                    EnablePrivilege(SE_BACKUP_NAME, NULL, TRUE);
+                    lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL);
+                    if (lResult == ERROR_ALREADY_EXISTS)
+                    {
+                        /*
+                         * We are here, that means that we already said "yes" to the confirmation dialog.
+                         * So we absolutely want to replace the hive file.
+                         */
+                        if (DeleteFileW(ofn.lpstrFile))
+                        {
+                            /* Try again */
+                            lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL);
+                        }
+                    }
+                    EnablePrivilege(SE_BACKUP_NAME, NULL, FALSE);
+
+                    if (lResult != ERROR_SUCCESS)
+                    {
+                        /*
+                         * If we are here, it's because RegSaveKeyW has failed for any reason.
+                         * The problem is that even if it has failed, it has created or
+                         * replaced the exported hive file with a new empty file. We don't
+                         * want to keep this file, so we delete it.
+                         */
+                        DeleteFileW(ofn.lpstrFile);
+                    }
+
+                    /* Close the subkey */
+                    RegCloseKey(hSubKey);
+                }
+
+                /* Set the return value */
+                bRet = (lResult == ERROR_SUCCESS);
+
+                /* Display error, if any */
+                if (!bRet) ErrorMessageBox(hWnd, Caption, lResult);
+
+                break;
+            }
+
+            case 1:  /* Windows Registry Editor Version 5.00 */
+            case 3:  /* REGEDIT4 */
+            default: /* All files ==> use Windows Registry Editor Version 5.00 */
+            {
+                if (!export_registry_key(ofn.lpstrFile, ExportKeyPath,
+                                         (ofn.nFilterIndex == 3 ? REG_FORMAT_4
+                                                                : REG_FORMAT_5)))
+                {
+                    /* Error creating the file */
+                    LoadStringW(hInst, IDS_APP_TITLE, szTitle, COUNT_OF(szTitle));
+                    LoadStringW(hInst, IDS_EXPORT_ERROR, szText, COUNT_OF(szText));
+                    InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile);
+                    bRet = FALSE;
+                }
+                else
+                {
+                    bRet = TRUE;
+                }
+
+                break;
+            }
         }
     }
     else
     {
         CheckCommDlgError(hWnd);
     }
-    return TRUE;
+
+    return bRet;
 }
 
-BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
+BOOL PrintRegistryHive(HWND hWnd, LPWSTR path)
 {
 #if 1
     PRINTDLG pd;
@@ -607,18 +765,18 @@ BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
     return TRUE;
 }
 
-static void ChooseFavorite(LPCTSTR pszFavorite)
+static void ChooseFavorite(LPCWSTR pszFavorite)
 {
     HKEY hKey = NULL;
-    TCHAR szFavoritePath[512];
+    WCHAR szFavoritePath[512];
     DWORD cbData, dwType;
 
-    if (RegOpenKeyEx(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+    if (RegOpenKeyExW(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
         goto done;
 
-    cbData = (sizeof(szFavoritePath) / sizeof(szFavoritePath[0])) - 1;
+    cbData = sizeof(szFavoritePath);
     memset(szFavoritePath, 0, sizeof(szFavoritePath));
-    if (RegQueryValueEx(hKey, pszFavorite, NULL, &dwType, (LPBYTE) szFavoritePath, &cbData) != ERROR_SUCCESS)
+    if (RegQueryValueExW(hKey, pszFavorite, NULL, &dwType, (LPBYTE) szFavoritePath, &cbData) != ERROR_SUCCESS)
         goto done;
 
     if (dwType == REG_SZ)
@@ -629,13 +787,13 @@ done:
         RegCloseKey(hKey);
 }
 
-BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCTSTR keyName)
+BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCWSTR keyName)
 {
     BOOL bClipboardOpened = FALSE;
     BOOL bSuccess = FALSE;
-    TCHAR szBuffer[512];
+    WCHAR szBuffer[512];
     HGLOBAL hGlobal;
-    LPTSTR s;
+    LPWSTR s;
 
     if (!OpenClipboard(hWnd))
         goto done;
@@ -647,19 +805,15 @@ BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCTSTR keyName)
     if (!GetKeyName(szBuffer, COUNT_OF(szBuffer), hRootKey, keyName))
         goto done;
 
-    hGlobal = GlobalAlloc(GMEM_MOVEABLE, (lstrlen(szBuffer) + 1) * sizeof(TCHAR));
+    hGlobal = GlobalAlloc(GMEM_MOVEABLE, (wcslen(szBuffer) + 1) * sizeof(WCHAR));
     if (!hGlobal)
         goto done;
 
     s = GlobalLock(hGlobal);
-    _tcscpy(s, szBuffer);
+    wcscpy(s, szBuffer);
     GlobalUnlock(hGlobal);
 
-#ifdef UNICODE
     SetClipboardData(CF_UNICODETEXT, hGlobal);
-#else
-    SetClipboardData(CF_TEXT, hGlobal);
-#endif
     bSuccess = TRUE;
 
 done:
@@ -668,10 +822,10 @@ done:
     return bSuccess;
 }
 
-static BOOL CreateNewValue(HKEY hRootKey, LPCTSTR pszKeyPath, DWORD dwType)
+static BOOL CreateNewValue(HKEY hRootKey, LPCWSTR pszKeyPath, DWORD dwType)
 {
-    TCHAR szNewValueFormat[128];
-    TCHAR szNewValue[128];
+    WCHAR szNewValueFormat[128];
+    WCHAR szNewValue[128];
     int iIndex = 1;
     BYTE data[128];
     DWORD dwExistingType, cbData;
@@ -679,41 +833,50 @@ static BOOL CreateNewValue(HKEY hRootKey, LPCTSTR pszKeyPath, DWORD dwType)
     HKEY hKey;
     LVFINDINFO lvfi;
 
-    if (RegOpenKeyEx(hRootKey, pszKeyPath, 0, KEY_QUERY_VALUE | KEY_SET_VALUE,
-                     &hKey) != ERROR_SUCCESS)
+    if (RegOpenKeyExW(hRootKey, pszKeyPath, 0, KEY_QUERY_VALUE | KEY_SET_VALUE,
+                      &hKey) != ERROR_SUCCESS)
         return FALSE;
 
-    LoadString(hInst, IDS_NEW_VALUE, szNewValueFormat, COUNT_OF(szNewValueFormat));
+    LoadStringW(hInst, IDS_NEW_VALUE, szNewValueFormat, COUNT_OF(szNewValueFormat));
 
     do
     {
         wsprintf(szNewValue, szNewValueFormat, iIndex++);
         cbData = sizeof(data);
-        lResult = RegQueryValueEx(hKey, szNewValue, NULL, &dwExistingType, data, &cbData);
+        lResult = RegQueryValueExW(hKey, szNewValue, NULL, &dwExistingType, data, &cbData);
     }
     while(lResult == ERROR_SUCCESS);
 
     switch(dwType)
     {
-    case REG_DWORD:
-        cbData = sizeof(DWORD);
-        break;
-    case REG_SZ:
-    case REG_EXPAND_SZ:
-        cbData = sizeof(TCHAR);
-        break;
-    case REG_MULTI_SZ:
-        cbData = sizeof(TCHAR) * 2;
-        break;
-    case REG_QWORD:
-        cbData = sizeof(DWORD) * 2;
-        break;
-    default:
-        cbData = 0;
-        break;
+        case REG_DWORD:
+            cbData = sizeof(DWORD);
+            break;
+        case REG_SZ:
+        case REG_EXPAND_SZ:
+            cbData = sizeof(WCHAR);
+            break;
+        case REG_MULTI_SZ:
+            /*
+             * WARNING: An empty multi-string has only one null char.
+             * Indeed, multi-strings are built in the following form:
+             * str1\0str2\0...strN\0\0
+             * where each strI\0 is a null-terminated string, and it
+             * ends with a terminating empty string.
+             * Therefore an empty multi-string contains only the terminating
+             * empty string, that is, one null char.
+             */
+            cbData = sizeof(WCHAR);
+            break;
+        case REG_QWORD: /* REG_QWORD_LITTLE_ENDIAN */
+            cbData = sizeof(DWORDLONG); // == sizeof(DWORD) * 2;
+            break;
+        default:
+            cbData = 0;
+            break;
     }
     memset(data, 0, cbData);
-    lResult = RegSetValueEx(hKey, szNewValue, 0, dwType, data, cbData);
+    lResult = RegSetValueExW(hKey, szNewValue, 0, dwType, data, cbData);
     RegCloseKey(hKey);
     if (lResult != ERROR_SUCCESS)
     {
@@ -773,7 +936,7 @@ InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
 
         InitInfo.cbSize = sizeof(InitInfo);
         InitInfo.pwzTargetComputer = NULL;
-        InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]);
+        InitInfo.cDsScopeInfos = COUNT_OF(Scopes);
         InitInfo.aDsScopeInfos = Scopes;
         InitInfo.flOptions = 0;
         InitInfo.cAttributesToFetch = 0;
@@ -795,7 +958,7 @@ InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
 static HRESULT
 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
                                  IN HWND hwndParent  OPTIONAL,
-                                 OUT LPTSTR lpBuffer,
+                                 OUT LPWSTR lpBuffer,
                                  IN UINT uSize)
 {
     IDataObject *pdo = NULL;
@@ -809,7 +972,7 @@ InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
         STGMEDIUM stm;
         FORMATETC fe;
 
-        fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
+        fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST);
         fe.ptd = NULL;
         fe.dwAspect = DVASPECT_CONTENT;
         fe.lindex = -1;
@@ -830,20 +993,11 @@ InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
                     {
                         nlen = uSize - 1;
                     }
-#if UNICODE
+
                     memcpy(lpBuffer,
                            SelectionList->aDsSelection[0].pwzName,
                            nlen * sizeof(WCHAR));
-#else
-                    WideCharToMultiByte(CP_ACP,
-                                        0,
-                                        SelectionList->aDsSelection[0].pwzName,
-                                        nlen,
-                                        lpBuffer,
-                                        uSize,
-                                        NULL,
-                                        NULL);
-#endif
+
                     lpBuffer[nlen] = L'\0';
                 }
 
@@ -875,11 +1029,10 @@ FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 {
     HKEY hKeyRoot = 0, hKey = 0;
-    LPCTSTR keyPath;
-    LPCTSTR valueName;
+    LPCWSTR keyPath;
+    LPCWSTR valueName;
     BOOL result = TRUE;
     REGSAM regsam = KEY_READ;
-    LONG lRet;
     int item;
 
     UNREFERENCED_PARAMETER(lParam);
@@ -902,7 +1055,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     case ID_REGISTRY_CONNECTNETWORKREGISTRY:
     {
         IDsObjectPicker *ObjectPicker;
-        TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
+        WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
         HRESULT hRet;
 
         hRet = CoInitialize(NULL);
@@ -914,7 +1067,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
                                                         hWnd,
                                                         szComputerName,
-                                                        sizeof(szComputerName) / sizeof(szComputerName[0]));
+                                                        COUNT_OF(szComputerName));
                 if (hRet == S_OK)
                 {
                     /* FIXME - connect to the registry */
@@ -931,7 +1084,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
         return TRUE;
     case ID_REGISTRY_PRINT:
-        PrintRegistryHive(hWnd, _T(""));
+        PrintRegistryHive(hWnd, L"");
         return TRUE;
     case ID_REGISTRY_EXIT:
         DestroyWindow(hWnd);
@@ -940,7 +1093,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         toggle_child(hWnd, LOWORD(wParam), hStatusBar);
         return TRUE;
     case ID_HELP_HELPTOPICS:
-        WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
+        WinHelpW(hWnd, getAppName(), HELP_FINDER, 0);
         return TRUE;
     case ID_HELP_ABOUT:
         ShowAboutBox(hWnd);
@@ -956,8 +1109,8 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         if(ClientToScreen(g_pChildWnd->hWnd, &pts))
         {
             SetCursorPos(pts.x, pts.y);
-            SetCursor(LoadCursor(0, IDC_SIZEWE));
-            SendMessage(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
+            SetCursor(LoadCursorW(0, IDC_SIZEWE));
+            SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y));
         }
         return TRUE;
     }
@@ -973,8 +1126,8 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     valueName = GetValueName(g_pChildWnd->hListWnd, -1);
     if (keyPath)
     {
-        lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, regsam, &hKey);
-        if (lRet != ERROR_SUCCESS) hKey = 0;
+        if (RegOpenKeyExW(hKeyRoot, keyPath, 0, regsam, &hKey) != ERROR_SUCCESS)
+            hKey = 0;
     }
 
     switch (LOWORD(wParam))
@@ -1009,15 +1162,15 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         break;
     case ID_EDIT_DELETE:
     {
-        if (GetFocus() == g_pChildWnd->hListWnd)
+        if (GetFocus() == g_pChildWnd->hListWnd && hKey)
         {
             UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd);
             if(nSelected >= 1)
             {
-                TCHAR msg[128], caption[128];
-                LoadString(hInst, IDS_QUERY_DELETE_CONFIRM, caption, sizeof(caption)/sizeof(TCHAR));
-                LoadString(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, sizeof(msg)/sizeof(TCHAR));
-                if(MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
+                WCHAR msg[128], caption[128];
+                LoadStringW(hInst, IDS_QUERY_DELETE_CONFIRM, caption, COUNT_OF(caption));
+                LoadStringW(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, COUNT_OF(msg));
+                if(MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES)
                 {
                     int ni, errs;
 
@@ -1026,7 +1179,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                     while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
                     {
                         valueName = GetValueName(g_pChildWnd->hListWnd, item);
-                        if(RegDeleteValue(hKey, valueName) != ERROR_SUCCESS)
+                        if(RegDeleteValueW(hKey, valueName) != ERROR_SUCCESS)
                         {
                             errs++;
                         }
@@ -1036,16 +1189,16 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
                     RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
                     if(errs > 0)
                     {
-                        LoadString(hInst, IDS_ERR_DELVAL_CAPTION, caption, sizeof(caption)/sizeof(TCHAR));
-                        LoadString(hInst, IDS_ERR_DELETEVALUE, msg, sizeof(msg)/sizeof(TCHAR));
-                        MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
+                        LoadStringW(hInst, IDS_ERR_DELVAL_CAPTION, caption, COUNT_OF(caption));
+                        LoadStringW(hInst, IDS_ERR_DELETEVALUE, msg, COUNT_OF(msg));
+                        MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP);
                     }
                 }
             }
         }
         else if (GetFocus() == g_pChildWnd->hTreeWnd)
         {
-            if (keyPath == 0 || *keyPath == 0)
+            if (keyPath == NULL || *keyPath == UNICODE_NULL)
             {
                 MessageBeep(MB_ICONHAND);
             }
@@ -1095,7 +1248,8 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
 
     case ID_VIEW_REFRESH:
         RefreshTreeView(g_pChildWnd->hTreeWnd);
-        /*RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL); */
+        keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
+        RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
         break;
         /*case ID_OPTIONS_TOOLBAR:*/
         /*     toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
@@ -1107,8 +1261,8 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX))
         {
             HMENU hMenu;
-            MENUITEMINFO mii;
-            TCHAR szFavorite[512];
+            MENUITEMINFOW mii;
+            WCHAR szFavorite[512];
 
             hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
 
@@ -1117,7 +1271,7 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
             mii.fMask = MIIM_TYPE;
             mii.fType = MFT_STRING;
             mii.dwTypeData = szFavorite;
-            mii.cch = sizeof(szFavorite) / sizeof(szFavorite[0]);
+            mii.cch = COUNT_OF(szFavorite);
 
             if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii))
             {
@@ -1152,16 +1306,16 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
     switch (message)
     {
     case WM_CREATE:
-        CreateWindowEx(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
+        CreateWindowExW(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                        hWnd, (HMENU)0, hInst, 0);
         break;
     case WM_COMMAND:
         if (!_CmdWndProc(hWnd, message, wParam, lParam))
-            return DefWindowProc(hWnd, message, wParam, lParam);
+            return DefWindowProcW(hWnd, message, wParam, lParam);
         break;
     case WM_ACTIVATE:
-        if (LOWORD(hWnd))
+        if (LOWORD(hWnd) && g_pChildWnd)
             SetFocus(g_pChildWnd->hWnd);
         break;
     case WM_SIZE:
@@ -1183,14 +1337,15 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
         break;
     case WM_SYSCOLORCHANGE:
         /* Forward WM_SYSCOLORCHANGE to common controls */
-        SendMessage(g_pChildWnd->hListWnd, WM_SYSCOLORCHANGE, 0, 0);
-        SendMessage(g_pChildWnd->hTreeWnd, WM_SYSCOLORCHANGE, 0, 0);
+        SendMessageW(g_pChildWnd->hListWnd, WM_SYSCOLORCHANGE, 0, 0);
+        SendMessageW(g_pChildWnd->hTreeWnd, WM_SYSCOLORCHANGE, 0, 0);
         break;
     case WM_DESTROY:
-        WinHelp(hWnd, _T("regedit"), HELP_QUIT, 0);
+        WinHelpW(hWnd, getAppName(), HELP_QUIT, 0);
+        SaveSettings();
         PostQuitMessage(0);
     default:
-        return DefWindowProc(hWnd, message, wParam, lParam);
+        return DefWindowProcW(hWnd, message, wParam, lParam);
     }
     return 0;
 }