//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft shared
// source or premium shared source license agreement under which you licensed
// this source code. If you did not accept the terms of the license agreement,
// you are not authorized to use this source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the SOURCE.RTF on your install media or the root of your tools installation.
// THE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//******************************************************************************
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//******************************************************************************
/*++
Module Name: 
	usbclass.cpp

Abstract:  
    USB driver access class.

Author:
    davli

Modified:
    weichen

Functions:

Notes: 

--*/
#define __THIS_FILE__   TEXT("UsbClass.cpp")

#include <windows.h>
#include "syncobj.h"
#include "usbclass.h"
#include "usbserv.h"


UsbDriverArray::UsbDriverArray(BOOL bAutoDelete,DWORD arraySize) : autoDelete(bAutoDelete)
{
	DEBUGMSG(DBG_INI, (TEXT("UsbDriverArray Initial")));
	if (arraySize<5)
		arraySize=5;
	arrayUsbClientDrv= (UsbClientDrv **)malloc(sizeof(UsbClientDrv *)*arraySize);
	DEBUGMSG(DBG_INI, (TEXT("UsbDriverArray Initial addr=%lx,length=%ld"),arrayUsbClientDrv,arraySize));
	ASSERT(arrayUsbClientDrv);
	memset(arrayUsbClientDrv,0,sizeof(UsbClientDrv *)*arraySize);
	dwArraySize=arraySize;
	dwCurDevs = 0;
};
UsbDriverArray::~UsbDriverArray()
{
	if (autoDelete) {
		for (int i=0;i<(int)dwArraySize;i++) {
			if (arrayUsbClientDrv[i]!=NULL)
				delete arrayUsbClientDrv[i];
			arrayUsbClientDrv[i]=NULL;
		};
	}
	free(arrayUsbClientDrv);
}
UsbClientDrv * UsbDriverArray::operator[](int nIndex) const
{
	return GetAt(nIndex);
}
UsbDriverArray& UsbDriverArray::operator=(UsbClientDrv * oneDriver)
{
	AddClientDrv(oneDriver);
	return *this;
}

BOOL UsbDriverArray::AddClientDrv(UsbClientDrv * oneDriver)
{
	DEBUGMSG(DBG_INI, (TEXT("AddClientDrv addr=%lx,length=%ld"),arrayUsbClientDrv,dwArraySize));
	ASSERT(oneDriver);
	Lock();
	for (int i=0;i<(int)dwArraySize;i++){
		if (*(arrayUsbClientDrv+i)==NULL)
			break;
	};
	DEBUGMSG(DBG_INI,(TEXT("AddClientDrv position=%d"),i));
	BOOL bReturn;
	if ((DWORD)i<dwArraySize) {
		*(arrayUsbClientDrv+i)=oneDriver;
		DEBUGMSG(DBG_INI,(TEXT("AddClientDrv return success")));
		bReturn=TRUE;
		dwCurDevs ++;
	}
	else {
		DEBUGMSG(DBG_INI,(TEXT("AddClientDrv return failure")));
		bReturn=FALSE;
	};
	Unlock();
	return bReturn;
}
BOOL UsbDriverArray::RemoveClientDrv(UsbClientDrv * pClientDriver,BOOL bDelete)
{
	if (pClientDriver==NULL)
		return FALSE;
	Lock();
	for (int i=0;i<(int)dwArraySize;i++)
		if (arrayUsbClientDrv[i]==pClientDriver)
			break;
	BOOL bReturn;
	if ((DWORD)i<dwArraySize) {
		arrayUsbClientDrv[i]=NULL;
		if (bDelete) 
			delete pClientDriver;
		bReturn=TRUE;
		dwCurDevs --;
	}
	else
		bReturn=FALSE;
	Unlock();
	return bReturn;
}
BOOL UsbDriverArray::IsContainClientDrv(UsbClientDrv * pClientDriver)
{
	for (int i=0;i<(int)dwArraySize;i++)
		if (arrayUsbClientDrv[i]==pClientDriver)
			break;
	BOOL bReturn=(i<(int)dwArraySize);
	return bReturn;
}
BOOL UsbDriverArray::IsEmpty()
{
	Lock();
	for (int i=0;i<(int)dwArraySize;i++)
		if (arrayUsbClientDrv[i]!=NULL)
			break;
	Unlock();
	if ((DWORD)i<dwArraySize)
		return TRUE;
	else
		return FALSE;
}

UsbClientDrv * UsbDriverArray::GetAt(int nIndex) const
{
	if ((DWORD)nIndex<dwArraySize) 
		return arrayUsbClientDrv[nIndex];
	else
		return NULL;
}

BOOL USBDriverClass::CreateUsbAccessHandle(HINSTANCE hInst)
{
	lpOpenClientRegistyKey=(LPOPEN_CLIENT_REGISTRY_KEY)GetProcAddress(hInst,TEXT("OpenClientRegistryKey"));
    lpRegisterClientDriverID=(LPREGISTER_CLIENT_DRIVER_ID)GetProcAddress(hInst,TEXT("RegisterClientDriverID"));
    lpUnRegisterClientDriverID=(LPUN_REGISTER_CLIENT_DRIVER_ID)GetProcAddress(hInst,TEXT("UnRegisterClientDriverID"));
    lpRegisterClientSettings=(LPREGISTER_CLIENT_SETTINGS)GetProcAddress(hInst,TEXT("RegisterClientSettings"));
    lpUnRegisterClientSettings=(LPUN_REGISTER_CLIENT_SETTINGS)GetProcAddress(hInst,TEXT("UnRegisterClientSettings"));
    lpGetUSBDVersion=(LPGET_USBD_VERSION)GetProcAddress(hInst,TEXT("GetUSBDVersion"));
	if (lpOpenClientRegistyKey &&
			lpRegisterClientDriverID &&
			lpUnRegisterClientDriverID &&
			lpRegisterClientSettings &&
			lpUnRegisterClientSettings &&
			lpGetUSBDVersion ) {
		UsbDriverClassError=FALSE;
		return TRUE;
	}
	else {
		UsbDriverClassError=TRUE;
		DEBUGMSG(DBG_ERR,(TEXT(" Usb Liberary Load Error")));
		return FALSE;
	};
};
USBDriverClass::USBDriverClass(BOOL bAutoDelete) :UsbDriverArray(bAutoDelete)
{
	DEBUGMSG(DBG_INI,(TEXT("USBDriverClass Initial")));
    CreateUsbAccessHandle(hInst=LoadLibrary(DEFAULT_USB_DRIVER));
}
USBDriverClass::USBDriverClass(LPCTSTR lpDrvName,BOOL bAutoDelete):UsbDriverArray(bAutoDelete)
{
	DEBUGMSG(DBG_INI,(TEXT("USBDriverClass Initial")));
    CreateUsbAccessHandle(hInst=LoadLibrary(lpDrvName));
}
VOID USBDriverClass::GetUSBDVersion(LPDWORD lpdwMajorVersion, LPDWORD lpdwMinorVersion)
{
	if(lpGetUSBDVersion == NULL)
	    return;
	
	(*lpGetUSBDVersion)(lpdwMajorVersion,lpdwMinorVersion);
};
BOOL USBDriverClass::RegisterClientDriverID(LPCWSTR szUniqueDriverId)
{
	if(lpRegisterClientDriverID == NULL)
	    return FALSE;
	return (*lpRegisterClientDriverID)(szUniqueDriverId);
};
BOOL USBDriverClass::UnRegisterClientDriverID(LPCWSTR szUniqueDriverId)
{
	if(lpUnRegisterClientDriverID == NULL)
	    return FALSE;
	return (*lpUnRegisterClientDriverID)(szUniqueDriverId);
};
BOOL USBDriverClass::RegisterClientSettings(LPCWSTR lpszDriverLibFile,
                            LPCWSTR lpszUniqueDriverId, LPCWSTR szReserved,
                            LPCUSB_DRIVER_SETTINGS lpDriverSettings)
{
	if(lpRegisterClientSettings == NULL)
	    return FALSE;
	return (*lpRegisterClientSettings)(lpszDriverLibFile,lpszUniqueDriverId,szReserved,lpDriverSettings);
}
BOOL USBDriverClass::UnRegisterClientSettings(LPCWSTR lpszUniqueDriverId, LPCWSTR szReserved,
                              LPCUSB_DRIVER_SETTINGS lpDriverSettings)
{
	if(lpUnRegisterClientSettings == NULL)
	    return FALSE;
	return (*lpUnRegisterClientSettings)(lpszUniqueDriverId,szReserved,lpDriverSettings);
}
HKEY USBDriverClass::OpenClientRegistryKey(LPCWSTR szUniqueDriverId)
{
	if(lpOpenClientRegistyKey == NULL)
	    return NULL;
	return (*lpOpenClientRegistyKey)(szUniqueDriverId);
};




