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