diff options
| author | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
|---|---|---|
| committer | Dave Wilson <[email protected]> | 2015-03-17 19:50:07 -0700 |
| commit | 97cf5197cf5b882b2c689d8dc2b555f2edf8f418 (patch) | |
| tree | 46f3701832d70b420eb0fc0eb93261f9da45db3f /usb/usbview/uvcview.c | |
| parent | ef1905bf1e8825bb31120dfb27e0daf3154d859a (diff) | |
Initial publish
Diffstat (limited to 'usb/usbview/uvcview.c')
| -rw-r--r-- | usb/usbview/uvcview.c | 2153 |
1 files changed, 2153 insertions, 0 deletions
diff --git a/usb/usbview/uvcview.c b/usb/usbview/uvcview.c new file mode 100644 index 00000000..f5600175 --- /dev/null +++ b/usb/usbview/uvcview.c @@ -0,0 +1,2153 @@ +/*++ + +Copyright (c) 1997-2011 Microsoft Corporation + +Module Name: + +USBVIEW.C + +Abstract: + +This is the GUI goop for the USBVIEW application. + +Environment: + +user mode + +Revision History: + +04-25-97 : created +11-20-02 : minor changes to support more reporting options +04/13/2005 : major bug fixing +07/01/2008 : add UVC 1.1 support and move to Dev branch + +--*/ + +/***************************************************************************** +I N C L U D E S +*****************************************************************************/ + +#include "resource.h" +#include "uvcview.h" +#include "h264.h" +#include "xmlhelper.h" + +#include <commdlg.h> + + +/***************************************************************************** +D E F I N E S +*****************************************************************************/ + +// window control defines +// +#define SIZEBAR 0 +#define WINDOWSCALEFACTOR 15 + +/***************************************************************************** + L O C A L T Y P E D E F S +*****************************************************************************/ +typedef struct _TREEITEMINFO +{ + struct _TREEITEMINFO *Next; + USHORT Depth; + PCHAR Name; + +} TREEITEMINFO, *PTREEITEMINFO; + + +/***************************************************************************** +L O C A L E N U M S +*****************************************************************************/ + +typedef enum _USBVIEW_SAVE_FILE_TYPE +{ + UsbViewNone = 0, + UsbViewXmlFile, + UsbViewTxtFile +} USBVIEW_SAVE_FILE_TYPE; + +/***************************************************************************** +L O C A L F U N C T I O N P R O T O T Y P E S +*****************************************************************************/ + +int WINAPI +WinMain ( + _In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPSTR lpszCmdLine, + _In_ int nCmdShow + ); + +BOOL +CreateMainWindow ( + int nCmdShow + ); + +VOID +ResizeWindows ( + BOOL bSizeBar, + int BarLocation + ); + +LRESULT CALLBACK +MainDlgProc ( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ); + +BOOL +USBView_OnInitDialog ( + HWND hWnd, + HWND hWndFocus, + LPARAM lParam + ); + +VOID +USBView_OnClose ( + HWND hWnd + ); + +VOID +USBView_OnCommand ( + HWND hWnd, + int id, + HWND hwndCtl, + UINT codeNotify + ); + +VOID +USBView_OnLButtonDown ( + HWND hWnd, + BOOL fDoubleClick, + int x, + int y, + UINT keyFlags + ); + +VOID +USBView_OnLButtonUp ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ); + +VOID +USBView_OnMouseMove ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ); + +VOID +USBView_OnSize ( + HWND hWnd, + UINT state, + int cx, + int cy + ); + +LRESULT +USBView_OnNotify ( + HWND hWnd, + int DlgItem, + LPNMHDR lpNMHdr + ); + +BOOL +USBView_OnDeviceChange ( + HWND hwnd, + UINT uEvent, + DWORD dwEventData + ); + +VOID DestroyTree (VOID); + +VOID RefreshTree (VOID); + +LRESULT CALLBACK +AboutDlgProc ( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ); + +VOID +WalkTree ( + _In_ HTREEITEM hTreeItem, + _In_ LPFNTREECALLBACK lpfnTreeCallback, + _In_opt_ PVOID pContext + ); + +VOID +ExpandItem ( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ); + +VOID +AddItemInformationToFile( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ); + +DWORD +DisplayLastError( + _Inout_updates_bytes_(count) char *szString, + int count); + +VOID AddItemInformationToXmlView( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ); +HRESULT InitializeConsole(); +VOID UnInitializeConsole(); +BOOL IsStdOutFile(); +VOID DisplayMessage(DWORD dwMsgId, ...); +VOID PrintString(LPTSTR lpszString); +LPTSTR WStringToAnsiString(LPWSTR lpwszString); +VOID WaitForKeyPress(); +BOOL ProcessCommandLine(); +HRESULT ProcessCommandSaveFile(LPTSTR szFileName, DWORD dwCreationDisposition, USBVIEW_SAVE_FILE_TYPE fileType); +HRESULT SaveAllInformationAsText(LPTSTR lpstrTextFileName, DWORD dwCreationDisposition); +HRESULT SaveAllInformationAsXml(LPTSTR lpstrTextFileName , DWORD dwCreationDisposition); + +/***************************************************************************** +G L O B A L S +*****************************************************************************/ +BOOL gDoConfigDesc = TRUE; +BOOL gDoAnnotation = TRUE; +BOOL gLogDebug = FALSE; +int TotalHubs = 0; + +extern DEVICE_GUID_LIST gHubList; +extern DEVICE_GUID_LIST gDeviceList; + +/***************************************************************************** +G L O B A L S P R I V A T E T O T H I S F I L E +*****************************************************************************/ + +HINSTANCE ghInstance = NULL; +HWND ghMainWnd = NULL; +HWND ghTreeWnd = NULL; +HWND ghEditWnd = NULL; +HWND ghStatusWnd = NULL; +HMENU ghMainMenu = NULL; +HTREEITEM ghTreeRoot = NULL; +HCURSOR ghSplitCursor = NULL; +HDEVNOTIFY gNotifyDevHandle = NULL; +HDEVNOTIFY gNotifyHubHandle = NULL; +HANDLE ghStdOut = NULL; + +BOOL gbConsoleFile = FALSE; +BOOL gbConsoleInitialized = FALSE; +BOOL gbButtonDown = FALSE; +BOOL gDoAutoRefresh = TRUE; + +int gBarLocation = 0; +int giGoodDevice = 0; +int giBadDevice = 0; +int giComputer = 0; +int giHub = 0; +int giNoDevice = 0; +int giGoodSsDevice = 0; +int giNoSsDevice = 0; + + +/***************************************************************************** + +WinMain() + +*****************************************************************************/ + +int WINAPI +WinMain ( + _In_ HINSTANCE hInstance, + _In_opt_ HINSTANCE hPrevInstance, + _In_ LPSTR lpszCmdLine, + _In_ int nCmdShow + ) +{ + MSG msg; + HACCEL hAccel; + int retStatus = 0; + + UNREFERENCED_PARAMETER(hPrevInstance); + UNREFERENCED_PARAMETER(lpszCmdLine); + + InitXmlHelper(); + + ghInstance = hInstance; + + ghSplitCursor = LoadCursor(ghInstance, + MAKEINTRESOURCE(IDC_SPLIT)); + + if (!ghSplitCursor) + { + OOPS(); + return retStatus; + } + + hAccel = LoadAccelerators(ghInstance, + MAKEINTRESOURCE(IDACCEL)); + + if (!hAccel) + { + OOPS(); + return retStatus; + } + + if (!CreateTextBuffer()) + { + return retStatus; + } + + if (!ProcessCommandLine()) + { + // There were no command line flags, open GUI + if (CreateMainWindow(nCmdShow)) + { + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!TranslateAccelerator(ghMainWnd, + hAccel, + &msg) && + !IsDialogMessage(ghMainWnd, + &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + retStatus = 1; + } + } + + DestroyTextBuffer(); + + ReleaseXmlWriter(); + + CHECKFORLEAKS(); + + return retStatus; +} + + +/***************************************************************************** + +ProcessCommandLine() + +Parses the command line and takes appropriate actions. Returns FALSE If there is no action to +perform +*****************************************************************************/ +BOOL ProcessCommandLine() +{ + LPWSTR *szArgList = NULL; + LPTSTR szArg = NULL; + LPTSTR szAnsiArg= NULL; + BOOL quietMode = FALSE; + + HRESULT hr = S_OK; + DWORD dwCreationDisposition = CREATE_NEW; + USBVIEW_SAVE_FILE_TYPE fileType = UsbViewNone; + + int nArgs = 0; + int i = 0; + BOOL bStatus = FALSE; + BOOL bStopArgProcessing = FALSE; + + szArgList = CommandLineToArgvW(GetCommandLineW(), &nArgs); + + // If there are no arguments we return false + bStatus = (nArgs > 1)? TRUE:FALSE; + + if (NULL != szArgList) + { + if (nArgs > 1) + { + // If there are arguments, initialize console for ouput + InitializeConsole(); + } + + for (i = 1; (i < nArgs) && (bStopArgProcessing == FALSE); i++) + { + // Convert argument to ANSI string for futher processing + + szAnsiArg = WStringToAnsiString(szArgList[i]); + + if(NULL == szAnsiArg) + { + DisplayMessage(IDS_USBVIEW_INVALIDARG, szAnsiArg); + DisplayMessage(IDS_USBVIEW_USAGE); + break; + } + + if (0 == _stricmp(szAnsiArg, "/?")) + { + DisplayMessage(IDS_USBVIEW_USAGE); + break; + } + else if (NULL != StrStrI(szAnsiArg, "/saveall:")) + { + fileType = UsbViewTxtFile; + } + else if (NULL != StrStrI(szAnsiArg, "/savexml:")) + { + fileType = UsbViewXmlFile; + } + else if (0 == _stricmp(szAnsiArg, "/f")) + { + dwCreationDisposition = CREATE_ALWAYS; + } + else if (0 == _stricmp(szAnsiArg, "/q")) + { + quietMode = TRUE; + } + else + { + DisplayMessage(IDS_USBVIEW_INVALIDARG, szAnsiArg); + DisplayMessage(IDS_USBVIEW_USAGE); + bStopArgProcessing = TRUE; + } + + if (fileType != UsbViewNone) + { + // Save view information as to file + szArg = strchr(szAnsiArg, ':'); + + if (NULL == szArg || strlen(szArg) == 1) + { + // No ':' or just a ':' + DisplayMessage(IDS_USBVIEW_INVALID_FILENAME, szAnsiArg); + DisplayMessage(IDS_USBVIEW_USAGE); + bStopArgProcessing = TRUE; + } + else + { + hr = ProcessCommandSaveFile(szArg + 1, dwCreationDisposition, fileType); + + if (FAILED(hr)) + { + // No more processing + bStopArgProcessing = TRUE; + } + + fileType = UsbViewNone; + } + } + + if (NULL != szAnsiArg) + { + LocalFree(szAnsiArg); + } + } + + if(!quietMode) + { + WaitForKeyPress(); + } + + if (gbConsoleInitialized) + { + UnInitializeConsole(); + } + + LocalFree(szArgList); + } + return bStatus; +} + + +/***************************************************************************** + +ProcessCommandSaveFile() + +Process the save file command line + +*****************************************************************************/ +HRESULT ProcessCommandSaveFile(LPTSTR szFileName, DWORD dwCreationDisposition, USBVIEW_SAVE_FILE_TYPE fileType) +{ + HRESULT hr = S_OK; + LPTSTR szErrorBuffer = NULL; + + if (UsbViewNone == fileType || NULL == szFileName) + { + hr = E_INVALIDARG; + // Invalid arguments, return + return (hr); + } + + // The UI is not created yet, open the UI, but HIDE it + CreateMainWindow(SW_HIDE); + + if (UsbViewXmlFile == fileType) + { + hr = SaveAllInformationAsXml(szFileName, dwCreationDisposition); + } + + if (UsbViewTxtFile == fileType) + { + hr = SaveAllInformationAsText(szFileName, dwCreationDisposition); + } + + if (FAILED(hr)) + { + if (GetLastError() == ERROR_FILE_EXISTS || hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)) + { + // The operation failed because the file we tried to write to already existed and '/f' option + // was not present. Display error message to user describing '/f' option + switch(fileType) + { + case UsbViewXmlFile: + DisplayMessage(IDS_USBVIEW_FILE_EXISTS_XML, szFileName); + break; + case UsbViewTxtFile: + DisplayMessage(IDS_USBVIEW_FILE_EXISTS_TXT, szFileName); + break; + default: + DisplayMessage(IDS_USBVIEW_INTERNAL_ERROR); + break; + } + } + else + { + // Try to obtain system error message + FormatMessage( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + hr, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR) &szErrorBuffer, // FormatMessage expects this buffer to be cast as LPTSTR + 0, + NULL); + PrintString("Unable to save file.\n"); + PrintString(szErrorBuffer); + LocalFree(szErrorBuffer); + } + } + else + { + // Display file saved to message in console + DisplayMessage(IDS_USBVIEW_SAVED_TO, szFileName); + } + + return (hr); +} + +/***************************************************************************** + +InitializeConsole() + +Initializes the std output in console + +*****************************************************************************/ +HRESULT InitializeConsole() +{ + HRESULT hr = S_OK; + + SetLastError(0); + + // Find if STD_OUTPUT is a console or has been redirected to a File + gbConsoleFile = IsStdOutFile(); + + if (!gbConsoleFile) + { + // Output is not redirected and GUI application do not have console by default, create a console + if(AllocConsole()) + { +#pragma warning(disable:4996) // We don' need the FILE * returned by freopen + // Reopen STDOUT , STDIN and STDERR + if((freopen("conout$", "w", stdout) != NULL) && + (freopen("conin$", "r", stdin) != NULL) && + (freopen("conout$","w", stderr) != NULL)) + { + gbConsoleInitialized = TRUE; + ghStdOut = GetStdHandle(STD_OUTPUT_HANDLE); + } +#pragma warning(default:4996) + } + } + + if (INVALID_HANDLE_VALUE == ghStdOut || FALSE == gbConsoleInitialized) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + OOPS(); + } + return hr; +} + +/***************************************************************************** + +UnInitializeConsole() + +UnInitializes the console + +*****************************************************************************/ +VOID UnInitializeConsole() +{ + gbConsoleInitialized = FALSE; + FreeConsole(); +} + +/***************************************************************************** + +IsStdOutFile() + +Finds if the STD_OUTPUT has been redirected to a file +*****************************************************************************/ +BOOL IsStdOutFile() +{ + unsigned htype; + HANDLE hFile; + + // 1 = STDOUT + hFile = (HANDLE) _get_osfhandle(1); + htype = GetFileType(hFile); + htype &= ~FILE_TYPE_REMOTE; + + + // Check if file type is character file + if (FILE_TYPE_DISK == htype) + { + return TRUE; + } + + return FALSE; +} + + +/***************************************************************************** + +DisplayMessage() + +Displays a message to standard output +*****************************************************************************/ +VOID DisplayMessage(DWORD dwResId, ...) +{ + CHAR szFormat[4096]; + HRESULT hr = S_OK; + LPTSTR lpszMessage = NULL; + DWORD dwLen = 0; + va_list ap; + + va_start(ap, dwResId); + + // Initialize console if needed + if (!gbConsoleInitialized) + { + hr = InitializeConsole(); + if (FAILED(hr)) + { + OOPS(); + return; + } + } + + // Load the string resource + dwLen = LoadString(GetModuleHandle(NULL), + dwResId, + szFormat, + ARRAYSIZE(szFormat) + ); + + if(0 == dwLen) + { + PrintString("Unable to find message for given resource ID"); + + // Return if resource ID could not be found + return; + } + + dwLen = FormatMessage( + FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER, + szFormat, + dwResId, + 0, + (LPTSTR) &lpszMessage, + ARRAYSIZE(szFormat), + &ap); + + if (dwLen > 0) + { + PrintString(lpszMessage); + LocalFree(lpszMessage); + } + else + { + PrintString("Unable to find message for given ID"); + } + + va_end(ap); + return; +} + +/***************************************************************************** + +WStringToAnsiString() + +Converts the Wide char string to ANSI string and returns the allocated ANSI string. +*****************************************************************************/ +LPTSTR WStringToAnsiString(LPWSTR lpwszString) +{ + int strLen = 0; + LPTSTR szAnsiBuffer = NULL; + + szAnsiBuffer = LocalAlloc(LPTR, (MAX_PATH + 1) * sizeof(CHAR)); + + // Convert string from from WCHAR to ANSI + if (NULL != szAnsiBuffer) + { + strLen = WideCharToMultiByte( + CP_ACP, + 0, + lpwszString, + -1, + szAnsiBuffer, + MAX_PATH + 1, + NULL, + NULL); + + if (strLen > 0) + { + return szAnsiBuffer; + } + } + return NULL; +} + +/***************************************************************************** + +PrintString() + +Displays a string to standard output +*****************************************************************************/ +VOID PrintString(LPTSTR lpszString) +{ + DWORD dwBytesWritten = 0; + size_t Len = 0; + LPSTR lpOemString = NULL; + + if (INVALID_HANDLE_VALUE == ghStdOut || NULL == lpszString) + { + OOPS(); + // Return if invalid inputs + return; + } + + if (FAILED(StringCchLength(lpszString, OUTPUT_MESSAGE_MAX_LENGTH, &Len))) + { + OOPS(); + // Return if string is too long + return; + } + + if (gbConsoleFile) + { + // Console has been redirected to a file, ex: `usbview /savexml:xx > test.txt`. We need to use WriteFile instead of + // WriteConsole for text output. + lpOemString = (LPSTR) LocalAlloc(LPTR, (Len + 1) * sizeof(CHAR)); + if (lpOemString != NULL) + { + if (CharToOemBuff(lpszString, lpOemString, (DWORD) Len)) + { + WriteFile(ghStdOut, (LPVOID) lpOemString, (DWORD) Len, &dwBytesWritten, NULL); + } + else + { + OOPS(); + } + } + } + else + { + // Write to std out in console + WriteConsole(ghStdOut, (LPVOID) lpszString, (DWORD) Len, &dwBytesWritten, NULL); + } + + return; +} + +/***************************************************************************** + +WaitForKeyPress() + +Waits for key press in case of console +*****************************************************************************/ +VOID WaitForKeyPress() +{ + // Wait for key press if console + if (!gbConsoleFile && gbConsoleInitialized) + { + DisplayMessage(IDS_USBVIEW_PRESSKEY); + (VOID) _getch(); + } + return; +} + +/***************************************************************************** + +CreateMainWindow() + +*****************************************************************************/ + +BOOL +CreateMainWindow ( + int nCmdShow + ) +{ + RECT rc; + + InitCommonControls(); + + ghMainWnd = CreateDialog(ghInstance, + MAKEINTRESOURCE(IDD_MAINDIALOG), + NULL, + (DLGPROC) MainDlgProc); + + if (ghMainWnd == NULL) + { + OOPS(); + return FALSE; + } + + GetWindowRect(ghMainWnd, &rc); + + gBarLocation = (rc.right - rc.left) / 3; + + ResizeWindows(FALSE, 0); + + ShowWindow(ghMainWnd, nCmdShow); + + UpdateWindow(ghMainWnd); + + return TRUE; +} + + +/***************************************************************************** + +ResizeWindows() + +Handles resizing the two child windows of the main window. If +bSizeBar is true, then the sizing is happening because the user is +moving the bar. If bSizeBar is false, the sizing is happening +because of the WM_SIZE or something like that. + +*****************************************************************************/ + +VOID +ResizeWindows ( + BOOL bSizeBar, + int BarLocation + ) +{ + RECT MainClientRect; + RECT MainWindowRect; + RECT TreeWindowRect; + RECT StatusWindowRect; + int right; + + // Is the user moving the bar? + // + if (!bSizeBar) + { + BarLocation = gBarLocation; + } + + GetClientRect(ghMainWnd, &MainClientRect); + + GetWindowRect(ghStatusWnd, &StatusWindowRect); + + // Make sure the bar is in a OK location + // + if (bSizeBar) + { + if (BarLocation < + GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR) + { + return; + } + + if ((MainClientRect.right - BarLocation) < + GetSystemMetrics(SM_CXSCREEN)/WINDOWSCALEFACTOR) + { + return; + } + } + + // Save the bar location + // + gBarLocation = BarLocation; + + // Move the tree window + // + MoveWindow(ghTreeWnd, + 0, + 0, + BarLocation, + MainClientRect.bottom - StatusWindowRect.bottom + StatusWindowRect.top, + TRUE); + + // Get the size of the window (in case move window failed + // + GetWindowRect(ghTreeWnd, &TreeWindowRect); + GetWindowRect(ghMainWnd, &MainWindowRect); + + right = TreeWindowRect.right - MainWindowRect.left; + + // Move the edit window with respect to the tree window + // + MoveWindow(ghEditWnd, + right+SIZEBAR, + 0, + MainClientRect.right-(right+SIZEBAR), + MainClientRect.bottom - StatusWindowRect.bottom + StatusWindowRect.top, + TRUE); + + // Move the Status window with respect to the tree window + // + MoveWindow(ghStatusWnd, + 0, + MainClientRect.bottom - StatusWindowRect.bottom + StatusWindowRect.top, + MainClientRect.right, + StatusWindowRect.bottom - StatusWindowRect.top, + TRUE); +} + + +/***************************************************************************** + +MainWndProc() + +*****************************************************************************/ + +LRESULT CALLBACK +MainDlgProc ( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ) +{ + + switch (uMsg) + { + + HANDLE_MSG(hWnd, WM_INITDIALOG, USBView_OnInitDialog); + HANDLE_MSG(hWnd, WM_CLOSE, USBView_OnClose); + HANDLE_MSG(hWnd, WM_COMMAND, USBView_OnCommand); + HANDLE_MSG(hWnd, WM_LBUTTONDOWN, USBView_OnLButtonDown); + HANDLE_MSG(hWnd, WM_LBUTTONUP, USBView_OnLButtonUp); + HANDLE_MSG(hWnd, WM_MOUSEMOVE, USBView_OnMouseMove); + HANDLE_MSG(hWnd, WM_SIZE, USBView_OnSize); + HANDLE_MSG(hWnd, WM_NOTIFY, USBView_OnNotify); + HANDLE_MSG(hWnd, WM_DEVICECHANGE, USBView_OnDeviceChange); + } + + return 0; +} + +/***************************************************************************** + +USBView_OnInitDialog() + +*****************************************************************************/ + +BOOL +USBView_OnInitDialog ( + HWND hWnd, + HWND hWndFocus, + LPARAM lParam + ) +{ + HFONT hFont; + HIMAGELIST himl; + HICON hicon; + DEV_BROADCAST_DEVICEINTERFACE broadcastInterface; + + UNREFERENCED_PARAMETER(lParam); + UNREFERENCED_PARAMETER(hWndFocus); + + // Register to receive notification when a USB device is plugged in. + broadcastInterface.dbcc_size = sizeof(DEV_BROADCAST_DEVICEINTERFACE); + broadcastInterface.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE; + + memcpy( &(broadcastInterface.dbcc_classguid), + &(GUID_DEVINTERFACE_USB_DEVICE), + sizeof(struct _GUID)); + + gNotifyDevHandle = RegisterDeviceNotification(hWnd, + &broadcastInterface, + DEVICE_NOTIFY_WINDOW_HANDLE); + + // Now register for Hub notifications. + memcpy( &(broadcastInterface.dbcc_classguid), + &(GUID_CLASS_USBHUB), + sizeof(struct _GUID)); + + gNotifyHubHandle = RegisterDeviceNotification(hWnd, + &broadcastInterface, + DEVICE_NOTIFY_WINDOW_HANDLE); + + gHubList.DeviceInfo = INVALID_HANDLE_VALUE; + InitializeListHead(&gHubList.ListHead); + gDeviceList.DeviceInfo = INVALID_HANDLE_VALUE; + InitializeListHead(&gDeviceList.ListHead); + + //end add + + ghTreeWnd = GetDlgItem(hWnd, IDC_TREE); + + //added + if ((himl = ImageList_Create(15, 15, + FALSE, 2, 0)) == NULL) + { + OOPS(); + } + + if(himl != NULL) + { + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_ICON)); + giGoodDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_BADICON)); + giBadDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_COMPUTER)); + giComputer = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_HUB)); + giHub = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_NODEVICE)); + giNoDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_SSICON)); + giGoodSsDevice = ImageList_AddIcon(himl, hicon); + + hicon = LoadIcon(ghInstance, MAKEINTRESOURCE(IDI_NOSSDEVICE)); + giNoSsDevice = ImageList_AddIcon(himl, hicon); + + TreeView_SetImageList(ghTreeWnd, himl, TVSIL_NORMAL); + // end add + } + + ghEditWnd = GetDlgItem(hWnd, IDC_EDIT); + +#ifdef H264_SUPPORT + // set the edit control to have a max text limit size + SendMessage(ghEditWnd, EM_LIMITTEXT, 0 /* USE DEFAULT MAX*/, 0); +#endif + + ghStatusWnd = GetDlgItem(hWnd, IDC_STATUS); + ghMainMenu = GetMenu(hWnd); + if (ghMainMenu == NULL) + { + OOPS(); + } + { + CHAR pszFont[256]; + CHAR pszHeight[8]; + + memset(pszFont, 0, sizeof(pszFont)); + LoadString(ghInstance, IDS_STANDARD_FONT, pszFont, sizeof(pszFont) - 1); + memset(pszHeight, 0, sizeof(pszHeight)); + LoadString(ghInstance, IDS_STANDARD_FONT_HEIGHT, pszHeight, sizeof(pszHeight) - 1); + + hFont = CreateFont((int) pszHeight[0], 0, 0, 0, + 400, 0, 0, 0, + 0, 1, 2, 1, + 49, pszFont); + } + SendMessage(ghEditWnd, + WM_SETFONT, + (WPARAM) hFont, + 0); + + RefreshTree(); + + return FALSE; +} + +/***************************************************************************** + +USBView_OnClose() + +*****************************************************************************/ + +VOID +USBView_OnClose ( + HWND hWnd + ) +{ + + UNREFERENCED_PARAMETER(hWnd); + + DestroyTree(); + + PostQuitMessage(0); +} + + +/***************************************************************************** + +AddItemInformationToFile() + +Saves the information about the current item to the list +*****************************************************************************/ +VOID +AddItemInformationToFile( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ) +{ + HRESULT hr = S_OK; + HANDLE hf = NULL; + DWORD dwBytesWritten = 0; + + hf = *((PHANDLE) pContext); + + ResetTextBuffer(); + + hr = UpdateTreeItemDeviceInfo(hTreeWnd, hTreeItem); + + if (FAILED(hr)) + { + OOPS(); + } + else + { + WriteFile(hf, GetTextBuffer(), GetTextBufferPos()*sizeof(CHAR), &dwBytesWritten, NULL); + } + + ResetTextBuffer(); +} + + + +/***************************************************************************** + +SaveAllInformationAsText() + +Saves the entire USB tree as a text file +*****************************************************************************/ +HRESULT +SaveAllInformationAsText( + LPTSTR lpstrTextFileName, + DWORD dwCreationDisposition + ) +{ + HRESULT hr = S_OK; + HANDLE hf = NULL; + + hf = CreateFile(lpstrTextFileName, + GENERIC_WRITE, + 0, + NULL, + dwCreationDisposition, + FILE_ATTRIBUTE_NORMAL, + NULL); + + if (hf == INVALID_HANDLE_VALUE) + { + hr = HRESULT_FROM_WIN32(GetLastError()); + OOPS(); + } + else + { + if (GetLastError() == ERROR_ALREADY_EXISTS) + { + // CreateFile() sets this error if we are overwriting an existing file + // Reset this error to avoid false alarms + SetLastError(0); + } + + if (ghTreeRoot == NULL) + { + // If tree has not been populated yet, try a refresh + RefreshTree(); + } + + if (ghTreeRoot) + { + + LockFile(hf, 0, 0, 0, 0); + WalkTreeTopDown(ghTreeRoot, AddItemInformationToFile, &hf, NULL); + UnlockFile(hf, 0, 0, 0, 0); + CloseHandle(hf); + + hr = S_OK; + } + else + { + hr = HRESULT_FROM_WIN32(GetLastError()); + OOPS(); + } + } + + ResetTextBuffer(); + return hr; +} + + +/***************************************************************************** + +USBView_OnCommand() + +*****************************************************************************/ + +VOID +USBView_OnCommand ( + HWND hWnd, + int id, + HWND hwndCtl, + UINT codeNotify + ) +{ + MENUITEMINFO menuInfo; + char szFile[MAX_PATH + 1]; + OPENFILENAME ofn; + HANDLE hf = NULL; + DWORD dwBytesWritten = 0; + int nTextLength = 0; + size_t lengthToNull = 0; + HRESULT hr = S_OK; + + UNREFERENCED_PARAMETER(hwndCtl); + UNREFERENCED_PARAMETER(codeNotify); + + //initialize save dialog variables + memset(szFile, 0, sizeof(szFile)); + memset(&ofn, 0, sizeof(OPENFILENAME)); + + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = hWnd; + ofn.nFilterIndex = 1; + ofn.lpstrFile = szFile; + ofn.nMaxFile = MAX_PATH; + ofn.lpstrFileTitle = NULL; + ofn.nMaxFileTitle = 0; + ofn.lpstrInitialDir = 0; + ofn.lpstrTitle = NULL; + ofn.Flags = OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST; + + + switch (id) + { + case ID_AUTO_REFRESH: + gDoAutoRefresh = !gDoAutoRefresh; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gDoAutoRefresh ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_SAVE: + { + // initialize the save file name + StringCchCopy(szFile, MAX_PATH, "USBView.txt"); + ofn.lpstrFilter = "Text\0*.TXT\0\0"; + ofn.lpstrDefExt = "txt"; + + //call dialog box + if (! GetSaveFileName(&ofn)) + { + OOPS(); + break; + } + + //create new file + hf = CreateFile((LPTSTR)ofn.lpstrFile, + GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_NORMAL, + NULL); + if (hf == INVALID_HANDLE_VALUE) + { + OOPS(); + } + else + { + char *szText = NULL; + + //get data from display window to transfer to file + nTextLength = GetWindowTextLength(ghEditWnd); + nTextLength++; + + szText = ALLOC((DWORD)nTextLength); + if (NULL != szText) + { + GetWindowText(ghEditWnd, (LPSTR) szText, nTextLength); + + // + // Constrain length to the first null, which should be at + // the end of the window text. This prevents writing extra + // null characters. + // + if (StringCchLength(szText, nTextLength, &lengthToNull) == S_OK) + { + nTextLength = (int) lengthToNull; + + //lock the file, write to the file, unlock file + LockFile(hf, 0, 0, 0, 0); + + WriteFile(hf, szText, nTextLength, &dwBytesWritten, NULL); + + UnlockFile(hf, 0, 0, 0, 0); + } + else + { + OOPS(); + } + CloseHandle(hf); + FREE(szText); + } + else + { + OOPS(); + } + } + + break; + } + + case ID_SAVEALL: + { + // initialize the save file name + StringCchCopy(szFile, MAX_PATH, "USBViewAll.txt"); + ofn.lpstrFilter = "Text\0*.txt\0\0"; + ofn.lpstrDefExt = "txt"; + + //call dialog box + if (! GetSaveFileName(&ofn)) + { + OOPS(); + break; + } + + // Save the file, overwrite in case of UI since UI gives popup for confirmation + hr = SaveAllInformationAsText(ofn.lpstrFile, CREATE_ALWAYS); + if (FAILED(hr)) + { + OOPS(); + } + + break; + } + + case ID_SAVEXML: + { + // initialize the save file name + StringCchCopy(szFile, MAX_PATH, "USBViewAll.xml"); + ofn.lpstrFilter = "Xml\0*.xml\0\0"; + ofn.lpstrDefExt = "xml"; + + //call dialog box + if (! GetSaveFileName(&ofn)) + { + OOPS(); + break; + } + + // Save the file, overwrite in case of UI since UI gives popup for confirmation + hr = SaveAllInformationAsXml(ofn.lpstrFile, CREATE_ALWAYS); + if (FAILED(hr)) + { + OOPS(); + } + + break; + } + + case ID_CONFIG_DESCRIPTORS: + gDoConfigDesc = !gDoConfigDesc; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gDoConfigDesc ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_ANNOTATION: + gDoAnnotation = !gDoAnnotation; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gDoAnnotation ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_LOG_DEBUG: + gLogDebug = !gLogDebug; + menuInfo.cbSize = sizeof(menuInfo); + menuInfo.fMask = MIIM_STATE; + menuInfo.fState = gLogDebug ? MFS_CHECKED : MFS_UNCHECKED; + SetMenuItemInfo(ghMainMenu, + id, + FALSE, + &menuInfo); + break; + + case ID_ABOUT: + DialogBox(ghInstance, + MAKEINTRESOURCE(IDD_ABOUT), + ghMainWnd, + (DLGPROC) AboutDlgProc); + break; + + case ID_EXIT: + UnregisterDeviceNotification(gNotifyDevHandle); + UnregisterDeviceNotification(gNotifyHubHandle); + DestroyTree(); + PostQuitMessage(0); + break; + + case ID_REFRESH: + RefreshTree(); + break; + } +} + +/***************************************************************************** + +USBView_OnLButtonDown() + +*****************************************************************************/ + +VOID +USBView_OnLButtonDown ( + HWND hWnd, + BOOL fDoubleClick, + int x, + int y, + UINT keyFlags + ) +{ + + UNREFERENCED_PARAMETER(fDoubleClick); + UNREFERENCED_PARAMETER(x); + UNREFERENCED_PARAMETER(y); + UNREFERENCED_PARAMETER(keyFlags); + + gbButtonDown = TRUE; + SetCapture(hWnd); +} + +/***************************************************************************** + +USBView_OnLButtonUp() + +*****************************************************************************/ + +VOID +USBView_OnLButtonUp ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ) +{ + + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(x); + UNREFERENCED_PARAMETER(y); + UNREFERENCED_PARAMETER(keyFlags); + + gbButtonDown = FALSE; + ReleaseCapture(); +} + +/***************************************************************************** + +USBView_OnMouseMove() + +*****************************************************************************/ + +VOID +USBView_OnMouseMove ( + HWND hWnd, + int x, + int y, + UINT keyFlags + ) +{ + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(y); + UNREFERENCED_PARAMETER(keyFlags); + + SetCursor(ghSplitCursor); + + if (gbButtonDown) + { + ResizeWindows(TRUE, x); + } +} + +/***************************************************************************** + +USBView_OnSize(); + +*****************************************************************************/ + +VOID +USBView_OnSize ( + HWND hWnd, + UINT state, + int cx, + int cy + ) +{ + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(state); + UNREFERENCED_PARAMETER(cx); + UNREFERENCED_PARAMETER(cy); + + ResizeWindows(FALSE, 0); +} + +/***************************************************************************** + +USBView_OnNotify() + +*****************************************************************************/ + +LRESULT +USBView_OnNotify ( + HWND hWnd, + int DlgItem, + LPNMHDR lpNMHdr + ) +{ + UNREFERENCED_PARAMETER(hWnd); + UNREFERENCED_PARAMETER(DlgItem); + + if (lpNMHdr->code == TVN_SELCHANGED) + { + HTREEITEM hTreeItem; + + hTreeItem = ((NM_TREEVIEW *)lpNMHdr)->itemNew.hItem; + + if (hTreeItem) + { + UpdateEditControl(ghEditWnd, + ghTreeWnd, + hTreeItem); + } + } + + return 0; +} + + +/***************************************************************************** + +USBView_OnDeviceChange() + +*****************************************************************************/ + +BOOL +USBView_OnDeviceChange ( + HWND hwnd, + UINT uEvent, + DWORD dwEventData + ) +{ + UNREFERENCED_PARAMETER(hwnd); + UNREFERENCED_PARAMETER(dwEventData); + + if (gDoAutoRefresh) + { + switch (uEvent) + { + case DBT_DEVICEARRIVAL: + case DBT_DEVICEREMOVECOMPLETE: + RefreshTree(); + break; + } + } + + return TRUE; +} + + + +/***************************************************************************** + +DestroyTree() + +*****************************************************************************/ + +VOID DestroyTree (VOID) +{ + // Clear the selection of the TreeView, so that when the tree is + // destroyed, the control won't try to constantly "shift" the + // selection to another item. + // + TreeView_SelectItem(ghTreeWnd, NULL); + + // Destroy the current contents of the TreeView + // + if (ghTreeRoot) + { + WalkTree(ghTreeRoot, CleanupItem, NULL); + + TreeView_DeleteAllItems(ghTreeWnd); + + ghTreeRoot = NULL; + } + + ClearDeviceList(&gDeviceList); + ClearDeviceList(&gHubList); +} + +/***************************************************************************** + +RefreshTree() + +*****************************************************************************/ + +VOID RefreshTree (VOID) +{ + CHAR statusText[128]; + ULONG devicesConnected; + + // Clear the edit control + // + SetWindowText(ghEditWnd, ""); + + // Destroy the current contents of the TreeView + // + DestroyTree(); + + // Create the root tree node + // + ghTreeRoot = AddLeaf(TVI_ROOT, 0, "My Computer", ComputerIcon); + + if (ghTreeRoot != NULL) + { + // Enumerate all USB buses and populate the tree + // + EnumerateHostControllers(ghTreeRoot, &devicesConnected); + + // + // Expand all tree nodes + // + WalkTree(ghTreeRoot, ExpandItem, NULL); + + // Update Status Line with number of devices connected + // + memset(statusText, 0, sizeof(statusText)); + StringCchPrintf(statusText, sizeof(statusText), +#ifdef H264_SUPPORT + "UVC Spec Version: %d.%d Version: %d.%d Devices Connected: %d Hubs Connected: %d", + UVC_SPEC_MAJOR_VERSION, UVC_SPEC_MINOR_VERSION, USBVIEW_MAJOR_VERSION, USBVIEW_MINOR_VERSION, + devicesConnected, TotalHubs); +#else + "Devices Connected: %d Hubs Connected: %d", + devicesConnected, TotalHubs); +#endif + + SetWindowText(ghStatusWnd, statusText); + } + else + { + OOPS(); + } + +} + +/***************************************************************************** + +AboutDlgProc() + +*****************************************************************************/ + +LRESULT CALLBACK +AboutDlgProc ( + HWND hwnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam + ) +{ + UNREFERENCED_PARAMETER(lParam); + + switch (uMsg) + { + case WM_INITDIALOG: + { + HRESULT hr; + char TextBuffer[TEXT_ITEM_LENGTH]; + HWND hItem; + + hItem = GetDlgItem(hwnd, IDC_VERSION); + + if (hItem != NULL) + { + hr = StringCbPrintfA(TextBuffer, + sizeof(TextBuffer), + "USBView version: %d.%d", + USBVIEW_MAJOR_VERSION, + USBVIEW_MINOR_VERSION); + if (SUCCEEDED(hr)) + { + SetWindowText(hItem,TextBuffer); + } + } + + hItem = GetDlgItem(hwnd, IDC_UVCVERSION); + + if (hItem != NULL) + { + hr = StringCbPrintfA(TextBuffer, + sizeof(TextBuffer), + "USB Video Class Spec version: %d.%d", + UVC_SPEC_MAJOR_VERSION, + UVC_SPEC_MINOR_VERSION); + if (SUCCEEDED(hr)) + { + SetWindowText(hItem,TextBuffer); + } + } + } + break; + case WM_COMMAND: + + switch (LOWORD(wParam)) + { + case IDOK: + case IDCANCEL: + + EndDialog (hwnd, 0); + break; + } + break; + + } + + return FALSE; +} + + +/***************************************************************************** + +AddLeaf() + +*****************************************************************************/ + +HTREEITEM +AddLeaf ( + HTREEITEM hTreeParent, + LPARAM lParam, + _In_ LPTSTR lpszText, + TREEICON TreeIcon + ) +{ + TV_INSERTSTRUCT tvins; + HTREEITEM hti; + + memset(&tvins, 0, sizeof(tvins)); + + // Set the parent item + // + tvins.hParent = hTreeParent; + + tvins.hInsertAfter = TVI_LAST; + + // pszText and lParam members are valid + // + tvins.item.mask = TVIF_TEXT | TVIF_PARAM; + + // Set the text of the item. + // + tvins.item.pszText = lpszText; + + // Set the user context item + // + tvins.item.lParam = lParam; + + // Add the item to the tree-view control. + // + hti = TreeView_InsertItem(ghTreeWnd, &tvins); + + // added + tvins.item.mask = TVIF_IMAGE | TVIF_SELECTEDIMAGE; + tvins.item.hItem = hti; + + // Determine which icon to display for the device + // + switch (TreeIcon) + { + case ComputerIcon: + tvins.item.iImage = giComputer; + tvins.item.iSelectedImage = giComputer; + break; + + case HubIcon: + tvins.item.iImage = giHub; + tvins.item.iSelectedImage = giHub; + break; + + case NoDeviceIcon: + tvins.item.iImage = giNoDevice; + tvins.item.iSelectedImage = giNoDevice; + break; + + case GoodDeviceIcon: + tvins.item.iImage = giGoodDevice; + tvins.item.iSelectedImage = giGoodDevice; + break; + + case GoodSsDeviceIcon: + tvins.item.iImage = giGoodSsDevice; + tvins.item.iSelectedImage = giGoodSsDevice; + break; + + case NoSsDeviceIcon: + tvins.item.iImage = giNoSsDevice; + tvins.item.iSelectedImage = giNoSsDevice; + break; + + case BadDeviceIcon: + default: + tvins.item.iImage = giBadDevice; + tvins.item.iSelectedImage = giBadDevice; + break; + } + TreeView_SetItem(ghTreeWnd, &tvins.item); + + return hti; +} + + +/***************************************************************************** + +WalkTreeTopDown() + +*****************************************************************************/ + +VOID +WalkTreeTopDown( + _In_ HTREEITEM hTreeItem, + _In_ LPFNTREECALLBACK lpfnTreeCallback, + _In_opt_ PVOID pContext, + _In_opt_ LPFNTREENOTIFYCALLBACK lpfnTreeNotifyCallback + ) +{ + if (hTreeItem) + { + HTREEITEM hTreeChild = TreeView_GetChild(ghTreeWnd, hTreeItem); + HTREEITEM hTreeSibling = TreeView_GetNextSibling(ghTreeWnd, hTreeItem); + + // + // Call the lpfnCallBack on the node itself. + // + (*lpfnTreeCallback)(ghTreeWnd, hTreeItem, pContext); + + // + // Recursively call WalkTree on the node's first child. + // + + if (hTreeChild) + { + WalkTreeTopDown(hTreeChild, + lpfnTreeCallback, + pContext, + lpfnTreeNotifyCallback); + } + + // + // Recursively call WalkTree on the node's first sibling. + // + if (hTreeSibling) + { + WalkTreeTopDown(hTreeSibling, + lpfnTreeCallback, + pContext, + lpfnTreeNotifyCallback); + } + else + { + // If there are no more siblings, we have reached the end of + // list of child nodes. Call notify function + if (lpfnTreeNotifyCallback != NULL) + { + (*lpfnTreeNotifyCallback)(pContext); + } + } + } +} + +/***************************************************************************** + +WalkTree() + +*****************************************************************************/ + +VOID +WalkTree ( + _In_ HTREEITEM hTreeItem, + _In_ LPFNTREECALLBACK lpfnTreeCallback, + _In_opt_ PVOID pContext + ) +{ + if (hTreeItem) + { + // Recursively call WalkTree on the node's first child. + // + WalkTree(TreeView_GetChild(ghTreeWnd, hTreeItem), + lpfnTreeCallback, + pContext); + + // + // Call the lpfnCallBack on the node itself. + // + (*lpfnTreeCallback)(ghTreeWnd, hTreeItem, pContext); + + // + // + // Recursively call WalkTree on the node's first sibling. + // + WalkTree(TreeView_GetNextSibling(ghTreeWnd, hTreeItem), + lpfnTreeCallback, + pContext); + } +} + +/***************************************************************************** + +ExpandItem() + +*****************************************************************************/ + +VOID +ExpandItem ( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ) +{ + // + // Make this node visible. + // + UNREFERENCED_PARAMETER(pContext); + + TreeView_Expand(hTreeWnd, hTreeItem, TVE_EXPAND); +} + +/***************************************************************************** + +SaveAllInformationAsXML() + +Saves the entire USB tree as an XML file +*****************************************************************************/ +HRESULT +SaveAllInformationAsXml( + LPTSTR lpstrTextFileName, + DWORD dwCreationDisposition + ) +{ + HRESULT hr = S_OK; + + if (ghTreeRoot == NULL) + { + // If tree has not been populated yet, try a refresh + RefreshTree(); + } + if (ghTreeRoot) + { + WalkTreeTopDown(ghTreeRoot, AddItemInformationToXmlView, NULL, XmlNotifyEndOfNodeList); + + hr = SaveXml(lpstrTextFileName, dwCreationDisposition); + } + else + { + hr = E_FAIL; + OOPS(); + } + ResetTextBuffer(); + return hr; +} + +//***************************************************************************** +// +// AddItemInformationToXmlView +// +// hTreeItem - Handle of selected TreeView item for which information should +// be added to the XML View +// +//***************************************************************************** +VOID +AddItemInformationToXmlView( + HWND hTreeWnd, + HTREEITEM hTreeItem, + PVOID pContext + ) +{ + TV_ITEM tvi; + PVOID info; + PCHAR tviName = NULL; + + UNREFERENCED_PARAMETER(pContext); + +#ifdef H264_SUPPORT + ResetErrorCounts(); +#endif + + tviName = (PCHAR) ALLOC(256); + + if (NULL == tviName) + { + return; + } + + // + // Get the name of the TreeView item, along with the a pointer to the + // info we stored about the item in the item's lParam. + // + + tvi.mask = TVIF_HANDLE | TVIF_TEXT | TVIF_PARAM; + tvi.hItem = hTreeItem; + tvi.pszText = (LPSTR) tviName; + tvi.cchTextMax = 256; + + TreeView_GetItem(hTreeWnd, + &tvi); + + info = (PVOID)tvi.lParam; + + if (NULL != info) + { + // + // Add Item to XML object + // + switch (*(PUSBDEVICEINFOTYPE)info) + { + case HostControllerInfo: + XmlAddHostController(tviName, (PUSBHOSTCONTROLLERINFO) info); + break; + + case RootHubInfo: + XmlAddRootHub(tviName, (PUSBROOTHUBINFO) info); + break; + + case ExternalHubInfo: + XmlAddExternalHub(tviName, (PUSBEXTERNALHUBINFO) info); + break; + + case DeviceInfo: + XmlAddUsbDevice(tviName, (PUSBDEVICEINFO) info); + break; + } + + } + return; +} + +/***************************************************************************** + +DisplayLastError() + +*****************************************************************************/ + +DWORD +DisplayLastError( + _Inout_updates_bytes_(count) char *szString, + int count) +{ + LPVOID lpMsgBuf; + + // get the last error code + DWORD dwError = GetLastError(); + + // get the system message for this error code + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM | + FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, + dwError, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL )) + { + StringCchPrintf(szString, count, "Error: %s", (LPTSTR)lpMsgBuf ); + } + + // Free the local buffer + LocalFree( lpMsgBuf ); + + // return the error + return dwError; +} + +#if DBG + +/***************************************************************************** + +Oops() + +*****************************************************************************/ + +VOID +Oops +( + _In_ PCHAR File, + ULONG Line + ) +{ + char szBuf[1024]; + LPTSTR lpMsgBuf; + DWORD dwGLE = GetLastError(); + + memset(szBuf, 0, sizeof(szBuf)); + + // get the system message for this error code + if (FormatMessage( + FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + dwGLE, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language + (LPTSTR) &lpMsgBuf, + 0, + NULL)) + { + StringCchPrintf(szBuf, sizeof(szBuf), + "File: %s, Line %d\r\nGetLastError 0x%x %u %s\n", + File, Line, dwGLE, dwGLE, lpMsgBuf); + } + else + { + StringCchPrintf(szBuf, sizeof(szBuf), + "File: %s, Line %d\r\nGetLastError 0x%x %u\r\n", + File, Line, dwGLE, dwGLE); + } + OutputDebugString(szBuf); + + // Free the system allocated local buffer + LocalFree(lpMsgBuf); + + return; +} + +#endif |
