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