2 * (C) 2005 - Hervé Poussineau (hpoussin@reactos.org)
3 * GUI: Michael Fritscher (michael@fritscher.net)
15 #if defined (__GNUC__)
19 /* FIXME: should be in cfgmgr32.h */
20 typedef DWORD CONFIGRET
;
21 typedef DWORD DEVINST
, *PDEVINST
;
22 #define CM_DRP_DEVICEDESC 0x00000001
23 #define MAX_DEVICE_ID_LEN 200
24 #define MAX_CLASS_NAME_LEN 32
25 #define CR_SUCCESS 0x00000000
26 #define CR_NO_SUCH_DEVINST 0x0000000D
27 #define CR_NO_SUCH_VALUE 0x00000025
29 typedef WCHAR
*DEVINSTID_W
;
30 CONFIGRET WINAPI
CM_Get_DevNode_Registry_PropertyW(DEVINST
, ULONG
, PULONG
, PVOID
, PULONG
, ULONG
);
31 CONFIGRET WINAPI
CM_Locate_DevNodeW(PDEVINST
, DEVINSTID_W
, ULONG
);
32 #define CM_Get_DevNode_Registry_Property CM_Get_DevNode_Registry_PropertyW
33 #define CM_Locate_DevNode CM_Locate_DevNodeW
35 typedef CHAR
*DEVINSTID_A
;
36 CONFIGRET WINAPI
CM_Get_DevNode_Registry_PropertyA(DEVINST
, ULONG
, PULONG
, PVOID
, PULONG
, ULONG
);
37 CONFIGRET WINAPI
CM_Locate_DevNodeA(PDEVINST
, DEVINSTID_A
, ULONG
);
38 #define CM_Get_DevNode_Registry_Property CM_Get_DevNode_Registry_PropertyA
39 #define CM_Locate_DevNode CM_Locate_DevNodeA
41 CONFIGRET WINAPI
CM_Enumerate_Classes(ULONG
, LPGUID
, ULONG
);
42 CONFIGRET WINAPI
CM_Get_Child(PDEVINST
, DEVINST
, ULONG
);
43 CONFIGRET WINAPI
CM_Get_Sibling(PDEVINST
, DEVINST
, ULONG
);
44 /* end of cfgmgr32.h */
46 /**************************************************************************
48 **************************************************************************/
50 BOOL
InitApplication(HINSTANCE
);
51 BOOL
InitInstance(HINSTANCE
, int);
52 LRESULT CALLBACK
MainWndProc(HWND
, UINT
, WPARAM
, LPARAM
);
53 void CreateListView(HINSTANCE
, HWND
);
54 void ResizeListView(HWND
);
56 void InsertIntoListView(int, LPTSTR
, LPTSTR
);
59 LRESULT
ListViewNotify(HWND
, LPARAM
);
60 void SwitchView(HWND
, DWORD
);
61 BOOL
DoContextMenu(HWND
, WPARAM
, LPARAM
);
62 void UpdateMenu(HWND
, HMENU
);
63 BOOL
InsertListViewItems();
64 void PositionHeader();
69 /**************************************************************************
71 **************************************************************************/
74 TCHAR g_szClassName
[] = TEXT("VListVwClass");
77 HWND hwndButtonListByClass
;
78 HWND hwndButtonListByConnection
;
79 HWND hwndButtonListByInterface
;
83 TCHAR empty
[255] = TEXT(" ");
88 TCHAR ClassDescription
[MAX_PATH
];
89 TCHAR ClassName
[MAX_CLASS_NAME_LEN
];
90 TCHAR PropertyBuffer
[256];
93 SP_DEVINFO_DATA DeviceInfoData
;
98 SendMessage(hwndListView
, WM_SETREDRAW
, FALSE
, 0);
100 ListView_DeleteAllItems(hwndListView
);
104 res
= CM_Enumerate_Classes(i
, &ClassGuid
, 0);
105 if (res
== CR_NO_SUCH_VALUE
)
110 if (!SetupDiClassNameFromGuid(
113 sizeof(ClassName
) / sizeof(ClassName
[0]),
116 _tprintf(_T("SetupDiClassNameFromGuid() failed with status 0x%lx\n"), GetLastError());
120 /* Get class description */
121 KeyClass
= SetupDiOpenClassRegKey(
124 if (KeyClass
== INVALID_HANDLE_VALUE
)
126 _tprintf(_T("SetupDiOpenClassRegKey() failed with status 0x%lx\n"), GetLastError());
129 Size
= sizeof(ClassDescription
);
130 rc
= RegQueryValue(KeyClass
, NULL
, ClassDescription
, &Size
);
131 if (rc
== ERROR_SUCCESS
)
133 InsertIntoListView(i
,ClassDescription
,ClassName
);
134 TextOut(hDC
, 200, 40, empty
, strlen(empty
));
135 TextOut(hDC
, 200, 40, ClassDescription
, strlen(ClassDescription
));
136 _tprintf(_T("%d %s (%s)\n"), i
, ClassName
, ClassDescription
);
139 _tprintf(_T("RegQueryValue() failed with status 0x%lx\n"), rc
);
140 RegCloseKey(KeyClass
);
142 /* Enumerate devices in the class */
143 hDevInfo
= SetupDiGetClassDevs(
145 NULL
, /* Enumerator */
146 NULL
, /* hWnd parent */
148 if (hDevInfo
== INVALID_HANDLE_VALUE
)
154 DeviceInfoData
.cbSize
= sizeof(SP_DEVINFO_DATA
);
155 if (!SetupDiEnumDeviceInfo(
163 if (SetupDiGetDeviceRegistryProperty(
167 NULL
, /* Property reg data type */
168 (PBYTE
)PropertyBuffer
,
169 sizeof(PropertyBuffer
),
170 NULL
) /* Required size */)
172 _tprintf(_T("- %s\n"), PropertyBuffer
);
173 InsertIntoListView(0,PropertyBuffer
," ");
175 else if (SetupDiGetDeviceRegistryProperty(
178 SPDRP_PHYSICAL_DEVICE_OBJECT_NAME
,
179 NULL
, /* Property reg data type */
180 (PBYTE
)PropertyBuffer
,
181 sizeof(PropertyBuffer
),
182 NULL
) /* Required size */)
184 _tprintf(_T("- %s\n"), PropertyBuffer
);
185 InsertIntoListView(0,PropertyBuffer
," ");
186 TextOut(hDC
, 200, 40, empty
, strlen(empty
));
187 TextOut(hDC
, 200, 40, PropertyBuffer
, strlen(PropertyBuffer
));
190 _tprintf(_T("SetupDiGetDeviceRegistryProperty() failed with status 0x%lx\n"), GetLastError());
192 SetupDiDestroyDeviceInfoList(hDevInfo
);
194 SendMessage(hwndListView
, WM_SETREDRAW
, TRUE
, 0);
197 CONFIGRET
GetDeviceName(DEVINST DevInst
, LPTSTR Buffer
, DWORD BufferLength
)
199 ULONG BufferSize
= BufferLength
* sizeof(TCHAR
);
201 cr
= CM_Get_DevNode_Registry_Property(DevInst
, CM_DRP_DEVICEDESC
, NULL
, Buffer
, &BufferSize
, 0);
202 if (cr
!= CR_SUCCESS
)
204 _tprintf(_T("CM_Get_DevNode_Registry_Property() failed, cr= 0x%lx\n"), cr
);
209 CONFIGRET
ListSubNodes(DEVINST parent
, DWORD Level
)
214 cr
= CM_Get_Child(&child
, parent
, 0);
215 if (cr
== CR_NO_SUCH_DEVINST
)
217 else if (cr
!= CR_SUCCESS
)
219 _tprintf(_T("CM_Get_Child() failed, cr= 0x%lx\n"), cr
);
225 #define DISPLAY_LENGTH (MAX_PATH + MAX_DEVICE_ID_LEN)
226 DWORD DisplayLength
= DISPLAY_LENGTH
;
227 TCHAR DisplayName
[DISPLAY_LENGTH
];
229 TCHAR LevelSpaces
[ 255 ];
230 cr
= GetDeviceName(child
, DisplayName
, DisplayLength
);
231 LevelSpaces
[0] = '\0';
235 sprintf(LevelSpaces
,"%s%s",LevelSpaces
," ");
237 if (cr
== CR_SUCCESS
)
239 _tprintf(_T("%s\n"), DisplayName
);
240 sprintf(temp
,"%s%s",LevelSpaces
,DisplayName
);
241 InsertIntoListView(0,temp
," ");
242 TextOut(hDC
, 200, 40, empty
, strlen(empty
));
243 TextOut(hDC
, 200, 40, DisplayName
, strlen(DisplayName
));
247 _tprintf(_T("(unknown device)\n"));
248 sprintf(temp
,"%s%s",LevelSpaces
,"(unknown device)");
249 InsertIntoListView(0,temp
," ");
250 TextOut(hDC
, 200, 40, empty
, strlen(empty
));
251 TextOut(hDC
, 200, 40, "(unknown device)", strlen("(unknown device)"));
253 cr
= ListSubNodes(child
, Level
+ 1);
254 if (cr
!= CR_SUCCESS
)
256 cr
= CM_Get_Sibling(&child
, child
, 0);
257 if (cr
!= CR_SUCCESS
&& cr
!= CR_NO_SUCH_DEVINST
)
259 _tprintf(_T("CM_Get_Sibling() failed, cr= 0x%lx\n"), cr
);
262 } while (cr
== CR_SUCCESS
);
266 int ListByConnection()
270 ListView_DeleteAllItems(hwndListView
);
272 cr
= CM_Locate_DevNode(&root
, NULL
, 0);
274 if (cr
!= CR_SUCCESS
)
276 _tprintf(_T("CM_Locate_DevNode() failed, cr= 0x%lx\n"), cr
);
279 SendMessage(hwndListView
, WM_SETREDRAW
, FALSE
, 0);
280 cr
= ListSubNodes(root
, 0);
281 SendMessage(hwndListView
, WM_SETREDRAW
, TRUE
, 0);
282 if (cr
!= CR_SUCCESS
)
287 int ListByInterface(const GUID
* guid
)
290 CHAR Buffer
[sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA
) + 0x100];
291 PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData
;
293 SP_DEVICE_INTERFACE_DATA DeviceInterfaceData
;
295 ListView_DeleteAllItems(hwndListView
);
297 DeviceInterfaceDetailData
= (PSP_DEVICE_INTERFACE_DETAIL_DATA
)Buffer
;
298 DeviceInterfaceDetailData
->cbSize
= sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA
);
300 hDevInfo
= SetupDiGetClassDevs(
302 NULL
, /* Enumerator */
303 NULL
, /* hwndParent */
304 DIGCF_DEVICEINTERFACE
);
305 if (hDevInfo
== INVALID_HANDLE_VALUE
)
307 printf("SetupDiGetClassDevs() failed with status 0x%lx\n", GetLastError());
312 DeviceInterfaceData
.cbSize
= sizeof(SP_DEVICE_INTERFACE_DATA
);
313 SendMessage(hwndListView
, WM_SETREDRAW
, FALSE
, 0);
316 if (!SetupDiEnumDeviceInterfaces(
321 &DeviceInterfaceData
))
323 if (GetLastError() != ERROR_NO_MORE_ITEMS
)
324 printf("SetupDiEnumDeviceInterfaces() failed with status 0x%lx\n", GetLastError());
328 if (SetupDiGetDeviceInterfaceDetail(hDevInfo
, &DeviceInterfaceData
, DeviceInterfaceDetailData
, sizeof(Buffer
), NULL
, NULL
))
330 _tprintf(_T("- device %-2ld: %s\n"), i
, DeviceInterfaceDetailData
->DevicePath
);
331 TextOut(hDC
, 200, 40, empty
, strlen(empty
));
332 TextOut(hDC
, 200, 40, DeviceInterfaceDetailData
->DevicePath
, strlen(DeviceInterfaceDetailData
->DevicePath
));
333 InsertIntoListView(i
,DeviceInterfaceDetailData
->DevicePath
," ");
337 _tprintf(_T("- device %ld\n"), i
);
338 InsertIntoListView(i
," "," ");
342 SendMessage(hwndListView
, WM_SETREDRAW
, TRUE
, 0);
343 SetupDiDestroyDeviceInfoList(hDevInfo
);
350 ListByInterface(&GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR);
358 int WINAPI
WinMain( HINSTANCE hInstance
,
359 HINSTANCE hPrevInstance
,
368 if(!InitApplication(hInstance
))
371 //required to use the common controls
372 InitCommonControls();
374 /* Perform initializations that apply to a specific instance */
376 if (!InitInstance(hInstance
, nCmdShow
))
379 /* Acquire and dispatch messages until a WM_QUIT uMessage is received. */
381 while(GetMessage( &msg
, NULL
, 0x00, 0x00))
383 TranslateMessage(&msg
);
384 DispatchMessage(&msg
);
387 return (int)msg
.wParam
;
390 BOOL
InitApplication(HINSTANCE hInstance
)
395 wcex
.cbSize
= sizeof(WNDCLASSEX
);
397 wcex
.lpfnWndProc
= (WNDPROC
)MainWndProc
;
400 wcex
.hInstance
= hInstance
;
401 wcex
.hCursor
= LoadCursor(NULL
, IDC_ARROW
);
402 wcex
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
);
403 wcex
.lpszMenuName
= 0;
404 wcex
.lpszClassName
= g_szClassName
;
408 aReturn
= RegisterClassEx(&wcex
);
415 wc
.lpfnWndProc
= (WNDPROC
)MainWndProc
;
418 wc
.hInstance
= hInstance
;
421 wc
.hbrBackground
= (HBRUSH
)(COLOR_WINDOW
);
423 wc
.lpszClassName
= g_szClassName
;
425 aReturn
= RegisterClass(&wc
);
431 BOOL
InitInstance( HINSTANCE hInstance
,
435 TCHAR szTitle
[MAX_PATH
] = TEXT("Device viewer");
439 /* Create a main window for this application instance. */
440 hWnd
= CreateWindowEx( 0,
453 /* If window could not be created, return "failure" */
458 /* Make the window visible; update its client area; and return "success" */
460 ShowWindow(hWnd
, nCmdShow
);
467 LRESULT CALLBACK
MainWndProc( HWND hWnd
,
477 // create the TreeView control
478 CreateListView(g_hInst
, hWnd
);
480 //initialize the TreeView control
483 CreateButtons(g_hInst
, hWnd
);
484 TextOut(hDC
, 200, 40, empty
, strlen(empty
));
489 ResizeListView(hWnd
);
492 ReleaseDC(hWnd
, hDC
);
496 if (HIWORD(wParam
) == BN_CLICKED
&&
497 (HWND
) lParam
== hwndButtonListByClass
)
501 if (HIWORD(wParam
) == BN_CLICKED
&&
502 (HWND
) lParam
== hwndButtonListByConnection
)
506 if (HIWORD(wParam
) == BN_CLICKED
&&
507 (HWND
) lParam
== hwndButtonListByInterface
)
509 ListByInterface(&GUID_DEVINTERFACE_SERENUM_BUS_ENUMERATOR
);
511 if (HIWORD(wParam
) == BN_CLICKED
&&
512 (HWND
) lParam
== hwndButtonExit
)
514 /* Close the window. */
515 DestroyWindow (hWnd
);
521 return DefWindowProc(hWnd
, uMessage
, wParam
, lParam
);
524 void CreateListView(HINSTANCE hInstance
, HWND hwndParent
)
528 dwStyle
= WS_TABSTOP
|
536 hwndListView
= CreateWindowEx( WS_EX_CLIENTEDGE
, // ex style
537 WC_LISTVIEW
, // class name - defined in commctrl.h
538 TEXT(""), // dummy text
544 hwndParent
, // parent
545 0,//(HMENU)ID_LISTVIEW, // ID
547 NULL
); // no extra data
550 ResizeListView(hwndParent
);
553 void ResizeListView(HWND hwndParent
)
557 GetClientRect(hwndParent
, &rc
);
559 MoveWindow( hwndListView
,
563 rc
.bottom
- rc
.top
-60,
567 void PositionHeader()
569 HWND hwndHeader
= GetWindow(hwndListView
, GW_CHILD
);
570 DWORD dwStyle
= GetWindowLong(hwndListView
, GWL_STYLE
);
572 /*To ensure that the first item will be visible, create the control without
573 the LVS_NOSCROLL style and then add it here*/
574 dwStyle
|= LVS_NOSCROLL
;
575 SetWindowLong(hwndListView
, GWL_STYLE
, dwStyle
);
577 //only do this if we are in report view and were able to get the header hWnd
578 if(((dwStyle
& LVS_TYPEMASK
) == LVS_REPORT
) && hwndHeader
)
584 GetClientRect(hwndListView
, &rc
);
586 hdLayout
.pwpos
= &wpos
;
588 Header_Layout(hwndHeader
, &hdLayout
);
590 SetWindowPos( hwndHeader
,
591 wpos
.hwndInsertAfter
,
596 wpos
.flags
| SWP_SHOWWINDOW
);
598 ListView_EnsureVisible(hwndListView
, 0, FALSE
);
606 TCHAR szString
[3][20] = {TEXT("#"), TEXT("Name"), TEXT("Intern name")};
609 ListView_DeleteAllItems(hwndListView
);
611 //initialize the columns
612 lvColumn
.mask
= LVCF_FMT
| LVCF_WIDTH
| LVCF_TEXT
| LVCF_SUBITEM
;
613 lvColumn
.fmt
= LVCFMT_LEFT
;
616 lvColumn
.pszText
= szString
[i
];
617 ListView_InsertColumn(hwndListView
, i
, &lvColumn
);
620 lvColumn
.pszText
= szString
[i
];
621 ListView_InsertColumn(hwndListView
, i
, &lvColumn
);
624 lvColumn
.pszText
= szString
[i
];
625 ListView_InsertColumn(hwndListView
, i
, &lvColumn
);
631 typedef struct tagLINE_INFO
637 } LINE_INFO
, *PLINE_INFO
;
639 void InsertIntoListView(int typ
, LPTSTR name
, LPTSTR intern_name
)
641 //MessageBox(hWnd, "You just pressed Ctrl+a", "Hotkey", MB_OK | MB_ICONINFORMATION);
646 //linfo->name = Name;
647 item
.mask
= LVIF_TEXT
;
651 //item.statemask = 0;
652 item
.pszText
=malloc(10);
655 sprintf(temp
,"%i",typ
);
660 item
.cchTextMax
= _tcslen(item
.pszText
);
661 if (item
.cchTextMax
== 0)
662 item
.pszText
= LPSTR_TEXTCALLBACK
;
666 //item.cColumns = 0 ;
667 //item.puColumns = 0;
668 //item.lParam = (LPARAM)linfo;
669 index
= ListView_InsertItem(hwndListView
, &item
);
670 ListView_SetItemText(hwndListView
, index
, 1, name
);
671 ListView_SetItemText(hwndListView
, index
, 2, intern_name
);
676 void CreateButtons(HINSTANCE hInstance
, HWND hwndParent
)
679 hwndButtonListByClass
= CreateWindowEx (
681 "button", /* Builtin button class */
683 WS_CHILD
| WS_VISIBLE
| BS_PUSHBUTTON
,
685 hwndParent
, /* Parent is this window. */
686 0, /* Control ID: 1 */
690 hwndButtonListByConnection
= CreateWindowEx (
692 "button", /* Builtin button class */
693 "List by Connection",
694 WS_CHILD
| WS_VISIBLE
| BS_PUSHBUTTON
,
696 hwndParent
, /* Parent is this window. */
697 0, /* Control ID: 1 */
701 hwndButtonListByInterface
= CreateWindowEx (
703 "button", /* Builtin button class */
705 WS_CHILD
| WS_VISIBLE
| BS_PUSHBUTTON
,
707 hwndParent
, /* Parent is this window. */
708 0, /* Control ID: 1 */
712 hwndButtonExit
= CreateWindowEx (
714 "button", /* Builtin button class */
716 WS_CHILD
| WS_VISIBLE
| BS_PUSHBUTTON
,
718 hwndParent
, /* Parent is this window. */
719 0, /* Control ID: 1 */