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