* Sync with recent trunk (r52637).
[reactos.git] / base / applications / regedit / edit.c
index ba5e7be..cd77345 100644 (file)
@@ -31,6 +31,8 @@ static const TCHAR* editValueName;
 static TCHAR* stringValueData;
 static PVOID binValueData;
 static DWORD dwordValueData;
+static PCM_RESOURCE_LIST resourceValueData;
+static INT fullResourceIndex = -1;
 static DWORD valueDataLen;
 static EDIT_MODE dwordEditMode = EDIT_MODE_HEX;
 
@@ -429,6 +431,633 @@ INT_PTR CALLBACK modify_binary_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, L
 }
 
 
+static BOOL CreateResourceColumns(HWND hwnd)
+{
+    TCHAR szText[80];
+    RECT rc;
+    LV_COLUMN lvC;
+    HWND hwndLV;
+    INT width;
+
+    /* Create columns. */
+    lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
+    lvC.pszText = szText;
+    lvC.fmt = LVCFMT_LEFT;
+
+    hwndLV = GetDlgItem(hwnd, IDC_DMA_LIST);
+    ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
+    GetClientRect(hwndLV, &rc);
+
+    /* Load the column labels from the resource file. */
+    lvC.iSubItem = 0;
+    lvC.cx = (rc.right - rc.left) / 2;
+    LoadString(hInst, IDS_DMA_CHANNEL, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 1;
+    lvC.cx = (rc.right - rc.left) - lvC.cx;
+    LoadString(hInst, IDS_DMA_PORT, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
+        return FALSE;
+
+
+    /* Interrupt list */
+    hwndLV = GetDlgItem(hwnd, IDC_IRQ_LIST);
+    ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
+    GetClientRect(hwndLV, &rc);
+    width = (rc.right - rc.left) / 4;
+
+    /* Load the column labels from the resource file. */
+    lvC.iSubItem = 0;
+    lvC.cx = width;
+    LoadString(hInst, IDS_INTERRUPT_VECTOR, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 1;
+    LoadString(hInst, IDS_INTERRUPT_LEVEL, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 2;
+    LoadString(hInst, IDS_INTERRUPT_AFFINITY, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 3;
+    lvC.cx = (rc.right - rc.left) - 3 * width;
+    LoadString(hInst, IDS_INTERRUPT_TYPE, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 3, &lvC) == -1)
+        return FALSE;
+
+
+    /* Memory list */
+    hwndLV = GetDlgItem(hwnd, IDC_MEMORY_LIST);
+    ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
+    GetClientRect(hwndLV, &rc);
+    width = (rc.right - rc.left) / 3;
+
+    /* Load the column labels from the resource file. */
+    lvC.iSubItem = 0;
+    lvC.cx = width;
+    LoadString(hInst, IDS_MEMORY_ADDRESS, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 1;
+    LoadString(hInst, IDS_MEMORY_LENGTH, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 2;
+    lvC.cx = (rc.right - rc.left) - 2 * width;
+    LoadString(hInst, IDS_MEMORY_ACCESS, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
+        return FALSE;
+
+
+    /* Port list */
+    hwndLV = GetDlgItem(hwnd, IDC_PORT_LIST);
+    ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
+    GetClientRect(hwndLV, &rc);
+    width = (rc.right - rc.left) / 3;
+
+    /* Load the column labels from the resource file. */
+    lvC.iSubItem = 0;
+    lvC.cx = width;
+    LoadString(hInst, IDS_PORT_ADDRESS, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 1;
+    LoadString(hInst, IDS_PORT_LENGTH, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 2;
+    lvC.cx = (rc.right - rc.left) - 2 * width;
+    LoadString(hInst, IDS_PORT_ACCESS, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
+        return FALSE;
+
+    /* Device specific list */
+    hwndLV = GetDlgItem(hwnd, IDC_DEVICE_LIST);
+    ListView_SetExtendedListViewStyle(hwndLV, LVS_EX_FULLROWSELECT);
+    GetClientRect(hwndLV, &rc);
+    width = (rc.right - rc.left) / 3;
+
+    /* Load the column labels from the resource file. */
+    lvC.iSubItem = 0;
+    lvC.cx = width;
+    LoadString(hInst, IDS_SPECIFIC_RESERVED1, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 0, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 1;
+    LoadString(hInst, IDS_SPECIFIC_RESERVED2, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 1, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 2;
+    lvC.cx = (rc.right - rc.left) - 2 * width;
+    LoadString(hInst, IDS_SPECIFIC_DATASIZE, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hwndLV, 2, &lvC) == -1)
+        return FALSE;
+
+    return TRUE;
+}
+
+static VOID
+GetInterfaceType(INTERFACE_TYPE InterfaceType,
+                 LPTSTR pBuffer,
+                 DWORD dwLength)
+{
+//    LPTSTR lpInterfaceType;
+
+    switch (InterfaceType)
+    {
+        case InterfaceTypeUndefined:
+            LoadString(hInst, IDS_BUS_UNDEFINED, pBuffer, dwLength);
+//            lpInterfaceType = _T("Undefined");
+            break;
+        case Internal:
+            LoadString(hInst, IDS_BUS_INTERNAL, pBuffer, dwLength);
+//            lpInterfaceType = _T("Internal");
+            break;
+        case Isa:
+            LoadString(hInst, IDS_BUS_ISA, pBuffer, dwLength);
+//            lpInterfaceType = _T("Isa");
+            break;
+        case Eisa:
+            LoadString(hInst, IDS_BUS_EISA, pBuffer, dwLength);
+//            lpInterfaceType = _T("Eisa");
+            break;
+        case MicroChannel:
+            LoadString(hInst, IDS_BUS_MICROCHANNEL, pBuffer, dwLength);
+//            lpInterfaceType = _T("MicroChannel");
+            break;
+        case TurboChannel:
+            LoadString(hInst, IDS_BUS_TURBOCHANNEL, pBuffer, dwLength);
+//            lpInterfaceType = _T("TurboChannel");
+            break;
+        case PCIBus:
+            LoadString(hInst, IDS_BUS_PCIBUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("PCIBus");
+            break;
+        case VMEBus:
+            LoadString(hInst, IDS_BUS_VMEBUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("VMEBus");
+            break;
+        case NuBus:
+            LoadString(hInst, IDS_BUS_NUBUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("NuBus");
+            break;
+        case PCMCIABus:
+            LoadString(hInst, IDS_BUS_PCMCIABUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("PCMCIABus");
+            break;
+        case CBus:
+            LoadString(hInst, IDS_BUS_CBUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("CBus");
+            break;
+        case MPIBus:
+            LoadString(hInst, IDS_BUS_MPIBUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("MPIBus");
+            break;
+        case MPSABus:
+            LoadString(hInst, IDS_BUS_MPSABUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("MPSABus");
+            break;
+        case ProcessorInternal:
+            LoadString(hInst, IDS_BUS_PROCESSORINTERNAL, pBuffer, dwLength);
+//            lpInterfaceType = _T("ProcessorInternal");
+            break;
+        case InternalPowerBus:
+            LoadString(hInst, IDS_BUS_INTERNALPOWERBUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("InternalPowerBus");
+            break;
+        case PNPISABus:
+            LoadString(hInst, IDS_BUS_PNPISABUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("PNPISABus");
+            break;
+        case PNPBus:
+            LoadString(hInst, IDS_BUS_PNPBUS, pBuffer, dwLength);
+//            lpInterfaceType = _T("PNPBus");
+            break;
+        default:
+            LoadString(hInst, IDS_BUS_UNKNOWNTYPE, pBuffer, dwLength);
+//            lpInterfaceType = _T("Unknown interface type");
+            break;
+    }
+
+//    _tcscpy(pBuffer, lpInterfaceType);
+}
+
+
+static VOID
+ParseResources(HWND hwnd)
+{
+    PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor;
+    PCM_PARTIAL_RESOURCE_LIST pPartialResourceList;
+    PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
+    ULONG i;
+    HWND hwndLV;
+
+    TCHAR buffer[80];
+    LVITEM item;
+    INT iItem;
+
+    pFullDescriptor = &resourceValueData->List[fullResourceIndex];
+    pPartialResourceList = &pFullDescriptor->PartialResourceList;
+
+    /* Interface type */
+    GetInterfaceType(pFullDescriptor->InterfaceType, buffer, 80);
+    SetDlgItemText(hwnd, IDC_INTERFACETYPE, buffer);
+
+    /* Busnumber */
+    SetDlgItemInt(hwnd, IDC_BUSNUMBER, (UINT)pFullDescriptor->BusNumber, FALSE);
+
+    /* Version */
+    SetDlgItemInt(hwnd, IDC_VERSION, (UINT)pPartialResourceList->Version, FALSE);
+
+    /* Revision */
+    SetDlgItemInt(hwnd, IDC_REVISION, (UINT)pPartialResourceList->Revision, FALSE);
+
+    for (i = 0; i < pPartialResourceList->Count; i++)
+    {
+        pDescriptor = &pPartialResourceList->PartialDescriptors[i];
+
+        switch (pDescriptor->Type)
+        {
+            case CmResourceTypePort:
+                hwndLV = GetDlgItem(hwnd, IDC_PORT_LIST);
+
+#ifdef _M_AMD64
+                wsprintf(buffer, _T("0x%16I64x"), pDescriptor->u.Port.Start.QuadPart);
+#else
+                wsprintf(buffer, _T("0x%08lx"), pDescriptor->u.Port.Start.u.LowPart);
+#endif
+
+                item.mask = LVIF_TEXT | LVIF_PARAM;
+                item.iItem = 1000;
+                item.iSubItem = 0;
+                item.state = 0;
+                item.stateMask = 0;
+                item.pszText = buffer;
+                item.cchTextMax = (int)_tcslen(item.pszText);
+                item.lParam = (LPARAM)pDescriptor;
+
+                iItem = ListView_InsertItem(hwndLV, &item);
+                if (iItem != -1)
+                {
+                    wsprintf(buffer, _T("0x%lx"), pDescriptor->u.Port.Length);
+                    ListView_SetItemText(hwndLV, iItem, 1, buffer);
+
+                    if (pDescriptor->Flags & CM_RESOURCE_PORT_IO)
+                        LoadString(hInst, IDS_PORT_PORT_IO, buffer, sizeof(buffer)/sizeof(TCHAR));
+                    else
+                        LoadString(hInst, IDS_PORT_MEMORY_IO, buffer, sizeof(buffer)/sizeof(TCHAR));
+                    ListView_SetItemText(hwndLV, iItem, 2, buffer);
+                }
+                break;
+
+            case CmResourceTypeInterrupt:
+                hwndLV = GetDlgItem(hwnd, IDC_IRQ_LIST);
+
+                wsprintf(buffer, _T("%lu"), pDescriptor->u.Interrupt.Vector);
+
+                item.mask = LVIF_TEXT | LVIF_PARAM;
+                item.iItem = 1000;
+                item.iSubItem = 0;
+                item.state = 0;
+                item.stateMask = 0;
+                item.pszText = buffer;
+                item.cchTextMax = (int)_tcslen(item.pszText);
+                item.lParam = (LPARAM)pDescriptor;
+
+                iItem = ListView_InsertItem(hwndLV, &item);
+                if (iItem != -1)
+                {
+                    wsprintf(buffer, _T("%lu"), pDescriptor->u.Interrupt.Level);
+                    ListView_SetItemText(hwndLV, iItem, 1, buffer);
+
+                    wsprintf(buffer, _T("0x%08lx"), pDescriptor->u.Interrupt.Affinity);
+                    ListView_SetItemText(hwndLV, iItem, 2, buffer);
+
+                    if (pDescriptor->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
+                        LoadString(hInst, IDS_INTERRUPT_EDGE_SENSITIVE, buffer, sizeof(buffer)/sizeof(TCHAR));
+                    else
+                        LoadString(hInst, IDS_INTERRUPT_LEVEL_SENSITIVE, buffer, sizeof(buffer)/sizeof(TCHAR));
+
+                    ListView_SetItemText(hwndLV, iItem, 3, buffer);
+                }
+                break;
+
+            case CmResourceTypeMemory:
+                hwndLV = GetDlgItem(hwnd, IDC_MEMORY_LIST);
+
+#ifdef _M_AMD64
+                wsprintf(buffer, _T("0x%16I64x"), pDescriptor->u.Memory.Start.QuadPart);
+#else
+                wsprintf(buffer, _T("0x%08lx"), pDescriptor->u.Memory.Start.u.LowPart);
+#endif
+
+                item.mask = LVIF_TEXT | LVIF_PARAM;
+                item.iItem = 1000;
+                item.iSubItem = 0;
+                item.state = 0;
+                item.stateMask = 0;
+                item.pszText = buffer;
+                item.cchTextMax = (int)_tcslen(item.pszText);
+                item.lParam = (LPARAM)pDescriptor;
+
+                iItem = ListView_InsertItem(hwndLV, &item);
+                if (iItem != -1)
+                {
+                    wsprintf(buffer, _T("0x%lx"), pDescriptor->u.Memory.Length);
+                    ListView_SetItemText(hwndLV, iItem, 1, buffer);
+
+                    switch (pDescriptor->Flags & (CM_RESOURCE_MEMORY_READ_ONLY | CM_RESOURCE_MEMORY_WRITE_ONLY))
+                    {
+                        case CM_RESOURCE_MEMORY_READ_ONLY:
+                            LoadString(hInst, IDS_MEMORY_READ_ONLY, buffer, sizeof(buffer)/sizeof(TCHAR));
+                            break;
+
+                        case CM_RESOURCE_MEMORY_WRITE_ONLY:
+                            LoadString(hInst, IDS_MEMORY_WRITE_ONLY, buffer, sizeof(buffer)/sizeof(TCHAR));
+                            break;
+
+                        default:
+                            LoadString(hInst, IDS_MEMORY_READ_WRITE, buffer, sizeof(buffer)/sizeof(TCHAR));
+                            break;
+                    }
+
+                    ListView_SetItemText(hwndLV, iItem, 2, buffer);
+                }
+                break;
+
+            case CmResourceTypeDma:
+                hwndLV = GetDlgItem(hwnd, IDC_DMA_LIST);
+
+                wsprintf(buffer, _T("%lu"), pDescriptor->u.Dma.Channel);
+
+                item.mask = LVIF_TEXT | LVIF_PARAM;
+                item.iItem = 1000;
+                item.iSubItem = 0;
+                item.state = 0;
+                item.stateMask = 0;
+                item.pszText = buffer;
+                item.cchTextMax = (int)_tcslen(item.pszText);
+                item.lParam = (LPARAM)pDescriptor;
+
+                iItem = ListView_InsertItem(hwndLV, &item);
+                if (iItem != -1)
+                {
+                    wsprintf(buffer, _T("%lu"), pDescriptor->u.Dma.Port);
+                    ListView_SetItemText(hwndLV, iItem, 1, buffer);
+                }
+                break;
+
+            case CmResourceTypeDeviceSpecific:
+                hwndLV = GetDlgItem(hwnd, IDC_DEVICE_LIST);
+
+                wsprintf(buffer, _T("0x%08lx"), pDescriptor->u.DeviceSpecificData.Reserved1);
+
+                item.mask = LVIF_TEXT | LVIF_PARAM;
+                item.iItem = 1000;
+                item.iSubItem = 0;
+                item.state = 0;
+                item.stateMask = 0;
+                item.pszText = buffer;
+                item.cchTextMax = (int)_tcslen(item.pszText);
+                item.lParam = (LPARAM)pDescriptor;
+
+                iItem = ListView_InsertItem(hwndLV, &item);
+                if (iItem != -1)
+                {
+                    wsprintf(buffer, _T("0x%08lx"), pDescriptor->u.DeviceSpecificData.Reserved2);
+                    ListView_SetItemText(hwndLV, iItem, 1, buffer);
+
+                    wsprintf(buffer, _T("0x%lx"), pDescriptor->u.DeviceSpecificData.DataSize);
+                    ListView_SetItemText(hwndLV, iItem, 2, buffer);
+                }
+                break;
+        }
+    }
+}
+
+
+static BOOL
+OnResourceNotify(HWND hwndDlg, NMHDR *phdr)
+{
+    LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
+
+    switch (phdr->idFrom)
+    {
+        case IDC_PORT_LIST:
+        case IDC_MEMORY_LIST:
+        case IDC_DMA_LIST:
+        case IDC_IRQ_LIST:
+        case IDC_DEVICE_LIST:
+            switch(phdr->code)
+            {
+                case NM_CLICK:
+                    if (lpnmlv->iItem != -1)
+                    {
+                        PCM_PARTIAL_RESOURCE_DESCRIPTOR pDescriptor;
+                        LVITEM item;
+
+                        item.mask = LVIF_PARAM;
+                        item.iItem = lpnmlv->iItem;
+                        item.iSubItem = 0;
+
+                        if (ListView_GetItem(phdr->hwndFrom, &item))
+                        {
+                            pDescriptor = (PCM_PARTIAL_RESOURCE_DESCRIPTOR)item.lParam;
+
+                            EnableWindow(GetDlgItem(hwndDlg, IDC_UNDETERMINED),
+                                         (pDescriptor->ShareDisposition == CmResourceShareUndetermined));
+
+                            EnableWindow(GetDlgItem(hwndDlg, IDC_SHARED),
+                                         (pDescriptor->ShareDisposition == CmResourceShareShared));
+
+                            EnableWindow(GetDlgItem(hwndDlg, IDC_DEVICE_EXCLUSIVE),
+                                         (pDescriptor->ShareDisposition == CmResourceShareDeviceExclusive));
+
+                            EnableWindow(GetDlgItem(hwndDlg, IDC_DRIVER_EXCLUSIVE),
+                                         (pDescriptor->ShareDisposition == CmResourceShareDriverExclusive));
+                        }
+                    }
+                    else
+                    {
+                        EnableWindow(GetDlgItem(hwndDlg, IDC_UNDETERMINED), FALSE);
+                        EnableWindow(GetDlgItem(hwndDlg, IDC_SHARED), FALSE);
+                        EnableWindow(GetDlgItem(hwndDlg, IDC_DEVICE_EXCLUSIVE), FALSE);
+                        EnableWindow(GetDlgItem(hwndDlg, IDC_DRIVER_EXCLUSIVE), FALSE);
+                    }
+                    break;
+            }
+            break;
+    }
+
+    return FALSE;
+}
+
+
+static INT_PTR CALLBACK modify_resource_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    UNREFERENCED_PARAMETER(lParam);
+
+    switch(uMsg)
+    {
+    case WM_INITDIALOG:
+        CreateResourceColumns(hwndDlg);
+        ParseResources(hwndDlg);
+        return FALSE;
+
+    case WM_NOTIFY:
+        return OnResourceNotify(hwndDlg, (NMHDR *)lParam);
+
+    case WM_COMMAND:
+        switch (LOWORD(wParam))
+        {
+        case IDOK:
+            EndDialog(hwndDlg, IDOK);
+            break;
+        case IDCANCEL:
+            EndDialog(hwndDlg, IDCANCEL);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+static BOOL CreateResourceListColumns(HWND hWndListView)
+{
+    TCHAR szText[80];
+    RECT rc;
+    LV_COLUMN lvC;
+
+    ListView_SetExtendedListViewStyle(hWndListView, LVS_EX_FULLROWSELECT);
+
+    GetClientRect(hWndListView, &rc);
+
+    /* Create columns. */
+    lvC.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
+    lvC.pszText = szText;
+    lvC.fmt = LVCFMT_LEFT;
+
+    /* Load the column labels from the resource file. */
+    lvC.iSubItem = 0;
+    lvC.cx = (rc.right - rc.left) / 2;
+    LoadString(hInst, IDS_BUSNUMBER, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hWndListView, 0, &lvC) == -1)
+        return FALSE;
+
+    lvC.iSubItem = 1;
+    lvC.cx = (rc.right - rc.left) - lvC.cx;
+    LoadString(hInst, IDS_INTERFACE, szText, sizeof(szText)/sizeof(TCHAR));
+    if (ListView_InsertColumn(hWndListView, 1, &lvC) == -1)
+        return FALSE;
+
+    return TRUE;
+}
+
+static VOID AddFullResourcesToList(HWND hwnd)
+{
+    PCM_FULL_RESOURCE_DESCRIPTOR pFullDescriptor;
+    TCHAR buffer[80];
+    LVITEM item;
+    ULONG i;
+    INT iItem;
+
+    for (i = 0; i < resourceValueData->Count; i++)
+    {
+        pFullDescriptor = &resourceValueData->List[i];
+
+        wsprintf(buffer, _T("%lu"), pFullDescriptor->BusNumber);
+
+        item.mask = LVIF_TEXT;
+        item.iItem = i;
+        item.iSubItem = 0;
+        item.state = 0;
+        item.stateMask = 0;
+        item.pszText = buffer;
+        item.cchTextMax = (int)_tcslen(item.pszText);
+
+        iItem = ListView_InsertItem(hwnd, &item);
+        if (iItem != -1)
+        {
+            GetInterfaceType(pFullDescriptor->InterfaceType, buffer, 80);
+            ListView_SetItemText(hwnd, iItem, 1, buffer);
+        }
+    }
+}
+
+static BOOL
+OnResourceListNotify(HWND hwndDlg, NMHDR *phdr)
+{
+    LPNMLISTVIEW lpnmlv = (LPNMLISTVIEW)phdr;
+
+    switch (phdr->idFrom)
+    {
+        case IDC_RESOURCE_LIST:
+            switch(phdr->code)
+            {
+                case NM_CLICK:
+                    fullResourceIndex = lpnmlv->iItem;
+                    EnableWindow(GetDlgItem(hwndDlg, IDC_SHOW_RESOURCE), (lpnmlv->iItem != -1));
+                    break;
+
+                case NM_DBLCLK:
+                    if (lpnmlv->iItem != -1)
+                    {
+                        fullResourceIndex = lpnmlv->iItem;
+                        DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_RESOURCE), hwndDlg, modify_resource_dlgproc);
+                    }
+                    break;
+            }
+            break;
+    }
+
+    return FALSE;
+}
+
+
+static INT_PTR CALLBACK modify_resource_list_dlgproc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+    UNREFERENCED_PARAMETER(lParam);
+
+    switch(uMsg)
+    {
+    case WM_INITDIALOG:
+        CreateResourceListColumns(GetDlgItem(hwndDlg, IDC_RESOURCE_LIST));
+        AddFullResourcesToList(GetDlgItem(hwndDlg, IDC_RESOURCE_LIST));
+        return FALSE;
+
+    case WM_NOTIFY:
+        return OnResourceListNotify(hwndDlg, (NMHDR *)lParam);
+
+    case WM_COMMAND:
+        switch (LOWORD(wParam))
+        {
+        case IDC_SHOW_RESOURCE:
+            if (fullResourceIndex != -1)
+                DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_RESOURCE), hwndDlg, modify_resource_dlgproc);
+            break;
+        case IDOK:
+            EndDialog(hwndDlg, IDOK);
+            break;
+        case IDCANCEL:
+            EndDialog(hwndDlg, IDCANCEL);
+            return TRUE;
+        }
+    }
+    return FALSE;
+}
+
+
 BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName, BOOL EditBin)
 {
     DWORD type;
@@ -612,6 +1241,33 @@ BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName, BOOL EditBin)
                 result = TRUE;
         }
     }
+    else if (EditBin == FALSE && type == REG_RESOURCE_LIST)
+    {
+        if (valueDataLen > 0)
+        {
+            resourceValueData = HeapAlloc(GetProcessHeap(), 0, valueDataLen);
+            if (resourceValueData == NULL)
+            {
+                error(hwnd, IDS_TOO_BIG_VALUE, valueDataLen);
+                goto done;
+            }
+
+            lRet = RegQueryValueEx(hKey, valueName, 0, 0, (LPBYTE)resourceValueData, &valueDataLen);
+            if (lRet != ERROR_SUCCESS)
+            {
+                error(hwnd, IDS_BAD_VALUE, valueName);
+                goto done;
+            }
+        }
+        else
+        {
+            resourceValueData = NULL;
+        }
+
+        if (DialogBox(0, MAKEINTRESOURCE(IDD_EDIT_RESOURCE_LIST), hwnd, modify_resource_list_dlgproc) == IDOK)
+        {
+        }
+    }
     else if (EditBin == TRUE || type == REG_NONE || type == REG_BINARY)
     {
 #ifndef UNICODE
@@ -690,6 +1346,10 @@ BOOL ModifyValue(HWND hwnd, HKEY hKey, LPCTSTR valueName, BOOL EditBin)
     }
 
 done:
+    if (resourceValueData)
+        HeapFree(GetProcessHeap(), 0, resourceValueData);
+    resourceValueData = NULL;
+
     if (stringValueData)
         HeapFree(GetProcessHeap(), 0, stringValueData);
     stringValueData = NULL;