1 /*
2 * Registry editing UI functions.
3 *
4 * Copyright (C) 2003 Dimitrie O. Paun
5 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
6 */
7
8 #include "regedit.h"
9
10 #define NTOS_MODE_USER
11 #include <ndk/cmtypes.h>
12
13 typedef enum _EDIT_MODE
14 {
15 EDIT_MODE_DEC,
16 EDIT_MODE_HEX
17 } EDIT_MODE;
18
19
20 static const WCHAR* editValueName;
21 static WCHAR* stringValueData;
22 static PVOID binValueData;
23 static DWORD dwordValueData;
24 static PCM_RESOURCE_LIST resourceValueData;
25 static INT fullResourceIndex = -1;
26 static DWORD valueDataLen;
27 static PIO_RESOURCE_REQUIREMENTS_LIST requirementsValueData;
28 static INT requirementsIndex = -1;
29 static EDIT_MODE dwordEditMode = EDIT_MODE_HEX;
30
error(HWND hwnd,INT resId,...)31 void error(HWND hwnd, INT resId, ...)
32 {
33 va_list ap;
34 WCHAR title[256];
35 WCHAR errfmt[1024];
36 WCHAR errstr[1024];
37 HINSTANCE hInstance;
38
39 hInstance = GetModuleHandle(0);
40
41 if (!LoadStringW(hInstance, IDS_ERROR, title, ARRAY_SIZE(title)))
42 StringCbCopyW(title, sizeof(title), L"Error");
43
44 if (!LoadStringW(hInstance, resId, errfmt, ARRAY_SIZE(errfmt)))
45 StringCbCopyW(errfmt, sizeof(errfmt), L"Unknown error string!");
46
47 va_start(ap, resId);
48 _vsnwprintf(errstr, ARRAY_SIZE(errstr), errfmt, ap);
49 va_end(ap);
50
51 MessageBoxW(hwnd, errstr, title, MB_OK | MB_ICONERROR);
52 }
53
error_code_messagebox(HWND hwnd,DWORD error_code)54 static void error_code_messagebox(HWND hwnd, DWORD error_code)
55 {
56 WCHAR title[256];
57 if (!LoadStringW(hInst, IDS_ERROR, title, ARRAY_SIZE(title)))
58 StringCbCopyW(title, sizeof(title), L"Error");
59 ErrorMessageBox(hwnd, title, error_code);
60 }
61
warning(HWND hwnd,INT resId,...)62 void warning(HWND hwnd, INT resId, ...)
63 {
64 va_list ap;
65 WCHAR title[256];
66 WCHAR errfmt[1024];
67 WCHAR errstr[1024];
68 HINSTANCE hInstance;
69
70 hInstance = GetModuleHandle(0);
71
72 if (!LoadStringW(hInstance, IDS_WARNING, title, ARRAY_SIZE(title)))
73 StringCbCopyW(title, sizeof(title), L"Warning");
74
75 if (!LoadStringW(hInstance, resId, errfmt, ARRAY_SIZE(errfmt)))
76 StringCbCopyW(errfmt, sizeof(errfmt), L"Unknown error string!");
77
78 va_start(ap, resId);
79 StringCbVPrintfW(errstr, sizeof(errstr), errfmt, ap);
80 va_end(ap);
81
82 MessageBoxW(hwnd, errstr, title, MB_OK | MB_ICONSTOP);
83 }
84
modify_string_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)85 INT_PTR CALLBACK modify_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
86 {
87 WCHAR* valueData;
88 HWND hwndValue;
89 int len;
90
91 UNREFERENCED_PARAMETER(lParam);
92
93 switch(uMsg)
94 {
95 case WM_INITDIALOG:
96 if (editValueName && wcscmp(editValueName, L""))
97 {
98 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
99 }
100 else
101 {
102 WCHAR buffer[255];
103 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, ARRAY_SIZE(buffer));
104 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
105 }
106 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, stringValueData);
107 SendMessage(GetDlgItem(hwndDlg, IDC_VALUE_DATA), EM_SETSEL, 0, -1);
108 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
109 return FALSE;
110 case WM_COMMAND:
111 switch (LOWORD(wParam))
112 {
113 case IDOK:
114 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
115 {
116 if ((len = GetWindowTextLength(hwndValue)))
117 {
118 if (stringValueData)
119 {
120 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(WCHAR))))
121 {
122 stringValueData = valueData;
123 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
124 *stringValueData = 0;
125 }
126 }
127 else
128 {
129 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
130 {
131 stringValueData = valueData;
132 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
133 *stringValueData = 0;
134 }
135 }
136 }
137 else
138 {
139 if (stringValueData)
140 *stringValueData = 0;
141 }
142 }
143 EndDialog(hwndDlg, IDOK);
144 break;
145 case IDCANCEL:
146 EndDialog(hwndDlg, IDCANCEL);
147 return TRUE;
148 }
149 }
150 return FALSE;
151 }
152
modify_multi_string_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)153 INT_PTR CALLBACK modify_multi_string_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
154 {
155 WCHAR* valueData;
156 HWND hwndValue;
157 int len;
158
159 UNREFERENCED_PARAMETER(lParam);
160
161 switch(uMsg)
162 {
163 case WM_INITDIALOG:
164 if (editValueName && wcscmp(editValueName, L""))
165 {
166 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
167 }
168 else
169 {
170 WCHAR buffer[255];
171 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, ARRAY_SIZE(buffer));
172 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
173 }
174 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, stringValueData);
175 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
176 return FALSE;
177 case WM_COMMAND:
178 switch (LOWORD(wParam))
179 {
180 case IDOK:
181 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
182 {
183 if ((len = GetWindowTextLength(hwndValue)))
184 {
185 if (stringValueData)
186 {
187 if ((valueData = HeapReAlloc(GetProcessHeap(), 0, stringValueData, (len + 1) * sizeof(WCHAR))))
188 {
189 stringValueData = valueData;
190 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
191 *stringValueData = 0;
192 }
193 }
194 else
195 {
196 if ((valueData = HeapAlloc(GetProcessHeap(), 0, (len + 1) * sizeof(WCHAR))))
197 {
198 stringValueData = valueData;
199 if (!GetWindowTextW(hwndValue, stringValueData, len + 1))
200 *stringValueData = 0;
201 }
202 }
203 }
204 else
205 {
206 if (stringValueData)
207 *stringValueData = 0;
208 }
209 }
210 EndDialog(hwndDlg, IDOK);
211 break;
212 case IDCANCEL:
213 EndDialog(hwndDlg, IDCANCEL);
214 return TRUE;
215 }
216 }
217 return FALSE;
218 }
219
DwordEditSubclassProc(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam)220 LRESULT CALLBACK DwordEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
221 {
222 WNDPROC oldwndproc;
223
224 oldwndproc = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
225
226 switch (uMsg)
227 {
228 case WM_CHAR:
229 if (dwordEditMode == EDIT_MODE_DEC)
230 {
231 if (isdigit((int)wParam & 0xff) || iscntrl((int)wParam & 0xff))
232 {
233 break;
234 }
235 else
236 {
237 return 0;
238 }
239 }
240 else if (dwordEditMode == EDIT_MODE_HEX)
241 {
242 if (isxdigit((int)wParam & 0xff) || iscntrl((int)wParam & 0xff))
243 {
244 break;
245 }
246 else
247 {
248 return 0;
249 }
250 }
251 else
252 {
253 break;
254 }
255 }
256
257 return CallWindowProcW(oldwndproc, hwnd, uMsg, wParam, lParam);
258 }
259
modify_dword_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)260 INT_PTR CALLBACK modify_dword_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
261 {
262 WNDPROC oldproc;
263 HWND hwndValue;
264 WCHAR ValueString[32];
265 LPWSTR Remainder;
266 DWORD Base;
267 DWORD Value = 0;
268
269 UNREFERENCED_PARAMETER(lParam);
270
271 switch(uMsg)
272 {
273 case WM_INITDIALOG:
274 dwordEditMode = EDIT_MODE_HEX;
275
276 /* subclass the edit control */
277 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
278 oldproc = (WNDPROC)GetWindowLongPtr(hwndValue, GWLP_WNDPROC);
279 SetWindowLongPtr(hwndValue, GWLP_USERDATA, (DWORD_PTR)oldproc);
280 SetWindowLongPtr(hwndValue, GWLP_WNDPROC, (DWORD_PTR)DwordEditSubclassProc);
281
282 if (editValueName && wcscmp(editValueName, L""))
283 {
284 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
285 }
286 else
287 {
288 WCHAR buffer[255];
289 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, ARRAY_SIZE(buffer));
290 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
291 }
292 CheckRadioButton (hwndDlg, IDC_FORMAT_HEX, IDC_FORMAT_DEC, IDC_FORMAT_HEX);
293 StringCbPrintfW(ValueString, sizeof(ValueString), L"%lx", dwordValueData);
294 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, ValueString);
295 SendMessage(GetDlgItem(hwndDlg, IDC_VALUE_DATA), EM_SETSEL, 0, -1);
296 SetFocus(GetDlgItem(hwndDlg, IDC_VALUE_DATA));
297 return FALSE;
298
299 case WM_COMMAND:
300 switch (LOWORD(wParam))
301 {
302 case IDC_FORMAT_HEX:
303 if (HIWORD(wParam) == BN_CLICKED && dwordEditMode == EDIT_MODE_DEC)
304 {
305 dwordEditMode = EDIT_MODE_HEX;
306 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
307 {
308 if (GetWindowTextLength(hwndValue))
309 {
310 if (GetWindowTextW(hwndValue, ValueString, 32))
311 {
312 Value = wcstoul (ValueString, &Remainder, 10);
313 }
314 }
315 }
316 StringCbPrintfW(ValueString, sizeof(ValueString), L"%lx", Value);
317 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, ValueString);
318 return TRUE;
319 }
320 break;
321
322 case IDC_FORMAT_DEC:
323 if (HIWORD(wParam) == BN_CLICKED && dwordEditMode == EDIT_MODE_HEX)
324 {
325 dwordEditMode = EDIT_MODE_DEC;
326 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
327 {
328 if (GetWindowTextLength(hwndValue))
329 {
330 if (GetWindowTextW(hwndValue, ValueString, 32))
331 {
332 Value = wcstoul (ValueString, &Remainder, 16);
333 }
334 }
335 }
336 StringCbPrintfW(ValueString, sizeof(ValueString), L"%lu", Value);
337 SetDlgItemTextW(hwndDlg, IDC_VALUE_DATA, ValueString);
338 return TRUE;
339 }
340 break;
341
342 case IDOK:
343 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
344 {
345 if (GetWindowTextLength(hwndValue))
346 {
347 if (!GetWindowTextW(hwndValue, ValueString, 32))
348 {
349 EndDialog(hwndDlg, IDCANCEL);
350 return TRUE;
351 }
352
353 Base = (dwordEditMode == EDIT_MODE_HEX) ? 16 : 10;
354 dwordValueData = wcstoul (ValueString, &Remainder, Base);
355 }
356 else
357 {
358 EndDialog(hwndDlg, IDCANCEL);
359 return TRUE;
360 }
361 }
362 EndDialog(hwndDlg, IDOK);
363 return TRUE;
364
365 case IDCANCEL:
366 EndDialog(hwndDlg, IDCANCEL);
367 return TRUE;
368 }
369 }
370 return FALSE;
371 }
372
modify_binary_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)373 INT_PTR CALLBACK modify_binary_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
374 {
375 HWND hwndValue;
376 UINT len;
377
378 UNREFERENCED_PARAMETER(lParam);
379
380 switch(uMsg)
381 {
382 case WM_INITDIALOG:
383 if (editValueName && wcscmp(editValueName, L""))
384 {
385 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, editValueName);
386 }
387 else
388 {
389 WCHAR buffer[255];
390 LoadStringW(hInst, IDS_DEFAULT_VALUE_NAME, buffer, ARRAY_SIZE(buffer));
391 SetDlgItemTextW(hwndDlg, IDC_VALUE_NAME, buffer);
392 }
393 hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA);
394 HexEdit_LoadBuffer(hwndValue, binValueData, valueDataLen);
395 /* reset the hex edit control's font */
396 SendMessageW(hwndValue, WM_SETFONT, 0, 0);
397 SetFocus(hwndValue);
398 return FALSE;
399 case WM_COMMAND:
400 switch (LOWORD(wParam))
401 {
402 case IDOK:
403 if ((hwndValue = GetDlgItem(hwndDlg, IDC_VALUE_DATA)))
404 {
405 len = (UINT)HexEdit_GetBufferSize(hwndValue);
406 if (len > 0 && binValueData)
407 binValueData = HeapReAlloc(GetProcessHeap(), 0, binValueData, len);
408 else
409 binValueData = HeapAlloc(GetProcessHeap(), 0, len + 1);
410 HexEdit_CopyBuffer(hwndValue, binValueData, len);
411 valueDataLen = len;
412 }
413 EndDialog(hwndDlg, IDOK);
414 break;
415 case IDCANCEL:
416 EndDialog(hwndDlg, IDCANCEL);
417 return TRUE;
418 }
419 }
420 return FALSE;
421 }
422
CreateResourceColumns(HWND hwnd)423 static BOOL CreateResourceColumns(HWND hwnd)
424 {
425 WCHAR szText[80];
426 RECT rc;
427 LVCOLUMN lvC;
428 HWND hwndLV;
429 INT width;
430
431 /* Create columns. */
432 lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
433 lvC.pszText = szText;
434 lvC.fmt = LVCFMT_LEFT;
435
436 hwndLV = GetDlgItem(hwnd, IDC_DMA_LIST);
437 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
438 GetClientRect(hwndLV, &rc);
439
440 /* Load the column labels from the resource file. */
441 lvC.iSubItem = 0;
442 lvC.cx = (rc.right - rc.left) / 2;
443 LoadStringW(hInst, IDS_DMA_CHANNEL, szText, ARRAY_SIZE(szText));
444 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
445 return FALSE;
446
447 lvC.iSubItem = 1;
448 lvC.cx = (rc.right - rc.left) - lvC.cx;
449 LoadStringW(hInst, IDS_DMA_PORT, szText, ARRAY_SIZE(szText));
450 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
451 return FALSE;
452
453
454 /* Interrupt list */
455 hwndLV = GetDlgItem(hwnd, IDC_IRQ_LIST);
456 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
457 GetClientRect(hwndLV, &rc);
458 width = (rc.right - rc.left) / 4;
459
460 /* Load the column labels from the resource file. */
461 lvC.iSubItem = 0;
462 lvC.cx = width;
463 LoadStringW(hInst, IDS_INTERRUPT_VECTOR, szText, ARRAY_SIZE(szText));
464 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
465 return FALSE;
466
467 lvC.iSubItem = 1;
468 LoadStringW(hInst, IDS_INTERRUPT_LEVEL, szText, ARRAY_SIZE(szText));
469 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
470 return FALSE;
471
472 lvC.iSubItem = 2;
473 LoadStringW(hInst, IDS_INTERRUPT_AFFINITY, szText, ARRAY_SIZE(szText));
474 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
475 return FALSE;
476
477 lvC.iSubItem = 3;
478 lvC.cx = (rc.right - rc.left) - 3 * width;
479 LoadStringW(hInst, IDS_INTERRUPT_TYPE, szText, ARRAY_SIZE(szText));
480 if (ListView_InsertColumn(hwndLV, 3, &lvC) == -1)
481 return FALSE;
482
483
484 /* Memory list */
485 hwndLV = GetDlgItem(hwnd, IDC_MEMORY_LIST);
486 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
487 GetClientRect(hwndLV, &rc);
488 width = (rc.right - rc.left) / 3;
489
490 /* Load the column labels from the resource file. */
491 lvC.iSubItem = 0;
492 lvC.cx = width;
493 LoadStringW(hInst, IDS_MEMORY_ADDRESS, szText, ARRAY_SIZE(szText));
494 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
495 return FALSE;
496
497 lvC.iSubItem = 1;
498 LoadStringW(hInst, IDS_MEMORY_LENGTH, szText, ARRAY_SIZE(szText));
499 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
500 return FALSE;
501
502 lvC.iSubItem = 2;
503 lvC.cx = (rc.right - rc.left) - 2 * width;
504 LoadStringW(hInst, IDS_MEMORY_ACCESS, szText, ARRAY_SIZE(szText));
505 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
506 return FALSE;
507
508
509 /* Port list */
510 hwndLV = GetDlgItem(hwnd, IDC_PORT_LIST);
511 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
512 GetClientRect(hwndLV, &rc);
513 width = (rc.right - rc.left) / 3;
514
515 /* Load the column labels from the resource file. */
516 lvC.iSubItem = 0;
517 lvC.cx = width;
518 LoadStringW(hInst, IDS_PORT_ADDRESS, szText, ARRAY_SIZE(szText));
519 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
520 return FALSE;
521
522 lvC.iSubItem = 1;
523 LoadStringW(hInst, IDS_PORT_LENGTH, szText, ARRAY_SIZE(szText));
524 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
525 return FALSE;
526
527 lvC.iSubItem = 2;
528 lvC.cx = (rc.right - rc.left) - 2 * width;
529 LoadStringW(hInst, IDS_PORT_ACCESS, szText, ARRAY_SIZE(szText));
530 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
531 return FALSE;
532
533 /* Device specific list */
534 hwndLV = GetDlgItem(hwnd, IDC_DEVICE_LIST);
535 ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
536 GetClientRect(hwndLV, &rc);
537 width = (rc.right - rc.left) / 3;
538
539 /* Load the column labels from the resource file. */
540 lvC.iSubItem = 0;
541 lvC.cx = width;
542 LoadStringW(hInst, IDS_SPECIFIC_RESERVED1, szText, ARRAY_SIZE(szText));
543 if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
544 return FALSE;
545
546 lvC.iSubItem = 1;
547 LoadStringW(hInst, IDS_SPECIFIC_RESERVED2, szText, ARRAY_SIZE(szText));
548 if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
549 return FALSE;
550
551 lvC.iSubItem = 2;
552 lvC.cx = (rc.right - rc.left) - 2 * width;
553 LoadStringW(hInst, IDS_SPECIFIC_DATASIZE, szText, ARRAY_SIZE(szText));
554 if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
555 return FALSE;
556
557 return TRUE;
558 }
559
560 static VOID
GetInterfaceType(INTERFACE_TYPE InterfaceType,LPWSTR pBuffer,DWORD dwLength)561 GetInterfaceType(INTERFACE_TYPE InterfaceType,
562 LPWSTR pBuffer,
563 DWORD dwLength)
564 {
565 // LPWSTR lpInterfaceType;
566
567 switch (InterfaceType)
568 {
569 case InterfaceTypeUndefined:
570 LoadStringW(hInst, IDS_BUS_UNDEFINED, pBuffer, dwLength);
571 // lpInterfaceType = L"Undefined";
572 break;
573 case Internal:
574 LoadStringW(hInst, IDS_BUS_INTERNAL, pBuffer, dwLength);
575 // lpInterfaceType = L"Internal";
576 break;
577 case Isa:
578 LoadStringW(hInst, IDS_BUS_ISA, pBuffer, dwLength);
579 // lpInterfaceType = L"Isa";
580 break;
581 case Eisa:
582 LoadStringW(hInst, IDS_BUS_EISA, pBuffer, dwLength);
583 // lpInterfaceType = L"Eisa";
584 break;
585 case MicroChannel:
586 LoadStringW(hInst, IDS_BUS_MICROCHANNEL, pBuffer, dwLength);
587 // lpInterfaceType = L"MicroChannel";
588 break;
589 case TurboChannel:
590 LoadStringW(hInst, IDS_BUS_TURBOCHANNEL, pBuffer, dwLength);
591 // lpInterfaceType = L"TurboChannel";
592 break;
593 case PCIBus:
594 LoadStringW(hInst, IDS_BUS_PCIBUS, pBuffer, dwLength);
595 // lpInterfaceType = L"PCIBus";
596 break;
597 case VMEBus:
598 LoadStringW(hInst, IDS_BUS_VMEBUS, pBuffer, dwLength);
599 // lpInterfaceType = L"VMEBus";
600 break;
601 case NuBus:
602 LoadStringW(hInst, IDS_BUS_NUBUS, pBuffer, dwLength);
603 // lpInterfaceType = L"NuBus";
604 break;
605 case PCMCIABus:
606 LoadStringW(hInst, IDS_BUS_PCMCIABUS, pBuffer, dwLength);
607 // lpInterfaceType = L"PCMCIABus";
608 break;
609 case CBus:
610 LoadStringW(hInst, IDS_BUS_CBUS, pBuffer, dwLength);
611 // lpInterfaceType = L"CBus";
612 break;
613 case MPIBus:
614 LoadStringW(hInst, IDS_BUS_MPIBUS, pBuffer, dwLength);
615 // lpInterfaceType = L"MPIBus";
616 break;
617 case MPSABus:
618 LoadStringW(hInst, IDS_BUS_MPSABUS, pBuffer, dwLength);
619 // lpInterfaceType = L"MPSABus";
620 break;
621 case ProcessorInternal:
622 LoadStringW(hInst, IDS_BUS_PROCESSORINTERNAL, pBuffer, dwLength);
623 // lpInterfaceType = L"ProcessorInternal";
624 break;
625 case InternalPowerBus:
626 LoadStringW(hInst, IDS_BUS_INTERNALPOWERBUS, pBuffer, dwLength);
627 // lpInterfaceType = L"InternalPowerBus";
628 break;
629 case PNPISABus:
630 LoadStringW(hInst, IDS_BUS_PNPISABUS, pBuffer, dwLength);
631 // lpInterfaceType = L"PNPISABus";
632 break;
633 case PNPBus:
634 LoadStringW(hInst, IDS_BUS_PNPBUS, pBuffer, dwLength);
635 // lpInterfaceType = L"PNPBus";
636 break;
637 default:
638 LoadStringW(hInst, IDS_BUS_UNKNOWNTYPE, pBuffer, dwLength);
639 // lpInterfaceType = L"Unknown interface type";
640 break;
641 }
642
643 // wcscpy(pBuffer, lpInterfaceType);
644 }
645
646 static VOID
ParseResources(HWND hwnd)647 ParseResources(HWND hwnd)
648 {
649 PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor;
650 PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
651 PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
652 ULONG i;
653 HWND hwndLV;
654
655 WCHAR buffer[80];
656 LVITEMW item;
657 INT iItem;
658
659 pFullDescriptor = &resourceValueData->List[0];
660 for (i = 0; i < fullResourceIndex; i++)
661 {
662 pFullDescriptor = (PVOID)(pFullDescriptor->PartialResourceList.PartialDescriptors +
663 pFullDescriptor->PartialResourceList.Count);
664 }
665 pPartialResourceList = &pFullDescriptor->PartialResourceList;
666
667 /* Interface type */
668 GetInterfaceType(pFullDescriptor->InterfaceType, buffer, 80);
669 SetDlgItemTextW(hwnd, IDC_INTERFACETYPE, buffer);
670
671 /* Busnumber */
672 SetDlgItemInt(hwnd, IDC_BUSNUMBER, (UINT)pFullDescriptor->BusNumber, TRUE);
673
674 /* Version */
675 SetDlgItemInt(hwnd, IDC_VERSION, (UINT)pPartialResourceList->Version, FALSE);
676
677 /* Revision */
678 SetDlgItemInt(hwnd, IDC_REVISION, (UINT)pPartialResourceList->Revision, FALSE);
679
680 for (i = 0; i < pPartialResourceList->Count; i++)
681 {
682 pDescriptor = &pPartialResourceList->PartialDescriptors[i];
683
684 switch (pDescriptor->Type)
685 {
686 case CmResourceTypePort:
687 hwndLV = GetDlgItem(hwnd, IDC_PORT_LIST);
688
689 #ifdef _M_AMD64
690 wsprintf(buffer, L"0x%016I64x", pDescriptor->u.Port.Start.QuadPart);
691 #else
692 wsprintf(buffer, L"0x%08lx", pDescriptor->u.Port.Start.u.LowPart);
693 #endif
694
695 item.mask = LVIF_TEXT | LVIF_PARAM;
696 item.iItem = 1000;
697 item.iSubItem = 0;
698 item.state = 0;
699 item.stateMask = 0;
700 item.pszText = buffer;
701 item.cchTextMax = (int)wcslen(item.pszText);
702 item.lParam = (LPARAM)pDescriptor;
703
704 iItem = ListView_InsertItem(hwndLV, &item);
705 if (iItem != -1)
706 {
707 wsprintf(buffer, L"0x%lx", pDescriptor->u.Port.Length);
708 ListView_SetItemText(hwndLV, iItem, 1, buffer);
709
710 if (pDescriptor->Flags & CM_RESOURCE_PORT_IO)
711 LoadStringW(hInst, IDS_PORT_PORT_IO, buffer, ARRAY_SIZE(buffer));
712 else
713 LoadStringW(hInst, IDS_PORT_MEMORY_IO, buffer, ARRAY_SIZE(buffer));
714 ListView_SetItemText(hwndLV, iItem, 2, buffer);
715 }
716 break;
717
718 case CmResourceTypeInterrupt:
719 hwndLV = GetDlgItem(hwnd, IDC_IRQ_LIST);
720
721 wsprintf(buffer, L"%lu", pDescriptor->u.Interrupt.Vector);
722
723 item.mask = LVIF_TEXT | LVIF_PARAM;
724 item.iItem = 1000;
725 item.iSubItem = 0;
726 item.state = 0;
727 item.stateMask = 0;
728 item.pszText = buffer;
729 item.cchTextMax = (int)wcslen(item.pszText);
730 item.lParam = (LPARAM)pDescriptor;
731
732 iItem = ListView_InsertItem(hwndLV, &item);
733 if (iItem != -1)
734 {
735 wsprintf(buffer, L"%lu", pDescriptor->u.Interrupt.Level);
736 ListView_SetItemText(hwndLV, iItem, 1, buffer);
737
738 wsprintf(buffer, L"0x%08lx", pDescriptor->u.Interrupt.Affinity);
739 ListView_SetItemText(hwndLV, iItem, 2, buffer);
740
741 if (pDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
742 LoadStringW(hInst, IDS_INTERRUPT_EDGE_SENSITIVE, buffer, ARRAY_SIZE(buffer));
743 else
744 LoadStringW(hInst, IDS_INTERRUPT_LEVEL_SENSITIVE, buffer, ARRAY_SIZE(buffer));
745
746 ListView_SetItemText(hwndLV, iItem, 3, buffer);
747 }
748 break;
749
750 case CmResourceTypeMemory:
751 hwndLV = GetDlgItem(hwnd, IDC_MEMORY_LIST);
752
753 #ifdef _M_AMD64
754 wsprintf(buffer, L"0x%016I64x", pDescriptor->u.Memory.Start.QuadPart);
755 #else
756 wsprintf(buffer, L"0x%08lx", pDescriptor->u.Memory.Start.u.LowPart);
757 #endif
758
759 item.mask = LVIF_TEXT | LVIF_PARAM;
760 item.iItem = 1000;
761 item.iSubItem = 0;
762 item.state = 0;
763 item.stateMask = 0;
764 item.pszText = buffer;
765 item.cchTextMax = (int)wcslen(item.pszText);
766 item.lParam = (LPARAM)pDescriptor;
767
768 iItem = ListView_InsertItem(hwndLV, &item);
769 if (iItem != -1)
770 {
771 wsprintf(buffer, L"0x%lx", pDescriptor->u.Memory.Length);
772 ListView_SetItemText(hwndLV, iItem, 1, buffer);
773
774 switch (pDescriptor->Flags & (CM_RESOURCE_MEMORY_READ_ONLY | CM_RESOURCE_MEMORY_WRITE_ONLY))
775 {
776 case CM_RESOURCE_MEMORY_READ_ONLY:
777 LoadStringW(hInst, IDS_MEMORY_READ_ONLY, buffer, ARRAY_SIZE(buffer));
778 break;
779
780 case CM_RESOURCE_MEMORY_WRITE_ONLY:
781 LoadStringW(hInst, IDS_MEMORY_WRITE_ONLY, buffer, ARRAY_SIZE(buffer));
782 break;
783
784 default:
785 LoadStringW(hInst, IDS_MEMORY_READ_WRITE, buffer, ARRAY_SIZE(buffer));
786 break;
787 }
788
789 ListView_SetItemText(hwndLV, iItem, 2, buffer);
790 }
791 break;
792
793 case CmResourceTypeDma:
794 hwndLV = GetDlgItem(hwnd, IDC_DMA_LIST);
795
796 wsprintf(buffer, L"%lu", pDescriptor->u.Dma.Channel);
797
798 item.mask = LVIF_TEXT | LVIF_PARAM;
799 item.iItem = 1000;
800 item.iSubItem = 0;
801 item.state = 0;
802 item.stateMask = 0;
803 item.pszText = buffer;
804 item.cchTextMax = (int)wcslen(item.pszText);
805 item.lParam = (LPARAM)pDescriptor;
806
807 iItem = ListView_InsertItem(hwndLV, &item);
808 if (iItem != -1)
809 {
810 wsprintf(buffer, L"%lu", pDescriptor->u.Dma.Port);
811 ListView_SetItemText(hwndLV, iItem, 1, buffer);
812 }
813 break;
814
815 case CmResourceTypeDeviceSpecific:
816 hwndLV = GetDlgItem(hwnd, IDC_DEVICE_LIST);
817
818 wsprintf(buffer, L"0x%08lx", pDescriptor->u.DeviceSpecificData.Reserved1);
819
820 item.mask = LVIF_TEXT | LVIF_PARAM;
821 item.iItem = 1000;
822 item.iSubItem = 0;
823 item.state = 0;
824 item.stateMask = 0;
825 item.pszText = buffer;
826 item.cchTextMax = (int)wcslen(item.pszText);
827 item.lParam = (LPARAM)pDescriptor;
828
829 iItem = ListView_InsertItem(hwndLV, &item);
830 if (iItem != -1)
831 {
832 wsprintf(buffer, L"0x%08lx", pDescriptor->u.DeviceSpecificData.Reserved2);
833 ListView_SetItemText(hwndLV, iItem, 1, buffer);
834
835 wsprintf(buffer, L"0x%lx", pDescriptor->u.DeviceSpecificData.DataSize);
836 ListView_SetItemText(hwndLV, iItem, 2, buffer);
837 }
838 break;
839 }
840 }
841 }
842
843 static BOOL
OnResourceNotify(HWND hwndDlg,NMHDR * phdr)844 OnResourceNotify(HWND hwndDlg, NMHDR *phdr)
845 {
846 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
847
848 switch (phdr->idFrom)
849 {
850 case IDC_PORT_LIST:
851 case IDC_MEMORY_LIST:
852 case IDC_DMA_LIST:
853 case IDC_IRQ_LIST:
854 case IDC_DEVICE_LIST:
855 switch(phdr->code)
856 {
857 case NM_CLICK:
858 if (lpnmlv->iItem != -1)
859 {
860 PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
861 LVITEMW item;
862
863 item.mask = LVIF_PARAM;
864 item.iItem = lpnmlv->iItem;
865 item.iSubItem = 0;
866
867 if (ListView_GetItem(phdr->hwndFrom, &item))
868 {
869 pDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)item.lParam;
870
871 EnableWindow(GetDlgItem(hwndDlg, IDC_UNDETERMINED),
872 (pDescriptor->ShareDisposition == CmResourceShareUndetermined));
873
874 EnableWindow(GetDlgItem(hwndDlg, IDC_SHARED),
875 (pDescriptor->ShareDisposition == CmResourceShareShared));
876
877 EnableWindow(GetDlgItem(hwndDlg, IDC_DEVICE_EXCLUSIVE),
878 (pDescriptor->ShareDisposition == CmResourceShareDeviceExclusive));
879
880 EnableWindow(GetDlgItem(hwndDlg, IDC_DRIVER_EXCLUSIVE),
881 (pDescriptor->ShareDisposition == CmResourceShareDriverExclusive));
882 }
883 }
884 else
885 {
886 EnableWindow(GetDlgItem(hwndDlg, IDC_UNDETERMINED), FALSE);
887 EnableWindow(GetDlgItem(hwndDlg, IDC_SHARED), FALSE);
888 EnableWindow(GetDlgItem(hwndDlg, IDC_DEVICE_EXCLUSIVE), FALSE);
889 EnableWindow(GetDlgItem(hwndDlg, IDC_DRIVER_EXCLUSIVE), FALSE);
890 }
891 break;
892 }
893 break;
894 }
895
896 return FALSE;
897 }
898
modify_resource_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)899 static INT_PTR CALLBACK modify_resource_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
900 {
901 UNREFERENCED_PARAMETER(lParam);
902
903 switch(uMsg)
904 {
905 case WM_INITDIALOG:
906 CreateResourceColumns(hwndDlg);
907 ParseResources(hwndDlg);
908 return FALSE;
909
910 case WM_NOTIFY:
911 return OnResourceNotify(hwndDlg, (NMHDR *)lParam);
912
913 case WM_COMMAND:
914 switch (LOWORD(wParam))
915 {
916 case IDOK:
917 EndDialog(hwndDlg, IDOK);
918 break;
919 case IDCANCEL:
920 EndDialog(hwndDlg, IDCANCEL);
921 return TRUE;
922 }
923 }
924 return FALSE;
925 }
926
CreateResourceListColumns(HWND hWndListView)927 static BOOL CreateResourceListColumns(HWND hWndListView)
928 {
929 WCHAR szText[80];
930 RECT rc;
931 LVCOLUMN lvC;
932
933 ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_FULLROWSELECT);
934
935 GetClientRect(hWndListView, &rc);
936
937 /* Create columns. */
938 lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
939 lvC.pszText = szText;
940 lvC.fmt = LVCFMT_LEFT;
941
942 /* Load the column labels from the resource file. */
943 lvC.iSubItem = 0;
944 lvC.cx = (rc.right - rc.left) / 2;
945 LoadStringW(hInst, IDS_BUSNUMBER, szText, ARRAY_SIZE(szText));
946 if (ListView_InsertColumn(hWndListView, 0, &lvC) == -1)
947 return FALSE;
948
949 lvC.iSubItem = 1;
950 lvC.cx = (rc.right - rc.left) - lvC.cx;
951 LoadStringW(hInst, IDS_INTERFACE, szText, ARRAY_SIZE(szText));
952 if (ListView_InsertColumn(hWndListView, 1, &lvC) == -1)
953 return FALSE;
954
955 return TRUE;
956 }
957
AddFullResourcesToList(HWND hwnd)958 static VOID AddFullResourcesToList(HWND hwnd)
959 {
960 PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor;
961 WCHAR buffer[80];
962 LVITEMW item;
963 ULONG i;
964 INT iItem;
965
966 pFullDescriptor = &resourceValueData->List[0];
967 for (i = 0; i < resourceValueData->Count; i++)
968 {
969 wsprintf(buffer, L"%lu", pFullDescriptor->BusNumber);
970
971 item.mask = LVIF_TEXT;
972 item.iItem = i;
973 item.iSubItem = 0;
974 item.state = 0;
975 item.stateMask = 0;
976 item.pszText = buffer;
977 item.cchTextMax = (int)wcslen(item.pszText);
978
979 iItem = ListView_InsertItem(hwnd, &item);
980 if (iItem != -1)
981 {
982 GetInterfaceType(pFullDescriptor->InterfaceType, buffer, 80);
983 ListView_SetItemText(hwnd, iItem, 1, buffer);
984 }
985 pFullDescriptor = (PVOID)(pFullDescriptor->PartialResourceList.PartialDescriptors +
986 pFullDescriptor->PartialResourceList.Count);
987 }
988 }
989
990 static BOOL
OnResourceListNotify(HWND hwndDlg,NMHDR * phdr)991 OnResourceListNotify(HWND hwndDlg, NMHDR *phdr)
992 {
993 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
994
995 switch (phdr->idFrom)
996 {
997 case IDC_RESOURCE_LIST:
998 switch(phdr->code)
999 {
1000 case NM_CLICK:
1001 fullResourceIndex = lpnmlv->iItem;
1002 EnableWindow(GetDlgItem(hwndDlg, IDC_SHOW_RESOURCE), (lpnmlv->iItem != -1));
1003 break;
1004
1005 case NM_DBLCLK:
1006 if (lpnmlv->iItem != -1)
1007 {
1008 fullResourceIndex = lpnmlv->iItem;
1009 DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE), hwndDlg, modify_resource_dlgproc);
1010 }
1011 break;
1012 }
1013 break;
1014 }
1015
1016 return FALSE;
1017 }
1018
modify_resource_list_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1019 static INT_PTR CALLBACK modify_resource_list_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1020 {
1021 UNREFERENCED_PARAMETER(lParam);
1022
1023 switch(uMsg)
1024 {
1025 case WM_INITDIALOG:
1026 CreateResourceListColumns(GetDlgItem(hwndDlg, IDC_RESOURCE_LIST));
1027 AddFullResourcesToList(GetDlgItem(hwndDlg, IDC_RESOURCE_LIST));
1028 return FALSE;
1029
1030 case WM_NOTIFY:
1031 return OnResourceListNotify(hwndDlg, (NMHDR *)lParam);
1032
1033 case WM_COMMAND:
1034 switch (LOWORD(wParam))
1035 {
1036 case IDC_SHOW_RESOURCE:
1037 if (fullResourceIndex != -1)
1038 DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE), hwndDlg, modify_resource_dlgproc);
1039 break;
1040 case IDOK:
1041 EndDialog(hwndDlg, IDOK);
1042 break;
1043 case IDCANCEL:
1044 EndDialog(hwndDlg, IDCANCEL);
1045 return TRUE;
1046 }
1047 }
1048 return FALSE;
1049 }
1050
1051 static BOOL
CreateRequirementsListColumns(HWND hWndListView)1052 CreateRequirementsListColumns(HWND hWndListView)
1053 {
1054 WCHAR szText[80];
1055 RECT rc;
1056 LVCOLUMN lvC;
1057
1058 ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_FULLROWSELECT);
1059
1060 GetClientRect(hWndListView, &rc);
1061
1062 /* Create columns. */
1063 lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
1064 lvC.pszText = szText;
1065 lvC.fmt = LVCFMT_LEFT;
1066
1067 /* Load the column labels from the resource file. */
1068 lvC.iSubItem = 0;
1069 lvC.cx = (rc.right - rc.left) / 4;
1070 LoadStringW(hInst, IDS_REQALTERNATIVELIST, szText, ARRAY_SIZE(szText));
1071 if (ListView_InsertColumn(hWndListView, 0, &lvC) == -1)
1072 return FALSE;
1073
1074 lvC.iSubItem = 1;
1075 lvC.cx = (rc.right - rc.left) / 4;
1076 LoadStringW(hInst, IDS_REQRESOURCELIST, szText, ARRAY_SIZE(szText));
1077 if (ListView_InsertColumn(hWndListView, 1, &lvC) == -1)
1078 return FALSE;
1079
1080 lvC.iSubItem = 2;
1081 lvC.cx = (rc.right - rc.left) / 4;
1082 LoadStringW(hInst, IDS_REQDESCRIPTOR, szText, ARRAY_SIZE(szText));
1083 if (ListView_InsertColumn(hWndListView, 2, &lvC) == -1)
1084 return FALSE;
1085
1086 lvC.iSubItem = 3;
1087 lvC.cx = (rc.right - rc.left) - (3 * ((rc.right - rc.left) / 4));
1088 LoadStringW(hInst, IDS_REQDEVICETYPE, szText, ARRAY_SIZE(szText));
1089 if (ListView_InsertColumn(hWndListView, 3, &lvC) == -1)
1090 return FALSE;
1091
1092 return TRUE;
1093 }
1094
1095 static VOID
GetResourceType(UCHAR ResourceType,LPWSTR pBuffer,DWORD dwLength)1096 GetResourceType(UCHAR ResourceType,
1097 LPWSTR pBuffer,
1098 DWORD dwLength)
1099 {
1100 switch (ResourceType)
1101 {
1102 case CmResourceTypePort:
1103 LoadStringW(hInst, IDS_TYPE_PORT, pBuffer, dwLength);
1104 break;
1105
1106 case CmResourceTypeInterrupt:
1107 LoadStringW(hInst, IDS_TYPE_INTERRUPT, pBuffer, dwLength);
1108 break;
1109
1110 case CmResourceTypeMemory:
1111 LoadStringW(hInst, IDS_TYPE_MEMORY, pBuffer, dwLength);
1112 break;
1113
1114 case CmResourceTypeDma:
1115 LoadStringW(hInst, IDS_TYPE_DMA, pBuffer, dwLength);
1116 break;
1117
1118 default:
1119 wsprintf(pBuffer, L"Unknown %u", ResourceType);
1120 break;
1121 }
1122 }
1123
1124 static VOID
GetShareDisposition(UCHAR ShareDisposition,LPWSTR pBuffer,DWORD dwLength)1125 GetShareDisposition(
1126 UCHAR ShareDisposition,
1127 LPWSTR pBuffer,
1128 DWORD dwLength)
1129 {
1130 switch (ShareDisposition)
1131 {
1132 case CmResourceShareUndetermined:
1133 LoadStringW(hInst, IDS_SHARE_UNDETERMINED, pBuffer, dwLength);
1134 break;
1135
1136 case CmResourceShareDeviceExclusive:
1137 LoadStringW(hInst, IDS_SHARE_DEVICE_EXCLUSIVE, pBuffer, dwLength);
1138 break;
1139
1140 case CmResourceShareDriverExclusive:
1141 LoadStringW(hInst, IDS_SHARE_DRIVER_EXCLUSIVE, pBuffer, dwLength);
1142 break;
1143
1144 case CmResourceShareShared:
1145 LoadStringW(hInst, IDS_SHARE_SHARED, pBuffer, dwLength);
1146 break;
1147 }
1148 }
1149
1150 static VOID
GetPortType(USHORT Flags,LPWSTR pBuffer,DWORD dwLength)1151 GetPortType(
1152 USHORT Flags,
1153 LPWSTR pBuffer,
1154 DWORD dwLength)
1155 {
1156 if ((Flags & CM_RESOURCE_PORT_IO) == CM_RESOURCE_PORT_IO)
1157 {
1158 LoadStringW(hInst, IDS_PORT_PORT_IO, pBuffer, dwLength);
1159 }
1160 else if ((Flags & CM_RESOURCE_PORT_IO) == CM_RESOURCE_PORT_MEMORY)
1161 {
1162 LoadStringW(hInst, IDS_PORT_MEMORY_IO, pBuffer, dwLength);
1163 }
1164 }
1165
1166 static VOID
GetMemoryAccess(USHORT Flags,LPWSTR pBuffer,DWORD dwLength)1167 GetMemoryAccess(
1168 USHORT Flags,
1169 LPWSTR pBuffer,
1170 DWORD dwLength)
1171 {
1172 if ((Flags & (CM_RESOURCE_MEMORY_READ_ONLY | CM_RESOURCE_MEMORY_WRITE_ONLY)) == CM_RESOURCE_MEMORY_READ_WRITE)
1173 {
1174 LoadStringW(hInst, IDS_MEMORY_READ_WRITE, pBuffer, dwLength);
1175 }
1176 else if ((Flags & (CM_RESOURCE_MEMORY_READ_ONLY | CM_RESOURCE_MEMORY_WRITE_ONLY)) == CM_RESOURCE_MEMORY_READ_ONLY)
1177 {
1178 LoadStringW(hInst, IDS_MEMORY_READ_ONLY, pBuffer, dwLength);
1179 }
1180 else if ((Flags & (CM_RESOURCE_MEMORY_READ_ONLY | CM_RESOURCE_MEMORY_WRITE_ONLY)) == CM_RESOURCE_MEMORY_WRITE_ONLY)
1181 {
1182 LoadStringW(hInst, IDS_MEMORY_WRITE_ONLY, pBuffer, dwLength);
1183 }
1184 }
1185
1186 static VOID
GetInterruptType(USHORT Flags,LPWSTR pBuffer,DWORD dwLength)1187 GetInterruptType(
1188 USHORT Flags,
1189 LPWSTR pBuffer,
1190 DWORD dwLength)
1191 {
1192 if ((Flags & CM_RESOURCE_INTERRUPT_LEVEL_LATCHED_BITS) == CM_RESOURCE_INTERRUPT_LATCHED)
1193 {
1194 LoadStringW(hInst, IDS_INTERRUPT_EDGE_SENSITIVE, pBuffer, dwLength);
1195 }
1196 else
1197 {
1198 LoadStringW(hInst, IDS_INTERRUPT_LEVEL_SENSITIVE, pBuffer, dwLength);
1199 }
1200 }
1201
1202 static VOID
AddRequirementsToList(HWND hwndDlg,HWND hwnd)1203 AddRequirementsToList(HWND hwndDlg, HWND hwnd)
1204 {
1205 PIO_RESOURCE_LIST pResourceList;
1206 PIO_RESOURCE_DESCRIPTOR pDescriptor;
1207 WCHAR buffer[80];
1208 LVITEMW item;
1209 ULONG i, j, index;
1210 INT iItem;
1211
1212 index = 0;
1213 pResourceList = &requirementsValueData->List[0];
1214 for (i = 0; i < requirementsValueData->AlternativeLists; i++)
1215 {
1216 for (j = 0; j < pResourceList->Count; j++)
1217 {
1218 pDescriptor = &pResourceList->Descriptors[j];
1219
1220 wsprintf(buffer, L"%lu", i + 1);
1221
1222 item.mask = LVIF_TEXT | LVIF_PARAM;
1223 item.iItem = index;
1224 item.iSubItem = 0;
1225 item.state = 0;
1226 item.stateMask = 0;
1227 item.pszText = buffer;
1228 item.cchTextMax = (int)wcslen(item.pszText);
1229 item.lParam = (LPARAM)pDescriptor;
1230
1231 iItem = ListView_InsertItem(hwnd, &item);
1232 if (iItem != -1)
1233 {
1234 wsprintf(buffer, L"%lu", j + 1);
1235 ListView_SetItemText(hwnd, iItem, 1, buffer);
1236 wsprintf(buffer, L"%lu", 1);
1237 ListView_SetItemText(hwnd, iItem, 2, buffer);
1238
1239 GetResourceType(pDescriptor->Type, buffer, 80);
1240 ListView_SetItemText(hwnd, iItem, 3, buffer);
1241 }
1242
1243 index++;
1244 }
1245
1246
1247 pResourceList = (PIO_RESOURCE_LIST)(pResourceList->Descriptors + pResourceList->Count);
1248 }
1249
1250 GetInterfaceType(requirementsValueData->InterfaceType, buffer, 80);
1251 SetDlgItemTextW(hwndDlg, IDC_REQINTERFACETYPE, buffer);
1252 SetDlgItemInt(hwndDlg, IDC_REQBUSNUMBER, (UINT)requirementsValueData->BusNumber, TRUE);
1253 SetDlgItemInt(hwndDlg, IDC_REQSLOTNUMBER, (UINT)requirementsValueData->SlotNumber, FALSE);
1254 }
1255
show_requirements_port_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1256 static INT_PTR CALLBACK show_requirements_port_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1257 {
1258 PIO_RESOURCE_DESCRIPTOR pDescriptor;
1259 WCHAR Buffer[80];
1260
1261 switch(uMsg)
1262 {
1263 case WM_INITDIALOG:
1264 pDescriptor = (PIO_RESOURCE_DESCRIPTOR)lParam;
1265
1266 GetPortType(pDescriptor->Flags, Buffer, 80);
1267 SetDlgItemTextW(hwndDlg, IDC_REQ_PORT_TYPE, Buffer);
1268
1269 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Port.Length);
1270 SetDlgItemTextW(hwndDlg, IDC_REQ_PORT_LENGTH, Buffer);
1271 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Port.Alignment);
1272 SetDlgItemTextW(hwndDlg, IDC_REQ_PORT_ALIGN, Buffer);
1273 #ifdef _M_AMD64
1274 wsprintf(Buffer, L"0x%016I64x", pDescriptor->u.Port.MinimumAddress.QuadPart);
1275 #else
1276 wsprintf(Buffer, L"0x%08lx", pDescriptor->u.Port.MinimumAddress.u.LowPart);
1277 #endif
1278 SetDlgItemTextW(hwndDlg, IDC_REQ_PORT_MIN, Buffer);
1279 #ifdef _M_AMD64
1280 wsprintf(Buffer, L"0x%016I64x", pDescriptor->u.Port.MaximumAddress.QuadPart);
1281 #else
1282 wsprintf(Buffer, L"0x%08lx", pDescriptor->u.Port.MaximumAddress.u.LowPart);
1283 #endif
1284 SetDlgItemTextW(hwndDlg, IDC_REQ_PORT_MAX, Buffer);
1285
1286 GetShareDisposition(pDescriptor->ShareDisposition, Buffer, 80);
1287 SetDlgItemTextW(hwndDlg, IDC_REQ_PORT_SHARE, Buffer);
1288
1289 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_PORT_ALTERNATIVE), (pDescriptor->Option & IO_RESOURCE_ALTERNATIVE));
1290 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_PORT_PREFERRED), (pDescriptor->Option & IO_RESOURCE_PREFERRED));
1291 return FALSE;
1292
1293 case WM_COMMAND:
1294 switch (LOWORD(wParam))
1295 {
1296 case IDOK:
1297 case IDCANCEL:
1298 EndDialog(hwndDlg, IDOK);
1299 break;
1300 }
1301 }
1302 return FALSE;
1303 }
1304
show_requirements_memory_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1305 static INT_PTR CALLBACK show_requirements_memory_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1306 {
1307 PIO_RESOURCE_DESCRIPTOR pDescriptor;
1308 WCHAR Buffer[80];
1309
1310 switch(uMsg)
1311 {
1312 case WM_INITDIALOG:
1313 pDescriptor = (PIO_RESOURCE_DESCRIPTOR)lParam;
1314
1315 GetMemoryAccess(pDescriptor->Flags, Buffer, 80);
1316 SetDlgItemTextW(hwndDlg, IDC_REQ_MEMORY_ACCESS, Buffer);
1317
1318 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Memory.Length);
1319 SetDlgItemTextW(hwndDlg, IDC_REQ_MEMORY_LENGTH, Buffer);
1320 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Memory.Alignment);
1321 SetDlgItemTextW(hwndDlg, IDC_REQ_MEMORY_ALIGN, Buffer);
1322 #ifdef _M_AMD64
1323 wsprintf(Buffer, L"0x%016I64x", pDescriptor->u.Memory.MinimumAddress.QuadPart);
1324 #else
1325 wsprintf(Buffer, L"0x%08lx", pDescriptor->u.Memory.MinimumAddress.u.LowPart);
1326 #endif
1327 SetDlgItemTextW(hwndDlg, IDC_REQ_MEMORY_MIN, Buffer);
1328 #ifdef _M_AMD64
1329 wsprintf(Buffer, L"0x%016I64x", pDescriptor->u.Memory.MaximumAddress.QuadPart);
1330 #else
1331 wsprintf(Buffer, L"0x%08lx", pDescriptor->u.Memory.MaximumAddress.u.LowPart);
1332 #endif
1333 SetDlgItemTextW(hwndDlg, IDC_REQ_MEMORY_MAX, Buffer);
1334
1335 GetShareDisposition(pDescriptor->ShareDisposition, Buffer, 80);
1336 SetDlgItemTextW(hwndDlg, IDC_REQ_MEMORY_SHARE, Buffer);
1337
1338 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_MEMORY_ALTERNATIVE), (pDescriptor->Option & IO_RESOURCE_ALTERNATIVE));
1339 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_MEMORY_PREFERRED), (pDescriptor->Option & IO_RESOURCE_PREFERRED));
1340 return FALSE;
1341
1342 case WM_COMMAND:
1343 switch (LOWORD(wParam))
1344 {
1345 case IDOK:
1346 case IDCANCEL:
1347 EndDialog(hwndDlg, IDOK);
1348 break;
1349 }
1350 }
1351 return FALSE;
1352 }
1353
show_requirements_interrupt_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1354 static INT_PTR CALLBACK show_requirements_interrupt_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1355 {
1356 PIO_RESOURCE_DESCRIPTOR pDescriptor;
1357 WCHAR Buffer[80];
1358
1359 switch(uMsg)
1360 {
1361 case WM_INITDIALOG:
1362 pDescriptor = (PIO_RESOURCE_DESCRIPTOR)lParam;
1363
1364 GetInterruptType(pDescriptor->Flags, Buffer, 80);
1365 SetDlgItemTextW(hwndDlg, IDC_REQ_INT_TYPE, Buffer);
1366
1367 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Interrupt.MinimumVector);
1368 SetDlgItemTextW(hwndDlg, IDC_REQ_INT_MIN, Buffer);
1369 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Interrupt.MaximumVector);
1370 SetDlgItemTextW(hwndDlg, IDC_REQ_INT_MAX, Buffer);
1371
1372 GetShareDisposition(pDescriptor->ShareDisposition, Buffer, 80);
1373 SetDlgItemTextW(hwndDlg, IDC_REQ_INT_SHARE, Buffer);
1374
1375 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_INT_ALTERNATIVE), (pDescriptor->Option & IO_RESOURCE_ALTERNATIVE));
1376 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_INT_PREFERRED), (pDescriptor->Option & IO_RESOURCE_PREFERRED));
1377 return FALSE;
1378
1379 case WM_COMMAND:
1380 switch (LOWORD(wParam))
1381 {
1382 case IDOK:
1383 case IDCANCEL:
1384 EndDialog(hwndDlg, IDOK);
1385 break;
1386 }
1387 }
1388 return FALSE;
1389 }
1390
show_requirements_dma_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1391 static INT_PTR CALLBACK show_requirements_dma_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1392 {
1393 PIO_RESOURCE_DESCRIPTOR pDescriptor;
1394 WCHAR Buffer[80];
1395
1396 switch(uMsg)
1397 {
1398 case WM_INITDIALOG:
1399 pDescriptor = (PIO_RESOURCE_DESCRIPTOR)lParam;
1400 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Dma.MinimumChannel);
1401 SetDlgItemTextW(hwndDlg, IDC_REQ_DMA_MIN, Buffer);
1402 wsprintf(Buffer, L"0x%lx", pDescriptor->u.Dma.MaximumChannel);
1403 SetDlgItemTextW(hwndDlg, IDC_REQ_DMA_MAX, Buffer);
1404
1405 GetShareDisposition(pDescriptor->ShareDisposition, Buffer, 80);
1406 SetDlgItemTextW(hwndDlg, IDC_REQ_DMA_SHARE, Buffer);
1407
1408 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_DMA_ALTERNATIVE), (pDescriptor->Option & IO_RESOURCE_ALTERNATIVE));
1409 EnableWindow(GetDlgItem(hwndDlg, IDC_REQ_DMA_PREFERRED), (pDescriptor->Option & IO_RESOURCE_PREFERRED));
1410 return FALSE;
1411
1412 case WM_COMMAND:
1413 switch (LOWORD(wParam))
1414 {
1415 case IDOK:
1416 case IDCANCEL:
1417 EndDialog(hwndDlg, IDOK);
1418 break;
1419 }
1420 }
1421 return FALSE;
1422 }
1423
1424 static VOID
ShowRequirement(HWND hwndDlg)1425 ShowRequirement(HWND hwndDlg)
1426 {
1427 PIO_RESOURCE_DESCRIPTOR pDescriptor;
1428 LVITEMW item;
1429
1430 if (requirementsIndex == -1)
1431 return;
1432
1433 item.mask = LVIF_PARAM;
1434 item.iItem = requirementsIndex;
1435 item.iSubItem = 0;
1436 ListView_GetItem(GetDlgItem(hwndDlg, IDC_REQUIREMENTS_LIST), &item);
1437
1438 pDescriptor = (PIO_RESOURCE_DESCRIPTOR)item.lParam;
1439 if (pDescriptor)
1440 {
1441 switch (pDescriptor->Type)
1442 {
1443 case CmResourceTypePort:
1444 DialogBoxParamW(0, MAKEINTRESOURCEW(IDD_EDIT_REQUIREMENTS_PORT), hwndDlg, show_requirements_port_dlgproc, (LPARAM)pDescriptor);
1445 break;
1446 case CmResourceTypeMemory:
1447 DialogBoxParamW(0, MAKEINTRESOURCEW(IDD_EDIT_REQUIREMENTS_MEMORY), hwndDlg, show_requirements_memory_dlgproc, (LPARAM)pDescriptor);
1448 break;
1449 case CmResourceTypeInterrupt:
1450 DialogBoxParamW(0, MAKEINTRESOURCEW(IDD_EDIT_REQUIREMENTS_INT), hwndDlg, show_requirements_interrupt_dlgproc, (LPARAM)pDescriptor);
1451 break;
1452 case CmResourceTypeDma:
1453 DialogBoxParamW(0, MAKEINTRESOURCEW(IDD_EDIT_REQUIREMENTS_DMA), hwndDlg, show_requirements_dma_dlgproc, (LPARAM)pDescriptor);
1454 break;
1455 default:
1456 break;
1457 }
1458 }
1459 }
1460
1461 static BOOL
OnRequirementsListNotify(HWND hwndDlg,NMHDR * phdr)1462 OnRequirementsListNotify(HWND hwndDlg, NMHDR *phdr)
1463 {
1464 LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
1465
1466 switch (phdr->idFrom)
1467 {
1468 case IDC_REQUIREMENTS_LIST:
1469 switch(phdr->code)
1470 {
1471 case NM_CLICK:
1472 requirementsIndex = lpnmlv->iItem;
1473 EnableWindow(GetDlgItem(hwndDlg, IDC_SHOW_REQUIREMENT), (lpnmlv->iItem != -1));
1474 break;
1475
1476 case NM_DBLCLK:
1477 if (lpnmlv->iItem != -1)
1478 {
1479 requirementsIndex = lpnmlv->iItem;
1480 ShowRequirement(hwndDlg);
1481 }
1482 break;
1483 }
1484 break;
1485 }
1486
1487 return FALSE;
1488 }
1489
modify_requirements_list_dlgproc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)1490 static INT_PTR CALLBACK modify_requirements_list_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
1491 {
1492 UNREFERENCED_PARAMETER(lParam);
1493
1494 switch(uMsg)
1495 {
1496 case WM_INITDIALOG:
1497 CreateRequirementsListColumns(GetDlgItem(hwndDlg, IDC_REQUIREMENTS_LIST));
1498 AddRequirementsToList(hwndDlg, GetDlgItem(hwndDlg, IDC_REQUIREMENTS_LIST));
1499 return FALSE;
1500
1501 case WM_NOTIFY:
1502 return OnRequirementsListNotify(hwndDlg, (NMHDR *)lParam);
1503
1504 case WM_COMMAND:
1505 switch (LOWORD(wParam))
1506 {
1507 case IDC_SHOW_REQUIREMENT:
1508 if (requirementsIndex != -1)
1509 ShowRequirement(hwndDlg);
1510 break;
1511 case IDOK:
1512 EndDialog(hwndDlg, IDOK);
1513 break;
1514 case IDCANCEL:
1515 EndDialog(hwndDlg, IDCANCEL);
1516 return TRUE;
1517 }
1518 }
1519 return FALSE;
1520 }
1521
ModifyValue(HWND hwnd,HKEY hKey,LPCWSTR valueName,BOOL EditBin)1522 BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCWSTR valueName, BOOL EditBin)
1523 {
1524 DWORD type;
1525 LONG lRet;
1526 BOOL result = FALSE;
1527
1528 if (!hKey)
1529 return FALSE;
1530
1531 editValueName = valueName;
1532
1533 lRet = RegQueryValueExW(hKey, valueName, 0, &type, 0, &valueDataLen);
1534 if (lRet != ERROR_SUCCESS && (valueName == NULL || !valueName[0]))
1535 {
1536 lRet = ERROR_SUCCESS; /* Allow editing of (Default) values which don't exist */
1537 type = REG_SZ;
1538 valueDataLen = 0;
1539 stringValueData = NULL;
1540 binValueData = NULL;
1541 }
1542
1543 if (lRet != ERROR_SUCCESS)
1544 {
1545 error(hwnd, IDS_BAD_VALUE, valueName);
1546 goto done;
1547 }
1548
1549 if (EditBin == FALSE && ((type == REG_SZ) || (type == REG_EXPAND_SZ)))
1550 {
1551 if (valueDataLen > 0)
1552 {
1553 if (!(stringValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen)))
1554 {
1555 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1556 goto done;
1557 }
1558 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
1559 if (lRet != ERROR_SUCCESS)
1560 {
1561 error(hwnd, IDS_BAD_VALUE, valueName);
1562 goto done;
1563 }
1564 }
1565 else
1566 {
1567 stringValueData = NULL;
1568 }
1569
1570 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_STRING), hwnd, modify_string_dlgproc) == IDOK)
1571 {
1572 if (stringValueData)
1573 {
1574 lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)stringValueData, (DWORD)(wcslen(stringValueData) + 1) * sizeof(WCHAR));
1575 }
1576 else
1577 {
1578 lRet = RegSetValueExW(hKey, valueName, 0, type, NULL, 0);
1579 }
1580 if (lRet == ERROR_SUCCESS)
1581 result = TRUE;
1582 }
1583 }
1584 else if (EditBin == FALSE && type == REG_MULTI_SZ)
1585 {
1586 if (valueDataLen > 0)
1587 {
1588 size_t llen, listlen, nl_len;
1589 LPWSTR src, lines = NULL;
1590
1591 if (!(stringValueData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, valueDataLen + sizeof(WCHAR))))
1592 {
1593 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1594 goto done;
1595 }
1596 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)stringValueData, &valueDataLen);
1597 if (lRet != ERROR_SUCCESS)
1598 {
1599 error(hwnd, IDS_BAD_VALUE, valueName);
1600 goto done;
1601 }
1602
1603 /* convert \0 to \r\n */
1604 src = stringValueData;
1605 nl_len = wcslen(L"\r\n") * sizeof(WCHAR);
1606 listlen = sizeof(WCHAR);
1607 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, listlen + sizeof(WCHAR));
1608 while(*src != L'\0')
1609 {
1610 llen = wcslen(src);
1611 if(llen == 0)
1612 break;
1613 listlen += (llen * sizeof(WCHAR)) + nl_len;
1614 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, listlen);
1615 wcscat(lines, src);
1616 wcscat(lines, L"\r\n");
1617 src += llen + 1;
1618 }
1619 HeapFree(GetProcessHeap(), 0, stringValueData);
1620 stringValueData = lines;
1621 }
1622 else
1623 {
1624 stringValueData = NULL;
1625 }
1626
1627 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_MULTI_STRING), hwnd, modify_multi_string_dlgproc) == IDOK)
1628 {
1629 if (stringValueData)
1630 {
1631 /* convert \r\n to \0 */
1632 BOOL EmptyLines = FALSE;
1633 LPWSTR src, lines, nl;
1634 size_t linechars, buflen, c_nl, dest;
1635
1636 src = stringValueData;
1637 buflen = sizeof(WCHAR);
1638 lines = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, buflen + sizeof(WCHAR));
1639 c_nl = wcslen(L"\r\n");
1640 dest = 0;
1641 while(*src != L'\0')
1642 {
1643 if((nl = wcsstr(src, L"\r\n")))
1644 {
1645 linechars = nl - src;
1646 if(nl == src)
1647 {
1648 EmptyLines = TRUE;
1649 src = nl + c_nl;
1650 continue;
1651 }
1652 }
1653 else
1654 {
1655 linechars = wcslen(src);
1656 }
1657 if(linechars > 0)
1658 {
1659 buflen += ((linechars + 1) * sizeof(WCHAR));
1660 lines = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lines, buflen);
1661 memcpy((lines + dest), src, linechars * sizeof(WCHAR));
1662 dest += linechars;
1663 lines[dest++] = L'\0';
1664 }
1665 else
1666 {
1667 EmptyLines = TRUE;
1668 }
1669 src += linechars + (nl != NULL ? c_nl : 0);
1670 }
1671 lines[++dest] = L'\0';
1672
1673 if(EmptyLines)
1674 {
1675 warning(hwnd, IDS_MULTI_SZ_EMPTY_STRING);
1676 }
1677
1678 lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)lines, (DWORD)buflen);
1679 HeapFree(GetProcessHeap(), 0, lines);
1680 }
1681 else
1682 {
1683 lRet = RegSetValueExW(hKey, valueName, 0, type, NULL, 0);
1684 }
1685 if (lRet == ERROR_SUCCESS)
1686 result = TRUE;
1687 }
1688 }
1689 else if (EditBin == FALSE && type == REG_DWORD)
1690 {
1691 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)&dwordValueData, &valueDataLen);
1692 if (lRet != ERROR_SUCCESS)
1693 {
1694 error(hwnd, IDS_BAD_VALUE, valueName);
1695 goto done;
1696 }
1697
1698 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_DWORD), hwnd, modify_dword_dlgproc) == IDOK)
1699 {
1700 lRet = RegSetValueExW(hKey, valueName, 0, type, (LPBYTE)&dwordValueData, sizeof(DWORD));
1701 if (lRet == ERROR_SUCCESS)
1702 result = TRUE;
1703 }
1704 }
1705 else if (EditBin == FALSE && type == REG_RESOURCE_LIST)
1706 {
1707 if (valueDataLen > 0)
1708 {
1709 resourceValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen);
1710 if (resourceValueData == NULL)
1711 {
1712 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1713 goto done;
1714 }
1715
1716 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)resourceValueData, &valueDataLen);
1717 if (lRet != ERROR_SUCCESS)
1718 {
1719 error(hwnd, IDS_BAD_VALUE, valueName);
1720 goto done;
1721 }
1722 }
1723 else
1724 {
1725 resourceValueData = NULL;
1726 }
1727
1728 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE_LIST), hwnd, modify_resource_list_dlgproc) == IDOK)
1729 {
1730 }
1731 }
1732 else if (EditBin == FALSE && type == REG_FULL_RESOURCE_DESCRIPTOR)
1733 {
1734 if (valueDataLen > 0)
1735 {
1736 resourceValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen + sizeof(ULONG));
1737 if (resourceValueData == NULL)
1738 {
1739 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1740 goto done;
1741 }
1742
1743 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)&resourceValueData->List[0], &valueDataLen);
1744 if (lRet != ERROR_SUCCESS)
1745 {
1746 error(hwnd, IDS_BAD_VALUE, valueName);
1747 goto done;
1748 }
1749
1750 resourceValueData->Count = 1;
1751 fullResourceIndex = 0;
1752 }
1753 else
1754 {
1755 resourceValueData = NULL;
1756 }
1757
1758 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_RESOURCE), hwnd, modify_resource_dlgproc) == IDOK)
1759 {
1760 }
1761 }
1762 else if (EditBin == FALSE && type == REG_RESOURCE_REQUIREMENTS_LIST)
1763 {
1764 if (valueDataLen > 0)
1765 {
1766 requirementsValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen + sizeof(ULONG));
1767 if (requirementsValueData == NULL)
1768 {
1769 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1770 goto done;
1771 }
1772
1773 lRet = RegQueryValueExW(hKey, valueName, 0, 0, (LPBYTE)requirementsValueData, &valueDataLen);
1774 if (lRet != ERROR_SUCCESS)
1775 {
1776 error(hwnd, IDS_BAD_VALUE, valueName);
1777 goto done;
1778 }
1779
1780 }
1781 else
1782 {
1783 requirementsValueData = NULL;
1784 }
1785
1786 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_REQUIREMENTS_LIST), hwnd, modify_requirements_list_dlgproc) == IDOK)
1787 {
1788 }
1789 }
1790 else if ((EditBin != FALSE) || (type == REG_NONE) || (type == REG_BINARY))
1791 {
1792 if(valueDataLen > 0)
1793 {
1794 if(!(binValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen + 1)))
1795 {
1796 error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
1797 goto done;
1798 }
1799
1800 /* Use the unicode version, so editing strings in binary mode is correct */
1801 lRet = RegQueryValueExW(hKey, valueName,
1802 0, 0, (LPBYTE)binValueData, &valueDataLen);
1803 if (lRet != ERROR_SUCCESS)
1804 {
1805 HeapFree(GetProcessHeap(), 0, binValueData);
1806 error(hwnd, IDS_BAD_VALUE, valueName);
1807 goto done;
1808 }
1809 }
1810 else
1811 {
1812 binValueData = NULL;
1813 }
1814
1815 if (DialogBoxW(0, MAKEINTRESOURCEW(IDD_EDIT_BIN_DATA), hwnd, modify_binary_dlgproc) == IDOK)
1816 {
1817 /* Use the unicode version, so editing strings in binary mode is correct */
1818 lRet = RegSetValueExW(hKey, valueName,
1819 0, type, (LPBYTE)binValueData, valueDataLen);
1820 if (lRet == ERROR_SUCCESS)
1821 result = TRUE;
1822 }
1823 if(binValueData != NULL)
1824 HeapFree(GetProcessHeap(), 0, binValueData);
1825 }
1826 else
1827 {
1828 error(hwnd, IDS_UNSUPPORTED_TYPE, type);
1829 }
1830
1831 done:
1832 if (resourceValueData)
1833 HeapFree(GetProcessHeap(), 0, resourceValueData);
1834 resourceValueData = NULL;
1835
1836 if (stringValueData)
1837 HeapFree(GetProcessHeap(), 0, stringValueData);
1838 stringValueData = NULL;
1839
1840 if (requirementsValueData)
1841 HeapFree(GetProcessHeap(), 0, requirementsValueData);
1842 requirementsValueData = NULL;
1843
1844 return result;
1845 }
1846
CopyKey(HKEY hDestKey,LPCWSTR lpDestSubKey,HKEY hSrcKey,LPCWSTR lpSrcSubKey)1847 static LONG CopyKey(HKEY hDestKey, LPCWSTR lpDestSubKey, HKEY hSrcKey, LPCWSTR lpSrcSubKey)
1848 {
1849 LONG lResult;
1850 DWORD dwDisposition;
1851 HKEY hDestSubKey = NULL;
1852 HKEY hSrcSubKey = NULL;
1853 DWORD dwIndex, dwType, cbName, cbData;
1854 WCHAR szSubKey[256];
1855 WCHAR szValueName[256];
1856 BYTE szValueData[512];
1857
1858 FILETIME ft;
1859
1860 /* open the source subkey, if specified */
1861 if (lpSrcSubKey)
1862 {
1863 lResult = RegOpenKeyExW(hSrcKey, lpSrcSubKey, 0, KEY_ALL_ACCESS, &hSrcSubKey);
1864 if (lResult)
1865 goto done;
1866 hSrcKey = hSrcSubKey;
1867 }
1868
1869 /* create the destination subkey */
1870 lResult = RegCreateKeyExW(hDestKey, lpDestSubKey, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL,
1871 &hDestSubKey, &dwDisposition);
1872 if (lResult)
1873 goto done;
1874
1875 /* copy all subkeys */
1876 dwIndex = 0;
1877 do
1878 {
1879 cbName = ARRAY_SIZE(szSubKey);
1880 lResult = RegEnumKeyExW(hSrcKey, dwIndex++, szSubKey, &cbName, NULL, NULL, NULL, &ft);
1881 if (lResult == ERROR_SUCCESS)
1882 {
1883 lResult = CopyKey(hDestSubKey, szSubKey, hSrcKey, szSubKey);
1884 if (lResult)
1885 goto done;
1886 }
1887 }
1888 while(lResult == ERROR_SUCCESS);
1889
1890 /* copy all subvalues */
1891 dwIndex = 0;
1892 do
1893 {
1894 cbName = ARRAY_SIZE(szValueName);
1895 cbData = ARRAY_SIZE(szValueData);
1896 lResult = RegEnumValueW(hSrcKey, dwIndex++, szValueName, &cbName, NULL, &dwType, szValueData, &cbData);
1897 if (lResult == ERROR_SUCCESS)
1898 {
1899 lResult = RegSetValueExW(hDestSubKey, szValueName, 0, dwType, szValueData, cbData);
1900 if (lResult)
1901 goto done;
1902 }
1903 }
1904 while(lResult == ERROR_SUCCESS);
1905
1906 lResult = ERROR_SUCCESS;
1907
1908 done:
1909 if (hSrcSubKey)
1910 RegCloseKey(hSrcSubKey);
1911 if (hDestSubKey)
1912 RegCloseKey(hDestSubKey);
1913 if (lResult != ERROR_SUCCESS)
1914 SHDeleteKey(hDestKey, lpDestSubKey);
1915 return lResult;
1916 }
1917
MoveKey(HKEY hDestKey,LPCWSTR lpDestSubKey,HKEY hSrcKey,LPCWSTR lpSrcSubKey)1918 static LONG MoveKey(HKEY hDestKey, LPCWSTR lpDestSubKey, HKEY hSrcKey, LPCWSTR lpSrcSubKey)
1919 {
1920 LONG lResult;
1921
1922 if (!lpSrcSubKey)
1923 return ERROR_INVALID_FUNCTION;
1924
1925 if (_wcsicmp(lpDestSubKey, lpSrcSubKey) == 0)
1926 {
1927 /* Destination name equals source name */
1928 return ERROR_SUCCESS;
1929 }
1930
1931 lResult = CopyKey(hDestKey, lpDestSubKey, hSrcKey, lpSrcSubKey);
1932 if (lResult == ERROR_SUCCESS)
1933 SHDeleteKey(hSrcKey, lpSrcSubKey);
1934
1935 return lResult;
1936 }
1937
DeleteKey(HWND hwnd,HKEY hKeyRoot,LPCWSTR keyPath)1938 BOOL DeleteKey(HWND hwnd, HKEY hKeyRoot, LPCWSTR keyPath)
1939 {
1940 WCHAR msg[128], caption[128];
1941 BOOL result = FALSE;
1942 LONG lRet;
1943 HKEY hKey;
1944
1945 lRet = RegOpenKeyExW(hKeyRoot, keyPath, 0, KEY_READ|KEY_SET_VALUE, &hKey);
1946 if (lRet != ERROR_SUCCESS)
1947 {
1948 error_code_messagebox(hwnd, lRet);
1949 return FALSE;
1950 }
1951
1952 LoadStringW(hInst, IDS_QUERY_DELETE_KEY_CONFIRM, caption, ARRAY_SIZE(caption));
1953 LoadStringW(hInst, IDS_QUERY_DELETE_KEY_ONE, msg, ARRAY_SIZE(msg));
1954
1955 if (MessageBoxW(g_pChildWnd->hWnd, msg, caption, MB_ICONQUESTION | MB_YESNO) != IDYES)
1956 goto done;
1957
1958 lRet = SHDeleteKey(hKeyRoot, keyPath);
1959 if (lRet != ERROR_SUCCESS)
1960 {
1961 error(hwnd, IDS_BAD_KEY, keyPath);
1962 goto done;
1963 }
1964 result = TRUE;
1965
1966 done:
1967 RegCloseKey(hKey);
1968 return result;
1969 }
1970
RenameKey(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpNewName)1971 LONG RenameKey(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpNewName)
1972 {
1973 LPCWSTR s;
1974 LPWSTR lpNewSubKey = NULL;
1975 LONG Ret = 0;
1976 SIZE_T cbNewSubKey;
1977
1978 if (!lpSubKey)
1979 return Ret;
1980
1981 s = wcsrchr(lpSubKey, L'\\');
1982 if (s)
1983 {
1984 s++;
1985 cbNewSubKey = (s - lpSubKey + wcslen(lpNewName) + 1) * sizeof(WCHAR);
1986 lpNewSubKey = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, cbNewSubKey);
1987 if (lpNewSubKey != NULL)
1988 {
1989 StringCbCopyNW(lpNewSubKey, cbNewSubKey, lpSubKey, (s - lpSubKey) * sizeof(WCHAR));
1990 StringCbCatW(lpNewSubKey, cbNewSubKey, lpNewName);
1991 lpNewName = lpNewSubKey;
1992 }
1993 else
1994 return ERROR_NOT_ENOUGH_MEMORY;
1995 }
1996
1997 Ret = MoveKey(hKey, lpNewName, hKey, lpSubKey);
1998
1999 if (lpNewSubKey)
2000 {
2001 HeapFree(GetProcessHeap(), 0, lpNewSubKey);
2002 }
2003 return Ret;
2004 }
2005
RenameValue(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpDestValue,LPCWSTR lpSrcValue)2006 LONG RenameValue(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpDestValue, LPCWSTR lpSrcValue)
2007 {
2008 LONG lResult;
2009 HKEY hSubKey = NULL;
2010 DWORD dwType, cbData;
2011 BYTE data[512];
2012
2013 if (lpSubKey)
2014 {
2015 lResult = RegOpenKeyW(hKey, lpSubKey, &hSubKey);
2016 if (lResult != ERROR_SUCCESS)
2017 goto done;
2018 hKey = hSubKey;
2019 }
2020
2021 cbData = sizeof(data);
2022 lResult = RegQueryValueExW(hKey, lpSrcValue, NULL, &dwType, data, &cbData);
2023 if (lResult != ERROR_SUCCESS)
2024 goto done;
2025
2026 lResult = RegSetValueExW(hKey, lpDestValue, 0, dwType, data, cbData);
2027 if (lResult != ERROR_SUCCESS)
2028 goto done;
2029
2030 RegDeleteValue(hKey, lpSrcValue);
2031
2032 done:
2033 if (hSubKey)
2034 RegCloseKey(hSubKey);
2035 return lResult;
2036 }
2037
QueryStringValue(HKEY hKey,LPCWSTR lpSubKey,LPCWSTR lpValueName,LPWSTR pszBuffer,DWORD dwBufferLen)2038 LONG QueryStringValue(HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, LPWSTR pszBuffer, DWORD dwBufferLen)
2039 {
2040 LONG lResult;
2041 HKEY hSubKey = NULL;
2042 DWORD cbData, dwType;
2043
2044 if (lpSubKey)
2045 {
2046 lResult = RegOpenKeyW(hKey, lpSubKey, &hSubKey);
2047 if (lResult != ERROR_SUCCESS)
2048 goto done;
2049 hKey = hSubKey;
2050 }
2051
2052 cbData = (dwBufferLen - 1) * sizeof(*pszBuffer);
2053 lResult = RegQueryValueExW(hKey, lpValueName, NULL, &dwType, (LPBYTE)pszBuffer, &cbData);
2054 if (lResult != ERROR_SUCCESS)
2055 goto done;
2056 if (dwType != REG_SZ)
2057 {
2058 lResult = -1;
2059 goto done;
2060 }
2061
2062 pszBuffer[cbData / sizeof(*pszBuffer)] = L'\0';
2063
2064 done:
2065 if (lResult != ERROR_SUCCESS)
2066 pszBuffer[0] = L'\0';
2067 if (hSubKey)
2068 RegCloseKey(hSubKey);
2069 return lResult;
2070 }
2071
GetKeyName(LPWSTR pszDest,size_t iDestLength,HKEY hRootKey,LPCWSTR lpSubKey)2072 BOOL GetKeyName(LPWSTR pszDest, size_t iDestLength, HKEY hRootKey, LPCWSTR lpSubKey)
2073 {
2074 LPCWSTR pszRootKey;
2075
2076 if (hRootKey == HKEY_CLASSES_ROOT)
2077 pszRootKey = L"HKEY_CLASSES_ROOT";
2078 else if (hRootKey == HKEY_CURRENT_USER)
2079 pszRootKey = L"HKEY_CURRENT_USER";
2080 else if (hRootKey == HKEY_LOCAL_MACHINE)
2081 pszRootKey = L"HKEY_LOCAL_MACHINE";
2082 else if (hRootKey == HKEY_USERS)
2083 pszRootKey = L"HKEY_USERS";
2084 else if (hRootKey == HKEY_CURRENT_CONFIG)
2085 pszRootKey = L"HKEY_CURRENT_CONFIG";
2086 else if (hRootKey == HKEY_DYN_DATA)
2087 pszRootKey = L"HKEY_DYN_DATA";
2088 else
2089 return FALSE;
2090
2091 if (lpSubKey[0])
2092 _snwprintf(pszDest, iDestLength, L"%s\\%s", pszRootKey, lpSubKey);
2093 else
2094 _snwprintf(pszDest, iDestLength, L"%s", pszRootKey);
2095 return TRUE;
2096 }
2097