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