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
InitializeDevicesList(IN HWND hWndDevList)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
InsertListItem(IN HWND hWndDevList,IN INT ItemCount,IN LPWSTR ResourceType,IN LPWSTR ResourceDescription)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
AddResourceItems(IN PDEVADVPROP_INFO dap,IN HWND hWndDevList)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
UpdateDriverResourceDlg(IN HWND hwndDlg,IN PDEVADVPROP_INFO dap)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
ResourcesProcDriverDlgProc(IN HWND hwndDlg,IN UINT uMsg,IN WPARAM wParam,IN LPARAM lParam)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
GetResourceList(LPWSTR pszDeviceID)357 GetResourceList(
358 LPWSTR pszDeviceID)
359 {
360 PCM_RESOURCE_LIST pResourceList = NULL;
361 HKEY hKey = NULL;
362 DWORD dwError, dwSize;
363
364 CStringW keyName = L"SYSTEM\\CurrentControlSet\\Enum\\";
365 keyName += pszDeviceID;
366 keyName += L"\\Control";
367
368 dwError = RegOpenKeyExW(HKEY_LOCAL_MACHINE, keyName, 0, KEY_READ, &hKey);
369 if (dwError != ERROR_SUCCESS)
370 {
371 /* failed to open device instance log conf dir */
372 return NULL;
373 }
374
375 dwSize = 0;
376 RegQueryValueExW(hKey, L"AllocConfig", NULL, NULL, NULL, &dwSize);
377 if (dwSize == 0)
378 goto done;
379
380 pResourceList = static_cast<PCM_RESOURCE_LIST>(HeapAlloc(GetProcessHeap(), 0, dwSize));
381 if (pResourceList == NULL)
382 goto done;
383
384 dwError = RegQueryValueExW(hKey, L"AllocConfig", NULL, NULL, (LPBYTE)pResourceList, &dwSize);
385 if (dwError != ERROR_SUCCESS)
386 {
387 HeapFree(GetProcessHeap(), 0, pResourceList);
388 pResourceList = NULL;
389 }
390
391 done:
392 if (hKey != NULL)
393 RegCloseKey(hKey);
394
395 return (PVOID)pResourceList;
396 }
397