1 /*
2  * PROJECT:         ReactOS devmgr.dll
3  * FILE:            dll/win32/devmgr/hwresource.c
4  * PURPOSE:         ReactOS Device Manager
5  * PROGRAMMER:      Johannes Anderwald <johannes.anderwald@reactos.org>
6  * UPDATE HISTORY:
7  *      2005/11/24  Created
8  */
9 
10 #include "precomp.h"
11 #include "properties.h"
12 #include "resource.h"
13 
14 
15 typedef struct
16 {
17     HWND hWnd;
18     HWND hWndDevList;
19 
20 
21 }HARDWARE_RESOURCE_DATA, *PHARDWARE_RESOURCE_DATA;
22 
23 /* Physical Addresses are always treated as 64-bit wide */
24 typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS;
25 
26 #include <pshpack4.h>
27 typedef struct _CM_PARTIAL_RESOURCE_DESCRIPTOR {
28   UCHAR Type;
29   UCHAR ShareDisposition;
30   USHORT Flags;
31   union {
32     struct {
33       PHYSICAL_ADDRESS Start;
34       ULONG Length;
35     } Generic;
36     struct {
37       PHYSICAL_ADDRESS Start;
38       ULONG Length;
39     } Port;
40     struct {
41 #if defined(NT_PROCESSOR_GROUPS)
42       USHORT Level;
43       USHORT Group;
44 #else
45       ULONG Level;
46 #endif
47       ULONG Vector;
48       KAFFINITY Affinity;
49     } Interrupt;
50 #if (NTDDI_VERSION >= NTDDI_LONGHORN)
51     struct {
52       union {
53         struct {
54 #if defined(NT_PROCESSOR_GROUPS)
55           USHORT Group;
56 #else
57           USHORT Reserved;
58 #endif
59           USHORT MessageCount;
60           ULONG Vector;
61           KAFFINITY Affinity;
62         } Raw;
63         struct {
64 #if defined(NT_PROCESSOR_GROUPS)
65           USHORT Level;
66           USHORT Group;
67 #else
68           ULONG Level;
69 #endif
70           ULONG Vector;
71           KAFFINITY Affinity;
72         } Translated;
73       } DUMMYUNIONNAME;
74     } MessageInterrupt;
75 #endif
76     struct {
77       PHYSICAL_ADDRESS Start;
78       ULONG Length;
79     } Memory;
80     struct {
81       ULONG Channel;
82       ULONG Port;
83       ULONG Reserved1;
84     } Dma;
85     struct {
86       ULONG Data[3];
87     } DevicePrivate;
88     struct {
89       ULONG Start;
90       ULONG Length;
91       ULONG Reserved;
92     } BusNumber;
93     struct {
94       ULONG DataSize;
95       ULONG Reserved1;
96       ULONG Reserved2;
97     } DeviceSpecificData;
98 #if (NTDDI_VERSION >= NTDDI_LONGHORN)
99     struct {
100       PHYSICAL_ADDRESS Start;
101       ULONG Length40;
102     } Memory40;
103     struct {
104       PHYSICAL_ADDRESS Start;
105       ULONG Length48;
106     } Memory48;
107     struct {
108       PHYSICAL_ADDRESS Start;
109       ULONG Length64;
110     } Memory64;
111 #endif
112   } u;
113 } CM_PARTIAL_RESOURCE_DESCRIPTOR, *PCM_PARTIAL_RESOURCE_DESCRIPTOR;
114 #include <poppack.h>
115 typedef struct _CM_PARTIAL_RESOURCE_LIST {
116   USHORT Version;
117   USHORT Revision;
118   ULONG Count;
119   CM_PARTIAL_RESOURCE_DESCRIPTOR PartialDescriptors[1];
120 } CM_PARTIAL_RESOURCE_LIST, *PCM_PARTIAL_RESOURCE_LIST;
121 
122 #define CmResourceTypeNull              0
123 #define CmResourceTypePort              1
124 #define CmResourceTypeInterrupt         2
125 #define CmResourceTypeMemory            3
126 #define CmResourceTypeDma               4
127 #define CmResourceTypeDeviceSpecific    5
128 #define CmResourceTypeBusNumber         6
129 #define CmResourceTypeNonArbitrated     128
130 #define CmResourceTypeConfigData        128
131 #define CmResourceTypeDevicePrivate     129
132 #define CmResourceTypePcCardConfig      130
133 #define CmResourceTypeMfCardConfig      131
134 
135 typedef enum _INTERFACE_TYPE {
136   InterfaceTypeUndefined = -1,
137   Internal,
138   Isa,
139   Eisa,
140   MicroChannel,
141   TurboChannel,
142   PCIBus,
143   VMEBus,
144   NuBus,
145   PCMCIABus,
146   CBus,
147   MPIBus,
148   MPSABus,
149   ProcessorInternal,
150   InternalPowerBus,
151   PNPISABus,
152   PNPBus,
153   Vmcs,
154   MaximumInterfaceType
155 } INTERFACE_TYPE, *PINTERFACE_TYPE;
156 
157 typedef struct _CM_FULL_RESOURCE_DESCRIPTOR {
158   INTERFACE_TYPE InterfaceType;
159   ULONG BusNumber;
160   CM_PARTIAL_RESOURCE_LIST PartialResourceList;
161 } CM_FULL_RESOURCE_DESCRIPTOR, *PCM_FULL_RESOURCE_DESCRIPTOR;
162 
163 typedef struct _CM_RESOURCE_LIST {
164   ULONG                       Count;
165   CM_FULL_RESOURCE_DESCRIPTOR List[1];
166 } CM_RESOURCE_LIST, *PCM_RESOURCE_LIST;
167 
168 
169 #define CX_TYPECOLUMN_WIDTH 120
170 
171 static VOID
172 InitializeDevicesList(
173     IN HWND hWndDevList)
174 {
175     LVCOLUMN lvc;
176     RECT rcClient;
177     WCHAR szColName[255];
178     int iCol = 0;
179 
180     /* set the list view style */
181     (void)ListView_SetExtendedListViewStyle(hWndDevList,
182                                             LVS_EX_FULLROWSELECT);
183 
184     GetClientRect(hWndDevList,
185                   &rcClient);
186 
187     /* add the list view columns */
188     lvc.mask = LVCF_TEXT | LVCF_WIDTH;
189     lvc.fmt = LVCFMT_LEFT;
190     lvc.pszText = szColName;
191 
192     if (LoadString(hDllInstance,
193                    IDS_RESOURCE_COLUMN,
194                    szColName,
195                    sizeof(szColName) / sizeof(szColName[0])))
196     {
197         lvc.cx = CX_TYPECOLUMN_WIDTH;
198         (void)ListView_InsertColumn(hWndDevList,
199                                     iCol++,
200                                     &lvc);
201     }
202     if (LoadString(hDllInstance,
203                    IDS_SETTING_COLUMN,
204                    szColName,
205                    sizeof(szColName) / sizeof(szColName[0])))
206     {
207         lvc.cx = rcClient.right - CX_TYPECOLUMN_WIDTH -
208                  GetSystemMetrics(SM_CXVSCROLL);
209 
210         (void)ListView_InsertColumn(hWndDevList,
211                                     iCol++,
212                                     &lvc);
213     }
214 }
215 
216 VOID
217 InsertListItem(
218     IN HWND hWndDevList,
219     IN INT ItemCount,
220     IN LPWSTR ResourceType,
221     IN LPWSTR ResourceDescription)
222 {
223     INT iItem;
224     LVITEM li = {0};
225 
226     li.mask = LVIF_STATE | LVIF_TEXT;
227     li.iItem = ItemCount;
228     li.pszText = ResourceType;
229     //li.iImage = ClassDevInfo->ImageIndex;
230     iItem = ListView_InsertItem(hWndDevList, &li);
231 
232     if (iItem != -1)
233     {
234         li.mask = LVIF_TEXT;
235         li.iItem = iItem;
236         li.iSubItem = 1;
237         li.pszText = ResourceDescription;
238         (void)ListView_SetItem(hWndDevList, &li);
239     }
240 }
241 
242 VOID
243 AddResourceItems(
244     IN PDEVADVPROP_INFO dap,
245     IN HWND hWndDevList)
246 {
247     WCHAR szBuffer[100];
248     WCHAR szDetail[100];
249     PCM_RESOURCE_LIST ResourceList;
250     ULONG ItemCount = 0, Index;
251 
252     ResourceList = (PCM_RESOURCE_LIST)dap->pResourceList;
253 
254     for (Index = 0; Index < ResourceList->List[0].PartialResourceList.Count; Index++)
255     {
256          PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[Index];
257          if (Descriptor->Type == CmResourceTypeInterrupt)
258          {
259              if (LoadString(hDllInstance, IDS_RESOURCE_INTERRUPT, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
260              {
261                  wsprintf(szDetail, L"0x%08x (%d)", Descriptor->u.Interrupt.Level, Descriptor->u.Interrupt.Vector);
262                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
263                  ItemCount++;
264              }
265          }
266          else if (Descriptor->Type == CmResourceTypePort)
267          {
268              if (LoadString(hDllInstance, IDS_RESOURCE_PORT, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
269              {
270                  wsprintf(szDetail, L"%08lx - %08lx", Descriptor->u.Port.Start.LowPart, Descriptor->u.Port.Start.LowPart + Descriptor->u.Port.Length - 1);
271                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
272                  ItemCount++;
273              }
274          }
275          else if (Descriptor->Type == CmResourceTypeMemory)
276          {
277              if (LoadString(hDllInstance, IDS_RESOURCE_MEMORY_RANGE, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
278              {
279                  wsprintf(szDetail, L"%08I64x - %08I64x", Descriptor->u.Memory.Start.QuadPart, Descriptor->u.Memory.Start.QuadPart + Descriptor->u.Memory.Length - 1);
280                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
281                  ItemCount++;
282              }
283          }
284          else if (Descriptor->Type == CmResourceTypeDma)
285          {
286              if (LoadString(hDllInstance, IDS_RESOURCE_DMA, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
287              {
288                  wsprintf(szDetail, L"%08ld", Descriptor->u.Dma.Channel);
289                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
290                  ItemCount++;
291              }
292          }
293     }
294 }
295 
296 
297 static VOID
298 UpdateDriverResourceDlg(IN HWND hwndDlg,
299                         IN PDEVADVPROP_INFO dap)
300 {
301     /* set the device image */
302     SendDlgItemMessage(hwndDlg,
303                        IDC_DEVICON,
304                        STM_SETICON,
305                        (WPARAM)dap->hDevIcon,
306                        0);
307 
308     /* set the device name edit control text */
309     SetDlgItemText(hwndDlg,
310                    IDC_DEVNAME,
311                    dap->szDevName);
312 }
313 
314 INT_PTR
315 CALLBACK
316 ResourcesProcDriverDlgProc(IN HWND hwndDlg,
317                      IN UINT uMsg,
318                      IN WPARAM wParam,
319                      IN LPARAM lParam)
320 {
321     PDEVADVPROP_INFO hpd;
322     HWND hWndDevList;
323     INT_PTR Ret = FALSE;
324 
325     hpd = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
326 
327     if (hpd != NULL || uMsg == WM_INITDIALOG)
328     {
329         switch (uMsg)
330         {
331             case WM_INITDIALOG:
332             {
333                 /* init list */
334                 hWndDevList = GetDlgItem(hwndDlg, IDC_DRIVERRESOURCES);
335                 InitializeDevicesList(hWndDevList);
336 
337                 hpd = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
338                 if (hpd != NULL)
339                 {
340                     SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)hpd);
341 
342                     UpdateDriverResourceDlg(hwndDlg, hpd);
343                     AddResourceItems(hpd, hWndDevList);
344                 }
345 
346                 Ret = TRUE;
347                 break;
348             }
349         }
350     }
351 
352     return Ret;
353 }
354 
355 
356 PVOID
357 GetResourceList(
358     LPWSTR pszDeviceID)
359 {
360     WCHAR szBuffer[100];
361     PCM_RESOURCE_LIST pResourceList = NULL;
362     HKEY hKey = NULL;
363     DWORD dwError, dwSize;
364 
365     wsprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Enum\\%s\\LogConf", pszDeviceID);
366     dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey);
367     if (dwError != ERROR_SUCCESS)
368     {
369         /* failed to open device instance log conf dir */
370         return NULL;
371     }
372 
373     dwSize = 0;
374     RegQueryValueExW(hKey, L"BootConfig", NULL, NULL, NULL, &dwSize);
375     if (dwSize == 0)
376         goto done;
377 
378     pResourceList = static_cast<PCM_RESOURCE_LIST>(HeapAlloc(GetProcessHeap(), 0, dwSize));
379     if (pResourceList == NULL)
380         goto done;
381 
382     dwError = RegQueryValueExW(hKey, L"BootConfig", NULL, NULL, (LPBYTE)pResourceList, &dwSize);
383     if (dwError != ERROR_SUCCESS)
384     {
385         HeapFree(GetProcessHeap(), 0, pResourceList);
386         pResourceList = NULL;
387     }
388 
389 done:
390     if (hKey != NULL)
391         RegCloseKey(hKey);
392 
393     return (PVOID)pResourceList;
394 }
395