2 * Registry editing UI functions.
4 * Copyright (C) 2003 Dimitrie O. Paun
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #define WIN32_LEAN_AND_MEAN /* Exclude rarely-used stuff from Windows headers */
37 static const TCHAR
* editValueName
;
38 static TCHAR
* stringValueData
;
39 static BOOL isDecimal
;
41 INT
vmessagebox(HWND hwnd
, INT buttons
, INT titleId
, INT resId
, va_list ap
)
47 if (!LoadString(hInst
, titleId
, title
, COUNT_OF(title
)))
48 lstrcpy(title
, "Error");
50 if (!LoadString(hInst
, resId
, errfmt
, COUNT_OF(errfmt
)))
51 lstrcpy(errfmt
, "Unknown error string!");
53 _vsntprintf(errstr
, COUNT_OF(errstr
), errfmt
, ap
);
55 return MessageBox(hwnd
, errstr
, title
, buttons
);
58 INT
messagebox(HWND hwnd
, INT buttons
, INT titleId
, INT resId
, ...)
64 result
= vmessagebox(hwnd
, buttons
, titleId
, resId
, ap
);
70 void error(HWND hwnd
, INT resId
, ...)
75 vmessagebox(hwnd
, MB_OK
| MB_ICONERROR
, IDS_ERROR
, resId
, ap
);
79 BOOL
change_dword_base(HWND hwndDlg
, BOOL toHex
)
84 if (!GetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, buf
, COUNT_OF(buf
))) return FALSE
;
85 if (!_stscanf(buf
, toHex
? "%ld" : "%lx", &val
)) return FALSE
;
86 wsprintf(buf
, toHex
? "%lx" : "%ld", val
);
87 return SetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, buf
);
90 INT_PTR CALLBACK
modify_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
98 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, editValueName
);
99 SetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, stringValueData
);
100 CheckRadioButton(hwndDlg
, IDC_DWORD_HEX
, IDC_DWORD_DEC
, isDecimal
? IDC_DWORD_DEC
: IDC_DWORD_HEX
);
103 switch (LOWORD(wParam
)) {
105 if (isDecimal
&& change_dword_base(hwndDlg
, TRUE
)) isDecimal
= FALSE
;
108 if (!isDecimal
&& change_dword_base(hwndDlg
, FALSE
)) isDecimal
= TRUE
;
111 if ((hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
))) {
112 if ((len
= GetWindowTextLength(hwndValue
))) {
113 if ((valueData
= HeapReAlloc(GetProcessHeap(), 0, stringValueData
, (len
+ 1) * sizeof(TCHAR
)))) {
114 stringValueData
= valueData
;
115 if (!GetWindowText(hwndValue
, stringValueData
, len
+ 1))
116 *stringValueData
= 0;
122 EndDialog(hwndDlg
, wParam
);
129 static LPTSTR
read_value(HWND hwnd
, HKEY hKey
, LPCTSTR valueName
, DWORD
*lpType
, LONG
*len
)
132 LPTSTR buffer
= NULL
;
135 lRet
= RegQueryValueEx(hKey
, valueName
, 0, lpType
, 0, &valueDataLen
);
136 if (lRet
!= ERROR_SUCCESS
) {
137 error(hwnd
, IDS_BAD_VALUE
, valueName
);
140 if ( *lpType
== REG_DWORD
) valueDataLen
= sizeof(DWORD
);
141 if (!(buffer
= HeapAlloc(GetProcessHeap(), 0, valueDataLen
))) {
142 error(hwnd
, IDS_TOO_BIG_VALUE
, valueDataLen
);
145 lRet
= RegQueryValueEx(hKey
, valueName
, 0, 0, buffer
, &valueDataLen
);
146 if (lRet
!= ERROR_SUCCESS
) {
147 error(hwnd
, IDS_BAD_VALUE
, valueName
);
151 if(len
) *len
= valueDataLen
;
155 HeapFree(GetProcessHeap(), 0, buffer
);
159 BOOL
CreateKey(HWND hwnd
, HKEY hKeyRoot
, LPCTSTR keyPath
, LPTSTR keyName
)
162 LONG lRet
= ERROR_SUCCESS
;
164 TCHAR newKey
[MAX_NEW_KEY_LEN
- 4];
168 lRet
= RegOpenKeyEx(hKeyRoot
, keyPath
, 0, KEY_CREATE_SUB_KEY
, &hKey
);
169 if (lRet
!= ERROR_SUCCESS
) return FALSE
;
171 if (!LoadString(GetModuleHandle(0), IDS_NEWKEY
, newKey
, COUNT_OF(newKey
))) goto done
;
173 /* try to find out a name for the newly create key (max 100 times) */
174 for (keyNum
= 1; keyNum
< 100; keyNum
++) {
175 wsprintf(keyName
, newKey
, keyNum
);
176 lRet
= RegOpenKey(hKey
, keyName
, &retKey
);
177 if (lRet
!= ERROR_SUCCESS
) break;
180 if (lRet
== ERROR_SUCCESS
) goto done
;
182 lRet
= RegCreateKey(hKey
, keyName
, &retKey
);
183 if (lRet
!= ERROR_SUCCESS
) goto done
;
191 BOOL
ModifyValue(HWND hwnd
, HKEY hKeyRoot
, LPCTSTR keyPath
, LPCTSTR valueName
)
198 lRet
= RegOpenKeyEx(hKeyRoot
, keyPath
, 0, KEY_READ
| KEY_SET_VALUE
, &hKey
);
199 if (lRet
!= ERROR_SUCCESS
) return FALSE
;
201 editValueName
= valueName
;
202 if (!lstrcmp(valueName
, _T("(Default)")))
204 if(!(stringValueData
= read_value(hwnd
, hKey
, valueName
, &type
, 0))) goto done
;
206 if ( (type
== REG_SZ
) || (type
== REG_EXPAND_SZ
) ) {
207 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_STRING
), hwnd
, modify_dlgproc
) == IDOK
) {
208 lRet
= RegSetValueEx(hKey
, valueName
, 0, type
, stringValueData
, lstrlen(stringValueData
) + 1);
209 if (lRet
== ERROR_SUCCESS
) result
= TRUE
;
211 } else if ( type
== REG_DWORD
) {
212 wsprintf(stringValueData
, isDecimal
? "%ld" : "%lx", *((DWORD
*)stringValueData
));
213 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_DWORD
), hwnd
, modify_dlgproc
) == IDOK
) {
215 if (_stscanf(stringValueData
, isDecimal
? "%ld" : "%lx", &val
)) {
216 lRet
= RegSetValueEx(hKey
, valueName
, 0, type
, (BYTE
*)&val
, sizeof(val
));
217 if (lRet
== ERROR_SUCCESS
) result
= TRUE
;
221 error(hwnd
, IDS_UNSUPPORTED_TYPE
, type
);
225 HeapFree(GetProcessHeap(), 0, stringValueData
);
226 stringValueData
= NULL
;
231 BOOL
DeleteKey(HWND hwnd
, HKEY hKeyRoot
, LPCTSTR keyPath
)
237 lRet
= RegOpenKeyEx(hKeyRoot
, keyPath
, 0, KEY_SET_VALUE
, &hKey
);
238 if (lRet
!= ERROR_SUCCESS
) return FALSE
;
240 if (messagebox(hwnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_BOX_TITLE
, IDS_DELETE_BOX_TEXT
, keyPath
) != IDYES
)
243 lRet
= SHDeleteKey(hKeyRoot
, keyPath
);
244 if (lRet
!= ERROR_SUCCESS
) {
245 error(hwnd
, IDS_BAD_KEY
, keyPath
);
255 BOOL
DeleteValue(HWND hwnd
, HKEY hKeyRoot
, LPCTSTR keyPath
, LPCTSTR valueName
)
261 lRet
= RegOpenKeyEx(hKeyRoot
, keyPath
, 0, KEY_SET_VALUE
, &hKey
);
262 if (lRet
!= ERROR_SUCCESS
) return FALSE
;
264 if (messagebox(hwnd
, MB_YESNO
| MB_ICONEXCLAMATION
, IDS_DELETE_BOX_TITLE
, IDS_DELETE_BOX_TEXT
, valueName
) != IDYES
)
267 lRet
= RegDeleteValue(hKey
, valueName
);
268 if (lRet
!= ERROR_SUCCESS
) {
269 error(hwnd
, IDS_BAD_VALUE
, valueName
);
271 if (lRet
!= ERROR_SUCCESS
) goto done
;
279 BOOL
CreateValue(HWND hwnd
, HKEY hKeyRoot
, LPCTSTR keyPath
, DWORD valueType
)
281 LONG lRet
= ERROR_SUCCESS
;
283 TCHAR newValue
[COUNT_OF(valueName
) - 4];
284 DWORD valueDword
= 0;
289 lRet
= RegOpenKeyEx(hKeyRoot
, keyPath
, 0, KEY_READ
| KEY_SET_VALUE
, &hKey
);
290 if (lRet
!= ERROR_SUCCESS
) return FALSE
;
292 if (!LoadString(GetModuleHandle(0), IDS_NEWVALUE
, newValue
, COUNT_OF(newValue
))) goto done
;
294 /* try to find out a name for the newly create key (max 100 times) */
295 for (valueNum
= 1; valueNum
< 100; valueNum
++) {
296 wsprintf(valueName
, newValue
, valueNum
);
297 lRet
= RegQueryValueEx(hKey
, valueName
, 0, 0, 0, 0);
298 if (lRet
!= ERROR_SUCCESS
) break;
300 if (lRet
== ERROR_SUCCESS
) goto done
;
302 lRet
= RegSetValueEx(hKey
, valueName
, 0, valueType
, (BYTE
*)&valueDword
, sizeof(DWORD
));
303 if (lRet
!= ERROR_SUCCESS
) goto done
;
311 BOOL
RenameValue(HWND hwnd
, HKEY hKeyRoot
, LPCTSTR keyPath
, LPCTSTR oldName
, LPCTSTR newName
)
319 if (!newName
) return FALSE
;
321 lRet
= RegOpenKeyEx(hKeyRoot
, keyPath
, 0, KEY_READ
| KEY_SET_VALUE
, &hKey
);
322 if (lRet
!= ERROR_SUCCESS
) return FALSE
;
323 /* check if value already exists */
324 value
= read_value(hwnd
, hKey
, newName
, &type
, &len
);
325 if (value
) goto done
;
326 value
= read_value(hwnd
, hKey
, oldName
, &type
, &len
);
327 if(!value
) goto done
;
328 lRet
= RegSetValueEx(hKey
, newName
, 0, type
, (BYTE
*)value
, len
);
329 if (lRet
!= ERROR_SUCCESS
) goto done
;
330 lRet
= RegDeleteValue(hKey
, oldName
);
331 if (lRet
!= ERROR_SUCCESS
) {
332 RegDeleteValue(hKey
, newName
);
338 HeapFree(GetProcessHeap(), 0, value
);
344 BOOL
RenameKey(HWND hwnd
, HKEY hRootKey
, LPCTSTR keyPath
, LPCTSTR newName
)
346 LPTSTR parentPath
= 0;
347 LPCTSTR srcSubKey
= 0;
353 if (!keyPath
|| !newName
) return FALSE
;
355 if (!strrchr(keyPath
, '\\')) {
356 parentKey
= hRootKey
;
359 parentPath
= strdup(keyPath
);
360 srcSubKey
= strrchr(parentPath
, '\\') + 1;
361 *((LPTSTR
)srcSubKey
- 1) = 0;
362 lRet
= RegOpenKeyEx(hRootKey
, parentPath
, 0, KEY_READ
| KEY_CREATE_SUB_KEY
, &parentKey
);
363 if (lRet
!= ERROR_SUCCESS
) goto done
;
366 lRet
= RegCreateKey(parentKey
, newName
, &destKey
);
367 if (lRet
!= ERROR_SUCCESS
) goto done
;
369 /* FIXME: SHCopyKey does not copy the security attributes */
370 lRet
= SHCopyKey(parentKey
, srcSubKey
, destKey
, 0);
371 if (lRet
!= ERROR_SUCCESS
) goto done
;
373 lRet
= SHDeleteKey(hRootKey
, keyPath
);
374 if (lRet
!= ERROR_SUCCESS
) goto done
;
379 RegCloseKey(destKey
);
381 RegCloseKey(parentKey
);