sl@0: // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0: // All rights reserved.
sl@0: // This component and the accompanying materials are made available
sl@0: // under the terms of the License "Eclipse Public License v1.0"
sl@0: // which accompanies this distribution, and is available
sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0: //
sl@0: // Initial Contributors:
sl@0: // Nokia Corporation - initial contribution.
sl@0: //
sl@0: // Contributors:
sl@0: //
sl@0: // Description:
sl@0: // UsbcvControl.cpp: implementation of the UsbcvControl class.
sl@0: //
sl@0: 
sl@0: #include "stdafx.h"
sl@0: #include "t_usb_win.h"
sl@0: #include "UsbcvControl.h"
sl@0: 
sl@0: #include "usbio.h"											// USBIO Dev Kit
sl@0: 
sl@0: #include "global.h"
sl@0: 
sl@0: #ifdef _DEBUG
sl@0: #undef THIS_FILE
sl@0: static char THIS_FILE[]=__FILE__;
sl@0: #define new DEBUG_NEW
sl@0: #endif
sl@0: 
sl@0: extern void PrintOut(BOOL screenFlag, BOOL logFlag, BOOL timeFlag, const char *format, ...);
sl@0: 
sl@0: extern BOOL gAbort;
sl@0: 
sl@0: // define the CreateProcess strings for the Usbcv test app
sl@0: #define APPNAME "C:\\Program Files\\USB-IF Test Suite\\USBCommandVerifier\\UsbCV13.exe"
sl@0: #define APPTITLE "Automated USBCV"
sl@0: #define CMDLINE " /title \"Automated USBCV\" /drv hcdriver"
sl@0: #define CURDIR "C:\\Program Files\\USB-IF Test Suite\\USBCommandVerifier\\lib"
sl@0: 
sl@0: #define DIALOG_CLASS "#32770"
sl@0: #define BUTTON_CLASS "Button"
sl@0: #define STATIC_CLASS "Static"
sl@0: 
sl@0: #define ID_COMPLIANCE 0x3EC
sl@0: #define ID_RUN 0x3F5
sl@0: #define ID_EXIT 0x1
sl@0: 
sl@0: #define DEVLIST_TITLE ""
sl@0: #define ID_OKBUTTON 0x3E8
sl@0: #define ID_TESTLIST 0x3E9
sl@0: #define ID_DEVLIST 0x3EA
sl@0: #define ID_TEXTBOX 0x3EB
sl@0: #define ID_CONFIRM 0x3EC
sl@0: #define ID_ABORT 0x3ED
sl@0: 
sl@0: #define TESTRESULT_TITLE "Test Results"
sl@0: #define ID_RESULT_TEXT 0xFFFF
sl@0: #define ID_RESULT_OK 0x2
sl@0: 
sl@0: #define BUFFER_SIZE 256
sl@0: #define VIDPID_SIZE	16
sl@0: #define TEST_PASSED "Passed"
sl@0: #define TEST_FAILED "Failed"
sl@0: 
sl@0: // Wait sleep in milliseconds, other waits as repetitions of the sleep time
sl@0: #define WAIT_SLEEP 250					
sl@0: #define CREATE_WAIT 40
sl@0: #define SELECT_WAIT 20
sl@0: #define CONTINUE_WAIT 120
sl@0: #define RESULT_WAIT	1200
sl@0: #define EXIT_WAIT 40
sl@0: 
sl@0: #define USBMS_DEVICE_REQUEST_CONTINUES	6
sl@0: 
sl@0: //////////////////////////////////////////////////////////////////////
sl@0: // Construction/Destruction
sl@0: //////////////////////////////////////////////////////////////////////
sl@0: 
sl@0: UsbcvControl::UsbcvControl()
sl@0: {
sl@0: 
sl@0:     ZeroMemory( &si, sizeof(si) );
sl@0:     si.cb = sizeof(si);
sl@0:     ZeroMemory( &pi, sizeof(pi) );
sl@0: 
sl@0: }
sl@0: 
sl@0: UsbcvControl::~UsbcvControl()
sl@0: {
sl@0: 	DWORD exitCode;
sl@0: 	
sl@0: 	if (GetExitCodeProcess(pi.hProcess,(LPDWORD)&exitCode))
sl@0: 		{
sl@0: 		if (exitCode == STILL_ACTIVE)
sl@0: 			{
sl@0: 			SendMessage (mainWindow,WM_COMMAND,MAKEWPARAM(ID_EXIT,BN_CLICKED),(LPARAM)exitButton);
sl@0: 			}
sl@0: 		int i = 0;
sl@0: 		while (exitCode == STILL_ACTIVE && i++ < EXIT_WAIT)
sl@0: 			{
sl@0: 			Sleep (WAIT_SLEEP);
sl@0: 			GetExitCodeProcess(pi.hProcess,(LPDWORD)&exitCode);
sl@0: 			}
sl@0: 		// Force an unclean process termination only if necessary
sl@0: 		if (exitCode == STILL_ACTIVE)
sl@0: 			{
sl@0: 			TerminateProcess(pi.hProcess,0);
sl@0: 			}
sl@0: 		}	
sl@0: }
sl@0: 
sl@0: DWORD UsbcvControl::Create()
sl@0: {
sl@0: 	mainWindow = NULL;
sl@0: 	exitButton = NULL;
sl@0: 
sl@0: 	if (!CreateProcess (APPNAME,CMDLINE,NULL,NULL,FALSE,0,NULL,CURDIR,&si,&pi))
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 
sl@0: 	HWND complianceButton;
sl@0: 
sl@0: 	for (int i=0; i < CREATE_WAIT && !mainWindow; i++)
sl@0: 		{
sl@0: 		mainWindow = FindWindow(DIALOG_CLASS,APPTITLE);
sl@0: 		if (mainWindow)
sl@0: 			{
sl@0: 			complianceButton = GetDlgItem(mainWindow,ID_COMPLIANCE);
sl@0: 			runButton = GetDlgItem(mainWindow,ID_RUN);
sl@0: 			exitButton = GetDlgItem(mainWindow,ID_EXIT);	
sl@0: 			if (!complianceButton || !runButton || !exitButton)
sl@0: 				{
sl@0: 				mainWindow = NULL;
sl@0: 				}
sl@0: 			}
sl@0: 		if (!mainWindow)
sl@0: 			Sleep(WAIT_SLEEP);
sl@0: 		}
sl@0: 
sl@0: 	if (mainWindow)
sl@0: 		{
sl@0: 		SendMessage (mainWindow,WM_COMMAND,MAKEWPARAM(ID_COMPLIANCE,BN_CLICKED),(LPARAM)complianceButton);
sl@0: 
sl@0: 		return USBIO_ERR_SUCCESS;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 		}
sl@0: }
sl@0: 
sl@0: DWORD UsbcvControl::TestAllDevices(USHORT aVendorId, USHORT aProductId1, USHORT aProductId2)
sl@0: {
sl@0: 	DWORD dwRC = USBIO_ERR_SUCCESS;
sl@0: 	HWND testList;
sl@0: 	int chapter9_TestIndex = -1;
sl@0: 	int MSC_TestIndex = -1;
sl@0: 	LRESULT lResult;
sl@0: 
sl@0: 	testList = GetDlgItem(mainWindow,ID_TESTLIST);
sl@0: 
sl@0: 	LRESULT itemCount = SendMessage (testList,LB_GETCOUNT,0,0);
sl@0: 	if (!itemCount)
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 
sl@0: 	char strBuffer[BUFFER_SIZE];
sl@0: 	for (int i = 0; i < itemCount; i++)
sl@0: 		{
sl@0: 		LRESULT lResult = SendMessage (testList,LB_GETTEXT,(WPARAM)i,(LPARAM)&strBuffer);
sl@0: 		if (lResult > 0)
sl@0: 			{
sl@0: 			if (strstr (strBuffer,"Chapter 9 Tests"))
sl@0: 				chapter9_TestIndex = i;
sl@0: 			if (strstr (strBuffer,"MSC Tests"))
sl@0: 				MSC_TestIndex = i;
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 		
sl@0: 	if (chapter9_TestIndex < 0 || MSC_TestIndex < 0)
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 
sl@0: 
sl@0: 	int ch9DeviceIndex = 0;
sl@0: 	int numCh9Devices = 1;
sl@0: 	int mscDeviceIndex = 0;
sl@0: 	int numMscDevices = 1;
sl@0: 	int testResult;
sl@0: 	bool msDevice = false;
sl@0: 	while (numCh9Devices > 0 && dwRC == USBIO_ERR_SUCCESS)
sl@0: 		{
sl@0: 		// select the chapter 9 tests
sl@0: 		lResult = SendMessage (testList,LB_SETCURSEL,(WPARAM)chapter9_TestIndex,0);
sl@0: 		lResult = SendMessage (mainWindow,WM_COMMAND,MAKEWPARAM(ID_TESTLIST,LBN_SELCHANGE),(LPARAM)testList);
sl@0: 
sl@0: 		// then run it
sl@0: 		lResult = SendMessage (mainWindow,WM_COMMAND,MAKEWPARAM(ID_RUN,BN_CLICKED),(LPARAM)runButton);
sl@0: 
sl@0: 		dwRC = SelectDevice (aVendorId,aProductId1,aProductId2,&ch9DeviceIndex,&numCh9Devices,&msDevice);
sl@0: 		if (ch9DeviceIndex >= 0 && dwRC == USBIO_ERR_SUCCESS)
sl@0: 			{
sl@0: 
sl@0: 			dwRC = WaitForTestResult(&testResult);
sl@0: 			if (dwRC == USBIO_ERR_SUCCESS)
sl@0: 				{
sl@0: 				if (!testResult)
sl@0: 					{
sl@0: 					gAbort = TRUE;
sl@0: 					}
sl@0: 				PRINT_TIME "USBCV Chapter 9 Test Complete - %s  ",testResult ? "Passed" : "Failed");
sl@0: 				ch9DeviceIndex++;
sl@0: 				}
sl@0: 			else
sl@0: 				{
sl@0: 				PRINT_ALWAYS "Error in Running USBCV\n");
sl@0: 				return dwRC;
sl@0: 				}
sl@0: 			}
sl@0: 
sl@0: 		if (msDevice && numMscDevices > 0 && dwRC == USBIO_ERR_SUCCESS)
sl@0: 			{
sl@0: 			// select the mass storage tests
sl@0: 			lResult = SendMessage (testList,LB_SETCURSEL,(WPARAM)MSC_TestIndex,0);
sl@0: 			lResult = SendMessage (mainWindow,WM_COMMAND,MAKEWPARAM(ID_TESTLIST,LBN_SELCHANGE),(LPARAM)testList);
sl@0: 
sl@0: 			// then run it
sl@0: 			lResult = SendMessage (mainWindow,WM_COMMAND,MAKEWPARAM(ID_RUN,BN_CLICKED),(LPARAM)runButton);
sl@0: 
sl@0: 			if (dwRC == USBIO_ERR_SUCCESS)
sl@0: 				dwRC = SelectDevice (aVendorId,aProductId1,aProductId2,&mscDeviceIndex,&numMscDevices,&msDevice);
sl@0: 			if (mscDeviceIndex >= 0 && dwRC == USBIO_ERR_SUCCESS)
sl@0: 				{
sl@0: 				dwRC = ContinueOk ("The following test might destroy",ID_CONFIRM);
sl@0: 				for (int i = 0; i < USBMS_DEVICE_REQUEST_CONTINUES; i++)
sl@0: 					{
sl@0: 					if (dwRC == USBIO_ERR_SUCCESS)
sl@0: 						dwRC = ContinueOk ("Processing device request",ID_OKBUTTON);
sl@0: 					}
sl@0: 				if (dwRC == USBIO_ERR_SUCCESS)
sl@0: 					dwRC = ContinueOk ("Disconnect and power off",ID_CONFIRM);
sl@0: 
sl@0: 				if (dwRC == USBIO_ERR_SUCCESS)
sl@0: 					{
sl@0: 					dwRC = WaitForTestResult(&testResult);
sl@0: 					if (dwRC == USBIO_ERR_SUCCESS)
sl@0: 						{
sl@0: 						if (!testResult)
sl@0: 							{
sl@0: 							gAbort = TRUE;
sl@0: 							}
sl@0: 						PRINT_TIME "USBCV Mass Storage Class Test Complete - %s  ",testResult ? "Passed" : "Failed");
sl@0: 						mscDeviceIndex++;
sl@0: 						}
sl@0: 					else
sl@0: 						{
sl@0: 						PRINT_ALWAYS "Error in Running USBCV\n");
sl@0: 						return dwRC;
sl@0: 						}
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	return dwRC;
sl@0: }
sl@0: 
sl@0: DWORD UsbcvControl::ContinueOk (char * choiceText, int buttonId)
sl@0: {
sl@0: 	HWND choiceDialog = NULL;
sl@0: 	HWND okButton;
sl@0: 	char strBuffer[BUFFER_SIZE];
sl@0: 
sl@0: 	for (int i=0; i < CONTINUE_WAIT && !choiceDialog; i++)
sl@0: 		{
sl@0: 		choiceDialog = FindWindow(DIALOG_CLASS,"");
sl@0: 		if (choiceDialog)
sl@0: 			{
sl@0: 			UINT textSize = GetDlgItemText (choiceDialog,ID_TEXTBOX,strBuffer,BUFFER_SIZE);
sl@0: 			okButton = GetDlgItem(choiceDialog,buttonId);
sl@0: 			if (!textSize || !okButton || !strstr (strBuffer,choiceText))
sl@0: 				{
sl@0: 				choiceDialog = NULL;
sl@0: 				}
sl@0: 			}
sl@0: 		if (!choiceDialog)
sl@0: 			Sleep(WAIT_SLEEP);
sl@0: 		}
sl@0: 
sl@0: 	if (!choiceDialog)
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 
sl@0: 	SendMessage (choiceDialog,WM_COMMAND,MAKEWPARAM(buttonId,BN_CLICKED),(LPARAM)okButton);
sl@0: 
sl@0: 	return USBIO_ERR_SUCCESS;
sl@0: 
sl@0: }
sl@0: 
sl@0: DWORD UsbcvControl::SelectDevice(USHORT aVendorId, USHORT aProductId1, USHORT aProductId2, int * deviceIndex, int * numDevices, bool * msDevice)
sl@0: {
sl@0: 	HWND devListDialog = NULL;
sl@0: 	HWND devList;
sl@0: 	HWND okButton;
sl@0: 	LRESULT lResult;
sl@0: 	int i;
sl@0: 
sl@0: 	for (i=0; i < SELECT_WAIT && !devListDialog; i++)
sl@0: 		{
sl@0: 		devListDialog = FindWindow(DIALOG_CLASS,DEVLIST_TITLE);
sl@0: 		if (devListDialog)
sl@0: 			{
sl@0: 			devList = GetDlgItem(devListDialog,ID_DEVLIST);
sl@0: 			okButton = GetDlgItem(devListDialog,ID_OKBUTTON);
sl@0: 			if (!devList || !okButton)
sl@0: 				{
sl@0: 				devListDialog = NULL;
sl@0: 				}
sl@0: 			}
sl@0: 		if (!devListDialog)
sl@0: 			Sleep(WAIT_SLEEP);
sl@0: 		}
sl@0: 
sl@0: 	if (!devListDialog)
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 
sl@0: 	LRESULT itemCount = SendMessage (devList,LB_GETCOUNT,0,0);
sl@0: 	if (!itemCount)
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 
sl@0: 	* numDevices = 0;
sl@0: 	if (* deviceIndex >= itemCount)
sl@0: 		return USBIO_ERR_SUCCESS;
sl@0: 
sl@0: 	char strBuffer[BUFFER_SIZE];
sl@0: 	char strVID [VIDPID_SIZE];
sl@0: 	char strPID1 [VIDPID_SIZE];
sl@0: 	char strPID2 [VIDPID_SIZE];
sl@0: 	bool deviceFound = false;
sl@0: 
sl@0: 	for (i = * deviceIndex; i < itemCount; i++)
sl@0: 		{
sl@0: 		lResult = SendMessage (devList,LB_GETTEXT,(WPARAM)i,(LPARAM)&strBuffer);
sl@0: 		if (lResult > 0)
sl@0: 			{
sl@0: 			sprintf (strVID,"VID=%04x",aVendorId);
sl@0: 			sprintf (strPID1,"PID=%04x",aProductId1);
sl@0: 			sprintf (strPID2,"PID=%04x",aProductId2);
sl@0: 			if (strstr (strBuffer,strVID) && (strstr (strBuffer,strPID1) || strstr (strBuffer,strPID2)))
sl@0: 				{
sl@0: 				if (deviceFound)
sl@0: 					{
sl@0: 					(* numDevices)++;
sl@0: 					}
sl@0: 				else
sl@0: 					{
sl@0: 					deviceFound = true;
sl@0: 					* msDevice = strstr (strBuffer,strPID2) != NULL;
sl@0: 					* deviceIndex = i;
sl@0: 					lResult = SendMessage (devList,LB_SETCURSEL,(WPARAM)i,0);
sl@0: 					}
sl@0: 				}
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 
sl@0: 	if (deviceFound)
sl@0: 		{
sl@0: 		if (lResult == LB_ERR)
sl@0: 			{
sl@0: 			return USBIO_ERR_FAILED;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			lResult = SendMessage (devListDialog,WM_COMMAND,MAKEWPARAM(ID_OKBUTTON,BN_CLICKED),(LPARAM)okButton);
sl@0: 
sl@0: 			return USBIO_ERR_SUCCESS;
sl@0: 			}
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		* deviceIndex = -1;
sl@0: 
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 		}
sl@0: 
sl@0: }
sl@0: 
sl@0: 
sl@0: DWORD UsbcvControl::WaitForTestResult(BOOL * passFail)
sl@0: {
sl@0: 	HWND testResultDialog = NULL;
sl@0: 	HWND okButton;
sl@0: 	char strBuffer[BUFFER_SIZE];
sl@0: 
sl@0: 	for (int i=0; i < RESULT_WAIT && !testResultDialog; i++)
sl@0: 		{
sl@0: 		testResultDialog = FindWindow(DIALOG_CLASS,TESTRESULT_TITLE);
sl@0: 		if (testResultDialog)
sl@0: 			{
sl@0: 			UINT textSize = GetDlgItemText(testResultDialog,ID_RESULT_TEXT,(LPTSTR)&strBuffer,BUFFER_SIZE);
sl@0: 			okButton = GetDlgItem(testResultDialog,ID_RESULT_OK);
sl@0: 			if (!textSize || !okButton)
sl@0: 				{
sl@0: 				testResultDialog = NULL;
sl@0: 				}
sl@0: 			}
sl@0: 		if (!testResultDialog)
sl@0: 			Sleep(WAIT_SLEEP);
sl@0: 		}
sl@0: 
sl@0: 	if (!testResultDialog)
sl@0: 		return USBIO_ERR_FAILED;
sl@0: 
sl@0: 	if (strstr (strBuffer,TEST_PASSED))
sl@0: 		{
sl@0: 		* passFail = TRUE;
sl@0: 		}
sl@0: 	else
sl@0: 		{
sl@0: 		if (strstr (strBuffer,TEST_FAILED))
sl@0: 			{
sl@0: 			* passFail = FALSE;
sl@0: 			}
sl@0: 		else
sl@0: 			{
sl@0: 			return USBIO_ERR_FAILED;
sl@0: 			}
sl@0: 		}
sl@0: 
sl@0: 	SendMessage (testResultDialog,WM_COMMAND,MAKEWPARAM(ID_RESULT_OK,BN_CLICKED),(LPARAM)okButton);
sl@0: 
sl@0: 	return USBIO_ERR_SUCCESS;
sl@0: 
sl@0: }