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 */
39 typedef enum _EDIT_MODE
46 static const TCHAR
* editValueName
;
47 static TCHAR
* stringValueData
;
48 static PVOID binValueData
;
49 static DWORD dwordValueData
;
50 static DWORD valueDataLen
;
51 static EDIT_MODE dwordEditMode
= EDIT_MODE_HEX
;
54 void error(HWND hwnd
, INT resId
, ...)
62 hInstance
= GetModuleHandle(0);
64 if (!LoadString(hInstance
, IDS_ERROR
, title
, COUNT_OF(title
)))
65 _tcscpy(title
, _T("Error"));
67 if (!LoadString(hInstance
, resId
, errfmt
, COUNT_OF(errfmt
)))
68 _tcscpy(errfmt
, _T("Unknown error string!"));
71 _vsntprintf(errstr
, COUNT_OF(errstr
), errfmt
, ap
);
74 MessageBox(hwnd
, errstr
, title
, MB_OK
| MB_ICONERROR
);
77 void warning(HWND hwnd
, INT resId
, ...)
85 hInstance
= GetModuleHandle(0);
87 if (!LoadString(hInstance
, IDS_WARNING
, title
, COUNT_OF(title
)))
88 _tcscpy(title
, _T("Warning"));
90 if (!LoadString(hInstance
, resId
, errfmt
, COUNT_OF(errfmt
)))
91 _tcscpy(errfmt
, _T("Unknown error string!"));
94 _vsntprintf(errstr
, COUNT_OF(errstr
), errfmt
, ap
);
97 MessageBox(hwnd
, errstr
, title
, MB_OK
| MB_ICONSTOP
);
100 INT_PTR CALLBACK
modify_string_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
108 if(editValueName
&& _tcscmp(editValueName
, _T("")))
110 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, editValueName
);
115 LoadString(hInst
, IDS_DEFAULT_VALUE_NAME
, buffer
, sizeof(buffer
)/sizeof(TCHAR
));
116 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, buffer
);
118 SetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, stringValueData
);
119 SetFocus(GetDlgItem(hwndDlg
, IDC_VALUE_DATA
));
122 switch (LOWORD(wParam
))
125 if ((hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
)))
127 if ((len
= GetWindowTextLength(hwndValue
)))
131 if ((valueData
= HeapReAlloc(GetProcessHeap(), 0, stringValueData
, (len
+ 1) * sizeof(TCHAR
))))
133 stringValueData
= valueData
;
134 if (!GetWindowText(hwndValue
, stringValueData
, len
+ 1))
135 *stringValueData
= 0;
140 if ((valueData
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(TCHAR
))))
142 stringValueData
= valueData
;
143 if (!GetWindowText(hwndValue
, stringValueData
, len
+ 1))
144 *stringValueData
= 0;
151 *stringValueData
= 0;
154 EndDialog(hwndDlg
, IDOK
);
157 EndDialog(hwndDlg
, IDCANCEL
);
165 INT_PTR CALLBACK
modify_multi_string_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
173 if(editValueName
&& _tcscmp(editValueName
, _T("")))
175 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, editValueName
);
180 LoadString(hInst
, IDS_DEFAULT_VALUE_NAME
, buffer
, sizeof(buffer
)/sizeof(TCHAR
));
181 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, buffer
);
183 SetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, stringValueData
);
184 SetFocus(GetDlgItem(hwndDlg
, IDC_VALUE_DATA
));
187 switch (LOWORD(wParam
))
190 if ((hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
)))
192 if ((len
= GetWindowTextLength(hwndValue
)))
196 if ((valueData
= HeapReAlloc(GetProcessHeap(), 0, stringValueData
, (len
+ 1) * sizeof(TCHAR
))))
198 stringValueData
= valueData
;
199 if (!GetWindowText(hwndValue
, stringValueData
, len
+ 1))
200 *stringValueData
= 0;
205 if ((valueData
= HeapAlloc(GetProcessHeap(), 0, (len
+ 1) * sizeof(TCHAR
))))
207 stringValueData
= valueData
;
208 if (!GetWindowText(hwndValue
, stringValueData
, len
+ 1))
209 *stringValueData
= 0;
216 *stringValueData
= 0;
219 EndDialog(hwndDlg
, IDOK
);
222 EndDialog(hwndDlg
, IDCANCEL
);
230 LRESULT CALLBACK
DwordEditSubclassProc(HWND hwnd
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
234 oldwndproc
= (WNDPROC
)GetWindowLongPtr(hwnd
, GWL_USERDATA
);
239 if (dwordEditMode
== EDIT_MODE_DEC
)
241 if (isdigit(wParam
& 0xff))
250 else if (dwordEditMode
== EDIT_MODE_HEX
)
252 if (isxdigit(wParam
& 0xff))
267 return CallWindowProc(oldwndproc
, hwnd
, uMsg
, wParam
, lParam
);
271 INT_PTR CALLBACK
modify_dword_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
276 TCHAR ValueString
[32];
283 dwordEditMode
= EDIT_MODE_HEX
;
285 /* subclass the edit control */
286 hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
);
287 oldproc
= (WNDPROC
)GetWindowLongPtr(hwndValue
, GWL_WNDPROC
);
288 SetWindowLongPtr(hwndValue
, GWL_USERDATA
, (DWORD_PTR
)oldproc
);
289 SetWindowLongPtr(hwndValue
, GWL_WNDPROC
, (DWORD_PTR
)DwordEditSubclassProc
);
291 if(editValueName
&& _tcscmp(editValueName
, _T("")))
293 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, editValueName
);
298 LoadString(hInst
, IDS_DEFAULT_VALUE_NAME
, buffer
, sizeof(buffer
)/sizeof(TCHAR
));
299 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, buffer
);
301 CheckRadioButton (hwndDlg
, IDC_FORMAT_HEX
, IDC_FORMAT_DEC
, IDC_FORMAT_HEX
);
302 _stprintf (ValueString
, _T("%lx"), dwordValueData
);
303 SetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, ValueString
);
304 SetFocus(GetDlgItem(hwndDlg
, IDC_VALUE_DATA
));
308 switch (LOWORD(wParam
))
311 if (HIWORD(wParam
) == BN_CLICKED
&& dwordEditMode
== EDIT_MODE_DEC
)
313 dwordEditMode
= EDIT_MODE_HEX
;
314 if ((hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
)))
316 if ((len
= GetWindowTextLength(hwndValue
)))
318 if (GetWindowText(hwndValue
, ValueString
, 32))
320 Value
= _tcstoul (ValueString
, &Remainder
, 10);
324 _stprintf (ValueString
, _T("%lx"), Value
);
325 SetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, ValueString
);
331 if (HIWORD(wParam
) == BN_CLICKED
&& dwordEditMode
== EDIT_MODE_HEX
)
333 dwordEditMode
= EDIT_MODE_DEC
;
334 if ((hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
)))
336 if ((len
= GetWindowTextLength(hwndValue
)))
338 if (GetWindowText(hwndValue
, ValueString
, 32))
340 Value
= _tcstoul (ValueString
, &Remainder
, 16);
344 _stprintf (ValueString
, _T("%lu"), Value
);
345 SetDlgItemText(hwndDlg
, IDC_VALUE_DATA
, ValueString
);
351 if ((hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
)))
353 if ((len
= GetWindowTextLength(hwndValue
)))
355 if (!GetWindowText(hwndValue
, ValueString
, 32))
357 EndDialog(hwndDlg
, IDCANCEL
);
361 Base
= (dwordEditMode
== EDIT_MODE_HEX
) ? 16 : 10;
362 dwordValueData
= _tcstoul (ValueString
, &Remainder
, Base
);
366 EndDialog(hwndDlg
, IDCANCEL
);
370 EndDialog(hwndDlg
, IDOK
);
374 EndDialog(hwndDlg
, IDCANCEL
);
382 INT_PTR CALLBACK
modify_binary_dlgproc(HWND hwndDlg
, UINT uMsg
, WPARAM wParam
, LPARAM lParam
)
389 if(editValueName
&& _tcscmp(editValueName
, _T("")))
391 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, editValueName
);
396 LoadString(hInst
, IDS_DEFAULT_VALUE_NAME
, buffer
, sizeof(buffer
)/sizeof(TCHAR
));
397 SetDlgItemText(hwndDlg
, IDC_VALUE_NAME
, buffer
);
399 hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
);
400 HexEdit_LoadBuffer(hwndValue
, binValueData
, valueDataLen
);
401 /* reset the hex edit control's font */
402 SendMessage(hwndValue
, WM_SETFONT
, 0, 0);
406 switch (LOWORD(wParam
))
409 if ((hwndValue
= GetDlgItem(hwndDlg
, IDC_VALUE_DATA
)))
411 len
= HexEdit_GetBufferSize(hwndValue
);
412 if (len
!= valueDataLen
&& len
> 0)
414 binValueData
= HeapReAlloc(GetProcessHeap(), 0, binValueData
, len
);
418 HexEdit_CopyBuffer(hwndValue
, binValueData
, len
);
422 EndDialog(hwndDlg
, IDOK
);
425 EndDialog(hwndDlg
, IDCANCEL
);
433 BOOL
ModifyValue(HWND hwnd
, HKEY hKey
, LPCTSTR valueName
, BOOL EditBin
)
442 editValueName
= valueName
;
444 lRet
= RegQueryValueEx(hKey
, valueName
, 0, &type
, 0, &valueDataLen
);
445 if (lRet
!= ERROR_SUCCESS
&& (!_tcscmp(valueName
, _T("")) || valueName
== NULL
))
447 lRet
= ERROR_SUCCESS
; /* Allow editing of (Default) values which don't exist */
450 stringValueData
= NULL
;
454 if (lRet
!= ERROR_SUCCESS
)
456 error(hwnd
, IDS_BAD_VALUE
, valueName
);
460 if (EditBin
== FALSE
&& ((type
== REG_SZ
) || (type
== REG_EXPAND_SZ
)))
462 if (valueDataLen
> 0)
464 if (!(stringValueData
= HeapAlloc(GetProcessHeap(), 0, valueDataLen
)))
466 error(hwnd
, IDS_TOO_BIG_VALUE
, valueDataLen
);
469 lRet
= RegQueryValueEx(hKey
, valueName
, 0, 0, (LPBYTE
)stringValueData
, &valueDataLen
);
470 if (lRet
!= ERROR_SUCCESS
)
472 error(hwnd
, IDS_BAD_VALUE
, valueName
);
478 stringValueData
= NULL
;
481 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_STRING
), hwnd
, modify_string_dlgproc
) == IDOK
)
485 lRet
= RegSetValueEx(hKey
, valueName
, 0, type
, (LPBYTE
)stringValueData
, (_tcslen(stringValueData
) + 1) * sizeof(TCHAR
));
489 lRet
= RegSetValueEx(hKey
, valueName
, 0, type
, NULL
, 0);
491 if (lRet
== ERROR_SUCCESS
)
495 else if (EditBin
== FALSE
&& type
== REG_MULTI_SZ
)
497 if (valueDataLen
> 0)
499 DWORD llen
, listlen
, nl_len
;
500 LPTSTR src
, lines
= NULL
;
502 if (!(stringValueData
= HeapAlloc(GetProcessHeap(), 0, valueDataLen
)))
504 error(hwnd
, IDS_TOO_BIG_VALUE
, valueDataLen
);
507 lRet
= RegQueryValueEx(hKey
, valueName
, 0, 0, (LPBYTE
)stringValueData
, &valueDataLen
);
508 if (lRet
!= ERROR_SUCCESS
)
510 error(hwnd
, IDS_BAD_VALUE
, valueName
);
514 /* convert \0 to \r\n */
515 src
= stringValueData
;
516 nl_len
= _tcslen(_T("\r\n")) * sizeof(TCHAR
);
517 listlen
= sizeof(TCHAR
);
518 lines
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, listlen
+ sizeof(TCHAR
));
519 while(*src
!= _T('\0'))
524 listlen
+= (llen
* sizeof(TCHAR
)) + nl_len
;
525 lines
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, lines
, listlen
);
527 _tcscat(lines
, _T("\r\n"));
530 HeapFree(GetProcessHeap(), 0, stringValueData
);
531 stringValueData
= lines
;
535 stringValueData
= NULL
;
538 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_MULTI_STRING
), hwnd
, modify_multi_string_dlgproc
) == IDOK
)
542 /* convert \r\n to \0 */
543 BOOL EmptyLines
= FALSE
;
544 LPTSTR src
, lines
, nl
;
545 DWORD linechars
, buflen
, c_nl
, dest
;
547 src
= stringValueData
;
548 buflen
= sizeof(TCHAR
);
549 lines
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, buflen
+ sizeof(TCHAR
));
550 c_nl
= _tcslen(_T("\r\n"));
552 while(*src
!= _T('\0'))
554 if((nl
= _tcsstr(src
, _T("\r\n"))))
556 linechars
= nl
- src
;
566 linechars
= _tcslen(src
);
570 buflen
+= ((linechars
+ 1) * sizeof(TCHAR
));
571 lines
= HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, lines
, buflen
);
572 memcpy((lines
+ dest
), src
, linechars
* sizeof(TCHAR
));
574 lines
[dest
++] = _T('\0');
580 src
+= linechars
+ (nl
!= NULL
? c_nl
: 0);
582 lines
[++dest
] = _T('\0');
586 warning(hwnd
, IDS_MULTI_SZ_EMPTY_STRING
);
589 lRet
= RegSetValueEx(hKey
, valueName
, 0, type
, (LPBYTE
)lines
, buflen
);
590 HeapFree(GetProcessHeap(), 0, lines
);
594 lRet
= RegSetValueEx(hKey
, valueName
, 0, type
, NULL
, 0);
596 if (lRet
== ERROR_SUCCESS
)
600 else if (EditBin
== FALSE
&& type
== REG_DWORD
)
602 lRet
= RegQueryValueEx(hKey
, valueName
, 0, 0, (LPBYTE
)&dwordValueData
, &valueDataLen
);
603 if (lRet
!= ERROR_SUCCESS
)
605 error(hwnd
, IDS_BAD_VALUE
, valueName
);
609 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_DWORD
), hwnd
, modify_dword_dlgproc
) == IDOK
)
611 lRet
= RegSetValueEx(hKey
, valueName
, 0, type
, (LPBYTE
)&dwordValueData
, sizeof(DWORD
));
612 if (lRet
== ERROR_SUCCESS
)
616 else if (EditBin
== TRUE
|| type
== REG_NONE
|| type
== REG_BINARY
)
620 int len_vname
= lstrlen(valueName
);
624 if(!(u_valuename
= HeapAlloc(GetProcessHeap(), 0, (len_vname
+ 1) * sizeof(WCHAR
))))
626 error(hwnd
, IDS_TOO_BIG_VALUE
, len_vname
);
629 /* convert the ansi value name to an unicode string */
630 MultiByteToWideChar(CP_ACP
, 0, valueName
, -1, u_valuename
, len_vname
+ 1);
631 valueDataLen
*= sizeof(WCHAR
);
638 if(!(binValueData
= HeapAlloc(GetProcessHeap(), 0, valueDataLen
)))
640 error(hwnd
, IDS_TOO_BIG_VALUE
, valueDataLen
);
644 /* force to use the unicode version, so editing strings in binary mode is correct */
645 lRet
= RegQueryValueExW(hKey
,
651 0, 0, (LPBYTE
)binValueData
, &valueDataLen
);
652 if (lRet
!= ERROR_SUCCESS
)
654 HeapFree(GetProcessHeap(), 0, binValueData
);
657 HeapFree(GetProcessHeap(), 0, u_valuename
);
659 error(hwnd
, IDS_BAD_VALUE
, valueName
);
668 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_BIN_DATA
), hwnd
, modify_binary_dlgproc
) == IDOK
)
670 /* force to use the unicode version, so editing strings in binary mode is correct */
671 lRet
= RegSetValueExW(hKey
,
677 0, type
, (LPBYTE
)binValueData
, valueDataLen
);
678 if (lRet
== ERROR_SUCCESS
)
681 if(binValueData
!= NULL
)
682 HeapFree(GetProcessHeap(), 0, binValueData
);
685 HeapFree(GetProcessHeap(), 0, u_valuename
);
690 error(hwnd
, IDS_UNSUPPORTED_TYPE
, type
);
695 HeapFree(GetProcessHeap(), 0, stringValueData
);
696 stringValueData
= NULL
;