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