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