#include "StdAfx.h"
#include "device_detection.h"

CDeviceDetection::CDeviceDetection(void)
{
	devicefound = false;
	init		= false;	
}

CDeviceDetection::CDeviceDetection(PCSTR _pEnumerator,DWORD _Property,LPTSTR _CompareString)
{
	pEnumerator = _pEnumerator;
	Property = _Property;
	CompareString = _CompareString;

	devicefound = false;
	init		= true;	
}

CDeviceDetection::~CDeviceDetection(void)
{
	/*close the device info*/
	CloseDeviceInfo();

	/*reset the status*/
	devicefound = false;
	init		= false;	

}

DWORD CDeviceDetection::InitParam(PCSTR _pEnumerator,DWORD _Property,LPTSTR _CompareString)
{
	
	pEnumerator = _pEnumerator;
	Property = _Property;
	CompareString = _CompareString;

	devicefound = false;
	init		= true;

	return DEV_OK;
}

BOOL CDeviceDetection::IsInit(void)
{
	return init;
}


BOOL CDeviceDetection::IsDeviceFound(void)
{
	return devicefound;
}

//void CDeviceDetection::SearchDevices(PCSTR pEnumerator,DWORD Property,IN LPTSTR CompareString)
void CDeviceDetection::SearchDevices()
{
	 SP_DEVINFO_DATA	DeviceInfoData;

	 /*check if parameters are initialized*/
	 if (!IsInit()){
		printf("DEV not inited\n");
		return;		
	}
	
	 /*Create the device info*/
	 hDevInfo = CreateDeviceInfo(pEnumerator);

	 /*List the devices*/
	 //EnumDevices(hDevInfo,&DeviceInfoData,Property,NULL);
	 memset(&DeviceInfoData,0,sizeof(SP_DEVINFO_DATA));
	 EnumDevices(hDevInfo,&DeviceInfoData,Property,CompareString);

     /*Handle the events if error occurs*/
     ErrorHandle();
}

void CDeviceDetection::EnumDevices(HDEVINFO hDevInfo,PSP_DEVINFO_DATA pDeviceInfoData,DWORD Property,IN LPTSTR CompareString)
{
	  DWORD i=0;
 
	   pDeviceInfoData->cbSize=sizeof(SP_DEVINFO_DATA);
       for (i=0;SetupDiEnumDeviceInfo(hDevInfo,i,pDeviceInfoData);i++)
       {
           DWORD DataT;
           LPTSTR buffer = NULL;
           DWORD buffersize = 0;
		
           /*
			Call function with null to begin with, 
			then use the returned buffer size (doubled)
            to Alloc the buffer. Keep calling until
            success or an unknown failure.
           
            Double the returned buffersize to correct
            for underlying legacy CM functions that 
            return an incorrect buffersize value on 
            DBCS/MBCS systems.
           
		   */
           while (!SetupDiGetDeviceRegistryProperty(
               hDevInfo,
               pDeviceInfoData,
               Property,//SPDRP_HARDWAREID,//SPDRP_HARDWAREID,//SPDRP_DEVICEDESC,
               &DataT,
              (PBYTE)buffer,
				buffersize,
               &buffersize))
			 {
               if (GetLastError() ==ERROR_INSUFFICIENT_BUFFER)
               {
                   /* Change the buffer size.*/
                   if (buffer) LocalFree(buffer);
                   /* Double the size to avoid problems on 
                    W2k MBCS systems per KB 888609. */
                   buffer = (LPTSTR)LocalAlloc(LPTR,buffersize * 2);
               }
               else
               {
                   /* Insert error handling here.*/
				   DebugPrintW(1,(L"SetupDiGetDeviceRegistryProperty : Error\n"));
                   break;
               }
           }

		   DebugPrint(0,("Result%d:[%s]\n",i,buffer));
		  
		   	    

		   if(CompareString==NULL)
		   {
			  /*Free the buffer*/
			  if (buffer)
			  {
				LocalFree(buffer);
			  }	

			  /*List the next device*/
			  continue;
		   }

		   /*Make sure we found the specified device*/
		   if(strstr(buffer,CompareString)!=NULL)
		   {
				 DebugPrint(0,("Found device.\n"));
				 devicefound = true;
				 
				 /*Free the buffer*/
				 if (buffer)
				 {
					LocalFree(buffer);
				 }
				 /*Exit the function when we found the device*/
				 break; 
		   }
		 	 
		   /*Free the buffer*/
           if (buffer)
		   {
			   LocalFree(buffer);
		   }
       }
		//return bFound;
	   return;
}

int CDeviceDetection::ErrorHandle()
{
	 if ( GetLastError()!=NO_ERROR && GetLastError()!=ERROR_NO_MORE_ITEMS )
     {
         /* Insert error handling here.*/
         return 1;
     }
	 return 0;
}

//void CDeviceDetection::CloseDeviceInfo(HDEVINFO hDevInfo)
void CDeviceDetection::CloseDeviceInfo()
{
	/*  Cleanup*/
	SetupDiDestroyDeviceInfoList(hDevInfo);
}

HDEVINFO CDeviceDetection::CreateDeviceInfo(PCSTR pEnumerator)
{
	   HDEVINFO hDevInfo;
	   /* Create a HDEVINFO with all present devices.*/
       hDevInfo = SetupDiGetClassDevs(NULL,
		  //REGSTR_KEY_HDAUDIO, // Enumerator
		  pEnumerator, // Enumerator
          0,
          DIGCF_PRESENT | DIGCF_ALLCLASSES );
       
       if (hDevInfo == INVALID_HANDLE_VALUE)
       {
           /* Insert error handling here.*/
           return NULL;
       }
	   
	   return hDevInfo;
}