1 /* 2 * Regedit find dialog 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation; either 7 * version 2.1 of the License, or (at your option) any later version. 8 * 9 * This library is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 * Lesser General Public License for more details. 13 * 14 * You should have received a copy of the GNU Lesser General Public 15 * License along with this library; if not, write to the Free Software 16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17 */ 18 19 #include "regedit.h" 20 21 #define RSF_WHOLESTRING 0x00000001 22 #define RSF_LOOKATKEYS 0x00000002 23 #define RSF_LOOKATVALUES 0x00000004 24 #define RSF_LOOKATDATA 0x00000008 25 #define RSF_MATCHCASE 0x00010000 26 27 static WCHAR s_szFindWhat[256]; 28 static const WCHAR s_szFindFlags[] = L"FindFlags"; 29 static const WCHAR s_szFindFlagsR[] = L"FindFlagsReactOS"; 30 static HWND s_hwndAbortDialog; 31 static BOOL s_bAbort; 32 33 static DWORD s_dwFlags; 34 static WCHAR s_szName[MAX_PATH]; 35 static DWORD s_cchName; 36 static const WCHAR s_empty[] = L""; 37 static const WCHAR s_backslash[] = L"\\"; 38 39 extern VOID SetValueName(HWND hwndLV, LPCWSTR pszValueName); 40 41 BOOL DoEvents(VOID) 42 { 43 MSG msg; 44 if (PeekMessageW(&msg, NULL, 0, 0, PM_REMOVE)) 45 { 46 if (msg.message == WM_QUIT) 47 s_bAbort = TRUE; 48 if (!IsDialogMessageW(s_hwndAbortDialog, &msg)) 49 { 50 TranslateMessage(&msg); 51 DispatchMessageW(&msg); 52 } 53 } 54 return s_bAbort; 55 } 56 57 static LPWSTR lstrstri(LPCWSTR psz1, LPCWSTR psz2) 58 { 59 INT i, cch1, cch2; 60 61 cch1 = wcslen(psz1); 62 cch2 = wcslen(psz2); 63 for(i = 0; i <= cch1 - cch2; i++) 64 { 65 if (CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, 66 psz1 + i, cch2, psz2, cch2) == 2) 67 return (LPWSTR) (psz1 + i); 68 } 69 return NULL; 70 } 71 72 static BOOL CompareName(LPCWSTR pszName1, LPCWSTR pszName2) 73 { 74 if (s_dwFlags & RSF_WHOLESTRING) 75 { 76 if (s_dwFlags & RSF_MATCHCASE) 77 return wcscmp(pszName1, pszName2) == 0; 78 else 79 return _wcsicmp(pszName1, pszName2) == 0; 80 } 81 else 82 { 83 if (s_dwFlags & RSF_MATCHCASE) 84 return wcsstr(pszName1, pszName2) != NULL; 85 else 86 return lstrstri(pszName1, pszName2) != NULL; 87 } 88 } 89 90 /* Do not assume that pch1 is terminated with UNICODE_NULL */ 91 static BOOL MatchString(LPCWCH pch1, INT cch1, LPCWCH pch2, INT cch2) 92 { 93 INT i; 94 DWORD dwNorm = ((s_dwFlags & RSF_MATCHCASE) ? NORM_IGNORECASE : 0); 95 96 if (s_dwFlags & RSF_WHOLESTRING) 97 return 2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, dwNorm, pch1, cch1, pch2, cch2); 98 99 if (cch1 < cch2) 100 return FALSE; 101 102 for (i = 0; i <= cch1 - cch2; i++) 103 { 104 if (2 == CompareStringW(LOCALE_SYSTEM_DEFAULT, dwNorm, pch1 + i, cch2, pch2, cch2)) 105 return TRUE; 106 } 107 108 return FALSE; 109 } 110 111 static BOOL MatchData(DWORD dwType, LPCVOID pv1, DWORD cb1) 112 { 113 if (dwType == REG_SZ || dwType == REG_EXPAND_SZ || dwType == REG_MULTI_SZ) 114 return MatchString(pv1, (INT)(cb1 / sizeof(WCHAR)), s_szFindWhat, lstrlenW(s_szFindWhat)); 115 116 return FALSE; 117 } 118 119 int compare(const void *x, const void *y) 120 { 121 const LPCWSTR *a = (const LPCWSTR *)x; 122 const LPCWSTR *b = (const LPCWSTR *)y; 123 return _wcsicmp(*a, *b); 124 } 125 126 BOOL RegFindRecurse( 127 HKEY hKey, 128 LPCWSTR pszSubKey, 129 LPCWSTR pszValueName, 130 LPWSTR *ppszFoundSubKey, 131 LPWSTR *ppszFoundValueName) 132 { 133 HKEY hSubKey; 134 LONG lResult; 135 WCHAR szSubKey[MAX_PATH]; 136 DWORD i, c, cb, type; 137 BOOL fPast; 138 LPWSTR *ppszNames = NULL; 139 LPBYTE pb = NULL; 140 141 if (DoEvents()) 142 return FALSE; 143 144 if(wcslen(pszSubKey) >= _countof(szSubKey)) 145 return FALSE; 146 147 StringCbCopyW(szSubKey, sizeof(szSubKey), pszSubKey); 148 hSubKey = NULL; 149 150 lResult = RegOpenKeyExW(hKey, szSubKey, 0, KEY_ALL_ACCESS, &hSubKey); 151 if (lResult != ERROR_SUCCESS) 152 return FALSE; 153 154 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, NULL, NULL, NULL, 155 &c, NULL, NULL, NULL, NULL); 156 if (lResult != ERROR_SUCCESS) 157 goto err; 158 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 159 if (ppszNames == NULL) 160 goto err; 161 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 162 163 /* Retrieve the value names associated with the current key */ 164 for(i = 0; i < c; i++) 165 { 166 if (DoEvents()) 167 goto err; 168 169 s_cchName = _countof(s_szName); 170 lResult = RegEnumValueW(hSubKey, i, s_szName, &s_cchName, NULL, NULL, 171 NULL, &cb); 172 if (lResult == ERROR_NO_MORE_ITEMS) 173 { 174 c = i; 175 break; 176 } 177 if (lResult != ERROR_SUCCESS) 178 goto err; 179 if (s_cchName >= _countof(s_szName)) 180 continue; 181 182 ppszNames[i] = _wcsdup(s_szName); 183 } 184 185 qsort(ppszNames, c, sizeof(LPWSTR), compare); 186 187 /* If pszValueName is NULL, the function will search for all values within the key */ 188 fPast = (pszValueName == NULL); 189 190 /* Search within the values */ 191 for (i = 0; i < c; i++) 192 { 193 if (DoEvents()) 194 goto err; 195 196 if (!fPast && _wcsicmp(ppszNames[i], pszValueName) == 0) 197 { 198 fPast = TRUE; 199 continue; 200 } 201 if (!fPast) 202 continue; 203 204 if ((s_dwFlags & RSF_LOOKATVALUES) && 205 CompareName(ppszNames[i], s_szFindWhat)) 206 { 207 *ppszFoundSubKey = _wcsdup(szSubKey); 208 *ppszFoundValueName = _wcsdup(ppszNames[i]); 209 goto success; 210 } 211 212 lResult = RegQueryValueExW(hSubKey, ppszNames[i], NULL, &type, 213 NULL, &cb); 214 if (lResult != ERROR_SUCCESS) 215 goto err; 216 pb = malloc(cb); 217 if (pb == NULL) 218 goto err; 219 lResult = RegQueryValueExW(hSubKey, ppszNames[i], NULL, &type, 220 pb, &cb); 221 if (lResult != ERROR_SUCCESS) 222 goto err; 223 224 if ((s_dwFlags & RSF_LOOKATDATA) && MatchData(type, pb, cb)) 225 { 226 *ppszFoundSubKey = _wcsdup(szSubKey); 227 *ppszFoundValueName = _wcsdup(ppszNames[i]); 228 goto success; 229 } 230 free(pb); 231 pb = NULL; 232 } 233 234 if (ppszNames != NULL) 235 { 236 for(i = 0; i < c; i++) 237 free(ppszNames[i]); 238 free(ppszNames); 239 } 240 ppszNames = NULL; 241 242 /* Retrieve the number of sub-keys */ 243 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &c, NULL, NULL, 244 NULL, NULL, NULL, NULL, NULL); 245 if (lResult != ERROR_SUCCESS) 246 goto err; 247 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 248 if (ppszNames == NULL) 249 goto err; 250 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 251 252 /* Retrieve the names of the sub-keys */ 253 for(i = 0; i < c; i++) 254 { 255 if (DoEvents()) 256 goto err; 257 258 s_cchName = _countof(s_szName); 259 lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName, NULL, NULL, 260 NULL, NULL); 261 if (lResult == ERROR_NO_MORE_ITEMS) 262 { 263 c = i; 264 break; 265 } 266 if (lResult != ERROR_SUCCESS) 267 goto err; 268 if (s_cchName >= _countof(s_szName)) 269 continue; 270 271 ppszNames[i] = _wcsdup(s_szName); 272 } 273 274 qsort(ppszNames, c, sizeof(LPWSTR), compare); 275 276 /* Search within the sub-keys */ 277 for(i = 0; i < c; i++) 278 { 279 if (DoEvents()) 280 goto err; 281 282 if ((s_dwFlags & RSF_LOOKATKEYS) && 283 CompareName(ppszNames[i], s_szFindWhat)) 284 { 285 *ppszFoundSubKey = malloc( 286 (wcslen(szSubKey) + wcslen(ppszNames[i]) + 2) * 287 sizeof(WCHAR)); 288 if (*ppszFoundSubKey == NULL) 289 goto err; 290 if (szSubKey[0]) 291 { 292 wcscpy(*ppszFoundSubKey, szSubKey); 293 wcscat(*ppszFoundSubKey, s_backslash); 294 } 295 else 296 **ppszFoundSubKey = 0; 297 wcscat(*ppszFoundSubKey, ppszNames[i]); 298 *ppszFoundValueName = NULL; 299 goto success; 300 } 301 302 /* Search within the value entries of the sub-key */ 303 if (RegFindRecurse(hSubKey, ppszNames[i], NULL, ppszFoundSubKey, 304 ppszFoundValueName)) 305 { 306 LPWSTR psz = *ppszFoundSubKey; 307 SIZE_T cbFoundSubKey = (wcslen(szSubKey) + wcslen(psz) + 2) * sizeof(WCHAR); 308 *ppszFoundSubKey = malloc(cbFoundSubKey); 309 if (*ppszFoundSubKey == NULL) 310 goto err; 311 if (szSubKey[0]) 312 { 313 StringCbCopyW(*ppszFoundSubKey, cbFoundSubKey, szSubKey); 314 StringCbCatW(*ppszFoundSubKey, cbFoundSubKey, s_backslash); 315 } 316 else 317 **ppszFoundSubKey = 0; 318 wcscat(*ppszFoundSubKey, psz); 319 free(psz); 320 goto success; 321 } 322 } 323 324 err: 325 if (ppszNames != NULL) 326 { 327 for(i = 0; i < c; i++) 328 free(ppszNames[i]); 329 free(ppszNames); 330 } 331 free(pb); 332 RegCloseKey(hSubKey); 333 return FALSE; 334 335 success: 336 if (ppszNames != NULL) 337 { 338 for(i = 0; i < c; i++) 339 free(ppszNames[i]); 340 free(ppszNames); 341 } 342 RegCloseKey(hSubKey); 343 return TRUE; 344 } 345 346 BOOL RegFindWalk( 347 HKEY * phKey, 348 LPCWSTR pszSubKey, 349 LPCWSTR pszValueName, 350 LPWSTR *ppszFoundSubKey, 351 LPWSTR *ppszFoundValueName) 352 { 353 LONG lResult; 354 DWORD i, c; 355 HKEY hBaseKey, hSubKey; 356 WCHAR szKeyName[MAX_PATH]; 357 WCHAR szSubKey[MAX_PATH]; 358 LPWSTR pch; 359 BOOL fPast, fKeyMatched; 360 LPWSTR *ppszNames = NULL; 361 362 hBaseKey = *phKey; 363 364 if (wcslen(pszSubKey) >= _countof(szSubKey)) 365 return FALSE; 366 367 if (RegFindRecurse(hBaseKey, pszSubKey, pszValueName, ppszFoundSubKey, 368 ppszFoundValueName)) 369 return TRUE; 370 371 StringCbCopyW(szSubKey, sizeof(szSubKey), pszSubKey); 372 while(szSubKey[0] != 0) 373 { 374 if (DoEvents()) 375 return FALSE; 376 377 pch = wcsrchr(szSubKey, L'\\'); 378 if (pch == NULL) 379 { 380 wcscpy(szKeyName, szSubKey); 381 szSubKey[0] = 0; 382 hSubKey = hBaseKey; 383 } 384 else 385 { 386 lstrcpynW(szKeyName, pch + 1, MAX_PATH); 387 *pch = 0; 388 lResult = RegOpenKeyExW(hBaseKey, szSubKey, 0, KEY_ALL_ACCESS, 389 &hSubKey); 390 if (lResult != ERROR_SUCCESS) 391 return FALSE; 392 } 393 394 lResult = RegQueryInfoKeyW(hSubKey, NULL, NULL, NULL, &c, NULL, NULL, 395 NULL, NULL, NULL, NULL, NULL); 396 if (lResult != ERROR_SUCCESS) 397 goto err; 398 399 ppszNames = (LPWSTR *) malloc(c * sizeof(LPWSTR)); 400 if (ppszNames == NULL) 401 goto err; 402 ZeroMemory(ppszNames, c * sizeof(LPWSTR)); 403 404 for(i = 0; i < c; i++) 405 { 406 if (DoEvents()) 407 goto err; 408 409 s_cchName = _countof(s_szName); 410 lResult = RegEnumKeyExW(hSubKey, i, s_szName, &s_cchName, 411 NULL, NULL, NULL, NULL); 412 if (lResult == ERROR_NO_MORE_ITEMS) 413 { 414 c = i; 415 break; 416 } 417 if (lResult != ERROR_SUCCESS) 418 break; 419 ppszNames[i] = _wcsdup(s_szName); 420 } 421 422 qsort(ppszNames, c, sizeof(LPWSTR), compare); 423 424 fPast = FALSE; 425 for(i = 0; i < c; i++) 426 { 427 if (DoEvents()) 428 goto err; 429 430 if (!fPast && _wcsicmp(ppszNames[i], szKeyName) == 0) 431 { 432 fPast = TRUE; 433 continue; 434 } 435 if (!fPast) 436 continue; 437 438 if ((s_dwFlags & RSF_LOOKATKEYS) && 439 CompareName(ppszNames[i], s_szFindWhat)) 440 { 441 *ppszFoundSubKey = malloc( 442 (wcslen(szSubKey) + wcslen(ppszNames[i]) + 2) * 443 sizeof(WCHAR)); 444 if (*ppszFoundSubKey == NULL) 445 goto err; 446 if (szSubKey[0]) 447 { 448 wcscpy(*ppszFoundSubKey, szSubKey); 449 wcscat(*ppszFoundSubKey, s_backslash); 450 } 451 else 452 **ppszFoundSubKey = 0; 453 wcscat(*ppszFoundSubKey, ppszNames[i]); 454 *ppszFoundValueName = NULL; 455 goto success; 456 } 457 458 fKeyMatched = (_wcsicmp(ppszNames[i], szKeyName) == 0); 459 if (RegFindRecurse(hSubKey, ppszNames[i], (fKeyMatched ? pszValueName : NULL), 460 ppszFoundSubKey, ppszFoundValueName)) 461 { 462 LPWSTR psz = *ppszFoundSubKey; 463 SIZE_T cbFoundSubKey = (wcslen(szSubKey) + wcslen(psz) + 2) * sizeof(WCHAR); 464 *ppszFoundSubKey = malloc(cbFoundSubKey); 465 if (*ppszFoundSubKey == NULL) 466 goto err; 467 if (szSubKey[0]) 468 { 469 StringCbCopyW(*ppszFoundSubKey, cbFoundSubKey, szSubKey); 470 StringCbCatW(*ppszFoundSubKey, cbFoundSubKey, s_backslash); 471 } 472 else 473 **ppszFoundSubKey = 0; 474 wcscat(*ppszFoundSubKey, psz); 475 free(psz); 476 goto success; 477 } 478 } 479 if (ppszNames != NULL) 480 { 481 for(i = 0; i < c; i++) 482 free(ppszNames[i]); 483 free(ppszNames); 484 } 485 ppszNames = NULL; 486 487 if (hBaseKey != hSubKey) 488 RegCloseKey(hSubKey); 489 } 490 491 if (*phKey == HKEY_CLASSES_ROOT) 492 { 493 *phKey = HKEY_CURRENT_USER; 494 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 495 ppszFoundValueName)) 496 return TRUE; 497 } 498 499 if (*phKey == HKEY_CURRENT_USER) 500 { 501 *phKey = HKEY_LOCAL_MACHINE; 502 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 503 ppszFoundValueName)) 504 goto success; 505 } 506 507 if (*phKey == HKEY_LOCAL_MACHINE) 508 { 509 *phKey = HKEY_USERS; 510 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 511 ppszFoundValueName)) 512 goto success; 513 } 514 515 if (*phKey == HKEY_USERS) 516 { 517 *phKey = HKEY_CURRENT_CONFIG; 518 if (RegFindRecurse(*phKey, s_empty, NULL, ppszFoundSubKey, 519 ppszFoundValueName)) 520 goto success; 521 } 522 523 err: 524 if (ppszNames != NULL) 525 { 526 for(i = 0; i < c; i++) 527 free(ppszNames[i]); 528 free(ppszNames); 529 } 530 if (hBaseKey != hSubKey) 531 RegCloseKey(hSubKey); 532 return FALSE; 533 534 success: 535 if (ppszNames != NULL) 536 { 537 for(i = 0; i < c; i++) 538 free(ppszNames[i]); 539 free(ppszNames); 540 } 541 if (hBaseKey != hSubKey) 542 RegCloseKey(hSubKey); 543 return TRUE; 544 } 545 546 547 static DWORD GetFindFlags(void) 548 { 549 HKEY hKey; 550 DWORD dwType, dwValue, cbData; 551 DWORD dwFlags = RSF_LOOKATKEYS | RSF_LOOKATVALUES | RSF_LOOKATDATA; 552 553 if (RegOpenKeyW(HKEY_CURRENT_USER, g_szGeneralRegKey, &hKey) == ERROR_SUCCESS) 554 { 555 /* Retrieve flags from registry key */ 556 cbData = sizeof(dwValue); 557 if (RegQueryValueExW(hKey, s_szFindFlags, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS) 558 { 559 if (dwType == REG_DWORD) 560 dwFlags = (dwFlags & ~0x0000FFFF) | ((dwValue & 0x0000FFFF) << 0); 561 } 562 563 /* Retrieve ReactOS Regedit specific flags from registry key */ 564 cbData = sizeof(dwValue); 565 if (RegQueryValueExW(hKey, s_szFindFlagsR, NULL, &dwType, (LPBYTE) &dwValue, &cbData) == ERROR_SUCCESS) 566 { 567 if (dwType == REG_DWORD) 568 dwFlags = (dwFlags & ~0xFFFF0000) | ((dwValue & 0x0000FFFF) << 16); 569 } 570 571 RegCloseKey(hKey); 572 } 573 return dwFlags; 574 } 575 576 static void SetFindFlags(DWORD dwFlags) 577 { 578 HKEY hKey; 579 DWORD dwDisposition; 580 DWORD dwData; 581 582 if (RegCreateKeyExW(HKEY_CURRENT_USER, g_szGeneralRegKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &dwDisposition) == ERROR_SUCCESS) 583 { 584 dwData = (dwFlags >> 0) & 0x0000FFFF; 585 RegSetValueExW(hKey, s_szFindFlags, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData)); 586 587 dwData = (dwFlags >> 16) & 0x0000FFFF; 588 RegSetValueExW(hKey, s_szFindFlagsR, 0, REG_DWORD, (const BYTE *) &dwData, sizeof(dwData)); 589 590 RegCloseKey(hKey); 591 } 592 } 593 594 static INT_PTR CALLBACK AbortFindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 595 { 596 UNREFERENCED_PARAMETER(lParam); 597 UNREFERENCED_PARAMETER(hDlg); 598 599 switch(uMsg) 600 { 601 case WM_CLOSE: 602 s_bAbort = TRUE; 603 break; 604 605 case WM_COMMAND: 606 switch(HIWORD(wParam)) 607 { 608 case BN_CLICKED: 609 switch(LOWORD(wParam)) 610 { 611 case IDCANCEL: 612 s_bAbort = TRUE; 613 break; 614 } 615 break; 616 } 617 break; 618 } 619 return 0; 620 } 621 622 BOOL FindNext(HWND hWnd) 623 { 624 HKEY hKeyRoot; 625 LPCWSTR pszKeyPath; 626 BOOL fSuccess; 627 WCHAR szFullKey[512]; 628 LPCWSTR pszValueName; 629 LPWSTR pszFoundSubKey, pszFoundValueName; 630 631 if (wcslen(s_szFindWhat) == 0) 632 { 633 FindDialog(hWnd); 634 return TRUE; 635 } 636 637 s_dwFlags = GetFindFlags(); 638 639 pszKeyPath = GetItemPath(g_pChildWnd->hTreeWnd, 0, &hKeyRoot); 640 if (pszKeyPath == NULL) 641 { 642 hKeyRoot = HKEY_CLASSES_ROOT; 643 pszKeyPath = s_empty; 644 } 645 646 /* Create abort find dialog */ 647 s_hwndAbortDialog = CreateDialogW(GetModuleHandle(NULL), 648 MAKEINTRESOURCEW(IDD_FINDING), hWnd, AbortFindDialogProc); 649 if (s_hwndAbortDialog) 650 { 651 ShowWindow(s_hwndAbortDialog, SW_SHOW); 652 UpdateWindow(s_hwndAbortDialog); 653 } 654 s_bAbort = FALSE; 655 656 pszValueName = GetValueName(g_pChildWnd->hListWnd, -1); 657 658 EnableWindow(hFrameWnd, FALSE); 659 EnableWindow(g_pChildWnd->hTreeWnd, FALSE); 660 EnableWindow(g_pChildWnd->hListWnd, FALSE); 661 EnableWindow(g_pChildWnd->hAddressBarWnd, FALSE); 662 663 fSuccess = RegFindWalk(&hKeyRoot, pszKeyPath, pszValueName, 664 &pszFoundSubKey, &pszFoundValueName); 665 666 EnableWindow(hFrameWnd, TRUE); 667 EnableWindow(g_pChildWnd->hTreeWnd, TRUE); 668 EnableWindow(g_pChildWnd->hListWnd, TRUE); 669 EnableWindow(g_pChildWnd->hAddressBarWnd, TRUE); 670 671 if (s_hwndAbortDialog) 672 { 673 DestroyWindow(s_hwndAbortDialog); 674 s_hwndAbortDialog = NULL; 675 } 676 677 if (fSuccess) 678 { 679 GetKeyName(szFullKey, ARRAY_SIZE(szFullKey), hKeyRoot, pszFoundSubKey); 680 SelectNode(g_pChildWnd->hTreeWnd, szFullKey); 681 free(pszFoundSubKey); 682 683 if (pszFoundValueName != NULL) 684 { 685 SetValueName(g_pChildWnd->hListWnd, pszFoundValueName); 686 free(pszFoundValueName); 687 SetFocus(g_pChildWnd->hListWnd); 688 } 689 else 690 { 691 SetFocus(g_pChildWnd->hTreeWnd); 692 } 693 } 694 return fSuccess || s_bAbort; 695 } 696 697 static INT_PTR CALLBACK FindDialogProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) 698 { 699 INT_PTR iResult = 0; 700 HWND hControl; 701 LONG lStyle; 702 DWORD dwFlags; 703 static WCHAR s_szSavedFindValue[256]; 704 705 switch(uMsg) 706 { 707 case WM_INITDIALOG: 708 dwFlags = GetFindFlags(); 709 710 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS); 711 if (hControl) 712 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATKEYS) ? TRUE : FALSE, 0); 713 714 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES); 715 if (hControl) 716 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATVALUES) ? TRUE : FALSE, 0); 717 718 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA); 719 if (hControl) 720 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_LOOKATDATA) ? TRUE : FALSE, 0); 721 722 /* Match whole string */ 723 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING); 724 if (hControl) 725 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_WHOLESTRING) ? TRUE : FALSE, 0); 726 727 /* Case sensitivity */ 728 hControl = GetDlgItem(hDlg, IDC_MATCHCASE); 729 if (hControl) 730 SendMessageW(hControl, BM_SETCHECK, (dwFlags & RSF_MATCHCASE) ? TRUE : FALSE, 0); 731 732 hControl = GetDlgItem(hDlg, IDC_FINDWHAT); 733 if (hControl) 734 { 735 SetWindowTextW(hControl, s_szSavedFindValue); 736 SetFocus(hControl); 737 SendMessageW(hControl, EM_SETSEL, 0, -1); 738 } 739 break; 740 741 case WM_CLOSE: 742 EndDialog(hDlg, 0); 743 break; 744 745 case WM_COMMAND: 746 switch(HIWORD(wParam)) 747 { 748 case BN_CLICKED: 749 switch(LOWORD(wParam)) 750 { 751 case IDOK: 752 dwFlags = 0; 753 754 hControl = GetDlgItem(hDlg, IDC_LOOKAT_KEYS); 755 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 756 dwFlags |= RSF_LOOKATKEYS; 757 758 hControl = GetDlgItem(hDlg, IDC_LOOKAT_VALUES); 759 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 760 dwFlags |= RSF_LOOKATVALUES; 761 762 hControl = GetDlgItem(hDlg, IDC_LOOKAT_DATA); 763 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 764 dwFlags |= RSF_LOOKATDATA; 765 766 hControl = GetDlgItem(hDlg, IDC_MATCHSTRING); 767 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 768 dwFlags |= RSF_WHOLESTRING; 769 770 hControl = GetDlgItem(hDlg, IDC_MATCHCASE); 771 if (hControl && (SendMessageW(hControl, BM_GETCHECK, 0, 0) == BST_CHECKED)) 772 dwFlags |= RSF_MATCHCASE; 773 774 SetFindFlags(dwFlags); 775 776 hControl = GetDlgItem(hDlg, IDC_FINDWHAT); 777 if (hControl) 778 GetWindowTextW(hControl, s_szFindWhat, ARRAY_SIZE(s_szFindWhat)); 779 EndDialog(hDlg, 1); 780 break; 781 782 case IDCANCEL: 783 EndDialog(hDlg, 0); 784 break; 785 } 786 break; 787 788 case EN_CHANGE: 789 switch(LOWORD(wParam)) 790 { 791 case IDC_FINDWHAT: 792 GetWindowTextW((HWND) lParam, s_szSavedFindValue, ARRAY_SIZE(s_szSavedFindValue)); 793 hControl = GetDlgItem(hDlg, IDOK); 794 if (hControl) 795 { 796 lStyle = GetWindowLongPtr(hControl, GWL_STYLE); 797 if (s_szSavedFindValue[0]) 798 lStyle &= ~WS_DISABLED; 799 else 800 lStyle |= WS_DISABLED; 801 SetWindowLongPtr(hControl, GWL_STYLE, lStyle); 802 RedrawWindow(hControl, NULL, NULL, RDW_INVALIDATE); 803 } 804 break; 805 } 806 } 807 break; 808 } 809 return iResult; 810 } 811 812 void FindNextMessageBox(HWND hWnd) 813 { 814 if (!FindNext(hWnd)) 815 { 816 WCHAR msg[128], caption[128]; 817 818 LoadStringW(hInst, IDS_FINISHEDFIND, msg, ARRAY_SIZE(msg)); 819 LoadStringW(hInst, IDS_APP_TITLE, caption, ARRAY_SIZE(caption)); 820 MessageBoxW(hWnd, msg, caption, MB_ICONINFORMATION); 821 } 822 } 823 824 void FindDialog(HWND hWnd) 825 { 826 if (DialogBoxParamW(GetModuleHandle(NULL), MAKEINTRESOURCEW(IDD_FIND), 827 hWnd, FindDialogProc, 0) != 0) 828 { 829 FindNextMessageBox(hWnd); 830 } 831 } 832