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