Index: base/applications/regedit/lang/en-US.rc =================================================================== --- base/applications/regedit/lang/en-US.rc (revision 49398) +++ base/applications/regedit/lang/en-US.rc (working copy) @@ -274,6 +274,10 @@ ID_REGISTRY_IMPORTREGISTRYFILE "Imports a text file into the registry" ID_REGISTRY_EXPORTREGISTRYFILE "Exports all or part of the registry to a text file" + ID_REGISTRY_LOADHIVE + "Loads a hive file into the registry" + ID_REGISTRY_UNLOADHIVE + "Unloads a hive from the registry" ID_REGISTRY_CONNECTNETWORKREGISTRY "Connects to a remote computer's registry" ID_REGISTRY_DISCONNECTNETWORKREGISTRY @@ -330,6 +334,8 @@ IDS_MY_COMPUTER "My Computer" IDS_IMPORT_REG_FILE "Import Registry File" IDS_EXPORT_REG_FILE "Export Registry File" + IDS_LOAD_HIVE "Load Hive" + IDS_UNLOAD_HIVE "Unload Hive" IDS_INVALID_DWORD "(invalid DWORD value)" END @@ -392,6 +398,20 @@ EDITTEXT IDC_EXPORT_BRANCH_TEXT,30,34,335,12 END +// +// Dialog resources +// +IDD_LOADHIVE DIALOGEX DISCARDABLE 0, 0, 193, 34 +STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Load Hive" +FONT 8, "Ms Shell Dlg" +{ + LTEXT "&Key:", IDC_STATIC, 4, 4, 15, 8, SS_LEFT + EDITTEXT IDC_EDIT_KEY, 23, 2, 167, 13 + DEFPUSHBUTTON "OK", IDOK, 140, 17, 50, 14 + PUSHBUTTON "Cancel", IDCANCEL, 89, 17, 50, 14 +} + IDD_ADDFAVORITES DIALOGEX DISCARDABLE 0, 0, 186, 46 STYLE DS_SHELLFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Add to Favorites" Index: base/applications/regedit/framewnd.c =================================================================== --- base/applications/regedit/framewnd.c (revision 49398) +++ base/applications/regedit/framewnd.c (working copy) @@ -282,6 +282,105 @@ return TRUE; } +static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + static LPTSTR sKey = NULL; + static INT sLength = 0; + switch(uMsg) + { + case WM_INITDIALOG: + sKey = (LPTSTR)lParam; + sLength = 128; /* FIXME: Ugly hack! */ + case WM_COMMAND: + switch(LOWORD(wParam)) + { + case IDOK: + if(GetDlgItemText(hWndDlg, IDC_EDIT_KEY, sKey, sLength)) + return EndDialog(hWndDlg, -1); + else + return EndDialog(hWndDlg, 0); + case IDCANCEL: + return EndDialog(hWndDlg, 0); + } + break; + } + return FALSE; +} + +static BOOL LoadHive(HWND hWnd) +{ + OPENFILENAME ofn; + TCHAR Caption[128]; + LPCTSTR pszKeyPath; + TCHAR xPath[128]; + HKEY hRootKey; + TCHAR Filter[1024]; + FILTERPAIR filter; + /* get the item key to load the hive in */ + pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); + /* initialize the "open file" dialog */ + InitOpenFileName(hWnd, &ofn); + /* build the "All Files" filter up */ + filter.DisplayID = IDS_FLT_ALLFILES; + filter.FilterID = IDS_FLT_ALLFILES_FLT; + BuildFilterStrings(Filter, &filter, sizeof(filter)); + ofn.lpstrFilter = Filter; + /* load and set the caption and flags for dialog */ + LoadString(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)) + { + LONG regLoadResult = RegLoadKey(hRootKey, xPath, ofn.lpstrFile); + if(regLoadResult == ERROR_SUCCESS) + { + /* refresh tree and list views */ + RefreshTreeView(g_pChildWnd->hTreeWnd); + pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); + RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath); + } + else + { + ErrorMessageBox(hWnd, Caption, regLoadResult); + return FALSE; + } + } + } else { + CheckCommDlgError(hWnd); + } + return TRUE; +} + +static BOOL UnloadHive(HWND hWnd) +{ + TCHAR Caption[128]; + LPCTSTR pszKeyPath; + HKEY hRootKey; + /* 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 */ + LONG regUnloadResult = RegUnLoadKey(hRootKey, pszKeyPath); + if(regUnloadResult == ERROR_SUCCESS) + { + /* refresh tree and list views */ + RefreshTreeView(g_pChildWnd->hTreeWnd); + pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); + RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath); + } + else + { + ErrorMessageBox(hWnd, Caption, regUnloadResult); + return FALSE; + } + return TRUE; +} + static BOOL ImportRegistryFile(HWND hWnd) { OPENFILENAME ofn; @@ -316,7 +415,6 @@ return TRUE; } - static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) { HWND hwndExportAll; @@ -397,7 +495,7 @@ if (GetSaveFileName(&ofn)) { BOOL result; DWORD format; - + if (ofn.nFilterIndex == 1) format = REG_FORMAT_5; else @@ -758,6 +856,12 @@ UNREFERENCED_PARAMETER(message); switch (LOWORD(wParam)) { + case ID_REGISTRY_LOADHIVE: + LoadHive(hWnd); + return TRUE; + case ID_REGISTRY_UNLOADHIVE: + UnloadHive(hWnd); + return TRUE; case ID_REGISTRY_IMPORTREGISTRYFILE: ImportRegistryFile(hWnd); return TRUE; Index: base/applications/regedit/regedit.rbuild =================================================================== --- base/applications/regedit/regedit.rbuild (revision 49398) +++ base/applications/regedit/regedit.rbuild (working copy) @@ -23,6 +23,7 @@ hexedit.c listview.c main.c + error.c regedit.c regproc.c security.c Index: base/applications/regedit/edit.c =================================================================== --- base/applications/regedit/edit.c (revision 49398) +++ base/applications/regedit/edit.c (working copy) @@ -59,19 +59,10 @@ static void error_code_messagebox(HWND hwnd, DWORD error_code) { - LPTSTR lpMsgBuf; - DWORD status; TCHAR title[256]; - static const TCHAR fallback[] = TEXT("Error displaying error message.\n"); if (!LoadString(hInst, IDS_ERROR, title, COUNT_OF(title))) lstrcpy(title, TEXT("Error")); - status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, - NULL, error_code, 0, (LPTSTR)&lpMsgBuf, 0, NULL); - if (!status) - lpMsgBuf = (LPTSTR)fallback; - MessageBox(hwnd, lpMsgBuf, title, MB_OK | MB_ICONERROR); - if (lpMsgBuf != fallback) - LocalFree(lpMsgBuf); + ErrorMessageBox(hwnd, title, error_code); } void warning(HWND hwnd, INT resId, ...) Index: base/applications/regedit/main.h =================================================================== --- base/applications/regedit/main.h (revision 49398) +++ base/applications/regedit/main.h (working copy) @@ -58,6 +58,7 @@ HWND hTreeWnd; HWND hListWnd; HWND hAddressBarWnd; + HWND hAddressBtnWnd; int nFocusPanel; /* 0: left 1: right */ int nSplitPos; WINDOWPLACEMENT pos; @@ -88,6 +89,9 @@ /* childwnd.c */ extern LRESULT CALLBACK ChildWndProc(HWND, UINT, WPARAM, LPARAM); +/* error.c */ +extern void ErrorMessageBox(HWND hWnd, LPCTSTR title, DWORD code); + /* find.c */ extern void FindDialog(HWND hWnd); extern BOOL FindNext(HWND hWnd); Index: base/applications/regedit/treeview.c =================================================================== --- base/applications/regedit/treeview.c (revision 49398) +++ base/applications/regedit/treeview.c (working copy) @@ -633,7 +633,7 @@ TVITEM tvi; /* Total no-good hack */ - if (!_tcsncmp(keyPath, _T("My Computer\\"), 12)) + if (!_tcsnicmp(keyPath, _T("My Computer\\"), 12)) keyPath += 12; hRoot = TreeView_GetRoot(hwndTV); @@ -647,17 +647,17 @@ /* Special case for root to expand root key abbreviations */ if (hItem == hRoot) { - if (!_tcscmp(szPathPart, TEXT("HKCR"))) + if (!_tcsicmp(szPathPart, TEXT("HKCR"))) _tcscpy(szPathPart, TEXT("HKEY_CLASSES_ROOT")); - else if (!_tcscmp(szPathPart, TEXT("HKCU"))) + else if (!_tcsicmp(szPathPart, TEXT("HKCU"))) _tcscpy(szPathPart, TEXT("HKEY_CURRENT_USER")); - else if (!_tcscmp(szPathPart, TEXT("HKLM"))) + else if (!_tcsicmp(szPathPart, TEXT("HKLM"))) _tcscpy(szPathPart, TEXT("HKEY_LOCAL_MACHINE")); - else if (!_tcscmp(szPathPart, TEXT("HKU"))) + else if (!_tcsicmp(szPathPart, TEXT("HKU"))) _tcscpy(szPathPart, TEXT("HKEY_USERS")); - else if (!_tcscmp(szPathPart, TEXT("HKCC"))) + else if (!_tcsicmp(szPathPart, TEXT("HKCC"))) _tcscpy(szPathPart, TEXT("HKEY_CURRENT_CONFIG")); - else if (!_tcscmp(szPathPart, TEXT("HKDD"))) + else if (!_tcsicmp(szPathPart, TEXT("HKDD"))) _tcscpy(szPathPart, TEXT("HKEY_DYN_DATA")); } @@ -672,7 +672,7 @@ (void)TreeView_GetItem(hwndTV, &tvi); - if (!_tcscmp(szBuffer, szPathPart)) + if (!_tcsicmp(szBuffer, szPathPart)) break; } Index: base/applications/regedit/childwnd.c =================================================================== --- base/applications/regedit/childwnd.c (revision 49398) +++ base/applications/regedit/childwnd.c (working copy) @@ -67,19 +67,21 @@ static void ResizeWnd(ChildWnd* pChildWnd, int cx, int cy) { - HDWP hdwp = BeginDeferWindowPos(2); - RECT rt, rs; - + HDWP hdwp = BeginDeferWindowPos(3); + RECT rt, rs, rb; + const int tHeight = 18; SetRect(&rt, 0, 0, cx, cy); cy = 0; if (hStatusBar != NULL) { GetWindowRect(hStatusBar, &rs); - cy = rs.bottom - rs.top + 8; + cy = rs.bottom - rs.top; } + GetWindowRect(pChildWnd->hAddressBtnWnd, &rb); cx = pChildWnd->nSplitPos + SPLIT_WIDTH/2; - DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left, 23, SWP_NOZORDER|SWP_NOACTIVATE); - DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + 25, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); - DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx , rt.top + 25, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, pChildWnd->hAddressBarWnd, 0, rt.left, rt.top, rt.right-rt.left - tHeight-2, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, pChildWnd->hAddressBtnWnd, 0, rt.right - tHeight, rt.top, tHeight, tHeight, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, pChildWnd->hTreeWnd, 0, rt.left, rt.top + tHeight+2, pChildWnd->nSplitPos-SPLIT_WIDTH/2-rt.left, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); + DeferWindowPos(hdwp, pChildWnd->hListWnd, 0, rt.left+cx, rt.top + tHeight+2, rt.right-cx, rt.bottom-rt.top-cy, SWP_NOZORDER|SWP_NOACTIVATE); EndDeferWindowPos(hdwp); } @@ -259,7 +261,7 @@ /* Check CLSID key */ if (RegOpenKey(hRootKey, pszKeyPath, &hSubKey) == ERROR_SUCCESS) { - if (QueryStringValue(hSubKey, TEXT("CLSID"), NULL, szBuffer, + if (QueryStringValue(hSubKey, TEXT("CLSID"), NULL, szBuffer, COUNT_OF(szBuffer)) == ERROR_SUCCESS) { lstrcpyn(pszSuggestions, TEXT("HKCR\\CLSID\\"), (int) iSuggestionsLength); @@ -324,29 +326,35 @@ /* load "My Computer" string */ LoadString(hInst, IDS_MY_COMPUTER, buffer, sizeof(buffer)/sizeof(TCHAR)); - g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd)); + g_pChildWnd = pChildWnd = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ChildWnd)); if (!pChildWnd) return 0; _tcsncpy(pChildWnd->szPath, buffer, MAX_PATH); pChildWnd->nSplitPos = 250; pChildWnd->hWnd = hWnd; - pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP, + pChildWnd->hAddressBarWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Edit"), NULL, WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, hWnd, (HMENU)0, hInst, 0); + pChildWnd->hAddressBtnWnd = CreateWindowEx(WS_EX_CLIENTEDGE, _T("Button"), _T("ยป"), WS_CHILD | WS_VISIBLE | WS_CHILDWINDOW | WS_TABSTOP | BS_DEFPUSHBUTTON, + CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, + hWnd, (HMENU)0, hInst, 0); pChildWnd->hTreeWnd = CreateTreeView(hWnd, pChildWnd->szPath, (HMENU) TREE_WINDOW); pChildWnd->hListWnd = CreateListView(hWnd, (HMENU) LIST_WINDOW/*, pChildWnd->szPath*/); SetFocus(pChildWnd->hTreeWnd); - /* set the address bar font */ - if (pChildWnd->hAddressBarWnd) + /* set the address bar and button font */ + if ((pChildWnd->hAddressBarWnd) && (pChildWnd->hAddressBtnWnd)) { hFont = (HFONT)GetStockObject(DEFAULT_GUI_FONT); SendMessage(pChildWnd->hAddressBarWnd, WM_SETFONT, (WPARAM)hFont, 0); + SendMessage(pChildWnd->hAddressBtnWnd, + WM_SETFONT, + (WPARAM)hFont, + 0); } - /* Subclass the AddressBar */ oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_WNDPROC); SetWindowLongPtr(pChildWnd->hAddressBarWnd, GWL_USERDATA, (DWORD_PTR)oldproc); @@ -354,7 +362,10 @@ break; } case WM_COMMAND: - if (!_CmdWndProc(hWnd, message, wParam, lParam)) { + if(HIWORD(wParam) == BN_CLICKED){ + PostMessage(pChildWnd->hAddressBarWnd, WM_KEYUP, VK_RETURN, 0); + } + else if (!_CmdWndProc(hWnd, message, wParam, lParam)) { goto def; } break; @@ -477,10 +488,28 @@ rootName = get_root_key_name(hRootKey); fullPath = HeapAlloc(GetProcessHeap(), 0, (_tcslen(rootName) + 1 + _tcslen(keyPath) + 1) * sizeof(TCHAR)); if (fullPath) { - _stprintf(fullPath, _T("%s\\%s"), rootName, keyPath); + /* set (correct) the address bar text */ + if(keyPath[0] != '\0') + _stprintf(fullPath, _T("%s\\%s"), rootName, keyPath); + else + fullPath = _tcscpy(fullPath, rootName); SendMessage(hStatusBar, SB_SETTEXT, 0, (LPARAM)fullPath); SendMessage(pChildWnd->hAddressBarWnd, WM_SETTEXT, 0, (LPARAM)fullPath); - HeapFree(GetProcessHeap(), 0, fullPath); + HeapFree(GetProcessHeap(), 0, fullPath); + /* disable hive manipulation items temporarily (enable only if necessary) */ + EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_GRAYED); + EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_GRAYED); + /* compare the strings to see if we should enable/disable the "Load Hive" menus accordingly */ + if (!(_tcsicmp(rootName, TEXT("HKEY_LOCAL_MACHINE")) && + _tcsicmp(rootName, TEXT("HKEY_USERS")))) + { + // enable the unload menu item if at the root + // otherwise enable the load menu item if there is no slash in keyPath (ie. immediate child selected) + if(keyPath[0] == '\0') + EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_LOADHIVE, MF_BYCOMMAND | MF_ENABLED); + else if(!_tcschr(keyPath, _T('\\'))) + EnableMenuItem(GetSubMenu(hMenuFrame,0), ID_REGISTRY_UNLOADHIVE, MF_BYCOMMAND | MF_ENABLED); + } { HKEY hKey; Index: base/applications/regedit/resource.h =================================================================== --- base/applications/regedit/resource.h (revision 49398) +++ base/applications/regedit/resource.h (working copy) @@ -137,9 +137,11 @@ #define IDS_ERR_RENVAL_CAPTION 32856 #define IDS_ERR_RENVAL_TOEMPTY 32857 #define IDS_BAD_KEY 32858 +#define IDS_LOAD_HIVE 32859 +#define IDS_UNLOAD_HIVE 32860 -#define ID_EDIT_NEW_MULTISTRINGVALUE 32860 -#define ID_EDIT_NEW_EXPANDABLESTRINGVALUE 32861 +#define ID_EDIT_NEW_MULTISTRINGVALUE 32861 +#define ID_EDIT_NEW_EXPANDABLESTRINGVALUE 32862 #define ID_SWITCH_PANELS 32871 #define ID_EDIT_PERMISSIONS 32872 @@ -199,6 +201,8 @@ #define IDC_EXPORT_BRANCH 2009 #define IDC_EXPORT_BRANCH_TEXT 2010 +#define IDD_LOADHIVE 2500 +#define IDC_EDIT_KEY 2501 #define IDC_FAVORITENAME 2011 #define IDC_FAVORITESLIST 2012