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.
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.
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
22 static TCHAR s_szFindWhat
[256];
23 static const TCHAR s_szFindFlags
[] = _T("FindFlags");
24 static const TCHAR s_szFindFlagsR
[] = _T("FindFlagsReactOS");
25 static HWND s_hwndAbortDialog
;
28 static DWORD s_dwFlags
;
29 static TCHAR s_szName
[MAX_PATH
];
30 static DWORD s_cbName
;
31 static const TCHAR s_empty
[] = {0};
32 static const TCHAR s_backslash
[] = {'\\', 0};
34 extern VOID
SetValueName(HWND hwndLV
, LPCTSTR pszValueName
);
39 if (PeekMessage(&msg
, NULL
, 0, 0, PM_REMOVE
))
41 if (msg
.message
== WM_QUIT
)
43 if (!IsDialogMessage(s_hwndAbortDialog
, &msg
))
45 TranslateMessage(&msg
);
46 DispatchMessage(&msg
);
52 static LPTSTR
lstrstri(LPCTSTR psz1
, LPCTSTR psz2
)
58 for(i
= 0; i
<= cch1
- cch2
; i
++)
60 if (CompareString(LOCALE_SYSTEM_DEFAULT
, NORM_IGNORECASE
,
61 psz1
+ i
, cch2
, psz2
, cch2
) == 2)
62 return (LPTSTR
) (psz1
+ i
);
67 static BOOL
CompareName(LPCTSTR pszName1
, LPCTSTR pszName2
)
69 if (s_dwFlags
& RSF_WHOLESTRING
)
71 if (s_dwFlags
& RSF_MATCHCASE
)
72 return lstrcmp(pszName1
, pszName2
) == 0;
74 return lstrcmpi(pszName1
, pszName2
) == 0;
78 if (s_dwFlags
& RSF_MATCHCASE
)
79 return _tcsstr(pszName1
, pszName2
) != NULL
;
81 return lstrstri(pszName1
, pszName2
) != NULL
;
91 INT i
, cch1
= lstrlen(psz1
), cch2
= lstrlen(psz2
);
92 if (dwType
== REG_SZ
|| dwType
== REG_EXPAND_SZ
)
94 if (s_dwFlags
& RSF_WHOLESTRING
)
96 if (s_dwFlags
& RSF_MATCHCASE
)
97 return 2 == CompareString(LOCALE_SYSTEM_DEFAULT
, 0,
98 psz1
, cch1
, psz2
, cch2
);
100 return 2 == CompareString(LOCALE_SYSTEM_DEFAULT
,
101 NORM_IGNORECASE
, psz1
, cch1
, psz2
, cch2
);
104 for(i
= 0; i
<= cch1
- cch2
; i
++)
106 if (s_dwFlags
& RSF_MATCHCASE
)
108 if (2 == CompareString(LOCALE_SYSTEM_DEFAULT
, 0,
109 psz1
+ i
, cch2
, psz2
, cch2
))
114 if (2 == CompareString(LOCALE_SYSTEM_DEFAULT
,
115 NORM_IGNORECASE
, psz1
+ i
, cch2
, psz2
, cch2
))
123 int compare(const void *x
, const void *y
)
125 const LPCTSTR
*a
= (const LPCTSTR
*)x
;
126 const LPCTSTR
*b
= (const LPCTSTR
*)y
;
127 return lstrcmpi(*a
, *b
);
133 LPCTSTR pszValueName
,
134 LPTSTR
*ppszFoundSubKey
,
135 LPTSTR
*ppszFoundValueName
)
139 TCHAR szSubKey
[MAX_PATH
];
140 DWORD i
, c
, cb
, type
;
142 LPTSTR
*ppszNames
= NULL
;
148 lstrcpy(szSubKey
, pszSubKey
);
151 lResult
= RegOpenKeyEx(hKey
, szSubKey
, 0, KEY_ALL_ACCESS
, &hSubKey
);
152 if (lResult
!= ERROR_SUCCESS
)
155 if (pszValueName
== NULL
)
156 pszValueName
= s_empty
;
158 lResult
= RegQueryInfoKey(hSubKey
, NULL
, NULL
, NULL
, NULL
, NULL
, NULL
,
159 &c
, NULL
, NULL
, NULL
, NULL
);
160 if (lResult
!= ERROR_SUCCESS
)
162 ppszNames
= (LPTSTR
*) malloc(c
* sizeof(LPTSTR
));
163 if (ppszNames
== NULL
)
165 ZeroMemory(ppszNames
, c
* sizeof(LPTSTR
));
167 for(i
= 0; i
< c
; i
++)
172 s_cbName
= MAX_PATH
* sizeof(TCHAR
);
173 lResult
= RegEnumValue(hSubKey
, i
, s_szName
, &s_cbName
, NULL
, NULL
,
175 if (lResult
== ERROR_NO_MORE_ITEMS
)
180 if (lResult
!= ERROR_SUCCESS
)
182 if (s_cbName
>= MAX_PATH
* sizeof(TCHAR
))
185 ppszNames
[i
] = _tcsdup(s_szName
);
188 qsort(ppszNames
, c
, sizeof(LPTSTR
), compare
);
190 for(i
= 0; i
< c
; i
++)
195 if (!fPast
&& lstrcmpi(ppszNames
[i
], pszValueName
) == 0)
203 if ((s_dwFlags
& RSF_LOOKATVALUES
) &&
204 CompareName(ppszNames
[i
], s_szFindWhat
))
206 *ppszFoundSubKey
= _tcsdup(szSubKey
);
207 if (ppszNames
[i
][0] == 0)
208 *ppszFoundValueName
= NULL
;
210 *ppszFoundValueName
= _tcsdup(ppszNames
[i
]);
214 lResult
= RegQueryValueEx(hSubKey
, ppszNames
[i
], NULL
, &type
,
216 if (lResult
!= ERROR_SUCCESS
)
221 lResult
= RegQueryValueEx(hSubKey
, ppszNames
[i
], NULL
, &type
,
223 if (lResult
!= ERROR_SUCCESS
)
226 if ((s_dwFlags
& RSF_LOOKATDATA
) &&
227 CompareData(type
, (LPTSTR
) pb
, s_szFindWhat
))
229 *ppszFoundSubKey
= _tcsdup(szSubKey
);
230 if (ppszNames
[i
][0] == 0)
231 *ppszFoundValueName
= NULL
;
233 *ppszFoundValueName
= _tcsdup(ppszNames
[i
]);
240 if (ppszNames
!= NULL
)
242 for(i
= 0; i
< c
; i
++)
248 lResult
= RegQueryInfoKey(hSubKey
, NULL
, NULL
, NULL
, &c
, NULL
, NULL
,
249 NULL
, NULL
, NULL
, NULL
, NULL
);
250 if (lResult
!= ERROR_SUCCESS
)
252 ppszNames
= (LPTSTR
*) malloc(c
* sizeof(LPTSTR
));
253 if (ppszNames
== NULL
)
255 ZeroMemory(ppszNames
, c
* sizeof(LPTSTR
));
257 for(i
= 0; i
< c
; i
++)
262 s_cbName
= MAX_PATH
* sizeof(TCHAR
);
263 lResult
= RegEnumKeyEx(hSubKey
, i
, s_szName
, &s_cbName
, NULL
, NULL
,
265 if (lResult
== ERROR_NO_MORE_ITEMS
)
270 if (lResult
!= ERROR_SUCCESS
)
272 if (s_cbName
>= MAX_PATH
* sizeof(TCHAR
))
275 ppszNames
[i
] = _tcsdup(s_szName
);
278 qsort(ppszNames
, c
, sizeof(LPTSTR
), compare
);
280 for(i
= 0; i
< c
; i
++)
285 if ((s_dwFlags
& RSF_LOOKATKEYS
) &&
286 CompareName(ppszNames
[i
], s_szFindWhat
))
288 *ppszFoundSubKey
= malloc(
289 (lstrlen(szSubKey
) + lstrlen(ppszNames
[i
]) + 2) *
291 if (*ppszFoundSubKey
== NULL
)
295 lstrcpy(*ppszFoundSubKey
, szSubKey
);
296 lstrcatW(*ppszFoundSubKey
, s_backslash
);
299 **ppszFoundSubKey
= 0;
300 lstrcatW(*ppszFoundSubKey
, ppszNames
[i
]);
301 *ppszFoundValueName
= NULL
;
305 if (RegFindRecurse(hSubKey
, ppszNames
[i
], NULL
, ppszFoundSubKey
,
308 LPTSTR psz
= *ppszFoundSubKey
;
309 *ppszFoundSubKey
= malloc(
310 (lstrlen(szSubKey
) + lstrlen(psz
) + 2) * sizeof(TCHAR
));
311 if (*ppszFoundSubKey
== NULL
)
315 lstrcpy(*ppszFoundSubKey
, szSubKey
);
316 lstrcatW(*ppszFoundSubKey
, s_backslash
);
319 **ppszFoundSubKey
= 0;
320 lstrcatW(*ppszFoundSubKey
, psz
);
327 if (ppszNames
!= NULL
)
329 for(i
= 0; i
< c
; i
++)
334 RegCloseKey(hSubKey
);
338 if (ppszNames
!= NULL
)
340 for(i
= 0; i
< c
; i
++)
344 RegCloseKey(hSubKey
);
351 LPCTSTR pszValueName
,
352 LPTSTR
*ppszFoundSubKey
,
353 LPTSTR
*ppszFoundValueName
)
357 HKEY hBaseKey
, hSubKey
;
358 TCHAR szKeyName
[MAX_PATH
];
359 TCHAR szSubKey
[MAX_PATH
];
362 LPTSTR
*ppszNames
= NULL
;
365 if (RegFindRecurse(hBaseKey
, pszSubKey
, pszValueName
, ppszFoundSubKey
,
369 if (lstrlen(pszSubKey
) >= MAX_PATH
)
372 lstrcpy(szSubKey
, pszSubKey
);
373 while(szSubKey
[0] != 0)
378 pch
= _tcsrchr(szSubKey
, _T('\\'));
381 lstrcpy(szKeyName
, szSubKey
);
387 lstrcpyn(szKeyName
, pch
+ 1, MAX_PATH
);
389 lResult
= RegOpenKeyEx(hBaseKey
, szSubKey
, 0, KEY_ALL_ACCESS
,
391 if (lResult
!= ERROR_SUCCESS
)
395 lResult
= RegQueryInfoKey(hSubKey
, NULL
, NULL
, NULL
, &c
, NULL
, NULL
,
396 NULL
, NULL
, NULL
, NULL
, NULL
);
397 if (lResult
!= ERROR_SUCCESS
)
400 ppszNames
= (LPTSTR
*) malloc(c
* sizeof(LPTSTR
));
401 if (ppszNames
== NULL
)
403 ZeroMemory(ppszNames
, c
* sizeof(LPTSTR
));
405 for(i
= 0; i
< c
; i
++)
410 s_cbName
= MAX_PATH
* sizeof(TCHAR
);
411 lResult
= RegEnumKeyExW(hSubKey
, i
, s_szName
, &s_cbName
,
412 NULL
, NULL
, NULL
, NULL
);
413 if (lResult
== ERROR_NO_MORE_ITEMS
)
418 if (lResult
!= ERROR_SUCCESS
)
420 ppszNames
[i
] = _tcsdup(s_szName
);
423 qsort(ppszNames
, c
, sizeof(LPTSTR
), compare
);
426 for(i
= 0; i
< c
; i
++)
431 if (!fPast
&& lstrcmpi(ppszNames
[i
], szKeyName
) == 0)
439 if ((s_dwFlags
& RSF_LOOKATKEYS
) &&
440 CompareName(ppszNames
[i
], s_szFindWhat
))
442 *ppszFoundSubKey
= malloc(
443 (lstrlen(szSubKey
) + lstrlen(ppszNames
[i
]) + 2) *
445 if (*ppszFoundSubKey
== NULL
)
449 lstrcpy(*ppszFoundSubKey
, szSubKey
);
450 lstrcatW(*ppszFoundSubKey
, s_backslash
);
453 **ppszFoundSubKey
= 0;
454 lstrcatW(*ppszFoundSubKey
, ppszNames
[i
]);
455 *ppszFoundValueName
= NULL
;
459 if (RegFindRecurse(hSubKey
, ppszNames
[i
], NULL
,
460 ppszFoundSubKey
, ppszFoundValueName
))
462 LPTSTR psz
= *ppszFoundSubKey
;
463 *ppszFoundSubKey
= malloc(
464 (lstrlen(szSubKey
) + lstrlen(psz
) + 2) *
466 if (*ppszFoundSubKey
== NULL
)
470 lstrcpy(*ppszFoundSubKey
, szSubKey
);
471 lstrcatW(*ppszFoundSubKey
, s_backslash
);
474 **ppszFoundSubKey
= 0;
475 lstrcatW(*ppszFoundSubKey
, psz
);
480 if (ppszNames
!= NULL
)
482 for(i
= 0; i
< c
; i
++)
488 if (hBaseKey
!= hSubKey
)
489 RegCloseKey(hSubKey
);
492 if (*phKey
== HKEY_CLASSES_ROOT
)
494 *phKey
= HKEY_CURRENT_USER
;
495 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
500 if (*phKey
== HKEY_CURRENT_USER
)
502 *phKey
= HKEY_LOCAL_MACHINE
;
503 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
508 if (*phKey
== HKEY_LOCAL_MACHINE
)
511 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
516 if (*phKey
== HKEY_USERS
)
518 *phKey
= HKEY_CURRENT_CONFIG
;
519 if (RegFindRecurse(*phKey
, s_empty
, NULL
, ppszFoundSubKey
,
525 if (ppszNames
!= NULL
)
527 for(i
= 0; i
< c
; i
++)
531 if (hBaseKey
!= hSubKey
)
532 RegCloseKey(hSubKey
);
536 if (ppszNames
!= NULL
)
538 for(i
= 0; i
< c
; i
++)
542 if (hBaseKey
!= hSubKey
)
543 RegCloseKey(hSubKey
);
548 static DWORD
GetFindFlags(void)
551 DWORD dwType
, dwValue
, cbData
;
552 DWORD dwFlags
= RSF_LOOKATKEYS
| RSF_LOOKATVALUES
| RSF_LOOKATDATA
;
554 if (RegOpenKey(HKEY_CURRENT_USER
, g_szGeneralRegKey
, &hKey
) == ERROR_SUCCESS
)
556 /* Retrieve flags from registry key */
557 cbData
= sizeof(dwValue
);
558 if (RegQueryValueEx(hKey
, s_szFindFlags
, NULL
, &dwType
, (LPBYTE
) &dwValue
, &cbData
) == ERROR_SUCCESS
)
560 if (dwType
== REG_DWORD
)
561 dwFlags
= (dwFlags
& ~0x0000FFFF) | ((dwValue
& 0x0000FFFF) << 0);
564 /* Retrieve ReactOS Regedit specific flags from registry key */
565 cbData
= sizeof(dwValue
);
566 if (RegQueryValueEx(hKey
, s_szFindFlagsR
, NULL
, &dwType
, (LPBYTE
) &dwValue
, &cbData
) == ERROR_SUCCESS
)
568 if (dwType
== REG_DWORD
)
569 dwFlags
= (dwFlags
& ~0xFFFF0000) | ((dwValue
& 0x0000FFFF) << 16);
577 static void SetFindFlags(DWORD dwFlags
)
583 if (RegCreateKeyEx(HKEY_CURRENT_USER
, g_szGeneralRegKey
, 0, NULL
, 0, KEY_ALL_ACCESS
, NULL
, &hKey
, &dwDisposition
) == ERROR_SUCCESS
)
585 dwData
= (dwFlags
>> 0) & 0x0000FFFF;
586 RegSetValueEx(hKey
, s_szFindFlags
, 0, REG_DWORD
, (const BYTE
*) &dwData
, sizeof(dwData
));
588 dwData
= (dwFlags
>> 16) & 0x0000FFFF;
589 RegSetValueEx(hKey
, s_szFindFlagsR
, 0, REG_DWORD
, (const BYTE
*) &dwData
, sizeof(dwData
));
595 static INT_PTR CALLBACK
AbortFindDialogProc(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
597 UNREFERENCED_PARAMETER(lParam
);
598 UNREFERENCED_PARAMETER(hDlg
);
607 switch(HIWORD(wParam
))
610 switch(LOWORD(wParam
))
623 BOOL
FindNext(HWND hWnd
)
628 TCHAR szFullKey
[512];
629 LPCTSTR pszValueName
;
630 LPTSTR pszFoundSubKey
, pszFoundValueName
;
632 if (_tcslen(s_szFindWhat
) == 0)
638 s_dwFlags
= GetFindFlags();
640 pszKeyPath
= GetItemPath(g_pChildWnd
->hTreeWnd
, 0, &hKeyRoot
);
641 if (pszKeyPath
== NULL
)
643 hKeyRoot
= HKEY_CLASSES_ROOT
;
644 pszKeyPath
= s_empty
;
647 /* Create abort find dialog */
648 s_hwndAbortDialog
= CreateDialog(GetModuleHandle(NULL
),
649 MAKEINTRESOURCE(IDD_FINDING
), hWnd
, AbortFindDialogProc
);
650 if (s_hwndAbortDialog
)
652 ShowWindow(s_hwndAbortDialog
, SW_SHOW
);
653 UpdateWindow(s_hwndAbortDialog
);
657 pszValueName
= GetValueName(g_pChildWnd
->hListWnd
, -1);
659 EnableWindow(hFrameWnd
, FALSE
);
660 EnableWindow(g_pChildWnd
->hTreeWnd
, FALSE
);
661 EnableWindow(g_pChildWnd
->hListWnd
, FALSE
);
662 EnableWindow(g_pChildWnd
->hAddressBarWnd
, FALSE
);
664 fSuccess
= RegFindWalk(&hKeyRoot
, pszKeyPath
, pszValueName
,
665 &pszFoundSubKey
, &pszFoundValueName
);
667 EnableWindow(hFrameWnd
, TRUE
);
668 EnableWindow(g_pChildWnd
->hTreeWnd
, TRUE
);
669 EnableWindow(g_pChildWnd
->hListWnd
, TRUE
);
670 EnableWindow(g_pChildWnd
->hAddressBarWnd
, TRUE
);
672 if (s_hwndAbortDialog
)
674 DestroyWindow(s_hwndAbortDialog
);
675 s_hwndAbortDialog
= NULL
;
680 RegKeyGetName(szFullKey
, COUNT_OF(szFullKey
), hKeyRoot
, pszFoundSubKey
);
681 SelectNode(g_pChildWnd
->hTreeWnd
, szFullKey
);
682 SetValueName(g_pChildWnd
->hListWnd
, pszFoundValueName
);
683 free(pszFoundSubKey
);
684 free(pszFoundValueName
);
685 SetFocus(g_pChildWnd
->hListWnd
);
690 static INT_PTR CALLBACK
FindDialogProc(HWND hDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
696 static TCHAR s_szSavedFindValue
[256];
701 dwFlags
= GetFindFlags();
703 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_KEYS
);
705 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_LOOKATKEYS
) ? TRUE
: FALSE
, 0);
707 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_VALUES
);
709 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_LOOKATVALUES
) ? TRUE
: FALSE
, 0);
711 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_DATA
);
713 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_LOOKATDATA
) ? TRUE
: FALSE
, 0);
715 /* Match whole string */
716 hControl
= GetDlgItem(hDlg
, IDC_MATCHSTRING
);
718 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_WHOLESTRING
) ? TRUE
: FALSE
, 0);
720 /* Case sensitivity */
721 hControl
= GetDlgItem(hDlg
, IDC_MATCHCASE
);
723 SendMessage(hControl
, BM_SETCHECK
, (dwFlags
& RSF_MATCHCASE
) ? TRUE
: FALSE
, 0);
725 hControl
= GetDlgItem(hDlg
, IDC_FINDWHAT
);
728 SetWindowText(hControl
, s_szSavedFindValue
);
730 SendMessage(hControl
, EM_SETSEL
, 0, -1);
739 switch(HIWORD(wParam
))
742 switch(LOWORD(wParam
))
747 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_KEYS
);
748 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
749 dwFlags
|= RSF_LOOKATKEYS
;
751 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_VALUES
);
752 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
753 dwFlags
|= RSF_LOOKATVALUES
;
755 hControl
= GetDlgItem(hDlg
, IDC_LOOKAT_DATA
);
756 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
757 dwFlags
|= RSF_LOOKATDATA
;
759 hControl
= GetDlgItem(hDlg
, IDC_MATCHSTRING
);
760 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
761 dwFlags
|= RSF_WHOLESTRING
;
763 hControl
= GetDlgItem(hDlg
, IDC_MATCHCASE
);
764 if (hControl
&& (SendMessage(hControl
, BM_GETCHECK
, 0, 0) == BST_CHECKED
))
765 dwFlags
|= RSF_MATCHCASE
;
767 SetFindFlags(dwFlags
);
769 hControl
= GetDlgItem(hDlg
, IDC_FINDWHAT
);
771 GetWindowText(hControl
, s_szFindWhat
, sizeof(s_szFindWhat
) / sizeof(s_szFindWhat
[0]));
782 switch(LOWORD(wParam
))
785 GetWindowText((HWND
) lParam
, s_szSavedFindValue
, sizeof(s_szSavedFindValue
) / sizeof(s_szSavedFindValue
[0]));
786 hControl
= GetDlgItem(hDlg
, IDOK
);
789 lStyle
= GetWindowLongPtr(hControl
, GWL_STYLE
);
790 if (s_szSavedFindValue
[0])
791 lStyle
&= ~WS_DISABLED
;
793 lStyle
|= WS_DISABLED
;
794 SetWindowLongPtr(hControl
, GWL_STYLE
, lStyle
);
795 RedrawWindow(hControl
, NULL
, NULL
, RDW_INVALIDATE
);
805 void FindDialog(HWND hWnd
)
807 if (DialogBoxParam(GetModuleHandle(NULL
), MAKEINTRESOURCE(IDD_FIND
),
808 hWnd
, FindDialogProc
, 0) != 0)
810 if (FindNext(hWnd
) == FALSE
)
812 TCHAR msg
[128], caption
[128];
814 LoadString(hInst
, IDS_FINISHEDFIND
, msg
, sizeof(msg
)/sizeof(TCHAR
));
815 LoadString(hInst
, IDS_APP_TITLE
, caption
, sizeof(caption
)/sizeof(TCHAR
));
816 MessageBox(0, msg
, caption
, MB_ICONINFORMATION
);