1 /* 2 * Regedit frame window 3 * 4 * Copyright (C) 2002 Robert Dickenson <robd@reactos.org> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include "regedit.h" 22 23 #include <commdlg.h> 24 #include <cderr.h> 25 #include <objsel.h> 26 27 /******************************************************************************** 28 * Global and Local Variables: 29 */ 30 31 #define FAVORITES_MENU_POSITION 3 32 33 static WCHAR s_szFavoritesRegKey[] = L"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Regedit\\Favorites"; 34 35 static BOOL bInMenuLoop = FALSE; /* Tells us if we are in the menu loop */ 36 37 extern WCHAR Suggestions[256]; 38 /******************************************************************************* 39 * Local module support methods 40 */ 41 42 static UINT ErrorBox(HWND hWnd, UINT Error) 43 { 44 WCHAR buf[400]; 45 if (!FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 46 NULL, Error, 0, buf, _countof(buf), NULL)) 47 *(UINT*)buf = L'?'; 48 MessageBoxW(hWnd, buf, NULL, MB_ICONSTOP); 49 return Error; 50 } 51 52 static void resize_frame_rect(HWND hWnd, PRECT prect) 53 { 54 if (IsWindowVisible(hStatusBar)) 55 { 56 RECT rt; 57 58 SetupStatusBar(hWnd, TRUE); 59 GetWindowRect(hStatusBar, &rt); 60 prect->bottom -= rt.bottom - rt.top; 61 } 62 MoveWindow(g_pChildWnd->hWnd, prect->left, prect->top, prect->right, prect->bottom, TRUE); 63 } 64 65 static void resize_frame_client(HWND hWnd) 66 { 67 RECT rect; 68 69 GetClientRect(hWnd, &rect); 70 resize_frame_rect(hWnd, &rect); 71 } 72 73 /********************************************************************************/ 74 75 static void OnInitMenu(HWND hWnd) 76 { 77 LONG lResult; 78 HKEY hKey = NULL; 79 DWORD dwIndex, cbValueName, cbValueData, dwType; 80 WCHAR szValueName[256]; 81 BYTE abValueData[256]; 82 static int s_nFavoriteMenuSubPos = -1; 83 HMENU hMenu; 84 BOOL bDisplayedAny = FALSE; 85 HTREEITEM hSelTreeItem; 86 BOOL bCanAddFav; 87 88 /* Find Favorites menu and clear it out */ 89 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION); 90 if (!hMenu) 91 goto done; 92 if (s_nFavoriteMenuSubPos < 0) 93 { 94 s_nFavoriteMenuSubPos = GetMenuItemCount(hMenu); 95 } 96 else 97 { 98 while(RemoveMenu(hMenu, s_nFavoriteMenuSubPos, MF_BYPOSITION)) ; 99 } 100 101 hSelTreeItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd); 102 bCanAddFav = TreeView_GetParent(g_pChildWnd->hTreeWnd, hSelTreeItem) != NULL; 103 EnableMenuItem(GetMenu(hWnd), ID_FAVOURITES_ADDTOFAVOURITES, 104 MF_BYCOMMAND | (bCanAddFav ? MF_ENABLED : MF_GRAYED)); 105 106 lResult = RegOpenKeyW(HKEY_CURRENT_USER, s_szFavoritesRegKey, &hKey); 107 if (lResult != ERROR_SUCCESS) 108 goto done; 109 110 dwIndex = 0; 111 do 112 { 113 cbValueName = ARRAY_SIZE(szValueName); 114 cbValueData = sizeof(abValueData); 115 lResult = RegEnumValueW(hKey, dwIndex, szValueName, &cbValueName, NULL, &dwType, abValueData, &cbValueData); 116 if ((lResult == ERROR_SUCCESS) && (dwType == REG_SZ)) 117 { 118 if (!bDisplayedAny) 119 { 120 AppendMenu(hMenu, MF_SEPARATOR, 0, NULL); 121 bDisplayedAny = TRUE; 122 } 123 AppendMenu(hMenu, 0, ID_FAVORITES_MIN + GetMenuItemCount(hMenu), szValueName); 124 } 125 dwIndex++; 126 } 127 while(lResult == ERROR_SUCCESS); 128 129 done: 130 if (hKey) 131 RegCloseKey(hKey); 132 } 133 134 static void OnEnterMenuLoop(HWND hWnd) 135 { 136 int nParts; 137 UNREFERENCED_PARAMETER(hWnd); 138 139 /* Update the status bar pane sizes */ 140 nParts = -1; 141 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts); 142 bInMenuLoop = TRUE; 143 SendMessageW(hStatusBar, SB_SETTEXTW, (WPARAM)0, (LPARAM)L""); 144 } 145 146 static void OnExitMenuLoop(HWND hWnd) 147 { 148 bInMenuLoop = FALSE; 149 /* Update the status bar pane sizes*/ 150 SetupStatusBar(hWnd, TRUE); 151 UpdateStatusBar(); 152 } 153 154 static void OnMenuSelect(HWND hWnd, UINT nItemID, UINT nFlags, HMENU hSysMenu) 155 { 156 WCHAR str[100]; 157 158 str[0] = UNICODE_NULL; 159 if (nFlags & MF_POPUP) 160 { 161 if (hSysMenu != GetMenu(hWnd)) 162 { 163 if (nItemID == 2) nItemID = 5; 164 } 165 } 166 if (LoadStringW(hInst, nItemID, str, 100)) 167 { 168 /* load appropriate string*/ 169 LPWSTR lpsz = str; 170 /* first newline terminates actual string*/ 171 lpsz = wcschr(lpsz, L'\n'); 172 if (lpsz != NULL) 173 *lpsz = L'\0'; 174 } 175 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)str); 176 } 177 178 void SetupStatusBar(HWND hWnd, BOOL bResize) 179 { 180 RECT rc; 181 int nParts; 182 GetClientRect(hWnd, &rc); 183 nParts = rc.right; 184 /* nParts = -1;*/ 185 if (bResize) 186 SendMessageW(hStatusBar, WM_SIZE, 0, 0); 187 SendMessageW(hStatusBar, SB_SETPARTS, 1, (LPARAM)&nParts); 188 } 189 190 void UpdateStatusBar(void) 191 { 192 HKEY hKeyRoot; 193 LPCWSTR pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 194 195 SendMessageW(hStatusBar, SB_SETTEXTW, 0, (LPARAM)pszKeyPath); 196 } 197 198 static void toggle_child(HWND hWnd, UINT cmd, HWND hchild) 199 { 200 BOOL vis = IsWindowVisible(hchild); 201 HMENU hMenuView = GetSubMenu(hMenuFrame, ID_VIEW_MENU); 202 203 CheckMenuItem(hMenuView, cmd, vis?MF_BYCOMMAND:MF_BYCOMMAND|MF_CHECKED); 204 ShowWindow(hchild, vis?SW_HIDE:SW_SHOW); 205 resize_frame_client(hWnd); 206 } 207 208 static BOOL CheckCommDlgError(HWND hWnd) 209 { 210 DWORD dwErrorCode = CommDlgExtendedError(); 211 UNREFERENCED_PARAMETER(hWnd); 212 switch (dwErrorCode) 213 { 214 case CDERR_DIALOGFAILURE: 215 break; 216 case CDERR_FINDRESFAILURE: 217 break; 218 case CDERR_NOHINSTANCE: 219 break; 220 case CDERR_INITIALIZATION: 221 break; 222 case CDERR_NOHOOK: 223 break; 224 case CDERR_LOCKRESFAILURE: 225 break; 226 case CDERR_NOTEMPLATE: 227 break; 228 case CDERR_LOADRESFAILURE: 229 break; 230 case CDERR_STRUCTSIZE: 231 break; 232 case CDERR_LOADSTRFAILURE: 233 break; 234 case FNERR_BUFFERTOOSMALL: 235 break; 236 case CDERR_MEMALLOCFAILURE: 237 break; 238 case FNERR_INVALIDFILENAME: 239 break; 240 case CDERR_MEMLOCKFAILURE: 241 break; 242 case FNERR_SUBCLASSFAILURE: 243 break; 244 default: 245 break; 246 } 247 return TRUE; 248 } 249 250 WCHAR FileNameBuffer[MAX_PATH]; 251 252 typedef struct 253 { 254 UINT DisplayID; 255 UINT FilterID; 256 } FILTERPAIR, *PFILTERPAIR; 257 258 void 259 BuildFilterStrings(WCHAR *Filter, PFILTERPAIR Pairs, int PairCount) 260 { 261 int i, c; 262 263 c = 0; 264 for(i = 0; i < PairCount; i++) 265 { 266 c += LoadStringW(hInst, Pairs[i].DisplayID, &Filter[c], 255); 267 Filter[++c] = L'\0'; 268 c += LoadStringW(hInst, Pairs[i].FilterID, &Filter[c], 255); 269 Filter[++c] = L'\0'; 270 } 271 Filter[++c] = L'\0'; 272 } 273 274 static BOOL InitOpenFileName(HWND hWnd, OPENFILENAME* pofn, BOOL bSave) 275 { 276 FILTERPAIR FilterPairs[5]; 277 static WCHAR Filter[1024]; 278 279 memset(pofn, 0, sizeof(OPENFILENAME)); 280 pofn->lStructSize = sizeof(OPENFILENAME); 281 pofn->hwndOwner = hWnd; 282 pofn->hInstance = hInst; 283 284 /* create filter string */ 285 FilterPairs[0].DisplayID = IDS_FLT_REGFILES; 286 FilterPairs[0].FilterID = IDS_FLT_REGFILES_FLT; 287 FilterPairs[1].DisplayID = IDS_FLT_HIVFILES; 288 FilterPairs[1].FilterID = IDS_FLT_HIVFILES_FLT; 289 FilterPairs[2].DisplayID = IDS_FLT_REGEDIT4; 290 FilterPairs[2].FilterID = IDS_FLT_REGEDIT4_FLT; 291 if (bSave) 292 { 293 FilterPairs[3].DisplayID = IDS_FLT_TXTFILES; 294 FilterPairs[3].FilterID = IDS_FLT_TXTFILES_FLT; 295 FilterPairs[4].DisplayID = IDS_FLT_ALLFILES; 296 FilterPairs[4].FilterID = IDS_FLT_ALLFILES_FLT; 297 } 298 else 299 { 300 FilterPairs[3].DisplayID = IDS_FLT_ALLFILES; 301 FilterPairs[3].FilterID = IDS_FLT_ALLFILES_FLT; 302 } 303 304 BuildFilterStrings(Filter, FilterPairs, ARRAY_SIZE(FilterPairs) - !bSave); 305 306 pofn->lpstrFilter = Filter; 307 pofn->lpstrFile = FileNameBuffer; 308 pofn->nMaxFile = _countof(FileNameBuffer); 309 pofn->Flags = OFN_EXPLORER | OFN_HIDEREADONLY; 310 pofn->lpstrDefExt = L"reg"; 311 if (bSave) 312 pofn->Flags |= OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; 313 else 314 pofn->Flags |= OFN_FILEMUSTEXIST; 315 316 return TRUE; 317 } 318 319 #define LOADHIVE_KEYNAMELENGTH 128 320 321 static INT_PTR CALLBACK LoadHive_KeyNameInHookProc(HWND hWndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 322 { 323 static LPWSTR sKey = NULL; 324 switch(uMsg) 325 { 326 case WM_INITDIALOG: 327 sKey = (LPWSTR)lParam; 328 break; 329 case WM_COMMAND: 330 switch(LOWORD(wParam)) 331 { 332 case IDOK: 333 if(GetDlgItemTextW(hWndDlg, IDC_EDIT_KEY, sKey, LOADHIVE_KEYNAMELENGTH)) 334 return EndDialog(hWndDlg, -1); 335 else 336 return EndDialog(hWndDlg, 0); 337 case IDCANCEL: 338 return EndDialog(hWndDlg, 0); 339 } 340 break; 341 } 342 return FALSE; 343 } 344 345 static BOOL EnablePrivilege(LPCWSTR lpszPrivilegeName, LPCWSTR lpszSystemName, BOOL bEnablePrivilege) 346 { 347 BOOL bRet = FALSE; 348 HANDLE hToken = NULL; 349 350 if (OpenProcessToken(GetCurrentProcess(), 351 TOKEN_ADJUST_PRIVILEGES, 352 &hToken)) 353 { 354 TOKEN_PRIVILEGES tp; 355 356 tp.PrivilegeCount = 1; 357 tp.Privileges[0].Attributes = (bEnablePrivilege ? SE_PRIVILEGE_ENABLED : 0); 358 359 if (LookupPrivilegeValueW(lpszSystemName, 360 lpszPrivilegeName, 361 &tp.Privileges[0].Luid)) 362 { 363 bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL); 364 365 if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) 366 bRet = FALSE; 367 } 368 369 CloseHandle(hToken); 370 } 371 372 return bRet; 373 } 374 375 static BOOL LoadHive(HWND hWnd) 376 { 377 OPENFILENAME ofn; 378 WCHAR Caption[128]; 379 LPCWSTR pszKeyPath; 380 WCHAR xPath[LOADHIVE_KEYNAMELENGTH]; 381 HKEY hRootKey; 382 WCHAR Filter[1024]; 383 FILTERPAIR filter; 384 /* get the item key to load the hive in */ 385 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); 386 /* initialize the "open file" dialog */ 387 InitOpenFileName(hWnd, &ofn, FALSE); 388 /* build the "All Files" filter up */ 389 filter.DisplayID = IDS_FLT_ALLFILES; 390 filter.FilterID = IDS_FLT_ALLFILES_FLT; 391 BuildFilterStrings(Filter, &filter, 1); 392 ofn.lpstrFilter = Filter; 393 /* load and set the caption and flags for dialog */ 394 LoadStringW(hInst, IDS_LOAD_HIVE, Caption, ARRAY_SIZE(Caption)); 395 ofn.lpstrTitle = Caption; 396 ofn.Flags |= OFN_ENABLESIZING; 397 398 /* now load the hive */ 399 if (GetOpenFileName(&ofn)) 400 { 401 if (DialogBoxParamW(hInst, MAKEINTRESOURCEW(IDD_LOADHIVE), hWnd, 402 &LoadHive_KeyNameInHookProc, (LPARAM)xPath)) 403 { 404 LONG regLoadResult; 405 406 /* Enable the 'restore' privilege, load the hive, disable the privilege */ 407 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE); 408 regLoadResult = RegLoadKeyW(hRootKey, xPath, ofn.lpstrFile); 409 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE); 410 411 if(regLoadResult == ERROR_SUCCESS) 412 { 413 /* refresh tree and list views */ 414 RefreshTreeView(g_pChildWnd->hTreeWnd); 415 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); 416 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath, TRUE); 417 } 418 else 419 { 420 ErrorMessageBox(hWnd, Caption, regLoadResult); 421 return FALSE; 422 } 423 } 424 } 425 else 426 { 427 CheckCommDlgError(hWnd); 428 } 429 return TRUE; 430 } 431 432 static BOOL UnloadHive(HWND hWnd) 433 { 434 WCHAR Caption[128]; 435 LPCWSTR pszKeyPath; 436 HKEY hRootKey; 437 LONG regUnloadResult; 438 439 /* get the item key to unload */ 440 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); 441 /* load and set the caption and flags for dialog */ 442 LoadStringW(hInst, IDS_UNLOAD_HIVE, Caption, ARRAY_SIZE(Caption)); 443 444 /* Enable the 'restore' privilege, unload the hive, disable the privilege */ 445 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE); 446 regUnloadResult = RegUnLoadKeyW(hRootKey, pszKeyPath); 447 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE); 448 449 if(regUnloadResult == ERROR_SUCCESS) 450 { 451 /* refresh tree and list views */ 452 RefreshTreeView(g_pChildWnd->hTreeWnd); 453 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hRootKey); 454 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath, TRUE); 455 } 456 else 457 { 458 ErrorMessageBox(hWnd, Caption, regUnloadResult); 459 return FALSE; 460 } 461 return TRUE; 462 } 463 464 static BOOL ImportRegistryFile(HWND hWnd) 465 { 466 BOOL bRet = FALSE; 467 OPENFILENAME ofn; 468 WCHAR Caption[128], szTitle[512], szText[512]; 469 HKEY hKeyRoot; 470 LPCWSTR pszKeyPath; 471 472 /* Figure out in which key path we are importing */ 473 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 474 475 InitOpenFileName(hWnd, &ofn, FALSE); 476 LoadStringW(hInst, IDS_IMPORT_REG_FILE, Caption, ARRAY_SIZE(Caption)); 477 ofn.lpstrTitle = Caption; 478 ofn.Flags |= OFN_ENABLESIZING; 479 480 if (GetOpenFileName(&ofn)) 481 { 482 /* Look at the extension of the file to determine its type */ 483 if (ofn.nFileExtension >= 1 && 484 _wcsicmp(ofn.lpstrFile + ofn.nFileExtension, L"reg") == 0) /* REGEDIT4 or Windows Registry Editor Version 5.00 */ 485 { 486 /* Open the file */ 487 FILE* fp = _wfopen(ofn.lpstrFile, L"rb"); 488 489 /* Import it */ 490 if (fp == NULL || !import_registry_file(fp)) 491 { 492 /* Error opening the file */ 493 LoadStringW(hInst, IDS_APP_TITLE, szTitle, ARRAY_SIZE(szTitle)); 494 LoadStringW(hInst, IDS_IMPORT_ERROR, szText, ARRAY_SIZE(szText)); 495 InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile); 496 bRet = FALSE; 497 } 498 else 499 { 500 /* Show successful import */ 501 LoadStringW(hInst, IDS_APP_TITLE, szTitle, ARRAY_SIZE(szTitle)); 502 LoadStringW(hInst, IDS_IMPORT_OK, szText, ARRAY_SIZE(szText)); 503 InfoMessageBox(hWnd, MB_OK | MB_ICONINFORMATION, szTitle, szText, ofn.lpstrFile); 504 bRet = TRUE; 505 } 506 507 /* Close the file */ 508 if (fp) fclose(fp); 509 } 510 else /* Registry Hive Files */ 511 { 512 LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_CAPTION, szTitle, ARRAY_SIZE(szTitle)); 513 LoadStringW(hInst, IDS_QUERY_IMPORT_HIVE_MSG, szText, ARRAY_SIZE(szText)); 514 515 /* Display a confirmation message */ 516 if (MessageBoxW(g_pChildWnd->hWnd, szText, szTitle, MB_ICONWARNING | MB_YESNO) == IDYES) 517 { 518 LONG lResult; 519 HKEY hSubKey; 520 521 /* Open the subkey */ 522 lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_WRITE, &hSubKey); 523 if (lResult == ERROR_SUCCESS) 524 { 525 /* Enable the 'restore' privilege, restore the hive then disable the privilege */ 526 EnablePrivilege(SE_RESTORE_NAME, NULL, TRUE); 527 lResult = RegRestoreKey(hSubKey, ofn.lpstrFile, REG_FORCE_RESTORE); 528 EnablePrivilege(SE_RESTORE_NAME, NULL, FALSE); 529 530 /* Flush the subkey and close it */ 531 RegFlushKey(hSubKey); 532 RegCloseKey(hSubKey); 533 } 534 535 /* Set the return value */ 536 bRet = (lResult == ERROR_SUCCESS); 537 538 /* Display error, if any */ 539 if (!bRet) ErrorMessageBox(hWnd, Caption, lResult); 540 } 541 } 542 } 543 else 544 { 545 CheckCommDlgError(hWnd); 546 } 547 548 /* refresh tree and list views */ 549 RefreshTreeView(g_pChildWnd->hTreeWnd); 550 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 551 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, pszKeyPath, TRUE); 552 553 return bRet; 554 } 555 556 static UINT_PTR CALLBACK ExportRegistryFile_OFNHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) 557 { 558 HWND hwndExportAll; 559 HWND hwndExportBranch; 560 HWND hwndExportBranchText; 561 UINT_PTR iResult = 0; 562 OPENFILENAME *pOfn; 563 LPWSTR pszSelectedKey; 564 OFNOTIFY *pOfnNotify; 565 566 UNREFERENCED_PARAMETER(wParam); 567 568 switch(uiMsg) 569 { 570 case WM_INITDIALOG: 571 pOfn = (OPENFILENAME *) lParam; 572 pszSelectedKey = (LPWSTR) pOfn->lCustData; 573 574 hwndExportAll = GetDlgItem(hdlg, IDC_EXPORT_ALL); 575 if (hwndExportAll) 576 SendMessageW(hwndExportAll, BM_SETCHECK, pszSelectedKey ? BST_UNCHECKED : BST_CHECKED, 0); 577 578 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH); 579 if (hwndExportBranch) 580 SendMessageW(hwndExportBranch, BM_SETCHECK, pszSelectedKey ? BST_CHECKED : BST_UNCHECKED, 0); 581 582 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT); 583 if (hwndExportBranchText) 584 SetWindowTextW(hwndExportBranchText, pszSelectedKey); 585 break; 586 587 case WM_NOTIFY: 588 if (((NMHDR *) lParam)->code == CDN_FILEOK) 589 { 590 pOfnNotify = (OFNOTIFY *) lParam; 591 pszSelectedKey = (LPWSTR) pOfnNotify->lpOFN->lCustData; 592 593 hwndExportBranch = GetDlgItem(hdlg, IDC_EXPORT_BRANCH); 594 hwndExportBranchText = GetDlgItem(hdlg, IDC_EXPORT_BRANCH_TEXT); 595 if (hwndExportBranch && hwndExportBranchText 596 && (SendMessageW(hwndExportBranch, BM_GETCHECK, 0, 0) == BST_CHECKED)) 597 { 598 GetWindowTextW(hwndExportBranchText, pszSelectedKey, _MAX_PATH); 599 } 600 else if (pszSelectedKey) 601 { 602 pszSelectedKey[0] = L'\0'; 603 } 604 } 605 break; 606 } 607 return iResult; 608 } 609 610 BOOL ExportRegistryFile(HWND hWnd) 611 { 612 BOOL bRet = FALSE; 613 OPENFILENAME ofn; 614 WCHAR ExportKeyPath[_MAX_PATH] = {0}; 615 WCHAR Caption[128], szTitle[512], szText[512]; 616 HKEY hKeyRoot; 617 LPCWSTR pszKeyPath; 618 619 /* Figure out which key path we are exporting */ 620 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 621 GetKeyName(ExportKeyPath, ARRAY_SIZE(ExportKeyPath), hKeyRoot, pszKeyPath); 622 623 InitOpenFileName(hWnd, &ofn, TRUE); 624 LoadStringW(hInst, IDS_EXPORT_REG_FILE, Caption, ARRAY_SIZE(Caption)); 625 ofn.lpstrTitle = Caption; 626 627 /* Only set the path if a key (not the root node) is selected */ 628 if (hKeyRoot != 0) 629 { 630 ofn.lCustData = (LPARAM) ExportKeyPath; 631 } 632 ofn.Flags |= OFN_ENABLETEMPLATE | OFN_ENABLEHOOK; 633 ofn.lpfnHook = ExportRegistryFile_OFNHookProc; 634 ofn.lpTemplateName = MAKEINTRESOURCEW(IDD_EXPORTRANGE); 635 if (GetSaveFileName(&ofn)) 636 { 637 switch (ofn.nFilterIndex) 638 { 639 case 2: /* Registry Hive Files */ 640 { 641 LONG lResult; 642 HKEY hSubKey; 643 644 /* Open the subkey */ 645 lResult = RegOpenKeyExW(hKeyRoot, pszKeyPath, 0, KEY_READ, &hSubKey); 646 if (lResult == ERROR_SUCCESS) 647 { 648 /* Enable the 'backup' privilege, save the hive then disable the privilege */ 649 EnablePrivilege(SE_BACKUP_NAME, NULL, TRUE); 650 lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL); 651 if (lResult == ERROR_ALREADY_EXISTS) 652 { 653 /* 654 * We are here, that means that we already said "yes" to the confirmation dialog. 655 * So we absolutely want to replace the hive file. 656 */ 657 if (DeleteFileW(ofn.lpstrFile)) 658 { 659 /* Try again */ 660 lResult = RegSaveKeyW(hSubKey, ofn.lpstrFile, NULL); 661 } 662 } 663 EnablePrivilege(SE_BACKUP_NAME, NULL, FALSE); 664 665 if (lResult != ERROR_SUCCESS) 666 { 667 /* 668 * If we are here, it's because RegSaveKeyW has failed for any reason. 669 * The problem is that even if it has failed, it has created or 670 * replaced the exported hive file with a new empty file. We don't 671 * want to keep this file, so we delete it. 672 */ 673 DeleteFileW(ofn.lpstrFile); 674 } 675 676 /* Close the subkey */ 677 RegCloseKey(hSubKey); 678 } 679 680 /* Set the return value */ 681 bRet = (lResult == ERROR_SUCCESS); 682 683 /* Display error, if any */ 684 if (!bRet) ErrorMessageBox(hWnd, Caption, lResult); 685 686 break; 687 } 688 689 case 1: /* Windows Registry Editor Version 5.00 */ 690 case 3: /* REGEDIT4 */ 691 default: /* All files ==> use Windows Registry Editor Version 5.00 */ 692 { 693 if (!export_registry_key(ofn.lpstrFile, ExportKeyPath, 694 (ofn.nFilterIndex == 3 ? REG_FORMAT_4 695 : REG_FORMAT_5))) 696 { 697 /* Error creating the file */ 698 LoadStringW(hInst, IDS_APP_TITLE, szTitle, ARRAY_SIZE(szTitle)); 699 LoadStringW(hInst, IDS_EXPORT_ERROR, szText, ARRAY_SIZE(szText)); 700 InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile); 701 bRet = FALSE; 702 } 703 else 704 { 705 bRet = TRUE; 706 } 707 708 break; 709 } 710 711 case 4: /* Text File */ 712 { 713 bRet = txt_export_registry_key(ofn.lpstrFile, ExportKeyPath); 714 if (!bRet) 715 { 716 /* Error creating the file */ 717 LoadStringW(hInst, IDS_APP_TITLE, szTitle, ARRAY_SIZE(szTitle)); 718 LoadStringW(hInst, IDS_EXPORT_ERROR, szText, ARRAY_SIZE(szText)); 719 InfoMessageBox(hWnd, MB_OK | MB_ICONERROR, szTitle, szText, ofn.lpstrFile); 720 } 721 break; 722 } 723 } 724 } 725 else 726 { 727 CheckCommDlgError(hWnd); 728 } 729 730 return bRet; 731 } 732 733 BOOL PrintRegistryHive(HWND hWnd, LPWSTR path) 734 { 735 #if 1 736 PRINTDLG pd; 737 UNREFERENCED_PARAMETER(path); 738 739 ZeroMemory(&pd, sizeof(PRINTDLG)); 740 pd.lStructSize = sizeof(PRINTDLG); 741 pd.hwndOwner = hWnd; 742 pd.hDevMode = NULL; /* Don't forget to free or store hDevMode*/ 743 pd.hDevNames = NULL; /* Don't forget to free or store hDevNames*/ 744 pd.Flags = PD_USEDEVMODECOPIESANDCOLLATE | PD_RETURNDC; 745 pd.nCopies = 1; 746 pd.nFromPage = 0xFFFF; 747 pd.nToPage = 0xFFFF; 748 pd.nMinPage = 1; 749 pd.nMaxPage = 0xFFFF; 750 if (PrintDlg(&pd)) 751 { 752 /* GDI calls to render output. */ 753 DeleteDC(pd.hDC); /* Delete DC when done.*/ 754 } 755 #else 756 HRESULT hResult; 757 PRINTDLGEX pd; 758 759 hResult = PrintDlgEx(&pd); 760 if (hResult == S_OK) 761 { 762 switch (pd.dwResultAction) 763 { 764 case PD_RESULT_APPLY: 765 /*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. */ 766 break; 767 case PD_RESULT_CANCEL: 768 /*The user clicked the Cancel button. The information in the PRINTDLGEX structure is unchanged. */ 769 break; 770 case PD_RESULT_PRINT: 771 /*The user clicked the Print button. The PRINTDLGEX structure contains the information specified by the user. */ 772 break; 773 default: 774 break; 775 } 776 } 777 else 778 { 779 switch (hResult) 780 { 781 case E_OUTOFMEMORY: 782 /*Insufficient memory. */ 783 break; 784 case E_INVALIDARG: 785 /* One or more arguments are invalid. */ 786 break; 787 case E_POINTER: 788 /*Invalid pointer. */ 789 break; 790 case E_HANDLE: 791 /*Invalid handle. */ 792 break; 793 case E_FAIL: 794 /*Unspecified error. */ 795 break; 796 default: 797 break; 798 } 799 return FALSE; 800 } 801 #endif 802 return TRUE; 803 } 804 805 static void ChooseFavorite(LPCWSTR pszFavorite) 806 { 807 HKEY hKey = NULL; 808 WCHAR szFavoritePath[512]; 809 DWORD cbData, dwType; 810 811 if (RegOpenKeyExW(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) 812 goto done; 813 814 cbData = sizeof(szFavoritePath); 815 memset(szFavoritePath, 0, sizeof(szFavoritePath)); 816 if (RegQueryValueExW(hKey, pszFavorite, NULL, &dwType, (LPBYTE) szFavoritePath, &cbData) != ERROR_SUCCESS) 817 goto done; 818 819 if (dwType == REG_SZ) 820 SelectNode(g_pChildWnd->hTreeWnd, szFavoritePath); 821 822 done: 823 if (hKey) 824 RegCloseKey(hKey); 825 } 826 827 static LPWSTR GetItemFullPath(HTREEITEM hTI) 828 { 829 HKEY hRoot; 830 WCHAR rootname[MAX_PATH], *buffer; 831 SIZE_T rootlen, subkeylen; 832 LPCWSTR subkey = GetItemPath(g_pChildWnd->hTreeWnd, hTI, &hRoot); 833 if (!subkey || !hRoot) 834 return NULL; 835 if (!GetKeyName(rootname, ARRAY_SIZE(rootname), hRoot, L"")) 836 return NULL; 837 rootlen = lstrlenW(rootname) + 1; // + 1 for '\\' 838 subkeylen = lstrlenW(subkey); 839 buffer = (WCHAR*)malloc((rootlen + subkeylen + 1) * sizeof(WCHAR)); 840 if (buffer) 841 { 842 lstrcpyW(buffer, rootname); 843 buffer[rootlen - 1] = '\\'; 844 lstrcpyW(buffer + rootlen, subkey); 845 } 846 return buffer; 847 } 848 849 static INT_PTR CALLBACK AddToFavoritesDlgProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 850 { 851 HWND hName = GetDlgItem(hWnd, IDC_FAVORITENAME); 852 WCHAR name[MAX_PATH]; 853 switch (uMsg) 854 { 855 case WM_INITDIALOG: 856 { 857 TVITEM tvi; 858 tvi.mask = TVIF_HANDLE | TVIF_TEXT; 859 tvi.hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd); 860 tvi.pszText = name; 861 tvi.cchTextMax = _countof(name); 862 if (!TreeView_GetItem(g_pChildWnd->hTreeWnd, &tvi)) 863 tvi.pszText[0] = UNICODE_NULL; 864 SetWindowTextW(hName, tvi.pszText); 865 SendMessageW(hName, EM_LIMITTEXT, _countof(name) - 1, 0); 866 return TRUE; 867 } 868 case WM_COMMAND: 869 switch (LOWORD(wParam)) 870 { 871 case IDOK: 872 { 873 LPWSTR path; 874 HKEY hKey; 875 DWORD err; 876 if (!GetWindowTextW(hName, name, _countof(name))) 877 { 878 err = GetLastError(); 879 goto failed; 880 } 881 path = GetItemFullPath(NULL); 882 if (!path) 883 { 884 err = ERROR_NOT_ENOUGH_MEMORY; 885 goto failed; 886 } 887 err = RegCreateKeyExW(HKEY_CURRENT_USER, s_szFavoritesRegKey, 0, 888 NULL, 0, KEY_SET_VALUE, NULL, &hKey, NULL); 889 if (err) 890 goto failed; 891 err = RegSetValueExW(hKey, name, 0, REG_SZ, (BYTE*)path, (lstrlenW(path) + 1) * sizeof(WCHAR)); 892 RegCloseKey(hKey); 893 if (err) failed: 894 ErrorBox(hWnd, err); 895 free(path); 896 return EndDialog(hWnd, err); 897 } 898 case IDCANCEL: 899 return EndDialog(hWnd, ERROR_CANCELLED); 900 case IDC_FAVORITENAME: 901 if (HIWORD(wParam) == EN_UPDATE) 902 EnableWindow(GetDlgItem(hWnd, IDOK), GetWindowTextLengthW(hName) != 0); 903 break; 904 } 905 break; 906 } 907 return FALSE; 908 } 909 910 BOOL CopyKeyName(HWND hWnd, HKEY hRootKey, LPCWSTR keyName) 911 { 912 BOOL bClipboardOpened = FALSE; 913 BOOL bSuccess = FALSE; 914 WCHAR szBuffer[512]; 915 HGLOBAL hGlobal; 916 LPWSTR s; 917 SIZE_T cbGlobal; 918 919 if (!OpenClipboard(hWnd)) 920 goto done; 921 bClipboardOpened = TRUE; 922 923 if (!EmptyClipboard()) 924 goto done; 925 926 if (!GetKeyName(szBuffer, ARRAY_SIZE(szBuffer), hRootKey, keyName)) 927 goto done; 928 929 cbGlobal = (wcslen(szBuffer) + 1) * sizeof(WCHAR); 930 hGlobal = GlobalAlloc(GMEM_MOVEABLE, cbGlobal); 931 if (!hGlobal) 932 goto done; 933 934 s = GlobalLock(hGlobal); 935 StringCbCopyW(s, cbGlobal, szBuffer); 936 GlobalUnlock(hGlobal); 937 938 SetClipboardData(CF_UNICODETEXT, hGlobal); 939 bSuccess = TRUE; 940 941 done: 942 if (bClipboardOpened) 943 CloseClipboard(); 944 return bSuccess; 945 } 946 947 static BOOL CreateNewValue(HKEY hRootKey, LPCWSTR pszKeyPath, DWORD dwType) 948 { 949 WCHAR szNewValueFormat[128]; 950 WCHAR szNewValue[128]; 951 int iIndex = 1; 952 BYTE data[128]; 953 DWORD dwExistingType, cbData; 954 LONG lResult; 955 HKEY hKey; 956 LVFINDINFO lvfi; 957 958 if (RegOpenKeyExW(hRootKey, pszKeyPath, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, 959 &hKey) != ERROR_SUCCESS) 960 return FALSE; 961 962 LoadStringW(hInst, IDS_NEW_VALUE, szNewValueFormat, ARRAY_SIZE(szNewValueFormat)); 963 964 do 965 { 966 wsprintf(szNewValue, szNewValueFormat, iIndex++); 967 cbData = sizeof(data); 968 lResult = RegQueryValueExW(hKey, szNewValue, NULL, &dwExistingType, data, &cbData); 969 } 970 while(lResult == ERROR_SUCCESS); 971 972 switch(dwType) 973 { 974 case REG_DWORD: 975 cbData = sizeof(DWORD); 976 break; 977 case REG_SZ: 978 case REG_EXPAND_SZ: 979 cbData = sizeof(WCHAR); 980 break; 981 case REG_MULTI_SZ: 982 /* 983 * WARNING: An empty multi-string has only one null char. 984 * Indeed, multi-strings are built in the following form: 985 * str1\0str2\0...strN\0\0 986 * where each strI\0 is a null-terminated string, and it 987 * ends with a terminating empty string. 988 * Therefore an empty multi-string contains only the terminating 989 * empty string, that is, one null char. 990 */ 991 cbData = sizeof(WCHAR); 992 break; 993 case REG_QWORD: /* REG_QWORD_LITTLE_ENDIAN */ 994 cbData = sizeof(DWORDLONG); // == sizeof(DWORD) * 2; 995 break; 996 default: 997 cbData = 0; 998 break; 999 } 1000 memset(data, 0, cbData); 1001 lResult = RegSetValueExW(hKey, szNewValue, 0, dwType, data, cbData); 1002 RegCloseKey(hKey); 1003 if (lResult != ERROR_SUCCESS) 1004 { 1005 return FALSE; 1006 } 1007 1008 RefreshListView(g_pChildWnd->hListWnd, hRootKey, pszKeyPath, TRUE); 1009 1010 /* locate the newly added value, and get ready to rename it */ 1011 memset(&lvfi, 0, sizeof(lvfi)); 1012 lvfi.flags = LVFI_STRING; 1013 lvfi.psz = szNewValue; 1014 iIndex = ListView_FindItem(g_pChildWnd->hListWnd, -1, &lvfi); 1015 if (iIndex >= 0) 1016 { 1017 ListView_SetItemState(g_pChildWnd->hListWnd, iIndex, 1018 LVIS_SELECTED | LVIS_FOCUSED, LVIS_SELECTED | LVIS_FOCUSED); 1019 ListView_EnsureVisible(g_pChildWnd->hListWnd, iIndex, FALSE); 1020 (void)ListView_EditLabel(g_pChildWnd->hListWnd, iIndex); 1021 } 1022 1023 return TRUE; 1024 } 1025 1026 static HRESULT 1027 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker) 1028 { 1029 HRESULT hRet; 1030 1031 *pDsObjectPicker = NULL; 1032 1033 hRet = CoCreateInstance(&CLSID_DsObjectPicker, 1034 NULL, 1035 CLSCTX_INPROC_SERVER, 1036 &IID_IDsObjectPicker, 1037 (LPVOID*)pDsObjectPicker); 1038 if (SUCCEEDED(hRet)) 1039 { 1040 DSOP_INIT_INFO InitInfo; 1041 static DSOP_SCOPE_INIT_INFO Scopes[] = 1042 { 1043 { 1044 sizeof(DSOP_SCOPE_INIT_INFO), 1045 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE | 1046 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | 1047 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP | 1048 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN, 1049 0, 1050 { 1051 { 1052 DSOP_FILTER_COMPUTERS, 1053 0, 1054 0 1055 }, 1056 DSOP_DOWNLEVEL_FILTER_COMPUTERS 1057 }, 1058 NULL, 1059 NULL, 1060 S_OK 1061 }, 1062 }; 1063 1064 InitInfo.cbSize = sizeof(InitInfo); 1065 InitInfo.pwzTargetComputer = NULL; 1066 InitInfo.cDsScopeInfos = ARRAY_SIZE(Scopes); 1067 InitInfo.aDsScopeInfos = Scopes; 1068 InitInfo.flOptions = 0; 1069 InitInfo.cAttributesToFetch = 0; 1070 InitInfo.apwzAttributeNames = NULL; 1071 1072 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker, 1073 &InitInfo); 1074 1075 if (FAILED(hRet)) 1076 { 1077 /* delete the object picker in case initialization failed! */ 1078 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker); 1079 } 1080 } 1081 1082 return hRet; 1083 } 1084 1085 static HRESULT 1086 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker, 1087 IN HWND hwndParent OPTIONAL, 1088 OUT LPWSTR lpBuffer, 1089 IN UINT uSize) 1090 { 1091 IDataObject *pdo = NULL; 1092 HRESULT hRet; 1093 1094 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker, 1095 hwndParent, 1096 &pdo); 1097 if (hRet == S_OK) 1098 { 1099 STGMEDIUM stm; 1100 FORMATETC fe; 1101 1102 fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST); 1103 fe.ptd = NULL; 1104 fe.dwAspect = DVASPECT_CONTENT; 1105 fe.lindex = -1; 1106 fe.tymed = TYMED_HGLOBAL; 1107 1108 hRet = pdo->lpVtbl->GetData(pdo, 1109 &fe, 1110 &stm); 1111 if (SUCCEEDED(hRet)) 1112 { 1113 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal); 1114 if (SelectionList != NULL) 1115 { 1116 if (SelectionList->cItems == 1) 1117 { 1118 size_t nlen = wcslen(SelectionList->aDsSelection[0].pwzName); 1119 if (nlen >= uSize) 1120 { 1121 nlen = uSize - 1; 1122 } 1123 1124 memcpy(lpBuffer, 1125 SelectionList->aDsSelection[0].pwzName, 1126 nlen * sizeof(WCHAR)); 1127 1128 lpBuffer[nlen] = L'\0'; 1129 } 1130 1131 GlobalUnlock(stm.hGlobal); 1132 } 1133 1134 ReleaseStgMedium(&stm); 1135 } 1136 1137 pdo->lpVtbl->Release(pdo); 1138 } 1139 1140 return hRet; 1141 } 1142 1143 static VOID 1144 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker) 1145 { 1146 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker); 1147 } 1148 1149 /** 1150 * PURPOSE: Processes WM_COMMAND messages for the main frame window. 1151 */ 1152 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 1153 { 1154 HKEY hKeyRoot = 0, hKey = 0; 1155 LPCWSTR keyPath; 1156 LPCWSTR valueName; 1157 BOOL result = TRUE; 1158 REGSAM regsam = KEY_READ; 1159 int item; 1160 1161 UNREFERENCED_PARAMETER(lParam); 1162 UNREFERENCED_PARAMETER(message); 1163 1164 switch (LOWORD(wParam)) 1165 { 1166 case ID_REGISTRY_LOADHIVE: 1167 LoadHive(hWnd); 1168 return TRUE; 1169 case ID_REGISTRY_UNLOADHIVE: 1170 UnloadHive(hWnd); 1171 return TRUE; 1172 case ID_REGISTRY_IMPORTREGISTRYFILE: 1173 ImportRegistryFile(hWnd); 1174 return TRUE; 1175 case ID_REGISTRY_EXPORTREGISTRYFILE: 1176 ExportRegistryFile(hWnd); 1177 return TRUE; 1178 case ID_REGISTRY_CONNECTNETWORKREGISTRY: 1179 { 1180 IDsObjectPicker *ObjectPicker; 1181 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 1182 HRESULT hRet; 1183 1184 hRet = CoInitialize(NULL); 1185 if (SUCCEEDED(hRet)) 1186 { 1187 hRet = InitializeRemoteRegistryPicker(&ObjectPicker); 1188 if (SUCCEEDED(hRet)) 1189 { 1190 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker, 1191 hWnd, 1192 szComputerName, 1193 ARRAY_SIZE(szComputerName)); 1194 if (hRet == S_OK) 1195 { 1196 /* FIXME - connect to the registry */ 1197 } 1198 1199 FreeObjectPicker(ObjectPicker); 1200 } 1201 1202 CoUninitialize(); 1203 } 1204 1205 return TRUE; 1206 } 1207 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY: 1208 return TRUE; 1209 case ID_REGISTRY_PRINT: 1210 PrintRegistryHive(hWnd, L""); 1211 return TRUE; 1212 case ID_REGISTRY_EXIT: 1213 DestroyWindow(hWnd); 1214 return TRUE; 1215 case ID_VIEW_STATUSBAR: 1216 toggle_child(hWnd, LOWORD(wParam), hStatusBar); 1217 return TRUE; 1218 case ID_FAVOURITES_ADDTOFAVOURITES: 1219 DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_ADDFAVORITES), hWnd, AddToFavoritesDlgProc); 1220 return TRUE; 1221 case ID_HELP_HELPTOPICS: 1222 WinHelpW(hWnd, L"regedit", HELP_FINDER, 0); 1223 return TRUE; 1224 case ID_HELP_ABOUT: 1225 ShowAboutBox(hWnd); 1226 return TRUE; 1227 case ID_VIEW_SPLIT: 1228 { 1229 RECT rt; 1230 POINT pt, pts; 1231 GetClientRect(g_pChildWnd->hWnd, &rt); 1232 pt.x = rt.left + g_pChildWnd->nSplitPos; 1233 pt.y = (rt.bottom / 2); 1234 pts = pt; 1235 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) 1236 { 1237 SetCursorPos(pts.x, pts.y); 1238 SetCursor(LoadCursorW(0, IDC_SIZEWE)); 1239 SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y)); 1240 } 1241 return TRUE; 1242 } 1243 case ID_EDIT_RENAME: 1244 case ID_EDIT_MODIFY: 1245 case ID_EDIT_MODIFY_BIN: 1246 case ID_EDIT_DELETE: 1247 regsam |= KEY_WRITE; 1248 break; 1249 } 1250 1251 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 1252 valueName = GetValueName(g_pChildWnd->hListWnd, -1); 1253 if (keyPath) 1254 { 1255 if (RegOpenKeyExW(hKeyRoot, keyPath, 0, regsam, &hKey) != ERROR_SUCCESS) 1256 hKey = 0; 1257 } 1258 1259 switch (LOWORD(wParam)) 1260 { 1261 case ID_EDIT_MODIFY: 1262 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE)) 1263 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, FALSE); 1264 break; 1265 case ID_EDIT_MODIFY_BIN: 1266 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE)) 1267 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, FALSE); 1268 break; 1269 case ID_EDIT_RENAME: 1270 if (GetFocus() == g_pChildWnd->hListWnd) 1271 { 1272 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1) 1273 { 1274 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED); 1275 if(item > -1) 1276 { 1277 (void)ListView_EditLabel(g_pChildWnd->hListWnd, item); 1278 } 1279 } 1280 } 1281 else if (GetFocus() == g_pChildWnd->hTreeWnd) 1282 { 1283 /* Get focused entry of treeview (if any) */ 1284 HTREEITEM hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd); 1285 if (hItem != NULL) 1286 (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, hItem); 1287 } 1288 break; 1289 case ID_EDIT_DELETE: 1290 { 1291 if (GetFocus() == g_pChildWnd->hListWnd && hKey) 1292 { 1293 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd); 1294 if(nSelected >= 1) 1295 { 1296 WCHAR msg[128], caption[128]; 1297 LoadStringW(hInst, IDS_QUERY_DELETE_CONFIRM, caption, ARRAY_SIZE(caption)); 1298 LoadStringW(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, ARRAY_SIZE(msg)); 1299 if(MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES) 1300 { 1301 int ni, errs; 1302 1303 item = -1; 1304 errs = 0; 1305 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1) 1306 { 1307 valueName = GetValueName(g_pChildWnd->hListWnd, item); 1308 if(RegDeleteValueW(hKey, valueName) != ERROR_SUCCESS) 1309 { 1310 errs++; 1311 } 1312 item = ni; 1313 } 1314 1315 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, FALSE); 1316 if(errs > 0) 1317 { 1318 LoadStringW(hInst, IDS_ERR_DELVAL_CAPTION, caption, ARRAY_SIZE(caption)); 1319 LoadStringW(hInst, IDS_ERR_DELETEVALUE, msg, ARRAY_SIZE(msg)); 1320 MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP); 1321 } 1322 } 1323 } 1324 } 1325 else if (GetFocus() == g_pChildWnd->hTreeWnd) 1326 { 1327 if (keyPath == NULL || *keyPath == UNICODE_NULL) 1328 { 1329 MessageBeep(MB_ICONHAND); 1330 } 1331 else if (DeleteKey(hWnd, hKeyRoot, keyPath)) 1332 { 1333 DeleteNode(g_pChildWnd->hTreeWnd, 0); 1334 RefreshTreeView(g_pChildWnd->hTreeWnd); 1335 } 1336 } 1337 break; 1338 } 1339 case ID_EDIT_NEW_STRINGVALUE: 1340 CreateNewValue(hKeyRoot, keyPath, REG_SZ); 1341 break; 1342 case ID_EDIT_NEW_BINARYVALUE: 1343 CreateNewValue(hKeyRoot, keyPath, REG_BINARY); 1344 break; 1345 case ID_EDIT_NEW_DWORDVALUE: 1346 CreateNewValue(hKeyRoot, keyPath, REG_DWORD); 1347 break; 1348 case ID_EDIT_NEW_MULTISTRINGVALUE: 1349 CreateNewValue(hKeyRoot, keyPath, REG_MULTI_SZ); 1350 break; 1351 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE: 1352 CreateNewValue(hKeyRoot, keyPath, REG_EXPAND_SZ); 1353 break; 1354 case ID_EDIT_FIND: 1355 FindDialog(hWnd); 1356 break; 1357 case ID_EDIT_FINDNEXT: 1358 FindNextMessageBox(hWnd); 1359 break; 1360 case ID_EDIT_COPYKEYNAME: 1361 CopyKeyName(hWnd, hKeyRoot, keyPath); 1362 break; 1363 case ID_EDIT_PERMISSIONS: 1364 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath); 1365 break; 1366 case ID_REGISTRY_PRINTERSETUP: 1367 //PRINTDLG pd; 1368 //PrintDlg(&pd); 1369 //PAGESETUPDLG psd; 1370 //PageSetupDlg(&psd); 1371 break; 1372 case ID_REGISTRY_OPENLOCAL: 1373 break; 1374 case ID_VIEW_REFRESH: 1375 RefreshTreeView(g_pChildWnd->hTreeWnd); 1376 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 1377 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath, TRUE); 1378 break; 1379 //case ID_OPTIONS_TOOLBAR: 1380 // toggle_child(hWnd, LOWORD(wParam), hToolBar); 1381 // break; 1382 case ID_EDIT_NEW_KEY: 1383 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); 1384 break; 1385 case ID_TREE_EXPANDBRANCH: 1386 TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_EXPAND); 1387 break; 1388 case ID_TREE_COLLAPSEBRANCH: 1389 TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_COLLAPSE); 1390 break; 1391 case ID_TREE_RENAME: 1392 SetFocus(g_pChildWnd->hTreeWnd); 1393 TreeView_EditLabel(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); 1394 break; 1395 case ID_TREE_DELETE: 1396 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), &hKeyRoot); 1397 if (keyPath == 0 || *keyPath == 0) 1398 MessageBeep(MB_ICONHAND); 1399 else if (DeleteKey(hWnd, hKeyRoot, keyPath)) 1400 DeleteNode(g_pChildWnd->hTreeWnd, 0); 1401 break; 1402 case ID_TREE_EXPORT: 1403 ExportRegistryFile(g_pChildWnd->hTreeWnd); 1404 break; 1405 case ID_TREE_PERMISSIONS: 1406 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), &hKeyRoot); 1407 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath); 1408 break; 1409 case ID_SWITCH_PANELS: 1410 { 1411 BOOL bShiftDown = GetKeyState(VK_SHIFT) < 0; 1412 HWND hwndItem = GetNextDlgTabItem(g_pChildWnd->hWnd, GetFocus(), bShiftDown); 1413 if (hwndItem == g_pChildWnd->hAddressBarWnd) 1414 PostMessageW(hwndItem, EM_SETSEL, 0, -1); 1415 SetFocus(hwndItem); 1416 } 1417 break; 1418 case ID_ADDRESS_FOCUS: 1419 SendMessageW(g_pChildWnd->hAddressBarWnd, EM_SETSEL, 0, -1); 1420 SetFocus(g_pChildWnd->hAddressBarWnd); 1421 break; 1422 default: 1423 if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX)) 1424 { 1425 HMENU hMenu; 1426 MENUITEMINFOW mii; 1427 WCHAR szFavorite[512]; 1428 1429 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION); 1430 1431 memset(&mii, 0, sizeof(mii)); 1432 mii.cbSize = sizeof(mii); 1433 mii.fMask = MIIM_TYPE; 1434 mii.fType = MFT_STRING; 1435 mii.dwTypeData = szFavorite; 1436 mii.cch = ARRAY_SIZE(szFavorite); 1437 1438 if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii)) 1439 { 1440 ChooseFavorite(szFavorite); 1441 } 1442 } 1443 else if ((LOWORD(wParam) >= ID_TREE_SUGGESTION_MIN) && (LOWORD(wParam) <= ID_TREE_SUGGESTION_MAX)) 1444 { 1445 WORD wID = LOWORD(wParam); 1446 LPCWSTR s = Suggestions; 1447 while(wID > ID_TREE_SUGGESTION_MIN) 1448 { 1449 if (*s) 1450 s += wcslen(s) + 1; 1451 wID--; 1452 } 1453 SelectNode(g_pChildWnd->hTreeWnd, s); 1454 } 1455 else 1456 { 1457 result = FALSE; 1458 } 1459 break; 1460 } 1461 1462 if(hKey) 1463 RegCloseKey(hKey); 1464 return result; 1465 } 1466 1467 /** 1468 * PURPOSE: Processes messages for the main frame window 1469 * 1470 * WM_COMMAND - process the application menu 1471 * WM_DESTROY - post a quit message and return 1472 */ 1473 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 1474 { 1475 RECT rc; 1476 switch (message) 1477 { 1478 case WM_CREATE: 1479 // For now, the Help dialog item is disabled because of lacking of HTML Help support 1480 EnableMenuItem(GetMenu(hWnd), ID_HELP_HELPTOPICS, MF_BYCOMMAND | MF_GRAYED); 1481 GetClientRect(hWnd, &rc); 1482 CreateWindowExW(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE, 1483 rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 1484 hWnd, (HMENU)0, hInst, 0); 1485 break; 1486 case WM_COMMAND: 1487 if (!_CmdWndProc(hWnd, message, wParam, lParam)) 1488 return DefWindowProcW(hWnd, message, wParam, lParam); 1489 break; 1490 case WM_ACTIVATE: 1491 if (LOWORD(wParam) != WA_INACTIVE && g_pChildWnd) 1492 SetFocus(g_pChildWnd->hWnd); 1493 break; 1494 case WM_SIZE: 1495 resize_frame_client(hWnd); 1496 break; 1497 case WM_INITMENU: 1498 OnInitMenu(hWnd); 1499 break; 1500 case WM_ENTERMENULOOP: 1501 OnEnterMenuLoop(hWnd); 1502 break; 1503 case WM_EXITMENULOOP: 1504 OnExitMenuLoop(hWnd); 1505 break; 1506 case WM_MENUSELECT: 1507 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam); 1508 break; 1509 case WM_SYSCOLORCHANGE: 1510 /* Forward WM_SYSCOLORCHANGE to common controls */ 1511 SendMessageW(g_pChildWnd->hListWnd, WM_SYSCOLORCHANGE, 0, 0); 1512 SendMessageW(g_pChildWnd->hTreeWnd, WM_SYSCOLORCHANGE, 0, 0); 1513 break; 1514 case WM_DESTROY: 1515 WinHelpW(hWnd, L"regedit", HELP_QUIT, 0); 1516 SaveSettings(); 1517 PostQuitMessage(0); 1518 default: 1519 return DefWindowProcW(hWnd, message, wParam, lParam); 1520 } 1521 return 0; 1522 } 1523