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