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     HKEY hKey;
248     WCHAR szBuffer[100];
249     WCHAR szDetail[100];
250     BYTE szData[512];
251     DWORD dwSize;
252     PCM_RESOURCE_LIST ResourceList;
253     LONG Result;
254     ULONG ItemCount = 0, Index;
255 
256     wsprintf(szBuffer, L"SYSTEM\\CurrentControlSet\\Enum\\%s\\LogConf", dap->szDeviceID);
257     Result = RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey);
258     if (Result != ERROR_SUCCESS)
259     {
260         /* failed to open device instance log conf dir */
261         return;
262     }
263 
264     dwSize = sizeof(szData);
265     Result = RegQueryValueExW(hKey, L"BootConfig", NULL, NULL, szData, &dwSize);
266 
267     RegCloseKey(hKey);
268     if (Result != ERROR_SUCCESS)
269     {
270         /* failed to query resources */
271         return;
272     }
273 
274     ResourceList = (PCM_RESOURCE_LIST)szData;
275 
276     for (Index = 0; Index < ResourceList->List[0].PartialResourceList.Count; Index++)
277     {
278          PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor = &ResourceList->List[0].PartialResourceList.PartialDescriptors[Index];
279          if (Descriptor->Type == CmResourceTypeInterrupt)
280          {
281              if (LoadString(hDllInstance, IDS_RESOURCE_INTERRUPT, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
282              {
283                  wsprintf(szDetail, L"0x%08x (%d)", Descriptor->u.Interrupt.Level, Descriptor->u.Interrupt.Vector);
284                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
285                  ItemCount++;
286              }
287          }
288          else if (Descriptor->Type == CmResourceTypePort)
289          {
290              if (LoadString(hDllInstance, IDS_RESOURCE_PORT, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
291              {
292                  wsprintf(szDetail, L"%08lx - %08lx", Descriptor->u.Port.Start.LowPart, Descriptor->u.Port.Start.LowPart + Descriptor->u.Port.Length - 1);
293                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
294                  ItemCount++;
295              }
296          }
297          else if (Descriptor->Type == CmResourceTypeMemory)
298          {
299              if (LoadString(hDllInstance, IDS_RESOURCE_MEMORY_RANGE, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
300              {
301                  wsprintf(szDetail, L"%08I64x - %08I64x", Descriptor->u.Memory.Start.QuadPart, Descriptor->u.Memory.Start.QuadPart + Descriptor->u.Memory.Length - 1);
302                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
303                  ItemCount++;
304              }
305          }
306          else if (Descriptor->Type == CmResourceTypeDma)
307          {
308              if (LoadString(hDllInstance, IDS_RESOURCE_DMA, szBuffer, sizeof(szBuffer) / sizeof(szBuffer[0])))
309              {
310                  wsprintf(szDetail, L"%08ld", Descriptor->u.Dma.Channel);
311                  InsertListItem(hWndDevList, ItemCount, szBuffer, szDetail);
312                  ItemCount++;
313              }
314          }
315     }
316 }
317 
318 
319 static VOID
320 UpdateDriverResourceDlg(IN HWND hwndDlg,
321                         IN PDEVADVPROP_INFO dap)
322 {
323     /* set the device image */
324     SendDlgItemMessage(hwndDlg,
325                        IDC_DEVICON,
326                        STM_SETICON,
327                        (WPARAM)dap->hDevIcon,
328                        0);
329 
330     /* set the device name edit control text */
331     SetDlgItemText(hwndDlg,
332                    IDC_DEVNAME,
333                    dap->szDevName);
334 }
335 
336 INT_PTR
337 CALLBACK
338 ResourcesProcDriverDlgProc(IN HWND hwndDlg,
339                      IN UINT uMsg,
340                      IN WPARAM wParam,
341                      IN LPARAM lParam)
342 {
343     PDEVADVPROP_INFO hpd;
344     HWND hWndDevList;
345     INT_PTR Ret = FALSE;
346 
347     hpd = (PDEVADVPROP_INFO)GetWindowLongPtr(hwndDlg, DWLP_USER);
348 
349     if (hpd != NULL || uMsg == WM_INITDIALOG)
350     {
351         switch (uMsg)
352         {
353             case WM_INITDIALOG:
354             {
355                 /* init list */
356                 hWndDevList = GetDlgItem(hwndDlg, IDC_DRIVERRESOURCES);
357                 InitializeDevicesList(hWndDevList);
358 
359                 hpd = (PDEVADVPROP_INFO)((LPPROPSHEETPAGE)lParam)->lParam;
360                 if (hpd != NULL)
361                 {
362                     SetWindowLongPtr(hwndDlg, DWLP_USER, (DWORD_PTR)hpd);
363 
364                     UpdateDriverResourceDlg(hwndDlg, hpd);
365                     AddResourceItems(hpd, hWndDevList);
366                 }
367 
368                 Ret = TRUE;
369                 break;
370             }
371         }
372     }
373 
374     return Ret;
375 }
376 
377