- Get autochk, calc, cmd, devmgr, expand, format, gettype, hostname, lsass, msconfig...
[reactos.git] / reactos / subsys / system / regedit / framewnd.c
index 21865f9..01f271f 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 */
-
-#include <windows.h>
-#include <tchar.h>
-#include <commctrl.h>
-#include <commdlg.h>
-#include <cderr.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <shellapi.h>
-
-#include "main.h"
-#include "regproc.h"
+#include <regedit.h>
 
 /********************************************************************************
  * Global and Local Variables:
  */
 
+#define FAVORITES_MENU_POSITION 3
+
+static TCHAR s_szFavoritesRegKey[] = _T("Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites");
+
 static BOOL bInMenuLoop = FALSE;        /* Tells us if we are in the menu loop */
 
 /*******************************************************************************
@@ -61,7 +53,7 @@ static void resize_frame_rect(HWND hWnd, PRECT prect)
     MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE);
 }
 
-void resize_frame_client(HWND hWnd)
+static void resize_frame_client(HWND hWnd)
 {
     RECT rect;
 
@@ -71,13 +63,66 @@ void resize_frame_client(HWND hWnd)
 
 /********************************************************************************/
 
+static void OnInitMenu(HWND hWnd)
+{
+    LONG lResult;
+    HKEY hKey = NULL;
+    DWORD dwIndex, cbValueName, cbValueData, dwType;
+    TCHAR szValueName[256];
+    BYTE abValueData[256];
+    static int s_nFavoriteMenuSubPos = -1;
+    HMENU hMenu;
+    BOOL bDisplayedAny = FALSE;
+
+    /* Find Favorites menu and clear it out */
+    hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
+    if (!hMenu)
+        goto done;
+    if (s_nFavoriteMenuSubPos < 0)
+    {
+        s_nFavoriteMenuSubPos = GetMenuItemCount(hMenu);
+    }
+    else
+    {
+        while(RemoveMenu(hMenu, s_nFavoriteMenuSubPos, MF_BYPOSITION))
+            ;
+    }
+    
+    lResult = RegOpenKey(HKEY_CURRENT_USER, s_szFavoritesRegKey, &hKey);
+    if (lResult != ERROR_SUCCESS)
+        goto done;
+
+    dwIndex = 0;
+    do
+    {
+        cbValueName = sizeof(szValueName) / sizeof(szValueName[0]);
+        cbValueData = sizeof(abValueData);
+        lResult = RegEnumValue(hKey, dwIndex, szValueName, &cbValueName, NULL, &dwType, abValueData, &cbValueData);
+        if ((lResult == ERROR_SUCCESS) && (dwType == REG_SZ))
+        {
+            if (!bDisplayedAny)
+            {
+                AppendMenu(hMenu, MF_SEPARATOR, 0, NULL);
+                bDisplayedAny = TRUE;
+            }
+            AppendMenu(hMenu, 0, ID_FAVORITES_MIN + GetMenuItemCount(hMenu), szValueName);
+        }
+        dwIndex++;
+    }
+    while(lResult == ERROR_SUCCESS);
+
+done:
+    if (hKey)
+        RegCloseKey(hKey);
+}
+
 static void OnEnterMenuLoop(HWND hWnd)
 {
     int nParts;
 
     /* Update the status bar pane sizes */
     nParts = -1;
-    SendMessage(hStatusBar, SB_SETPARTS, 1, (long)&nParts);
+    SendMessage(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts);
     bInMenuLoop = TRUE;
     SendMessage(hStatusBar, SB_SETTEXT, (WPARAM)0, (LPARAM)_T(""));
 }
@@ -183,38 +228,53 @@ static BOOL CheckCommDlgError(HWND hWnd)
     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];
 
+typedef struct
+{
+  UINT DisplayID;
+  UINT FilterID;
+} FILTERPAIR, *PFILTERPAIR;
+
+void
+BuildFilterStrings(TCHAR *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';
+  }
+  Filter[++c] = '\0';
+}
+
 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
 {
+    FILTERPAIR FilterPairs[3];
+    static TCHAR Filter[1024];
+
     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");
+    /* 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));
+
+    pofn->lpstrFilter = Filter;
     pofn->lpstrCustomFilter = CustomFilterBuffer;
     pofn->nMaxCustFilter = MAX_CUSTOM_FILTER_SIZE;
     pofn->nFilterIndex = 0;
@@ -240,12 +300,15 @@ static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn)
 static BOOL ImportRegistryFile(HWND hWnd)
 {
     OPENFILENAME ofn;
+    TCHAR Caption[128];
 
     InitOpenFileName(hWnd, &ofn);
-    ofn.lpstrTitle = _T("Import Registry File");
+    LoadString(hInst, IDS_IMPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
+    ofn.lpstrTitle = Caption;
     /*    ofn.lCustData = ;*/
     if (GetOpenFileName(&ofn)) {
-        if (!import_registry_file(ofn.lpstrFile)) {
+        /* FIXME - convert to ascii */
+       if (!import_registry_file(ofn.lpstrFile)) {
             /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
             return FALSE;
         }
@@ -274,23 +337,90 @@ static BOOL ImportRegistryFile(HWND hWnd)
 }
 
 
-static BOOL ExportRegistryFile(HWND hWnd)
+static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
+{
+    HWND hwndExportAll;
+    HWND hwndExportBranch;
+    HWND hwndExportBranchText;
+    UINT_PTR iResult = 0;
+    OPENFILENAME *pOfn;
+    LPTSTR pszSelectedKey;
+    OFNOTIFY *pOfnNotify;
+
+       switch(uiMsg) {
+       case WM_INITDIALOG:
+        pOfn = (OPENFILENAME *) lParam;
+        pszSelectedKey = (LPTSTR) pOfn->lCustData;
+
+        hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL);
+        if (hwndExportAll)
+                       SendMessage(hwndExportAll, BM_SETCHECK, pszSelectedKey[0] ? BST_UNCHECKED : BST_CHECKED, 0);
+
+        hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH);
+        if (hwndExportBranch)
+            SendMessage(hwndExportBranch, BM_SETCHECK, pszSelectedKey[0] ? BST_CHECKED : BST_UNCHECKED, 0);
+
+        hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT);
+        if (hwndExportBranchText)
+            SetWindowText(hwndExportBranchText, pszSelectedKey);
+        break;
+
+       case WM_NOTIFY:
+        if (((NMHDR *) lParam)->code == CDN_FILEOK)
+        {
+            pOfnNotify = (OFNOTIFY *) lParam;
+            pszSelectedKey = (LPTSTR) 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))
+                       {
+                           GetWindowText(hwndExportBranchText, pszSelectedKey, _MAX_PATH);
+                       }
+                       else
+                       {
+                           pszSelectedKey[0] = '\0';
+                       }
+               }
+        break;
+    }
+    return iResult;
+}
+
+BOOL ExportRegistryFile(HWND hWnd)
 {
     OPENFILENAME ofn;
     TCHAR ExportKeyPath[_MAX_PATH];
+    TCHAR Caption[128];
+    HKEY hKeyRoot;
+    LPCTSTR pszKeyPath;
+
+    /* Figure out which key path we are exporting */
+    pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
+    RegKeyGetName(ExportKeyPath, sizeof(ExportKeyPath) / sizeof(ExportKeyPath[0]),
+        hKeyRoot, pszKeyPath);
 
-    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);
+    LoadString(hInst, IDS_EXPORT_REG_FILE, Caption, sizeof(Caption)/sizeof(TCHAR));
+    ofn.lpstrTitle = Caption;
+    ofn.lCustData = (LPARAM) ExportKeyPath;
+    ofn.Flags = OFN_ENABLETEMPLATE | OFN_EXPLORER | OFN_ENABLEHOOK;
+    ofn.lpfnHook = ExportRegistryFile_OFNHookProc;
+    ofn.lpTemplateName = MAKEINTRESOURCE(IDD_EXPORTRANGE);
     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)) {*/
+        LPSTR pszExportKeyPath;
+#ifdef UNICODE
+        CHAR buffer[_MAX_PATH];
+
+        WideCharToMultiByte(CP_ACP, 0, ExportKeyPath, -1, buffer, sizeof(buffer), NULL, NULL);
+        pszExportKeyPath = buffer;
+#else
+        pszExportKeyPath = ExportKeyPath;
+#endif
+
+        result = export_registry_key(ofn.lpstrFile, pszExportKeyPath);
         if (!result) {
             /*printf("Can't open file \"%s\"\n", ofn.lpstrFile);*/
             return FALSE;
@@ -307,7 +437,7 @@ static BOOL ExportRegistryFile(HWND hWnd)
         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);
+            export_registry_key((CHAR)filename, reg_key_name);
         } else {
             export_registry_key(filename, NULL);
         }
@@ -335,7 +465,7 @@ BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
     pd.nToPage     = 0xFFFF;
     pd.nMinPage    = 1;
     pd.nMaxPage    = 0xFFFF;
-    if (PrintDlg(&pd) == TRUE) {
+    if (PrintDlg(&pd)) {
         /* GDI calls to render output. */
         DeleteDC(pd.hDC); /* Delete DC when done.*/
     }
@@ -384,46 +514,260 @@ BOOL PrintRegistryHive(HWND hWnd, LPTSTR path)
     return TRUE;
 }
 
-BOOL CopyKeyName(HWND hWnd, LPTSTR keyName)
+static void ChooseFavorite(LPCTSTR pszFavorite)
 {
-    BOOL result;
+    HKEY hKey = NULL;
+    TCHAR szFavoritePath[512];
+    DWORD cbData, dwType;
 
-    result = OpenClipboard(hWnd);
-    if (result) {
-        result = EmptyClipboard();
-        if (result) {
+    if (RegOpenKeyEx(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
+        goto done;
 
-            /*HANDLE hClipData;*/
-            /*hClipData = SetClipboardData(UINT uFormat, HANDLE hMem);*/
+    cbData = (sizeof(szFavoritePath) / sizeof(szFavoritePath[0])) - 1;
+    memset(szFavoritePath, 0, sizeof(szFavoritePath));
+    if (RegQueryValueEx(hKey, pszFavorite, NULL, &dwType, (LPBYTE) szFavoritePath, &cbData) != ERROR_SUCCESS)
+        goto done;
 
-        } else {
-            /* error emptying clipboard*/
-            /* DWORD dwError = GetLastError(); */
-            ;
+    if (dwType == REG_SZ)
+        SelectNode(g_pChildWnd->hTreeWnd, szFavoritePath);
+
+done:
+    if (hKey)
+        RegCloseKey(hKey);
+}
+
+BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCTSTR keyName)
+{
+    BOOL bClipboardOpened = FALSE;
+    BOOL bSuccess = FALSE;
+    TCHAR szBuffer[512];
+    HGLOBAL hGlobal;
+    LPTSTR s;
+
+    if (!OpenClipboard(hWnd))
+        goto done;
+    bClipboardOpened = TRUE;
+
+    if (!EmptyClipboard())
+        goto done;
+
+    if (!RegKeyGetName(szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0]), hRootKey, keyName))
+        goto done;
+
+    hGlobal = GlobalAlloc(GMEM_MOVEABLE, (_tcslen(szBuffer) + 1) * sizeof(TCHAR));
+    if (!hGlobal)
+        goto done;
+
+    s = GlobalLock(hGlobal);
+    _tcscpy(s, szBuffer);
+    GlobalUnlock(hGlobal);
+
+#ifdef UNICODE
+    SetClipboardData(CF_UNICODETEXT, hGlobal);
+#else
+    SetClipboardData(CF_TEXT, hGlobal);
+#endif
+    bSuccess = TRUE;
+
+done:
+    if (bClipboardOpened)
+        CloseClipboard();
+    return bSuccess;
+}
+
+static BOOL CreateNewValue(HKEY hRootKey, LPCTSTR pszKeyPath, DWORD dwType)
+{
+    TCHAR szNewValueFormat[128];
+    TCHAR szNewValue[128];
+    int iIndex = 1;
+    BYTE data[128];
+    DWORD dwExistingType, cbData;
+    LONG lResult;
+    HKEY hKey;
+    LVFINDINFO lvfi;
+
+    if (RegOpenKey(hRootKey, pszKeyPath, &hKey) != ERROR_SUCCESS)
+        return FALSE;    
+
+    LoadString(hInst, IDS_NEW_VALUE, szNewValueFormat, sizeof(szNewValueFormat)
+        / sizeof(szNewValueFormat[0]));
+
+    do
+    {
+        _sntprintf(szNewValue, sizeof(szNewValue) / sizeof(szNewValue[0]),
+            szNewValueFormat, iIndex++);
+
+        cbData = sizeof(data);
+        lResult = RegQueryValueEx(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;
+    }
+    memset(data, 0, cbData);
+    lResult = RegSetValueEx(hKey, szNewValue, 0, dwType, data, cbData);
+    if (lResult != ERROR_SUCCESS)
+        return FALSE;
+
+    RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath);
+
+    /* locate the newly added value, and get ready to rename it */
+    memset(&lvfi, 0, sizeof(lvfi));
+    lvfi.flags = LVFI_STRING;
+    lvfi.psz = szNewValue;
+    iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi);
+    if (iIndex >= 0)
+        ListView_EditLabel(g_pChildWnd->hListWnd, iIndex);
+
+    return TRUE;
+}
+
+static HRESULT
+InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker)
+{
+    HRESULT hRet;
+
+    *pDsObjectPicker = NULL;
+
+    hRet = CoCreateInstance(&CLSID_DsObjectPicker,
+                            NULL,
+                            CLSCTX_INPROC_SERVER,
+                            &IID_IDsObjectPicker,
+                            (LPVOID*)pDsObjectPicker);
+    if (SUCCEEDED(hRet))
+    {
+        DSOP_INIT_INFO InitInfo;
+        static DSOP_SCOPE_INIT_INFO Scopes[] =
+        {
+            {
+                sizeof(DSOP_SCOPE_INIT_INFO),
+                DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE |
+                    DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN |
+                    DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP |
+                    DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN,
+                0,
+                {
+                    {
+                        DSOP_FILTER_COMPUTERS,
+                        0,
+                        0
+                    },
+                    DSOP_DOWNLEVEL_FILTER_COMPUTERS
+                },
+                NULL,
+                NULL,
+                S_OK
+            },
+        };
+
+        InitInfo.cbSize = sizeof(InitInfo);
+        InitInfo.pwzTargetComputer = NULL;
+        InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]);
+        InitInfo.aDsScopeInfos = Scopes;
+        InitInfo.flOptions = 0;
+        InitInfo.cAttributesToFetch = 0;
+        InitInfo.apwzAttributeNames = NULL;
+
+        hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker,
+                                                      &InitInfo);
+
+        if (FAILED(hRet))
+        {
+            /* delete the object picker in case initialization failed! */
+            (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker);
         }
-        if (!CloseClipboard()) {
-            /* error closing clipboard*/
-            /* DWORD dwError = GetLastError(); */
-            ;
+    }
+
+    return hRet;
+}
+
+static HRESULT
+InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker,
+                                 IN HWND hwndParent  OPTIONAL,
+                                 OUT LPTSTR lpBuffer,
+                                 IN UINT uSize)
+{
+    IDataObject *pdo = NULL;
+    HRESULT hRet;
+
+    hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker,
+                                                 hwndParent,
+                                                 &pdo);
+    if (hRet == S_OK)
+    {
+        STGMEDIUM stm;
+        FORMATETC fe;
+
+        fe.cfFormat = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST);
+        fe.ptd = NULL;
+        fe.dwAspect = DVASPECT_CONTENT;
+        fe.lindex = -1;
+        fe.tymed = TYMED_HGLOBAL;
+
+        hRet = pdo->lpVtbl->GetData(pdo,
+                                    &fe,
+                                    &stm);
+        if (SUCCEEDED(hRet))
+        {
+            PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal);
+            if (SelectionList != NULL)
+            {
+                if (SelectionList->cItems == 1)
+                {
+                    UINT nlen = wcslen(SelectionList->aDsSelection[0].pwzName);
+                    if (nlen >= uSize)
+                    {
+                        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';
+                }
+
+                GlobalUnlock(stm.hGlobal);
+            }
+
+            ReleaseStgMedium(&stm);
         }
-    } else {
-        /* error opening clipboard*/
-        /* DWORD dwError = GetLastError(); */
-        ;
+
+        pdo->lpVtbl->Release(pdo);
     }
-    return result;
+
+    return hRet;
 }
 
-BOOL RefreshView(HWND hWnd)
+static VOID
+FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker)
 {
-    /* TODO:*/
-    MessageBeep(-1);
-    MessageBeep(MB_ICONASTERISK);
-    MessageBeep(MB_ICONEXCLAMATION);
-    MessageBeep(MB_ICONHAND);
-    MessageBeep(MB_ICONQUESTION);
-    MessageBeep(MB_OK);
-    return TRUE;
+    pDsObjectPicker->lpVtbl->Release(pDsObjectPicker);
 }
 
 /*******************************************************************************
@@ -439,35 +783,194 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
     LPCTSTR keyPath;
     LPCTSTR valueName;
     BOOL result = TRUE;
+    REGSAM regsam = KEY_READ;
     LONG lRet;
-
-    keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
-    valueName = GetValueName(g_pChildWnd->hListWnd);
-    if (keyPath) {
-        lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, KEY_READ, &hKey);
-        if (lRet != ERROR_SUCCESS) hKey = 0;
-    }
+    int item;
 
     switch (LOWORD(wParam)) {
     case ID_REGISTRY_IMPORTREGISTRYFILE:
         ImportRegistryFile(hWnd);
-        break;
+        return TRUE;
     case ID_REGISTRY_EXPORTREGISTRYFILE:
         ExportRegistryFile(hWnd);
-        break;
+        return TRUE;
     case ID_REGISTRY_CONNECTNETWORKREGISTRY:
-        break;
+    {
+        IDsObjectPicker *ObjectPicker;
+        TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1];
+        HRESULT hRet;
+        
+        hRet = CoInitialize(NULL);
+        if (SUCCEEDED(hRet))
+        {
+            hRet = InitializeRemoteRegistryPicker(&ObjectPicker);
+            if (SUCCEEDED(hRet))
+            {
+                hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker,
+                                                        hWnd,
+                                                        szComputerName,
+                                                        sizeof(szComputerName) / sizeof(szComputerName[0]));
+                if (hRet == S_OK)
+                {
+                    /* FIXME - connect to the registry */
+                }
+
+                FreeObjectPicker(ObjectPicker);
+            }
+
+            CoUninitialize();
+        }
+
+        return TRUE;
+    }
     case ID_REGISTRY_DISCONNECTNETWORKREGISTRY:
-        break;
+        return TRUE;
     case ID_REGISTRY_PRINT:
         PrintRegistryHive(hWnd, _T(""));
+        return TRUE;
+    case ID_REGISTRY_EXIT:
+        DestroyWindow(hWnd);
+        return TRUE;
+    case ID_VIEW_STATUSBAR:
+        toggle_child(hWnd, LOWORD(wParam), hStatusBar);
+        return TRUE;
+    case ID_HELP_HELPTOPICS:
+        WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
+        return TRUE;
+    case ID_HELP_ABOUT:
+        ShowAboutBox(hWnd);
+        return TRUE;
+    case ID_VIEW_SPLIT:
+    {
+        RECT rt;
+        POINT pt, pts;
+        GetClientRect(g_pChildWnd->hWnd, &rt);
+        pt.x = rt.left + g_pChildWnd->nSplitPos;
+        pt.y = (rt.bottom / 2);
+        pts = pt;
+        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));
+        }
+        return TRUE;
+    }
+    case ID_EDIT_RENAME:
+    case ID_EDIT_MODIFY:
+    case ID_EDIT_MODIFY_BIN:
+    case ID_EDIT_DELETE:
+        regsam |= KEY_WRITE;
         break;
+    }
+
+    keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot);
+    valueName = GetValueName(g_pChildWnd->hListWnd, -1);
+    if (keyPath) {
+        lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, regsam, &hKey);
+        if (lRet != ERROR_SUCCESS) hKey = 0;
+    }
+
+     switch (LOWORD(wParam)) {
     case ID_EDIT_MODIFY:
-        if (ModifyValue(hWnd, hKey, valueName))
+        if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE))
             RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
         break;
+    case ID_EDIT_MODIFY_BIN:
+        if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE))
+            RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath);
+        break;
+    case ID_EDIT_RENAME:
+        if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1)
+        {
+          item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED);
+          if(item > -1)
+          {
+            ListView_EditLabel(g_pChildWnd->hListWnd, item);
+          }
+        }
+        break;
+    case ID_EDIT_DELETE:
+    {
+        if (GetFocus() == g_pChildWnd->hListWnd)
+        {
+          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)
+            {
+              int ni, errs;
+
+              item = -1;
+              errs = 0;
+              while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1)
+              {
+                valueName = GetValueName(g_pChildWnd->hListWnd, item);
+                if(RegDeleteValue(hKey, valueName) != ERROR_SUCCESS)
+                {
+                  errs++;
+                }
+                item = ni;
+              }
+
+              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);
+              }
+            }
+          }
+        } else 
+        if (GetFocus() == g_pChildWnd->hTreeWnd)
+        {
+          if (keyPath == 0 || *keyPath == 0)
+          {
+             MessageBeep(MB_ICONHAND); 
+          } else
+          if (DeleteKey(hWnd, hKeyRoot, keyPath))
+            DeleteNode(g_pChildWnd->hTreeWnd, 0);
+        }
+       break;
+    case ID_EDIT_NEW_STRINGVALUE:
+        CreateNewValue(hKeyRoot, keyPath, REG_SZ);
+        break;
+    case ID_EDIT_NEW_BINARYVALUE:
+        CreateNewValue(hKeyRoot, keyPath, REG_BINARY);
+        break;
+    case ID_EDIT_NEW_DWORDVALUE:
+        CreateNewValue(hKeyRoot, keyPath, REG_DWORD);
+        break;
+       case ID_EDIT_NEW_MULTISTRINGVALUE:
+        CreateNewValue(hKeyRoot, keyPath, REG_MULTI_SZ);
+        break;
+       case ID_EDIT_NEW_EXPANDABLESTRINGVALUE:
+        CreateNewValue(hKeyRoot, keyPath, REG_EXPAND_SZ);
+        break;
+
+    }
+    case ID_EDIT_FIND:
+        FindDialog(hWnd);
+        break;
+    case ID_EDIT_FINDNEXT:
+        FindNext(hWnd);
+        break;
     case ID_EDIT_COPYKEYNAME:
-        CopyKeyName(hWnd, _T(""));
+        CopyKeyName(hWnd, hKeyRoot, keyPath);
+        break;
+    case ID_EDIT_PERMISSIONS:
+        if(keyPath != NULL && _tcslen(keyPath) > 0)
+        {
+          RegKeyEditPermissions(hWnd, hKey, NULL, keyPath);
+        }
+        else
+        {
+          MessageBeep(MB_ICONASTERISK);
+        }
         break;
     case ID_REGISTRY_PRINTERSETUP:
         /*PRINTDLG pd;*/
@@ -477,29 +980,47 @@ static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
         break;
     case ID_REGISTRY_OPENLOCAL:
         break;
-    case ID_REGISTRY_EXIT:
-        DestroyWindow(hWnd);
-        break;
+
     case ID_VIEW_REFRESH:
-        RefreshView(hWnd);
+        RefreshTreeView(g_pChildWnd->hTreeWnd);
+        /*RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, NULL); */
         break;
    /*case ID_OPTIONS_TOOLBAR:*/
    /*  toggle_child(hWnd, LOWORD(wParam), hToolBar);*/
    /*    break;*/
-    case ID_VIEW_STATUSBAR:
-        toggle_child(hWnd, LOWORD(wParam), hStatusBar);
-        break;
-    case ID_HELP_HELPTOPICS:
-        WinHelp(hWnd, _T("regedit"), HELP_FINDER, 0);
-        break;
-    case ID_HELP_ABOUT:
-        ShowAboutBox(hWnd);
+    case ID_EDIT_NEW_KEY:
+        CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd));
         break;
     default:
-        result = FALSE;
+        if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX))
+        {
+            HMENU hMenu;
+            MENUITEMINFO mii;
+            TCHAR szFavorite[512];
+
+            hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION);
+
+            memset(&mii, 0, sizeof(mii));
+            mii.cbSize = sizeof(mii);
+            mii.fMask = MIIM_TYPE;
+            mii.fType = MFT_STRING;
+            mii.dwTypeData = szFavorite;
+            mii.cch = sizeof(szFavorite) / sizeof(szFavorite[0]);
+
+            if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii))
+            {
+                ChooseFavorite(szFavorite);
+            }
+        }
+        else
+        {
+            result = FALSE;
+        }
+        break;
     }
 
-    RegCloseKey(hKey);
+    if(hKey)
+      RegCloseKey(hKey);
     return result;
 }
 
@@ -518,7 +1039,7 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
 {
     switch (message) {
     case WM_CREATE:
-        CreateWindowEx(0, szChildClass, _T("regedit child window"), WS_CHILD | WS_VISIBLE,
+        CreateWindowEx(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE,
                        CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
                        hWnd, (HMENU)0, hInst, 0);
         break;
@@ -526,11 +1047,18 @@ LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lPa
         if (!_CmdWndProc(hWnd, message, wParam, lParam))
             return DefWindowProc(hWnd, message, wParam, lParam);
         break;
+    case WM_ACTIVATE:
+        if (LOWORD(hWnd)) 
+            SetFocus(g_pChildWnd->hWnd);
+        break;
     case WM_SIZE:
         resize_frame_client(hWnd);
         break;
     case WM_TIMER:
         break;
+    case WM_INITMENU:
+        OnInitMenu(hWnd);
+        break;
     case WM_ENTERMENULOOP:
         OnEnterMenuLoop(hWnd);
         break;