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); 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); 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); 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); 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 (void)ListView_EditLabel(g_pChildWnd->hListWnd, iIndex); 889 890 return TRUE; 891 } 892 893 static HRESULT 894 InitializeRemoteRegistryPicker(OUT IDsObjectPicker **pDsObjectPicker) 895 { 896 HRESULT hRet; 897 898 *pDsObjectPicker = NULL; 899 900 hRet = CoCreateInstance(&CLSID_DsObjectPicker, 901 NULL, 902 CLSCTX_INPROC_SERVER, 903 &IID_IDsObjectPicker, 904 (LPVOID*)pDsObjectPicker); 905 if (SUCCEEDED(hRet)) 906 { 907 DSOP_INIT_INFO InitInfo; 908 static DSOP_SCOPE_INIT_INFO Scopes[] = 909 { 910 { 911 sizeof(DSOP_SCOPE_INIT_INFO), 912 DSOP_SCOPE_TYPE_USER_ENTERED_UPLEVEL_SCOPE | DSOP_SCOPE_TYPE_USER_ENTERED_DOWNLEVEL_SCOPE | 913 DSOP_SCOPE_TYPE_GLOBAL_CATALOG | DSOP_SCOPE_TYPE_EXTERNAL_UPLEVEL_DOMAIN | 914 DSOP_SCOPE_TYPE_EXTERNAL_DOWNLEVEL_DOMAIN | DSOP_SCOPE_TYPE_WORKGROUP | 915 DSOP_SCOPE_TYPE_UPLEVEL_JOINED_DOMAIN | DSOP_SCOPE_TYPE_DOWNLEVEL_JOINED_DOMAIN, 916 0, 917 { 918 { 919 DSOP_FILTER_COMPUTERS, 920 0, 921 0 922 }, 923 DSOP_DOWNLEVEL_FILTER_COMPUTERS 924 }, 925 NULL, 926 NULL, 927 S_OK 928 }, 929 }; 930 931 InitInfo.cbSize = sizeof(InitInfo); 932 InitInfo.pwzTargetComputer = NULL; 933 InitInfo.cDsScopeInfos = ARRAY_SIZE(Scopes); 934 InitInfo.aDsScopeInfos = Scopes; 935 InitInfo.flOptions = 0; 936 InitInfo.cAttributesToFetch = 0; 937 InitInfo.apwzAttributeNames = NULL; 938 939 hRet = (*pDsObjectPicker)->lpVtbl->Initialize(*pDsObjectPicker, 940 &InitInfo); 941 942 if (FAILED(hRet)) 943 { 944 /* delete the object picker in case initialization failed! */ 945 (*pDsObjectPicker)->lpVtbl->Release(*pDsObjectPicker); 946 } 947 } 948 949 return hRet; 950 } 951 952 static HRESULT 953 InvokeRemoteRegistryPickerDialog(IN IDsObjectPicker *pDsObjectPicker, 954 IN HWND hwndParent OPTIONAL, 955 OUT LPWSTR lpBuffer, 956 IN UINT uSize) 957 { 958 IDataObject *pdo = NULL; 959 HRESULT hRet; 960 961 hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker, 962 hwndParent, 963 &pdo); 964 if (hRet == S_OK) 965 { 966 STGMEDIUM stm; 967 FORMATETC fe; 968 969 fe.cfFormat = (CLIPFORMAT) RegisterClipboardFormatW(CFSTR_DSOP_DS_SELECTION_LIST); 970 fe.ptd = NULL; 971 fe.dwAspect = DVASPECT_CONTENT; 972 fe.lindex = -1; 973 fe.tymed = TYMED_HGLOBAL; 974 975 hRet = pdo->lpVtbl->GetData(pdo, 976 &fe, 977 &stm); 978 if (SUCCEEDED(hRet)) 979 { 980 PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal); 981 if (SelectionList != NULL) 982 { 983 if (SelectionList->cItems == 1) 984 { 985 size_t nlen = wcslen(SelectionList->aDsSelection[0].pwzName); 986 if (nlen >= uSize) 987 { 988 nlen = uSize - 1; 989 } 990 991 memcpy(lpBuffer, 992 SelectionList->aDsSelection[0].pwzName, 993 nlen * sizeof(WCHAR)); 994 995 lpBuffer[nlen] = L'\0'; 996 } 997 998 GlobalUnlock(stm.hGlobal); 999 } 1000 1001 ReleaseStgMedium(&stm); 1002 } 1003 1004 pdo->lpVtbl->Release(pdo); 1005 } 1006 1007 return hRet; 1008 } 1009 1010 static VOID 1011 FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker) 1012 { 1013 pDsObjectPicker->lpVtbl->Release(pDsObjectPicker); 1014 } 1015 1016 /******************************************************************************* 1017 * 1018 * FUNCTION: _CmdWndProc(HWND, unsigned, WORD, LONG) 1019 * 1020 * PURPOSE: Processes WM_COMMAND messages for the main frame window. 1021 * 1022 */ 1023 static BOOL _CmdWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 1024 { 1025 HKEY hKeyRoot = 0, hKey = 0; 1026 LPCWSTR keyPath; 1027 LPCWSTR valueName; 1028 BOOL result = TRUE; 1029 REGSAM regsam = KEY_READ; 1030 int item; 1031 1032 UNREFERENCED_PARAMETER(lParam); 1033 UNREFERENCED_PARAMETER(message); 1034 1035 switch (LOWORD(wParam)) 1036 { 1037 case ID_REGISTRY_LOADHIVE: 1038 LoadHive(hWnd); 1039 return TRUE; 1040 case ID_REGISTRY_UNLOADHIVE: 1041 UnloadHive(hWnd); 1042 return TRUE; 1043 case ID_REGISTRY_IMPORTREGISTRYFILE: 1044 ImportRegistryFile(hWnd); 1045 return TRUE; 1046 case ID_REGISTRY_EXPORTREGISTRYFILE: 1047 ExportRegistryFile(hWnd); 1048 return TRUE; 1049 case ID_REGISTRY_CONNECTNETWORKREGISTRY: 1050 { 1051 IDsObjectPicker *ObjectPicker; 1052 WCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 1]; 1053 HRESULT hRet; 1054 1055 hRet = CoInitialize(NULL); 1056 if (SUCCEEDED(hRet)) 1057 { 1058 hRet = InitializeRemoteRegistryPicker(&ObjectPicker); 1059 if (SUCCEEDED(hRet)) 1060 { 1061 hRet = InvokeRemoteRegistryPickerDialog(ObjectPicker, 1062 hWnd, 1063 szComputerName, 1064 ARRAY_SIZE(szComputerName)); 1065 if (hRet == S_OK) 1066 { 1067 /* FIXME - connect to the registry */ 1068 } 1069 1070 FreeObjectPicker(ObjectPicker); 1071 } 1072 1073 CoUninitialize(); 1074 } 1075 1076 return TRUE; 1077 } 1078 case ID_REGISTRY_DISCONNECTNETWORKREGISTRY: 1079 return TRUE; 1080 case ID_REGISTRY_PRINT: 1081 PrintRegistryHive(hWnd, L""); 1082 return TRUE; 1083 case ID_REGISTRY_EXIT: 1084 DestroyWindow(hWnd); 1085 return TRUE; 1086 case ID_VIEW_STATUSBAR: 1087 toggle_child(hWnd, LOWORD(wParam), hStatusBar); 1088 return TRUE; 1089 case ID_HELP_HELPTOPICS: 1090 WinHelpW(hWnd, L"regedit", HELP_FINDER, 0); 1091 return TRUE; 1092 case ID_HELP_ABOUT: 1093 ShowAboutBox(hWnd); 1094 return TRUE; 1095 case ID_VIEW_SPLIT: 1096 { 1097 RECT rt; 1098 POINT pt, pts; 1099 GetClientRect(g_pChildWnd->hWnd, &rt); 1100 pt.x = rt.left + g_pChildWnd->nSplitPos; 1101 pt.y = (rt.bottom / 2); 1102 pts = pt; 1103 if(ClientToScreen(g_pChildWnd->hWnd, &pts)) 1104 { 1105 SetCursorPos(pts.x, pts.y); 1106 SetCursor(LoadCursorW(0, IDC_SIZEWE)); 1107 SendMessageW(g_pChildWnd->hWnd, WM_LBUTTONDOWN, 0, MAKELPARAM(pt.x, pt.y)); 1108 } 1109 return TRUE; 1110 } 1111 case ID_EDIT_RENAME: 1112 case ID_EDIT_MODIFY: 1113 case ID_EDIT_MODIFY_BIN: 1114 case ID_EDIT_DELETE: 1115 regsam |= KEY_WRITE; 1116 break; 1117 } 1118 1119 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 1120 valueName = GetValueName(g_pChildWnd->hListWnd, -1); 1121 if (keyPath) 1122 { 1123 if (RegOpenKeyExW(hKeyRoot, keyPath, 0, regsam, &hKey) != ERROR_SUCCESS) 1124 hKey = 0; 1125 } 1126 1127 switch (LOWORD(wParam)) 1128 { 1129 case ID_EDIT_MODIFY: 1130 if (valueName && ModifyValue(hWnd, hKey, valueName, FALSE)) 1131 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath); 1132 break; 1133 case ID_EDIT_MODIFY_BIN: 1134 if (valueName && ModifyValue(hWnd, hKey, valueName, TRUE)) 1135 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath); 1136 break; 1137 case ID_EDIT_RENAME: 1138 if (GetFocus() == g_pChildWnd->hListWnd) 1139 { 1140 if(ListView_GetSelectedCount(g_pChildWnd->hListWnd) == 1) 1141 { 1142 item = ListView_GetNextItem(g_pChildWnd->hListWnd, -1, LVNI_SELECTED); 1143 if(item > -1) 1144 { 1145 (void)ListView_EditLabel(g_pChildWnd->hListWnd, item); 1146 } 1147 } 1148 } 1149 else if (GetFocus() == g_pChildWnd->hTreeWnd) 1150 { 1151 /* Get focused entry of treeview (if any) */ 1152 HTREEITEM hItem = TreeView_GetSelection(g_pChildWnd->hTreeWnd); 1153 if (hItem != NULL) 1154 (void)TreeView_EditLabel(g_pChildWnd->hTreeWnd, hItem); 1155 } 1156 break; 1157 case ID_EDIT_DELETE: 1158 { 1159 if (GetFocus() == g_pChildWnd->hListWnd && hKey) 1160 { 1161 UINT nSelected = ListView_GetSelectedCount(g_pChildWnd->hListWnd); 1162 if(nSelected >= 1) 1163 { 1164 WCHAR msg[128], caption[128]; 1165 LoadStringW(hInst, IDS_QUERY_DELETE_CONFIRM, caption, ARRAY_SIZE(caption)); 1166 LoadStringW(hInst, (nSelected == 1 ? IDS_QUERY_DELETE_ONE : IDS_QUERY_DELETE_MORE), msg, ARRAY_SIZE(msg)); 1167 if(MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) == IDYES) 1168 { 1169 int ni, errs; 1170 1171 item = -1; 1172 errs = 0; 1173 while((ni = ListView_GetNextItem(g_pChildWnd->hListWnd, item, LVNI_SELECTED)) > -1) 1174 { 1175 valueName = GetValueName(g_pChildWnd->hListWnd, item); 1176 if(RegDeleteValueW(hKey, valueName) != ERROR_SUCCESS) 1177 { 1178 errs++; 1179 } 1180 item = ni; 1181 } 1182 1183 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath); 1184 if(errs > 0) 1185 { 1186 LoadStringW(hInst, IDS_ERR_DELVAL_CAPTION, caption, ARRAY_SIZE(caption)); 1187 LoadStringW(hInst, IDS_ERR_DELETEVALUE, msg, ARRAY_SIZE(msg)); 1188 MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONSTOP); 1189 } 1190 } 1191 } 1192 } 1193 else if (GetFocus() == g_pChildWnd->hTreeWnd) 1194 { 1195 if (keyPath == NULL || *keyPath == UNICODE_NULL) 1196 { 1197 MessageBeep(MB_ICONHAND); 1198 } 1199 else if (DeleteKey(hWnd, hKeyRoot, keyPath)) 1200 { 1201 DeleteNode(g_pChildWnd->hTreeWnd, 0); 1202 RefreshTreeView(g_pChildWnd->hTreeWnd); 1203 } 1204 } 1205 break; 1206 } 1207 case ID_EDIT_NEW_STRINGVALUE: 1208 CreateNewValue(hKeyRoot, keyPath, REG_SZ); 1209 break; 1210 case ID_EDIT_NEW_BINARYVALUE: 1211 CreateNewValue(hKeyRoot, keyPath, REG_BINARY); 1212 break; 1213 case ID_EDIT_NEW_DWORDVALUE: 1214 CreateNewValue(hKeyRoot, keyPath, REG_DWORD); 1215 break; 1216 case ID_EDIT_NEW_MULTISTRINGVALUE: 1217 CreateNewValue(hKeyRoot, keyPath, REG_MULTI_SZ); 1218 break; 1219 case ID_EDIT_NEW_EXPANDABLESTRINGVALUE: 1220 CreateNewValue(hKeyRoot, keyPath, REG_EXPAND_SZ); 1221 break; 1222 case ID_EDIT_FIND: 1223 FindDialog(hWnd); 1224 break; 1225 case ID_EDIT_FINDNEXT: 1226 FindNextMessageBox(hWnd); 1227 break; 1228 case ID_EDIT_COPYKEYNAME: 1229 CopyKeyName(hWnd, hKeyRoot, keyPath); 1230 break; 1231 case ID_EDIT_PERMISSIONS: 1232 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath); 1233 break; 1234 case ID_REGISTRY_PRINTERSETUP: 1235 /*PRINTDLG pd;*/ 1236 /*PrintDlg(&pd);*/ 1237 /*PAGESETUPDLG psd;*/ 1238 /*PageSetupDlg(&psd);*/ 1239 break; 1240 case ID_REGISTRY_OPENLOCAL: 1241 break; 1242 1243 case ID_VIEW_REFRESH: 1244 RefreshTreeView(g_pChildWnd->hTreeWnd); 1245 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 1246 RefreshListView(g_pChildWnd->hListWnd, hKeyRoot, keyPath); 1247 break; 1248 /*case ID_OPTIONS_TOOLBAR:*/ 1249 /* toggle_child(hWnd, LOWORD(wParam), hToolBar);*/ 1250 /* break;*/ 1251 case ID_EDIT_NEW_KEY: 1252 CreateNewKey(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); 1253 break; 1254 1255 case ID_TREE_EXPANDBRANCH: 1256 TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_EXPAND); 1257 break; 1258 case ID_TREE_COLLAPSEBRANCH: 1259 TreeView_Expand(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), TVE_COLLAPSE); 1260 break; 1261 case ID_TREE_RENAME: 1262 SetFocus(g_pChildWnd->hTreeWnd); 1263 TreeView_EditLabel(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd)); 1264 break; 1265 case ID_TREE_DELETE: 1266 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), &hKeyRoot); 1267 if (keyPath == 0 || *keyPath == 0) 1268 { 1269 MessageBeep(MB_ICONHAND); 1270 } 1271 else if (DeleteKey(hWnd, hKeyRoot, keyPath)) 1272 DeleteNode(g_pChildWnd->hTreeWnd, 0); 1273 break; 1274 case ID_TREE_EXPORT: 1275 ExportRegistryFile(g_pChildWnd->hTreeWnd); 1276 break; 1277 case ID_TREE_PERMISSIONS: 1278 keyPath = GetItemPath(g_pChildWnd->hTreeWnd, TreeView_GetSelection(g_pChildWnd->hTreeWnd), &hKeyRoot); 1279 RegKeyEditPermissions(hWnd, hKeyRoot, NULL, keyPath); 1280 break; 1281 case ID_SWITCH_PANELS: 1282 { 1283 BOOL bShiftDown = GetKeyState(VK_SHIFT) < 0; 1284 HWND hwndItem = GetNextDlgTabItem(g_pChildWnd->hWnd, GetFocus(), bShiftDown); 1285 if (hwndItem == g_pChildWnd->hAddressBarWnd) 1286 PostMessageW(hwndItem, EM_SETSEL, 0, -1); 1287 SetFocus(hwndItem); 1288 } 1289 break; 1290 1291 case ID_ADDRESS_FOCUS: 1292 SendMessageW(g_pChildWnd->hAddressBarWnd, EM_SETSEL, 0, -1); 1293 SetFocus(g_pChildWnd->hAddressBarWnd); 1294 break; 1295 1296 default: 1297 if ((LOWORD(wParam) >= ID_FAVORITES_MIN) && (LOWORD(wParam) <= ID_FAVORITES_MAX)) 1298 { 1299 HMENU hMenu; 1300 MENUITEMINFOW mii; 1301 WCHAR szFavorite[512]; 1302 1303 hMenu = GetSubMenu(GetMenu(hWnd), FAVORITES_MENU_POSITION); 1304 1305 memset(&mii, 0, sizeof(mii)); 1306 mii.cbSize = sizeof(mii); 1307 mii.fMask = MIIM_TYPE; 1308 mii.fType = MFT_STRING; 1309 mii.dwTypeData = szFavorite; 1310 mii.cch = ARRAY_SIZE(szFavorite); 1311 1312 if (GetMenuItemInfo(hMenu, LOWORD(wParam) - ID_FAVORITES_MIN, TRUE, &mii)) 1313 { 1314 ChooseFavorite(szFavorite); 1315 } 1316 } 1317 else if ((LOWORD(wParam) >= ID_TREE_SUGGESTION_MIN) && (LOWORD(wParam) <= ID_TREE_SUGGESTION_MAX)) 1318 { 1319 WORD wID = LOWORD(wParam); 1320 LPCWSTR s = Suggestions; 1321 while(wID > ID_TREE_SUGGESTION_MIN) 1322 { 1323 if (*s) 1324 s += wcslen(s) + 1; 1325 wID--; 1326 } 1327 SelectNode(g_pChildWnd->hTreeWnd, s); 1328 } 1329 else 1330 { 1331 result = FALSE; 1332 } 1333 break; 1334 } 1335 1336 if(hKey) 1337 RegCloseKey(hKey); 1338 return result; 1339 } 1340 1341 /******************************************************************************** 1342 * 1343 * FUNCTION: FrameWndProc(HWND, unsigned, WORD, LONG) 1344 * 1345 * PURPOSE: Processes messages for the main frame window. 1346 * 1347 * WM_COMMAND - process the application menu 1348 * WM_DESTROY - post a quit message and return 1349 * 1350 */ 1351 1352 LRESULT CALLBACK FrameWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 1353 { 1354 RECT rc; 1355 switch (message) 1356 { 1357 case WM_CREATE: 1358 // For now, the Help dialog item is disabled because of lacking of HTML Help support 1359 EnableMenuItem(GetMenu(hWnd), ID_HELP_HELPTOPICS, MF_BYCOMMAND | MF_GRAYED); 1360 GetClientRect(hWnd, &rc); 1361 CreateWindowExW(0, szChildClass, NULL, WS_CHILD | WS_VISIBLE, 1362 rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 1363 hWnd, (HMENU)0, hInst, 0); 1364 break; 1365 case WM_COMMAND: 1366 if (!_CmdWndProc(hWnd, message, wParam, lParam)) 1367 return DefWindowProcW(hWnd, message, wParam, lParam); 1368 break; 1369 case WM_ACTIVATE: 1370 if (LOWORD(hWnd) && g_pChildWnd) 1371 SetFocus(g_pChildWnd->hWnd); 1372 break; 1373 case WM_SIZE: 1374 resize_frame_client(hWnd); 1375 break; 1376 case WM_TIMER: 1377 break; 1378 case WM_INITMENU: 1379 OnInitMenu(hWnd); 1380 break; 1381 case WM_ENTERMENULOOP: 1382 OnEnterMenuLoop(hWnd); 1383 break; 1384 case WM_EXITMENULOOP: 1385 OnExitMenuLoop(hWnd); 1386 break; 1387 case WM_MENUSELECT: 1388 OnMenuSelect(hWnd, LOWORD(wParam), HIWORD(wParam), (HMENU)lParam); 1389 break; 1390 case WM_SYSCOLORCHANGE: 1391 /* Forward WM_SYSCOLORCHANGE to common controls */ 1392 SendMessageW(g_pChildWnd->hListWnd, WM_SYSCOLORCHANGE, 0, 0); 1393 SendMessageW(g_pChildWnd->hTreeWnd, WM_SYSCOLORCHANGE, 0, 0); 1394 break; 1395 case WM_DESTROY: 1396 WinHelpW(hWnd, L"regedit", HELP_QUIT, 0); 1397 SaveSettings(); 1398 PostQuitMessage(0); 1399 default: 1400 return DefWindowProcW(hWnd, message, wParam, lParam); 1401 } 1402 return 0; 1403 } 1404