[TRANSLATION][APPLICATIONS] Use correct font name in Chinese resources, CORE-9566...
[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 #define NTOS_MODE_USER
24 #include <ndk/cmtypes.h>
25
26 typedef enum _EDIT_MODE
27 {
28 EDIT_MODE_DEC,
29 EDIT_MODE_HEX
30 } EDIT_MODE;
31
32
33 static const WCHAR* editValueName;
34 static WCHAR* stringValueData;
35 static PVOID binValueData;
36 static DWORD dwordValueData;
37 static PCM_RESOURCE_LIST resourceValueData;
38 static INT fullResourceIndex = -1;
39 static DWORD valueDataLen;
40 static EDIT_MODE dwordEditMode = EDIT_MODE_HEX;
41
42 void error(HWND hwnd, INT resId, ...)
43 {
44 va_list ap;
45 WCHAR title[256];
46 WCHAR errfmt[1024];
47 WCHAR errstr[1024];
48 HINSTANCE hInstance;
49
50 hInstance = GetModuleHandle(0);
51
52 if (!LoadStringW(hInstance, IDS_ERROR, title, COUNT_OF(title)))
53 wcscpy(title, L"Error");
54
55 if (!LoadStringW(hInstance, resId, errfmt, COUNT_OF(errfmt)))
56 wcscpy(errfmt, L"Unknown error string!");
57
58 va_start(ap, resId);
59 _vsnwprintf(errstr, COUNT_OF(errstr), errfmt, ap);
60 va_end(ap);
61
62 MessageBoxW(hwnd, errstr, title, MB_OK | MB_ICONERROR);
63 }
64
65 static void error_code_messagebox(HWND hwnd, DWORD error_code)
66 {
67 WCHAR title[256];
68 if (!LoadStringW(hInst, IDS_ERROR, title, COUNT_OF(title)))
69 wcscpy(title, L"Error");
70 ErrorMessageBox(hwnd, title, error_code);
71 }
72
73 void warning(HWND hwnd, INT resId, ...)
74 {
75 va_list ap;
76 WCHAR title[256];
77 WCHAR errfmt[1024];
78 WCHAR errstr[1024];
79 HINSTANCE hInstance;
80
81 hInstance = GetModuleHandle(0);
82
83 if (!LoadStringW(hInstance, IDS_WARNING, title, COUNT_OF(title)))
84 wcscpy(title, L"Warning");
85
86 if (!LoadStringW(hInstance, resId, errfmt, COUNT_OF(errfmt)))
87 wcscpy(errfmt, L"Unknown error string!");
88
89 va_start(ap, resId);
90 _vsnwprintf(errstr, COUNT_OF(errstr), errfmt, ap);
91 va_end(ap);
92
93 MessageBoxW(hwnd, errstr, title, MB_OK | MB_ICONSTOP);
94 }
95
96 INT_PTR CALLBACK modify_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
97 {
98 WCHAR* valueData;
99 HWND hwndValue;
100 int len;
101
102 UNREFERENCED_PARAMETER(lParam);
103
104 switch(uMsg)
105 {
106 case WM_INITDIALOG:
107 if (editValueName && wcscmp(editValueName, L""))
108 {
109 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
110 }
111 else
112 {
113 WCHAR buffer[255];
114 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, COUNT_OF(buffer));
115 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
116 }
117 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, stringValueData);
118 SendMessage(GetDlgItem(hwndDlg, IDC_VALUE_DATA), EM_SETSEL, 0, -1);
119 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
120 return FALSE;
121 case WM_COMMAND:
122 switch (LOWORD(wParam))
123 {
124 case IDOK:
125 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
126 {
127 if ((len = GetWindowTextLength(hwndValue)))
128 {
129 if (stringValueData)
130 {
131 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(WCHAR))))
132 {
133 stringValueData = valueData;
134 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
135 *stringValueData = 0;
136 }
137 }
138 else
139 {
140 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
141 {
142 stringValueData = valueData;
143 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
144 *stringValueData = 0;
145 }
146 }
147 }
148 else
149 {
150 if (stringValueData)
151 *stringValueData = 0;
152 }
153 }
154 EndDialog(hwndDlg, IDOK);
155 break;
156 case IDCANCEL:
157 EndDialog(hwndDlg, IDCANCEL);
158 return TRUE;
159 }
160 }
161 return FALSE;
162 }
163
164
165 INT_PTR CALLBACK modify_multi_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
166 {
167 WCHAR* valueData;
168 HWND hwndValue;
169 int len;
170
171 UNREFERENCED_PARAMETER(lParam);
172
173 switch(uMsg)
174 {
175 case WM_INITDIALOG:
176 if (editValueName && wcscmp(editValueName, L""))
177 {
178 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
179 }
180 else
181 {
182 WCHAR buffer[255];
183 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, COUNT_OF(buffer));
184 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
185 }
186 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, stringValueData);
187 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
188 return FALSE;
189 case WM_COMMAND:
190 switch (LOWORD(wParam))
191 {
192 case IDOK:
193 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
194 {
195 if ((len = GetWindowTextLength(hwndValue)))
196 {
197 if (stringValueData)
198 {
199 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(WCHAR))))
200 {
201 stringValueData = valueData;
202 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
203 *stringValueData = 0;
204 }
205 }
206 else
207 {
208 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
209 {
210 stringValueData = valueData;
211 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
212 *stringValueData = 0;
213 }
214 }
215 }
216 else
217 {
218 if (stringValueData)
219 *stringValueData = 0;
220 }
221 }
222 EndDialog(hwndDlg, IDOK);
223 break;
224 case IDCANCEL:
225 EndDialog(hwndDlg, IDCANCEL);
226 return TRUE;
227 }
228 }
229 return FALSE;
230 }
231
232
233 LRESULT CALLBACK DwordEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
234 {
235 WNDPROC oldwndproc;
236
237 oldwndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
238
239 switch (uMsg)
240 {
241 case WM_CHAR:
242 if (dwordEditMode == EDIT_MODE_DEC)
243 {
244 if (isdigit((int) wParam & 0xff) || iscntrl((int) wParam & 0xff))
245 {
246 break;
247 }
248 else
249 {
250 return 0;
251 }
252 }
253 else if (dwordEditMode == EDIT_MODE_HEX)
254 {
255 if (isxdigit((int) wParam & 0xff) || iscntrl((int) wParam & 0xff))
256 {
257 break;
258 }
259 else
260 {
261 return 0;
262 }
263 }
264 else
265 {
266 break;
267 }
268 }
269
270 return CallWindowProcW(oldwndproc, hwnd, uMsg, wParam, lParam);
271 }
272
273
274 INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
275 {
276 WNDPROC oldproc;
277 HWND hwndValue;
278 WCHAR ValueString[32];
279 LPWSTR Remainder;
280 DWORD Base;
281 DWORD Value = 0;
282
283 UNREFERENCED_PARAMETER(lParam);
284
285 switch(uMsg)
286 {
287 case WM_INITDIALOG:
288 dwordEditMode = EDIT_MODE_HEX;
289
290 /* subclass the edit control */
291 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
292 oldproc = (WNDPROC)GetWindowLongPtr(hwndValue, GWLP_WNDPROC);
293 SetWindowLongPtr(hwndValue, GWLP_USERDATA, (DWORD_PTR)oldproc);
294 SetWindowLongPtr(hwndValue, GWLP_WNDPROC, (DWORD_PTR)DwordEditSubclassProc);
295
296 if (editValueName && wcscmp(editValueName, L""))
297 {
298 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
299 }
300 else
301 {
302 WCHAR buffer[255];
303 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, COUNT_OF(buffer));
304 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
305 }
306 CheckRadioButton (hwndDlg, IDC_FORMAT_HEX, IDC_FORMAT_DEC, IDC_FORMAT_HEX);
307 swprintf(ValueString, L"%lx", dwordValueData);
308 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, ValueString);
309 SendMessage(GetDlgItem(hwndDlg, IDC_VALUE_DATA), EM_SETSEL, 0, -1);
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 (GetWindowTextLength(hwndValue))
323 {
324 if (GetWindowTextW(hwndValue, ValueString, 32))
325 {
326 Value = wcstoul (ValueString, &Remainder, 10);
327 }
328 }
329 }
330 swprintf(ValueString, L"%lx", Value);
331 SetDlgItemTextW(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 (GetWindowTextLength(hwndValue))
343 {
344 if (GetWindowTextW(hwndValue, ValueString, 32))
345 {
346 Value = wcstoul (ValueString, &Remainder, 16);
347 }
348 }
349 }
350 swprintf(ValueString, L"%lu", Value);
351 SetDlgItemTextW(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 (GetWindowTextLength(hwndValue))
360 {
361 if (!GetWindowTextW(hwndValue, ValueString, 32))
362 {
363 EndDialog(hwndDlg, IDCANCEL);
364 return TRUE;
365 }
366
367 Base = (dwordEditMode == EDIT_MODE_HEX) ? 16 : 10;
368 dwordValueData = wcstoul (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 {
397 case WM_INITDIALOG:
398 if (editValueName && wcscmp(editValueName, L""))
399 {
400 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
401 }
402 else
403 {
404 WCHAR buffer[255];
405 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, COUNT_OF(buffer));
406 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
407 }
408 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
409 HexEdit_LoadBuffer(hwndValue, binValueData, valueDataLen);
410 /* reset the hex edit control's font */
411 SendMessageW(hwndValue, WM_SETFONT, 0, 0);
412 SetFocus(hwndValue);
413 return FALSE;
414 case WM_COMMAND:
415 switch (LOWORD(wParam))
416 {
417 case IDOK:
418 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
419 {
420 len = (UINT) HexEdit_GetBufferSize(hwndValue);
421 if (len > 0 && binValueData)
422 binValueData = HeapReAlloc(GetProcessHeap(), 0, binValueData, len);
423 else
424 binValueData = HeapAlloc(GetProcessHeap(), 0, len + 1);
425 HexEdit_CopyBuffer(hwndValue, binValueData, len);
426 valueDataLen = len;
427 }
428 EndDialog(hwndDlg, IDOK);
429 break;
430 case IDCANCEL:
431 EndDialog(hwndDlg, IDCANCEL);
432 return TRUE;
433 }
434 }
435 return FALSE;
436 }
437
438
439 static BOOL CreateResourceColumns(HWND hwnd)
440 {
441 WCHAR szText[80];
442 RECT rc;
443 LVCOLUMN lvC;
444 HWND hwndLV;
445 INT width;
446
447 /* Create columns. */
448 lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
449 lvC.pszText = szText;
450 lvC.fmt = LVCFMT_LEFT;
451
452 hwndLV = GetDlgItem(hwnd, IDC_DMA_LIST);
453 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
454 GetClientRect(hwndLV, &rc);
455
456 /* Load the column labels from the resource file. */
457 lvC.iSubItem = 0;
458 lvC.cx = (rc.right - rc.left) / 2;
459 LoadStringW(hInst, IDS_DMA_CHANNEL, szText, COUNT_OF(szText));
460 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
461 return FALSE;
462
463 lvC.iSubItem = 1;
464 lvC.cx = (rc.right - rc.left) - lvC.cx;
465 LoadStringW(hInst, IDS_DMA_PORT, szText, COUNT_OF(szText));
466 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
467 return FALSE;
468
469
470 /* Interrupt list */
471 hwndLV = GetDlgItem(hwnd, IDC_IRQ_LIST);
472 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
473 GetClientRect(hwndLV, &rc);
474 width = (rc.right - rc.left) / 4;
475
476 /* Load the column labels from the resource file. */
477 lvC.iSubItem = 0;
478 lvC.cx = width;
479 LoadStringW(hInst, IDS_INTERRUPT_VECTOR, szText, COUNT_OF(szText));
480 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
481 return FALSE;
482
483 lvC.iSubItem = 1;
484 LoadStringW(hInst, IDS_INTERRUPT_LEVEL, szText, COUNT_OF(szText));
485 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
486 return FALSE;
487
488 lvC.iSubItem = 2;
489 LoadStringW(hInst, IDS_INTERRUPT_AFFINITY, szText, COUNT_OF(szText));
490 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
491 return FALSE;
492
493 lvC.iSubItem = 3;
494 lvC.cx = (rc.right - rc.left) - 3 * width;
495 LoadStringW(hInst, IDS_INTERRUPT_TYPE, szText, COUNT_OF(szText));
496 if (ListView_InsertColumn(hwndLV, 3, &lvC) == -1)
497 return FALSE;
498
499
500 /* Memory list */
501 hwndLV = GetDlgItem(hwnd, IDC_MEMORY_LIST);
502 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
503 GetClientRect(hwndLV, &rc);
504 width = (rc.right - rc.left) / 3;
505
506 /* Load the column labels from the resource file. */
507 lvC.iSubItem = 0;
508 lvC.cx = width;
509 LoadStringW(hInst, IDS_MEMORY_ADDRESS, szText, COUNT_OF(szText));
510 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
511 return FALSE;
512
513 lvC.iSubItem = 1;
514 LoadStringW(hInst, IDS_MEMORY_LENGTH, szText, COUNT_OF(szText));
515 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
516 return FALSE;
517
518 lvC.iSubItem = 2;
519 lvC.cx = (rc.right - rc.left) - 2 * width;
520 LoadStringW(hInst, IDS_MEMORY_ACCESS, szText, COUNT_OF(szText));
521 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
522 return FALSE;
523
524
525 /* Port list */
526 hwndLV = GetDlgItem(hwnd, IDC_PORT_LIST);
527 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
528 GetClientRect(hwndLV, &rc);
529 width = (rc.right - rc.left) / 3;
530
531 /* Load the column labels from the resource file. */
532 lvC.iSubItem = 0;
533 lvC.cx = width;
534 LoadStringW(hInst, IDS_PORT_ADDRESS, szText, COUNT_OF(szText));
535 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
536 return FALSE;
537
538 lvC.iSubItem = 1;
539 LoadStringW(hInst, IDS_PORT_LENGTH, szText, COUNT_OF(szText));
540 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
541 return FALSE;
542
543 lvC.iSubItem = 2;
544 lvC.cx = (rc.right - rc.left) - 2 * width;
545 LoadStringW(hInst, IDS_PORT_ACCESS, szText, COUNT_OF(szText));
546 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
547 return FALSE;
548
549 /* Device specific list */
550 hwndLV = GetDlgItem(hwnd, IDC_DEVICE_LIST);
551 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
552 GetClientRect(hwndLV, &rc);
553 width = (rc.right - rc.left) / 3;
554
555 /* Load the column labels from the resource file. */
556 lvC.iSubItem = 0;
557 lvC.cx = width;
558 LoadStringW(hInst, IDS_SPECIFIC_RESERVED1, szText, COUNT_OF(szText));
559 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
560 return FALSE;
561
562 lvC.iSubItem = 1;
563 LoadStringW(hInst, IDS_SPECIFIC_RESERVED2, szText, COUNT_OF(szText));
564 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
565 return FALSE;
566
567 lvC.iSubItem = 2;
568 lvC.cx = (rc.right - rc.left) - 2 * width;
569 LoadStringW(hInst, IDS_SPECIFIC_DATASIZE, szText, COUNT_OF(szText));
570 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
571 return FALSE;
572
573 return TRUE;
574 }
575
576 static VOID
577 GetInterfaceType(INTERFACE_TYPE InterfaceType,
578 LPWSTR pBuffer,
579 DWORD dwLength)
580 {
581 // LPWSTR lpInterfaceType;
582
583 switch (InterfaceType)
584 {
585 case InterfaceTypeUndefined:
586 LoadStringW(hInst, IDS_BUS_UNDEFINED, pBuffer, dwLength);
587 // lpInterfaceType = L"Undefined";
588 break;
589 case Internal:
590 LoadStringW(hInst, IDS_BUS_INTERNAL, pBuffer, dwLength);
591 // lpInterfaceType = L"Internal";
592 break;
593 case Isa:
594 LoadStringW(hInst, IDS_BUS_ISA, pBuffer, dwLength);
595 // lpInterfaceType = L"Isa";
596 break;
597 case Eisa:
598 LoadStringW(hInst, IDS_BUS_EISA, pBuffer, dwLength);
599 // lpInterfaceType = L"Eisa";
600 break;
601 case MicroChannel:
602 LoadStringW(hInst, IDS_BUS_MICROCHANNEL, pBuffer, dwLength);
603 // lpInterfaceType = L"MicroChannel";
604 break;
605 case TurboChannel:
606 LoadStringW(hInst, IDS_BUS_TURBOCHANNEL, pBuffer, dwLength);
607 // lpInterfaceType = L"TurboChannel";
608 break;
609 case PCIBus:
610 LoadStringW(hInst, IDS_BUS_PCIBUS, pBuffer, dwLength);
611 // lpInterfaceType = L"PCIBus";
612 break;
613 case VMEBus:
614 LoadStringW(hInst, IDS_BUS_VMEBUS, pBuffer, dwLength);
615 // lpInterfaceType = L"VMEBus";
616 break;
617 case NuBus:
618 LoadStringW(hInst, IDS_BUS_NUBUS, pBuffer, dwLength);
619 // lpInterfaceType = L"NuBus";
620 break;
621 case PCMCIABus:
622 LoadStringW(hInst, IDS_BUS_PCMCIABUS, pBuffer, dwLength);
623 // lpInterfaceType = L"PCMCIABus";
624 break;
625 case CBus:
626 LoadStringW(hInst, IDS_BUS_CBUS, pBuffer, dwLength);
627 // lpInterfaceType = L"CBus";
628 break;
629 case MPIBus:
630 LoadStringW(hInst, IDS_BUS_MPIBUS, pBuffer, dwLength);
631 // lpInterfaceType = L"MPIBus";
632 break;
633 case MPSABus:
634 LoadStringW(hInst, IDS_BUS_MPSABUS, pBuffer, dwLength);
635 // lpInterfaceType = L"MPSABus";
636 break;
637 case ProcessorInternal:
638 LoadStringW(hInst, IDS_BUS_PROCESSORINTERNAL, pBuffer, dwLength);
639 // lpInterfaceType = L"ProcessorInternal";
640 break;
641 case InternalPowerBus:
642 LoadStringW(hInst, IDS_BUS_INTERNALPOWERBUS, pBuffer, dwLength);
643 // lpInterfaceType = L"InternalPowerBus";
644 break;
645 case PNPISABus:
646 LoadStringW(hInst, IDS_BUS_PNPISABUS, pBuffer, dwLength);
647 // lpInterfaceType = L"PNPISABus";
648 break;
649 case PNPBus:
650 LoadStringW(hInst, IDS_BUS_PNPBUS, pBuffer, dwLength);
651 // lpInterfaceType = L"PNPBus";
652 break;
653 default:
654 LoadStringW(hInst, IDS_BUS_UNKNOWNTYPE, pBuffer, dwLength);
655 // lpInterfaceType = L"Unknown interface type";
656 break;
657 }
658
659 // wcscpy(pBuffer, lpInterfaceType);
660 }
661
662
663 static VOID
664 ParseResources(HWND hwnd)
665 {
666 PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor;
667 PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
668 PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
669 ULONG i;
670 HWND hwndLV;
671
672 WCHAR buffer[80];
673 LVITEMW item;
674 INT iItem;
675
676 pFullDescriptor = &resourceValueData->List[0];
677 for (i = 0; i < fullResourceIndex; i++)
678 {
679 pFullDescriptor = (PVOID)(pFullDescriptor->PartialResourceList.PartialDescriptors +
680 pFullDescriptor->PartialResourceList.Count);
681 }
682 pPartialResourceList = &pFullDescriptor->PartialResourceList;
683
684 /* Interface type */
685 GetInterfaceType(pFullDescriptor->InterfaceType, buffer, 80);
686 SetDlgItemTextW(hwnd, IDC_INTERFACETYPE, buffer);
687
688 /* Busnumber */
689 SetDlgItemInt(hwnd, IDC_BUSNUMBER, (UINT)pFullDescriptor->BusNumber, FALSE);
690
691 /* Version */
692 SetDlgItemInt(hwnd, IDC_VERSION, (UINT)pPartialResourceList->Version, FALSE);
693
694 /* Revision */
695 SetDlgItemInt(hwnd, IDC_REVISION, (UINT)pPartialResourceList->Revision, FALSE);
696
697 for (i = 0; i < pPartialResourceList->Count; i++)
698 {
699 pDescriptor = &pPartialResourceList->PartialDescriptors[i];
700
701 switch (pDescriptor->Type)
702 {
703 case CmResourceTypePort:
704 hwndLV = GetDlgItem(hwnd, IDC_PORT_LIST);
705
706 #ifdef _M_AMD64
707 wsprintf(buffer, L"0x%016I64x", pDescriptor->u.Port.Start.QuadPart);
708 #else
709 wsprintf(buffer, L"0x%08lx", pDescriptor->u.Port.Start.u.LowPart);
710 #endif
711
712 item.mask = LVIF_TEXT | LVIF_PARAM;
713 item.iItem = 1000;
714 item.iSubItem = 0;
715 item.state = 0;
716 item.stateMask = 0;
717 item.pszText = buffer;
718 item.cchTextMax = (int)wcslen(item.pszText);
719 item.lParam = (LPARAM)pDescriptor;
720
721 iItem = ListView_InsertItem(hwndLV, &item);
722 if (iItem != -1)
723 {
724 wsprintf(buffer, L"0x%lx", pDescriptor->u.Port.Length);
725 ListView_SetItemText(hwndLV, iItem, 1, buffer);
726
727 if (pDescriptor->Flags & CM_RESOURCE_PORT_IO)
728 LoadStringW(hInst, IDS_PORT_PORT_IO, buffer, COUNT_OF(buffer));
729 else
730 LoadStringW(hInst, IDS_PORT_MEMORY_IO, buffer, COUNT_OF(buffer));
731 ListView_SetItemText(hwndLV, iItem, 2, buffer);
732 }
733 break;
734
735 case CmResourceTypeInterrupt:
736 hwndLV = GetDlgItem(hwnd, IDC_IRQ_LIST);
737
738 wsprintf(buffer, L"%lu", pDescriptor->u.Interrupt.Vector);
739
740 item.mask = LVIF_TEXT | LVIF_PARAM;
741 item.iItem = 1000;
742 item.iSubItem = 0;
743 item.state = 0;
744 item.stateMask = 0;
745 item.pszText = buffer;
746 item.cchTextMax = (int)wcslen(item.pszText);
747 item.lParam = (LPARAM)pDescriptor;
748
749 iItem = ListView_InsertItem(hwndLV, &item);
750 if (iItem != -1)
751 {
752 wsprintf(buffer, L"%lu", pDescriptor->u.Interrupt.Level);
753 ListView_SetItemText(hwndLV, iItem, 1, buffer);
754
755 wsprintf(buffer, L"0x%08lx", pDescriptor->u.Interrupt.Affinity);
756 ListView_SetItemText(hwndLV, iItem, 2, buffer);
757
758 if (pDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
759 LoadStringW(hInst, IDS_INTERRUPT_EDGE_SENSITIVE, buffer, COUNT_OF(buffer));
760 else
761 LoadStringW(hInst, IDS_INTERRUPT_LEVEL_SENSITIVE, buffer, COUNT_OF(buffer));
762
763 ListView_SetItemText(hwndLV, iItem, 3, buffer);
764 }
765 break;
766
767 case CmResourceTypeMemory:
768 hwndLV = GetDlgItem(hwnd, IDC_MEMORY_LIST);
769
770 #ifdef _M_AMD64
771 wsprintf(buffer, L"0x%016I64x", pDescriptor->u.Memory.Start.QuadPart);
772 #else
773 wsprintf(buffer, L"0x%08lx", pDescriptor->u.Memory.Start.u.LowPart);
774 #endif
775
776 item.mask = LVIF_TEXT | LVIF_PARAM;
777 item.iItem = 1000;
778 item.iSubItem = 0;
779 item.state = 0;
780 item.stateMask = 0;
781 item.pszText = buffer;
782 item.cchTextMax = (int)wcslen(item.pszText);
783 item.lParam = (LPARAM)pDescriptor;
784
785 iItem = ListView_InsertItem(hwndLV, &item);
786 if (iItem != -1)
787 {
788 wsprintf(buffer, L"0x%lx", pDescriptor->u.Memory.Length);
789 ListView_SetItemText(hwndLV, iItem, 1, buffer);
790
791 switch (pDescriptor->Flags & (CM_RESOURCE_MEMORY_READ_ONLY | CM_RESOURCE_MEMORY_WRITE_ONLY))
792 {
793 case CM_RESOURCE_MEMORY_READ_ONLY:
794 LoadStringW(hInst, IDS_MEMORY_READ_ONLY, buffer, COUNT_OF(buffer));
795 break;
796
797 case CM_RESOURCE_MEMORY_WRITE_ONLY:
798 LoadStringW(hInst, IDS_MEMORY_WRITE_ONLY, buffer, COUNT_OF(buffer));
799 break;
800
801 default:
802 LoadStringW(hInst, IDS_MEMORY_READ_WRITE, buffer, COUNT_OF(buffer));
803 break;
804 }
805
806 ListView_SetItemText(hwndLV, iItem, 2, buffer);
807 }
808 break;
809
810 case CmResourceTypeDma:
811 hwndLV = GetDlgItem(hwnd, IDC_DMA_LIST);
812
813 wsprintf(buffer, L"%lu", pDescriptor->u.Dma.Channel);
814
815 item.mask = LVIF_TEXT | LVIF_PARAM;
816 item.iItem = 1000;
817 item.iSubItem = 0;
818 item.state = 0;
819 item.stateMask = 0;
820 item.pszText = buffer;
821 item.cchTextMax = (int)wcslen(item.pszText);
822 item.lParam = (LPARAM)pDescriptor;
823
824 iItem = ListView_InsertItem(hwndLV, &item);
825 if (iItem != -1)
826 {
827 wsprintf(buffer, L"%lu", pDescriptor->u.Dma.Port);
828 ListView_SetItemText(hwndLV, iItem, 1, buffer);
829 }
830 break;
831
832 case CmResourceTypeDeviceSpecific:
833 hwndLV = GetDlgItem(hwnd, IDC_DEVICE_LIST);
834
835 wsprintf(buffer, L"0x%08lx", pDescriptor->u.DeviceSpecificData.Reserved1);
836
837 item.mask = LVIF_TEXT | LVIF_PARAM;
838 item.iItem = 1000;
839 item.iSubItem = 0;
840 item.state = 0;
841 item.stateMask = 0;
842 item.pszText = buffer;
843 item.cchTextMax = (int)wcslen(item.pszText);
844 item.lParam = (LPARAM)pDescriptor;
845
846 iItem = ListView_InsertItem(hwndLV, &item);
847 if (iItem != -1)
848 {
849 wsprintf(buffer, L"0x%08lx", pDescriptor->u.DeviceSpecificData.Reserved2);
850 ListView_SetItemText(hwndLV, iItem, 1, buffer);
851
852 wsprintf(buffer, L"0x%lx", pDescriptor->u.DeviceSpecificData.DataSize);
853 ListView_SetItemText(hwndLV, iItem, 2, buffer);
854 }
855 break;
856 }
857 }
858 }
859
860
861 static BOOL
862 OnResourceNotify(HWND hwndDlg, NMHDR *phdr)
863 {
864 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
865
866 switch (phdr->idFrom)
867 {
868 case IDC_PORT_LIST:
869 case IDC_MEMORY_LIST:
870 case IDC_DMA_LIST:
871 case IDC_IRQ_LIST:
872 case IDC_DEVICE_LIST:
873 switch(phdr->code)
874 {
875 case NM_CLICK:
876 if (lpnmlv->iItem != -1)
877 {
878 PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
879 LVITEMW item;
880
881 item.mask = LVIF_PARAM;
882 item.iItem = lpnmlv->iItem;
883 item.iSubItem = 0;
884
885 if (ListView_GetItem(phdr->hwndFrom, &item))
886 {
887 pDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)item.lParam;
888
889 EnableWindow(GetDlgItem(hwndDlg, IDC_UNDETERMINED),
890 (pDescriptor->ShareDisposition == CmResourceShareUndetermined));
891
892 EnableWindow(GetDlgItem(hwndDlg, IDC_SHARED),
893 (pDescriptor->ShareDisposition == CmResourceShareShared));
894
895 EnableWindow(GetDlgItem(hwndDlg, IDC_DEVICE_EXCLUSIVE),
896 (pDescriptor->ShareDisposition == CmResourceShareDeviceExclusive));
897
898 EnableWindow(GetDlgItem(hwndDlg, IDC_DRIVER_EXCLUSIVE),
899 (pDescriptor->ShareDisposition == CmResourceShareDriverExclusive));
900 }
901 }
902 else
903 {
904 EnableWindow(GetDlgItem(hwndDlg, IDC_UNDETERMINED), FALSE);
905 EnableWindow(GetDlgItem(hwndDlg, IDC_SHARED), FALSE);
906 EnableWindow(GetDlgItem(hwndDlg, IDC_DEVICE_EXCLUSIVE), FALSE);
907 EnableWindow(GetDlgItem(hwndDlg, IDC_DRIVER_EXCLUSIVE), FALSE);
908 }
909 break;
910 }
911 break;
912 }
913
914 return FALSE;
915 }
916
917
918 static INT_PTR CALLBACK modify_resource_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
919 {
920 UNREFERENCED_PARAMETER(lParam);
921
922 switch(uMsg)
923 {
924 case WM_INITDIALOG:
925 CreateResourceColumns(hwndDlg);
926 ParseResources(hwndDlg);
927 return FALSE;
928
929 case WM_NOTIFY:
930 return OnResourceNotify(hwndDlg, (NMHDR *)lParam);
931
932 case WM_COMMAND:
933 switch (LOWORD(wParam))
934 {
935 case IDOK:
936 EndDialog(hwndDlg, IDOK);
937 break;
938 case IDCANCEL:
939 EndDialog(hwndDlg, IDCANCEL);
940 return TRUE;
941 }
942 }
943 return FALSE;
944 }
945
946 static BOOL CreateResourceListColumns(HWND hWndListView)
947 {
948 WCHAR szText[80];
949 RECT rc;
950 LVCOLUMN lvC;
951
952 ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_FULLROWSELECT);
953
954 GetClientRect(hWndListView, &rc);
955
956 /* Create columns. */
957 lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
958 lvC.pszText = szText;
959 lvC.fmt = LVCFMT_LEFT;
960
961 /* Load the column labels from the resource file. */
962 lvC.iSubItem = 0;
963 lvC.cx = (rc.right - rc.left) / 2;
964 LoadStringW(hInst, IDS_BUSNUMBER, szText, COUNT_OF(szText));
965 if (ListView_InsertColumn(hWndListView, 0, &lvC) == -1)
966 return FALSE;
967
968 lvC.iSubItem = 1;
969 lvC.cx = (rc.right - rc.left) - lvC.cx;
970 LoadStringW(hInst, IDS_INTERFACE, szText, COUNT_OF(szText));
971 if (ListView_InsertColumn(hWndListView, 1, &lvC) == -1)
972 return FALSE;
973
974 return TRUE;
975 }
976
977 static VOID AddFullResourcesToList(HWND hwnd)
978 {
979 PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor;
980 WCHAR buffer[80];
981 LVITEMW item;
982 ULONG i;
983 INT iItem;
984
985 pFullDescriptor = &resourceValueData->List[0];
986 for (i = 0; i < resourceValueData->Count; i++)
987 {
988 wsprintf(buffer, L"%lu", pFullDescriptor->BusNumber);
989
990 item.mask = LVIF_TEXT;
991 item.iItem = i;
992 item.iSubItem = 0;
993 item.state = 0;
994 item.stateMask = 0;
995 item.pszText = buffer;
996 item.cchTextMax = (int)wcslen(item.pszText);
997
998 iItem = ListView_InsertItem(hwnd, &item);
999 if (iItem != -1)
1000 {
1001 GetInterfaceType(pFullDescriptor->InterfaceType, buffer, 80);
1002 ListView_SetItemText(hwnd, iItem, 1, buffer);
1003 }
1004 pFullDescriptor = (PVOID)(pFullDescriptor->PartialResourceList.PartialDescriptors +
1005 pFullDescriptor->PartialResourceList.Count);
1006 }
1007 }
1008
1009 static BOOL
1010 OnResourceListNotify(HWND hwndDlg, NMHDR *phdr)
1011 {
1012 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
1013
1014 switch (phdr->idFrom)
1015 {
1016 case IDC_RESOURCE_LIST:
1017 switch(phdr->code)
1018 {
1019 case NM_CLICK:
1020 fullResourceIndex = lpnmlv->iItem;
1021 EnableWindow(GetDlgItem(hwndDlg, IDC_SHOW_RESOURCE), (lpnmlv->iItem != -1));
1022 break;
1023
1024 case NM_DBLCLK:
1025 if (lpnmlv->iItem != -1)
1026 {
1027 fullResourceIndex = lpnmlv->iItem;
1028 DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE), hwndDlg, modify_resource_dlgproc);
1029 }
1030 break;
1031 }
1032 break;
1033 }
1034
1035 return FALSE;
1036 }
1037
1038
1039 static INT_PTR CALLBACK modify_resource_list_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1040 {
1041 UNREFERENCED_PARAMETER(lParam);
1042
1043 switch(uMsg)
1044 {
1045 case WM_INITDIALOG:
1046 CreateResourceListColumns(GetDlgItem(hwndDlg, IDC_RESOURCE_LIST));
1047 AddFullResourcesToList(GetDlgItem(hwndDlg, IDC_RESOURCE_LIST));
1048 return FALSE;
1049
1050 case WM_NOTIFY:
1051 return OnResourceListNotify(hwndDlg, (NMHDR *)lParam);
1052
1053 case WM_COMMAND:
1054 switch (LOWORD(wParam))
1055 {
1056 case IDC_SHOW_RESOURCE:
1057 if (fullResourceIndex != -1)
1058 DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE), hwndDlg, modify_resource_dlgproc);
1059 break;
1060 case IDOK:
1061 EndDialog(hwndDlg, IDOK);
1062 break;
1063 case IDCANCEL:
1064 EndDialog(hwndDlg, IDCANCEL);
1065 return TRUE;
1066 }
1067 }
1068 return FALSE;
1069 }
1070
1071
1072 BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCWSTR valueName, BOOL EditBin)
1073 {
1074 DWORD type;
1075 LONG lRet;
1076 BOOL result = FALSE;
1077
1078 if (!hKey)
1079 return FALSE;
1080
1081 editValueName = valueName;
1082
1083 lRet = RegQueryValueExW(hKey, valueName, 0, &type, 0, &valueDataLen);
1084 if (lRet != ERROR_SUCCESS && (valueName == NULL || !valueName[0]))
1085 {
1086 lRet = ERROR_SUCCESS; /* Allow editing of (Default) values which don't exist */
1087 type = REG_SZ;
1088 valueDataLen = 0;
1089 stringValueData = NULL;
1090 binValueData = NULL;
1091 }
1092
1093 if (lRet != ERROR_SUCCESS)
1094 {
1095 error(hwnd, IDS_BAD_VALUE, valueName);
1096 goto done;
1097 }
1098
1099 if (EditBin == FALSE && ((type == REG_SZ) || (type == REG_EXPAND_SZ)))
1100 {
1101 if (valueDataLen > 0)
1102 {
1103 if (!(stringValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
1104 {
1105 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1106 goto done;
1107 }
1108 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
1109 if (lRet != ERROR_SUCCESS)
1110 {
1111 error(hwnd, IDS_BAD_VALUE, valueName);
1112 goto done;
1113 }
1114 }
1115 else
1116 {
1117 stringValueData = NULL;
1118 }
1119
1120 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_STRING), hwnd, modify_string_dlgproc) == IDOK)
1121 {
1122 if (stringValueData)
1123 {
1124 lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)stringValueData, (DWORD) (wcslen(stringValueData) + 1) * sizeof(WCHAR));
1125 }
1126 else
1127 {
1128 lRet = RegSetValueExW(hKey, valueName, 0, type, NULL, 0);
1129 }
1130 if (lRet == ERROR_SUCCESS)
1131 result = TRUE;
1132 }
1133 }
1134 else if (EditBin == FALSE && type == REG_MULTI_SZ)
1135 {
1136 if (valueDataLen > 0)
1137 {
1138 size_t llen, listlen, nl_len;
1139 LPWSTR src, lines = NULL;
1140
1141 if (!(stringValueData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, valueDataLen + sizeof(WCHAR))))
1142 {
1143 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1144 goto done;
1145 }
1146 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
1147 if (lRet != ERROR_SUCCESS)
1148 {
1149 error(hwnd, IDS_BAD_VALUE, valueName);
1150 goto done;
1151 }
1152
1153 /* convert \0 to \r\n */
1154 src = stringValueData;
1155 nl_len = wcslen(L"\r\n") * sizeof(WCHAR);
1156 listlen = sizeof(WCHAR);
1157 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, listlen + sizeof(WCHAR));
1158 while(*src != L'\0')
1159 {
1160 llen = wcslen(src);
1161 if(llen == 0)
1162 break;
1163 listlen += (llen * sizeof(WCHAR)) + nl_len;
1164 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, listlen);
1165 wcscat(lines, src);
1166 wcscat(lines, L"\r\n");
1167 src += llen + 1;
1168 }
1169 HeapFree(GetProcessHeap(), 0, stringValueData);
1170 stringValueData = lines;
1171 }
1172 else
1173 {
1174 stringValueData = NULL;
1175 }
1176
1177 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_MULTI_STRING), hwnd, modify_multi_string_dlgproc) == IDOK)
1178 {
1179 if (stringValueData)
1180 {
1181 /* convert \r\n to \0 */
1182 BOOL EmptyLines = FALSE;
1183 LPWSTR src, lines, nl;
1184 size_t linechars, buflen, c_nl, dest;
1185
1186 src = stringValueData;
1187 buflen = sizeof(WCHAR);
1188 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buflen + sizeof(WCHAR));
1189 c_nl = wcslen(L"\r\n");
1190 dest = 0;
1191 while(*src != L'\0')
1192 {
1193 if((nl = wcsstr(src, L"\r\n")))
1194 {
1195 linechars = nl - src;
1196 if(nl == src)
1197 {
1198 EmptyLines = TRUE;
1199 src = nl + c_nl;
1200 continue;
1201 }
1202 }
1203 else
1204 {
1205 linechars = wcslen(src);
1206 }
1207 if(linechars > 0)
1208 {
1209 buflen += ((linechars + 1) * sizeof(WCHAR));
1210 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, buflen);
1211 memcpy((lines + dest), src, linechars * sizeof(WCHAR));
1212 dest += linechars;
1213 lines[dest++] = L'\0';
1214 }
1215 else
1216 {
1217 EmptyLines = TRUE;
1218 }
1219 src += linechars + (nl != NULL ? c_nl : 0);
1220 }
1221 lines[++dest] = L'\0';
1222
1223 if(EmptyLines)
1224 {
1225 warning(hwnd, IDS_MULTI_SZ_EMPTY_STRING);
1226 }
1227
1228 lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)lines, (DWORD) buflen);
1229 HeapFree(GetProcessHeap(), 0, lines);
1230 }
1231 else
1232 {
1233 lRet = RegSetValueExW(hKey, valueName, 0, type, NULL, 0);
1234 }
1235 if (lRet == ERROR_SUCCESS)
1236 result = TRUE;
1237 }
1238 }
1239 else if (EditBin == FALSE && type == REG_DWORD)
1240 {
1241 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)&dwordValueData, &valueDataLen);
1242 if (lRet != ERROR_SUCCESS)
1243 {
1244 error(hwnd, IDS_BAD_VALUE, valueName);
1245 goto done;
1246 }
1247
1248 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_DWORD), hwnd, modify_dword_dlgproc) == IDOK)
1249 {
1250 lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)&dwordValueData, sizeof(DWORD));
1251 if (lRet == ERROR_SUCCESS)
1252 result = TRUE;
1253 }
1254 }
1255 else if (EditBin == FALSE && type == REG_RESOURCE_LIST)
1256 {
1257 if (valueDataLen > 0)
1258 {
1259 resourceValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen);
1260 if (resourceValueData == NULL)
1261 {
1262 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1263 goto done;
1264 }
1265
1266 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)resourceValueData, &valueDataLen);
1267 if (lRet != ERROR_SUCCESS)
1268 {
1269 error(hwnd, IDS_BAD_VALUE, valueName);
1270 goto done;
1271 }
1272 }
1273 else
1274 {
1275 resourceValueData = NULL;
1276 }
1277
1278 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE_LIST), hwnd, modify_resource_list_dlgproc) == IDOK)
1279 {
1280 }
1281 }
1282 else if (EditBin == FALSE && type == REG_FULL_RESOURCE_DESCRIPTOR)
1283 {
1284 if (valueDataLen > 0)
1285 {
1286 resourceValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen + sizeof(ULONG));
1287 if (resourceValueData == NULL)
1288 {
1289 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1290 goto done;
1291 }
1292
1293 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)&resourceValueData->List[0], &valueDataLen);
1294 if (lRet != ERROR_SUCCESS)
1295 {
1296 error(hwnd, IDS_BAD_VALUE, valueName);
1297 goto done;
1298 }
1299
1300 resourceValueData->Count = 1;
1301 fullResourceIndex = 0;
1302 }
1303 else
1304 {
1305 resourceValueData = NULL;
1306 }
1307
1308 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE), hwnd, modify_resource_dlgproc) == IDOK)
1309 {
1310 }
1311 }
1312 else if ((EditBin != FALSE) || (type == REG_NONE) || (type == REG_BINARY))
1313 {
1314 if(valueDataLen > 0)
1315 {
1316 if(!(binValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen + 1)))
1317 {
1318 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1319 goto done;
1320 }
1321
1322 /* Use the unicode version, so editing strings in binary mode is correct */
1323 lRet = RegQueryValueExW(hKey, valueName,
1324 0, 0, (LPBYTE)binValueData, &valueDataLen);
1325 if (lRet != ERROR_SUCCESS)
1326 {
1327 HeapFree(GetProcessHeap(), 0, binValueData);
1328 error(hwnd, IDS_BAD_VALUE, valueName);
1329 goto done;
1330 }
1331 }
1332 else
1333 {
1334 binValueData = NULL;
1335 }
1336
1337 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_BIN_DATA), hwnd, modify_binary_dlgproc) == IDOK)
1338 {
1339 /* Use the unicode version, so editing strings in binary mode is correct */
1340 lRet = RegSetValueExW(hKey, valueName,
1341 0, type, (LPBYTE)binValueData, valueDataLen);
1342 if (lRet == ERROR_SUCCESS)
1343 result = TRUE;
1344 }
1345 if(binValueData != NULL)
1346 HeapFree(GetProcessHeap(), 0, binValueData);
1347 }
1348 else
1349 {
1350 error(hwnd, IDS_UNSUPPORTED_TYPE, type);
1351 }
1352
1353 done:
1354 if (resourceValueData)
1355 HeapFree(GetProcessHeap(), 0, resourceValueData);
1356 resourceValueData = NULL;
1357
1358 if (stringValueData)
1359 HeapFree(GetProcessHeap(), 0, stringValueData);
1360 stringValueData = NULL;
1361
1362 return result;
1363 }
1364
1365 static LONG CopyKey(HKEY hDestKey, LPCWSTR lpDestSubKey, HKEY hSrcKey, LPCWSTR lpSrcSubKey)
1366 {
1367 LONG lResult;
1368 DWORD dwDisposition;
1369 HKEY hDestSubKey = NULL;
1370 HKEY hSrcSubKey = NULL;
1371 DWORD dwIndex, dwType, cbName, cbData;
1372 WCHAR szSubKey[256];
1373 WCHAR szValueName[256];
1374 BYTE szValueData[512];
1375
1376 FILETIME ft;
1377
1378 /* open the source subkey, if specified */
1379 if (lpSrcSubKey)
1380 {
1381 lResult = RegOpenKeyExW(hSrcKey, lpSrcSubKey, 0, KEY_ALL_ACCESS, &hSrcSubKey);
1382 if (lResult)
1383 goto done;
1384 hSrcKey = hSrcSubKey;
1385 }
1386
1387 /* create the destination subkey */
1388 lResult = RegCreateKeyExW(hDestKey, lpDestSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
1389 &hDestSubKey, &dwDisposition);
1390 if (lResult)
1391 goto done;
1392
1393 /* copy all subkeys */
1394 dwIndex = 0;
1395 do
1396 {
1397 cbName = sizeof(szSubKey) / sizeof(szSubKey[0]);
1398 lResult = RegEnumKeyExW(hSrcKey, dwIndex++, szSubKey, &cbName, NULL, NULL, NULL, &ft);
1399 if (lResult == ERROR_SUCCESS)
1400 {
1401 lResult = CopyKey(hDestSubKey, szSubKey, hSrcKey, szSubKey);
1402 if (lResult)
1403 goto done;
1404 }
1405 }
1406 while(lResult == ERROR_SUCCESS);
1407
1408 /* copy all subvalues */
1409 dwIndex = 0;
1410 do
1411 {
1412 cbName = sizeof(szValueName) / sizeof(szValueName[0]);
1413 cbData = sizeof(szValueData) / sizeof(szValueData[0]);
1414 lResult = RegEnumValueW(hSrcKey, dwIndex++, szValueName, &cbName, NULL, &dwType, szValueData, &cbData);
1415 if (lResult == ERROR_SUCCESS)
1416 {
1417 lResult = RegSetValueExW(hDestSubKey, szValueName, 0, dwType, szValueData, cbData);
1418 if (lResult)
1419 goto done;
1420 }
1421 }
1422 while(lResult == ERROR_SUCCESS);
1423
1424 lResult = ERROR_SUCCESS;
1425
1426 done:
1427 if (hSrcSubKey)
1428 RegCloseKey(hSrcSubKey);
1429 if (hDestSubKey)
1430 RegCloseKey(hDestSubKey);
1431 if (lResult != ERROR_SUCCESS)
1432 SHDeleteKey(hDestKey, lpDestSubKey);
1433 return lResult;
1434 }
1435
1436 static LONG MoveKey(HKEY hDestKey, LPCWSTR lpDestSubKey, HKEY hSrcKey, LPCWSTR lpSrcSubKey)
1437 {
1438 LONG lResult;
1439
1440 if (!lpSrcSubKey)
1441 return ERROR_INVALID_FUNCTION;
1442
1443 if (_wcsicmp(lpDestSubKey, lpSrcSubKey) == 0)
1444 {
1445 /* Destination name equals source name */
1446 return ERROR_SUCCESS;
1447 }
1448
1449 lResult = CopyKey(hDestKey, lpDestSubKey, hSrcKey, lpSrcSubKey);
1450 if (lResult == ERROR_SUCCESS)
1451 SHDeleteKey(hSrcKey, lpSrcSubKey);
1452
1453 return lResult;
1454 }
1455
1456 BOOL DeleteKey(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath)
1457 {
1458 WCHAR msg[128], caption[128];
1459 BOOL result = FALSE;
1460 LONG lRet;
1461 HKEY hKey;
1462
1463 lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_READ|KEY_SET_VALUE, &hKey);
1464 if (lRet != ERROR_SUCCESS)
1465 {
1466 error_code_messagebox(hwnd, lRet);
1467 return FALSE;
1468 }
1469
1470 LoadStringW(hInst, IDS_QUERY_DELETE_KEY_CONFIRM, caption, COUNT_OF(caption));
1471 LoadStringW(hInst, IDS_QUERY_DELETE_KEY_ONE, msg, COUNT_OF(msg));
1472
1473 if (MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) != IDYES)
1474 goto done;
1475
1476 lRet = SHDeleteKey(hKeyRoot, keyPath);
1477 if (lRet != ERROR_SUCCESS)
1478 {
1479 error(hwnd, IDS_BAD_KEY, keyPath);
1480 goto done;
1481 }
1482 result = TRUE;
1483
1484 done:
1485 RegCloseKey(hKey);
1486 return result;
1487 }
1488
1489 LONG RenameKey(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewName)
1490 {
1491 LPCWSTR s;
1492 LPWSTR lpNewSubKey = NULL;
1493 LONG Ret = 0;
1494
1495 if (!lpSubKey)
1496 return Ret;
1497
1498 s = wcsrchr(lpSubKey, L'\\');
1499 if (s)
1500 {
1501 s++;
1502 lpNewSubKey = (LPWSTR) HeapAlloc(GetProcessHeap(), 0, (s - lpSubKey + wcslen(lpNewName) + 1) * sizeof(WCHAR));
1503 if (lpNewSubKey != NULL)
1504 {
1505 memcpy(lpNewSubKey, lpSubKey, (s - lpSubKey) * sizeof(WCHAR));
1506 wcscpy(lpNewSubKey + (s - lpSubKey), lpNewName);
1507 lpNewName = lpNewSubKey;
1508 }
1509 else
1510 return ERROR_NOT_ENOUGH_MEMORY;
1511 }
1512
1513 Ret = MoveKey(hKey, lpNewName, hKey, lpSubKey);
1514
1515 if (lpNewSubKey)
1516 {
1517 HeapFree(GetProcessHeap(), 0, lpNewSubKey);
1518 }
1519 return Ret;
1520 }
1521
1522 LONG RenameValue(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpDestValue, LPCWSTR lpSrcValue)
1523 {
1524 LONG lResult;
1525 HKEY hSubKey = NULL;
1526 DWORD dwType, cbData;
1527 BYTE data[512];
1528
1529 if (lpSubKey)
1530 {
1531 lResult = RegOpenKeyW(hKey, lpSubKey, &hSubKey);
1532 if (lResult != ERROR_SUCCESS)
1533 goto done;
1534 hKey = hSubKey;
1535 }
1536
1537 cbData = sizeof(data);
1538 lResult = RegQueryValueExW(hKey, lpSrcValue, NULL, &dwType, data, &cbData);
1539 if (lResult != ERROR_SUCCESS)
1540 goto done;
1541
1542 lResult = RegSetValueExW(hKey, lpDestValue, 0, dwType, data, cbData);
1543 if (lResult != ERROR_SUCCESS)
1544 goto done;
1545
1546 RegDeleteValue(hKey, lpSrcValue);
1547
1548 done:
1549 if (hSubKey)
1550 RegCloseKey(hSubKey);
1551 return lResult;
1552 }
1553
1554 LONG QueryStringValue(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR pszBuffer, DWORD dwBufferLen)
1555 {
1556 LONG lResult;
1557 HKEY hSubKey = NULL;
1558 DWORD cbData, dwType;
1559
1560 if (lpSubKey)
1561 {
1562 lResult = RegOpenKeyW(hKey, lpSubKey, &hSubKey);
1563 if (lResult != ERROR_SUCCESS)
1564 goto done;
1565 hKey = hSubKey;
1566 }
1567
1568 cbData = (dwBufferLen - 1) * sizeof(*pszBuffer);
1569 lResult = RegQueryValueExW(hKey, lpValueName, NULL, &dwType, (LPBYTE) pszBuffer, &cbData);
1570 if (lResult != ERROR_SUCCESS)
1571 goto done;
1572 if (dwType != REG_SZ)
1573 {
1574 lResult = -1;
1575 goto done;
1576 }
1577
1578 pszBuffer[cbData / sizeof(*pszBuffer)] = L'\0';
1579
1580 done:
1581 if (lResult != ERROR_SUCCESS)
1582 pszBuffer[0] = L'\0';
1583 if (hSubKey)
1584 RegCloseKey(hSubKey);
1585 return lResult;
1586 }
1587
1588 BOOL GetKeyName(LPWSTR pszDest, size_t iDestLength, HKEY hRootKey, LPCWSTR lpSubKey)
1589 {
1590 LPCWSTR pszRootKey;
1591
1592 if (hRootKey == HKEY_CLASSES_ROOT)
1593 pszRootKey = L"HKEY_CLASSES_ROOT";
1594 else if (hRootKey == HKEY_CURRENT_USER)
1595 pszRootKey = L"HKEY_CURRENT_USER";
1596 else if (hRootKey == HKEY_LOCAL_MACHINE)
1597 pszRootKey = L"HKEY_LOCAL_MACHINE";
1598 else if (hRootKey == HKEY_USERS)
1599 pszRootKey = L"HKEY_USERS";
1600 else if (hRootKey == HKEY_CURRENT_CONFIG)
1601 pszRootKey = L"HKEY_CURRENT_CONFIG";
1602 else if (hRootKey == HKEY_DYN_DATA)
1603 pszRootKey = L"HKEY_DYN_DATA";
1604 else
1605 return FALSE;
1606
1607 if (lpSubKey[0])
1608 _snwprintf(pszDest, iDestLength, L"%s\\%s", pszRootKey, lpSubKey);
1609 else
1610 _snwprintf(pszDest, iDestLength, L"%s", pszRootKey);
1611 return TRUE;
1612 }