ca4d5b3ac8fd2cdcdb01db97328110804737a0a9
[reactos.git] / base / applications / regedit / edit.c
1 /*
2 * Registry editing UI functions.
3 *
4 * Copyright (C) 2003 Dimitrie O. Paun
5 *
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.
10 *
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.
15 *
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <regedit.h>
22
23 typedef enum _EDIT_MODE
24 {
25 EDIT_MODE_DEC,
26 EDIT_MODE_HEX
27 } EDIT_MODE;
28
29
30 static const TCHAR* editValueName;
31 static TCHAR* stringValueData;
32 static PVOID binValueData;
33 static DWORD dwordValueData;
34 static DWORD valueDataLen;
35 static EDIT_MODE dwordEditMode = EDIT_MODE_HEX;
36
37 void error(HWND hwnd, INT resId, ...)
38 {
39 va_list ap;
40 TCHAR title[256];
41 TCHAR errfmt[1024];
42 TCHAR errstr[1024];
43 HINSTANCE hInstance;
44
45 hInstance = GetModuleHandle(0);
46
47 if (!LoadString(hInstance, IDS_ERROR, title, COUNT_OF(title)))
48 _tcscpy(title, _T("Error"));
49
50 if (!LoadString(hInstance, resId, errfmt, COUNT_OF(errfmt)))
51 _tcscpy(errfmt, _T("Unknown error string!"));
52
53 va_start(ap, resId);
54 _vsntprintf(errstr, COUNT_OF(errstr), errfmt, ap);
55 va_end(ap);
56
57 MessageBox(hwnd, errstr, title, MB_OK | MB_ICONERROR);
58 }
59
60 static void error_code_messagebox(HWND hwnd, DWORD error_code)
61 {
62 LPTSTR lpMsgBuf;
63 DWORD status;
64 TCHAR title[256];
65 static const TCHAR fallback[] = TEXT("Error displaying error message.\n");
66 if (!LoadString(hInst, IDS_ERROR, title, COUNT_OF(title)))
67 lstrcpy(title, TEXT("Error"));
68 status = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
69 NULL, error_code, 0, (LPTSTR)&lpMsgBuf, 0, NULL);
70 if (!status)
71 lpMsgBuf = (LPTSTR)fallback;
72 MessageBox(hwnd, lpMsgBuf, title, MB_OK | MB_ICONERROR);
73 if (lpMsgBuf != fallback)
74 LocalFree(lpMsgBuf);
75 }
76
77 void warning(HWND hwnd, INT resId, ...)
78 {
79 va_list ap;
80 TCHAR title[256];
81 TCHAR errfmt[1024];
82 TCHAR errstr[1024];
83 HINSTANCE hInstance;
84
85 hInstance = GetModuleHandle(0);
86
87 if (!LoadString(hInstance, IDS_WARNING, title, COUNT_OF(title)))
88 _tcscpy(title, _T("Warning"));
89
90 if (!LoadString(hInstance, resId, errfmt, COUNT_OF(errfmt)))
91 _tcscpy(errfmt, _T("Unknown error string!"));
92
93 va_start(ap, resId);
94 _vsntprintf(errstr, COUNT_OF(errstr), errfmt, ap);
95 va_end(ap);
96
97 MessageBox(hwnd, errstr, title, MB_OK | MB_ICONSTOP);
98 }
99
100 INT_PTR CALLBACK modify_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
101 {
102 TCHAR* valueData;
103 HWND hwndValue;
104 int len;
105
106 UNREFERENCED_PARAMETER(lParam);
107
108 switch(uMsg) {
109 case WM_INITDIALOG:
110 if(editValueName && _tcscmp(editValueName, _T("")))
111 {
112 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
113 }
114 else
115 {
116 TCHAR buffer[255];
117 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
118 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
119 }
120 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, stringValueData);
121 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
122 return FALSE;
123 case WM_COMMAND:
124 switch (LOWORD(wParam))
125 {
126 case IDOK:
127 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
128 {
129 if ((len = GetWindowTextLength(hwndValue)))
130 {
131 if (stringValueData)
132 {
133 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(TCHAR))))
134 {
135 stringValueData = valueData;
136 if (!GetWindowText(hwndValue, stringValueData, len + 1))
137 *stringValueData = 0;
138 }
139 }
140 else
141 {
142 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR))))
143 {
144 stringValueData = valueData;
145 if (!GetWindowText(hwndValue, stringValueData, len + 1))
146 *stringValueData = 0;
147 }
148 }
149 }
150 else
151 {
152 if (stringValueData)
153 *stringValueData = 0;
154 }
155 }
156 EndDialog(hwndDlg, IDOK);
157 break;
158 case IDCANCEL:
159 EndDialog(hwndDlg, IDCANCEL);
160 return TRUE;
161 }
162 }
163 return FALSE;
164 }
165
166
167 INT_PTR CALLBACK modify_multi_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
168 {
169 TCHAR* valueData;
170 HWND hwndValue;
171 int len;
172
173 UNREFERENCED_PARAMETER(lParam);
174
175 switch(uMsg) {
176 case WM_INITDIALOG:
177 if(editValueName && _tcscmp(editValueName, _T("")))
178 {
179 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
180 }
181 else
182 {
183 TCHAR buffer[255];
184 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
185 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
186 }
187 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, stringValueData);
188 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
189 return FALSE;
190 case WM_COMMAND:
191 switch (LOWORD(wParam))
192 {
193 case IDOK:
194 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
195 {
196 if ((len = GetWindowTextLength(hwndValue)))
197 {
198 if (stringValueData)
199 {
200 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(TCHAR))))
201 {
202 stringValueData = valueData;
203 if (!GetWindowText(hwndValue, stringValueData, len + 1))
204 *stringValueData = 0;
205 }
206 }
207 else
208 {
209 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(TCHAR))))
210 {
211 stringValueData = valueData;
212 if (!GetWindowText(hwndValue, stringValueData, len + 1))
213 *stringValueData = 0;
214 }
215 }
216 }
217 else
218 {
219 if (stringValueData)
220 *stringValueData = 0;
221 }
222 }
223 EndDialog(hwndDlg, IDOK);
224 break;
225 case IDCANCEL:
226 EndDialog(hwndDlg, IDCANCEL);
227 return TRUE;
228 }
229 }
230 return FALSE;
231 }
232
233
234 LRESULT CALLBACK DwordEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
235 {
236 WNDPROC oldwndproc;
237
238 oldwndproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(hwnd, GWL_USERDATA);
239
240 switch (uMsg)
241 {
242 case WM_CHAR:
243 if (dwordEditMode == EDIT_MODE_DEC)
244 {
245 if (isdigit((int) wParam & 0xff) || iscntrl((int) wParam & 0xff))
246 {
247 break;
248 }
249 else
250 {
251 return 0;
252 }
253 }
254 else if (dwordEditMode == EDIT_MODE_HEX)
255 {
256 if (isxdigit((int) wParam & 0xff) || iscntrl((int) wParam & 0xff))
257 {
258 break;
259 }
260 else
261 {
262 return 0;
263 }
264 }
265 else
266 {
267 break;
268 }
269 }
270
271 return CallWindowProc(oldwndproc, hwnd, uMsg, wParam, lParam);
272 }
273
274
275 INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
276 {
277 WNDPROC oldproc;
278 HWND hwndValue;
279 int len;
280 TCHAR ValueString[32];
281 LPTSTR Remainder;
282 DWORD Base;
283 DWORD Value = 0;
284
285 UNREFERENCED_PARAMETER(lParam);
286
287 switch(uMsg) {
288 case WM_INITDIALOG:
289 dwordEditMode = EDIT_MODE_HEX;
290
291 /* subclass the edit control */
292 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
293 oldproc = (WNDPROC)(LONG_PTR)GetWindowLongPtr(hwndValue, GWL_WNDPROC);
294 SetWindowLongPtr(hwndValue, GWL_USERDATA, (DWORD_PTR)oldproc);
295 SetWindowLongPtr(hwndValue, GWL_WNDPROC, (DWORD_PTR)DwordEditSubclassProc);
296
297 if(editValueName && _tcscmp(editValueName, _T("")))
298 {
299 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
300 }
301 else
302 {
303 TCHAR buffer[255];
304 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
305 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
306 }
307 CheckRadioButton (hwndDlg, IDC_FORMAT_HEX, IDC_FORMAT_DEC, IDC_FORMAT_HEX);
308 _stprintf (ValueString, _T("%lx"), dwordValueData);
309 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, ValueString);
310 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
311 return FALSE;
312
313 case WM_COMMAND:
314 switch (LOWORD(wParam))
315 {
316 case IDC_FORMAT_HEX:
317 if (HIWORD(wParam) == BN_CLICKED && dwordEditMode == EDIT_MODE_DEC)
318 {
319 dwordEditMode = EDIT_MODE_HEX;
320 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
321 {
322 if ((len = GetWindowTextLength(hwndValue)))
323 {
324 if (GetWindowText(hwndValue, ValueString, 32))
325 {
326 Value = _tcstoul (ValueString, &Remainder, 10);
327 }
328 }
329 }
330 _stprintf (ValueString, _T("%lx"), Value);
331 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, ValueString);
332 return TRUE;
333 }
334 break;
335
336 case IDC_FORMAT_DEC:
337 if (HIWORD(wParam) == BN_CLICKED && dwordEditMode == EDIT_MODE_HEX)
338 {
339 dwordEditMode = EDIT_MODE_DEC;
340 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
341 {
342 if ((len = GetWindowTextLength(hwndValue)))
343 {
344 if (GetWindowText(hwndValue, ValueString, 32))
345 {
346 Value = _tcstoul (ValueString, &Remainder, 16);
347 }
348 }
349 }
350 _stprintf (ValueString, _T("%lu"), Value);
351 SetDlgItemText(hwndDlg, IDC_VALUE_DATA, ValueString);
352 return TRUE;
353 }
354 break;
355
356 case IDOK:
357 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
358 {
359 if ((len = GetWindowTextLength(hwndValue)))
360 {
361 if (!GetWindowText(hwndValue, ValueString, 32))
362 {
363 EndDialog(hwndDlg, IDCANCEL);
364 return TRUE;
365 }
366
367 Base = (dwordEditMode == EDIT_MODE_HEX) ? 16 : 10;
368 dwordValueData = _tcstoul (ValueString, &Remainder, Base);
369 }
370 else
371 {
372 EndDialog(hwndDlg, IDCANCEL);
373 return TRUE;
374 }
375 }
376 EndDialog(hwndDlg, IDOK);
377 return TRUE;
378
379 case IDCANCEL:
380 EndDialog(hwndDlg, IDCANCEL);
381 return TRUE;
382 }
383 }
384 return FALSE;
385 }
386
387
388 INT_PTR CALLBACK modify_binary_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
389 {
390 HWND hwndValue;
391 UINT len;
392
393 UNREFERENCED_PARAMETER(lParam);
394
395 switch(uMsg) {
396 case WM_INITDIALOG:
397 if(editValueName && _tcscmp(editValueName, _T("")))
398 {
399 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, editValueName);
400 }
401 else
402 {
403 TCHAR buffer[255];
404 LoadString(hInst, IDS_DEFAULT_VALUE_NAME, buffer, sizeof(buffer)/sizeof(TCHAR));
405 SetDlgItemText(hwndDlg, IDC_VALUE_NAME, buffer);
406 }
407 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
408 HexEdit_LoadBuffer(hwndValue, binValueData, valueDataLen);
409 /* reset the hex edit control's font */
410 SendMessage(hwndValue, WM_SETFONT, 0, 0);
411 SetFocus(hwndValue);
412 return FALSE;
413 case WM_COMMAND:
414 switch (LOWORD(wParam))
415 {
416 case IDOK:
417 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
418 {
419 len = (UINT) HexEdit_GetBufferSize(hwndValue);
420 if (len != valueDataLen && len > 0)
421 {
422 binValueData = HeapReAlloc(GetProcessHeap(), 0, binValueData, len);
423 }
424 if (len > 0)
425 {
426 HexEdit_CopyBuffer(hwndValue, binValueData, len);
427 }
428 valueDataLen = len;
429 }
430 EndDialog(hwndDlg, IDOK);
431 break;
432 case IDCANCEL:
433 EndDialog(hwndDlg, IDCANCEL);
434 return TRUE;
435 }
436 }
437 return FALSE;
438 }
439
440
441 BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName, BOOL EditBin)
442 {
443 DWORD type;
444 LONG lRet;
445 BOOL result = FALSE;
446
447 if (!hKey)
448 return FALSE;
449
450 editValueName = valueName;
451
452 lRet = RegQueryValueEx(hKey, valueName, 0, &type, 0, &valueDataLen);
453 if (lRet != ERROR_SUCCESS && (!_tcscmp(valueName, _T("")) || valueName == NULL))
454 {
455 lRet = ERROR_SUCCESS; /* Allow editing of (Default) values which don't exist */
456 type = REG_SZ;
457 valueDataLen = 0;
458 stringValueData = NULL;
459 binValueData = NULL;
460 }
461
462 if (lRet != ERROR_SUCCESS)
463 {
464 error(hwnd, IDS_BAD_VALUE, valueName);
465 goto done;
466 }
467
468 if (EditBin == FALSE && ((type == REG_SZ) || (type == REG_EXPAND_SZ)))
469 {
470 if (valueDataLen > 0)
471 {
472 if (!(stringValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
473 {
474 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
475 goto done;
476 }
477 lRet = RegQueryValueEx(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
478 if (lRet != ERROR_SUCCESS)
479 {
480 error(hwnd, IDS_BAD_VALUE, valueName);
481 goto done;
482 }
483 }
484 else
485 {
486 stringValueData = NULL;
487 }
488
489 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_STRING), hwnd, modify_string_dlgproc) == IDOK)
490 {
491 if (stringValueData)
492 {
493 lRet = RegSetValueEx(hKey, valueName, 0, type, (LPBYTE)stringValueData, (DWORD) (_tcslen(stringValueData) + 1) * sizeof(TCHAR));
494 }
495 else
496 {
497 lRet = RegSetValueEx(hKey, valueName, 0, type, NULL, 0);
498 }
499 if (lRet == ERROR_SUCCESS)
500 result = TRUE;
501 }
502 }
503 else if (EditBin == FALSE && type == REG_MULTI_SZ)
504 {
505 if (valueDataLen > 0)
506 {
507 size_t llen, listlen, nl_len;
508 LPTSTR src, lines = NULL;
509
510 if (!(stringValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
511 {
512 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
513 goto done;
514 }
515 lRet = RegQueryValueEx(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
516 if (lRet != ERROR_SUCCESS)
517 {
518 error(hwnd, IDS_BAD_VALUE, valueName);
519 goto done;
520 }
521
522 /* convert \0 to \r\n */
523 src = stringValueData;
524 nl_len = _tcslen(_T("\r\n")) * sizeof(TCHAR);
525 listlen = sizeof(TCHAR);
526 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, listlen + sizeof(TCHAR));
527 while(*src != _T('\0'))
528 {
529 llen = _tcslen(src);
530 if(llen == 0)
531 break;
532 listlen += (llen * sizeof(TCHAR)) + nl_len;
533 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, listlen);
534 _tcscat(lines, src);
535 _tcscat(lines, _T("\r\n"));
536 src += llen + 1;
537 }
538 HeapFree(GetProcessHeap(), 0, stringValueData);
539 stringValueData = lines;
540 }
541 else
542 {
543 stringValueData = NULL;
544 }
545
546 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_MULTI_STRING), hwnd, modify_multi_string_dlgproc) == IDOK)
547 {
548 if (stringValueData)
549 {
550 /* convert \r\n to \0 */
551 BOOL EmptyLines = FALSE;
552 LPTSTR src, lines, nl;
553 size_t linechars, buflen, c_nl, dest;
554
555 src = stringValueData;
556 buflen = sizeof(TCHAR);
557 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buflen + sizeof(TCHAR));
558 c_nl = _tcslen(_T("\r\n"));
559 dest = 0;
560 while(*src != _T('\0'))
561 {
562 if((nl = _tcsstr(src, _T("\r\n"))))
563 {
564 linechars = nl - src;
565 if(nl == src)
566 {
567 EmptyLines = TRUE;
568 src = nl + c_nl;
569 continue;
570 }
571 }
572 else
573 {
574 linechars = _tcslen(src);
575 }
576 if(linechars > 0)
577 {
578 buflen += ((linechars + 1) * sizeof(TCHAR));
579 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, buflen);
580 memcpy((lines + dest), src, linechars * sizeof(TCHAR));
581 dest += linechars;
582 lines[dest++] = _T('\0');
583 }
584 else
585 {
586 EmptyLines = TRUE;
587 }
588 src += linechars + (nl != NULL ? c_nl : 0);
589 }
590 lines[++dest] = _T('\0');
591
592 if(EmptyLines)
593 {
594 warning(hwnd, IDS_MULTI_SZ_EMPTY_STRING);
595 }
596
597 lRet = RegSetValueEx(hKey, valueName, 0, type, (LPBYTE)lines, (DWORD) buflen);
598 HeapFree(GetProcessHeap(), 0, lines);
599 }
600 else
601 {
602 lRet = RegSetValueEx(hKey, valueName, 0, type, NULL, 0);
603 }
604 if (lRet == ERROR_SUCCESS)
605 result = TRUE;
606 }
607 }
608 else if (EditBin == FALSE && type == REG_DWORD)
609 {
610 lRet = RegQueryValueEx(hKey, valueName, 0, 0, (LPBYTE)&dwordValueData, &valueDataLen);
611 if (lRet != ERROR_SUCCESS)
612 {
613 error(hwnd, IDS_BAD_VALUE, valueName);
614 goto done;
615 }
616
617 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_DWORD), hwnd, modify_dword_dlgproc) == IDOK)
618 {
619 lRet = RegSetValueEx(hKey, valueName, 0, type, (LPBYTE)&dwordValueData, sizeof(DWORD));
620 if (lRet == ERROR_SUCCESS)
621 result = TRUE;
622 }
623 }
624 else if (EditBin == TRUE || type == REG_NONE || type == REG_BINARY)
625 {
626 #ifndef UNICODE
627 LPWSTR u_valuename;
628 int len_vname = lstrlen(valueName);
629
630 if(len_vname > 0)
631 {
632 if(!(u_valuename = HeapAlloc(GetProcessHeap(), 0, (len_vname + 1) * sizeof(WCHAR))))
633 {
634 error(hwnd, IDS_TOO_BIG_VALUE, len_vname);
635 goto done;
636 }
637 /* convert the ansi value name to an unicode string */
638 MultiByteToWideChar(CP_ACP, 0, valueName, -1, u_valuename, len_vname + 1);
639 valueDataLen *= sizeof(WCHAR);
640 }
641 else
642 u_valuename = L"";
643 #endif
644 if(valueDataLen > 0)
645 {
646 if(!(binValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
647 {
648 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
649 goto done;
650 }
651
652 /* force to use the unicode version, so editing strings in binary mode is correct */
653 lRet = RegQueryValueExW(hKey,
654 #ifndef UNICODE
655 u_valuename,
656 #else
657 valueName,
658 #endif
659 0, 0, (LPBYTE)binValueData, &valueDataLen);
660 if (lRet != ERROR_SUCCESS)
661 {
662 HeapFree(GetProcessHeap(), 0, binValueData);
663 #ifndef UNICODE
664 if(len_vname > 0)
665 HeapFree(GetProcessHeap(), 0, u_valuename);
666 #endif
667 error(hwnd, IDS_BAD_VALUE, valueName);
668 goto done;
669 }
670 }
671 else
672 {
673 binValueData = NULL;
674 }
675
676 if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_BIN_DATA), hwnd, modify_binary_dlgproc) == IDOK)
677 {
678 /* force to use the unicode version, so editing strings in binary mode is correct */
679 lRet = RegSetValueExW(hKey,
680 #ifndef UNICODE
681 u_valuename,
682 #else
683 valueName,
684 #endif
685 0, type, (LPBYTE)binValueData, valueDataLen);
686 if (lRet == ERROR_SUCCESS)
687 result = TRUE;
688 }
689 if(binValueData != NULL)
690 HeapFree(GetProcessHeap(), 0, binValueData);
691 #ifndef UNICODE
692 if(len_vname > 0)
693 HeapFree(GetProcessHeap(), 0, u_valuename);
694 #endif
695 }
696 else
697 {
698 error(hwnd, IDS_UNSUPPORTED_TYPE, type);
699 }
700
701 done:
702 if (stringValueData)
703 HeapFree(GetProcessHeap(), 0, stringValueData);
704 stringValueData = NULL;
705
706 return result;
707 }
708
709 BOOL DeleteKey(HWND hwnd, HKEY hKeyRoot, LPCTSTR keyPath)
710 {
711 TCHAR msg[128], caption[128];
712 BOOL result = FALSE;
713 LONG lRet;
714 HKEY hKey;
715
716 lRet = RegOpenKeyEx(hKeyRoot, keyPath, 0, KEY_READ|KEY_SET_VALUE, &hKey);
717 if (lRet != ERROR_SUCCESS) {
718 error_code_messagebox(hwnd, lRet);
719 return FALSE;
720 }
721
722 LoadString(hInst, IDS_QUERY_DELETE_KEY_CONFIRM, caption, sizeof(caption)/sizeof(TCHAR));
723 LoadString(hInst, IDS_QUERY_DELETE_KEY_ONE, msg, sizeof(msg)/sizeof(TCHAR));
724
725 if (MessageBox(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) != IDYES)
726 goto done;
727
728 lRet = SHDeleteKey(hKeyRoot, keyPath);
729 if (lRet != ERROR_SUCCESS) {
730 error(hwnd, IDS_BAD_KEY, keyPath);
731 goto done;
732 }
733 result = TRUE;
734
735 done:
736 RegCloseKey(hKey);
737 return result;
738 }