#include "usbdetect.h"
#include "usb3000.h"
#include "usb2185.h"

static const WORD MAX_DEVICE_NAME_LENGTH = 16;  	//	максимальная длина строки с названием устройства
																	// не включая null-terminating character
// идентификатор программного модуля
static HINSTANCE hInstance;

//------------------------------------------------------------------------
// точка входа в библиотеку
//------------------------------------------------------------------------
#if defined (__BORLANDC__)
BOOL WINAPI DllEntryPoint(HINSTANCE hInst, DWORD fdwReason, LPVOID /*lpvReserved*/)
#else
BOOL WINAPI DllMain(HINSTANCE hInst, DWORD fdwReason, LPVOID /*lpvReserved*/)
#endif
{
	if(fdwReason == DLL_PROCESS_ATTACH)
		// сохраним идентификатор программного модуля
		hInstance = hInst;

	return TRUE;
}

//------------------------------------------------------------------------
// возвращает текущую версию библиотеки
//------------------------------------------------------------------------
extern "C" DWORD WINAPI RtGetDllVersion(void)
{
	return CURRENT_VERSION_RTUSBAPI;
}

//------------------------------------------------------------------------
// создание экземпляра необходимого класса
//------------------------------------------------------------------------
extern "C" LPVOID WINAPI RtCreateInstance(PCHAR const DeviceName)
{
	WORD DevNameLength;
	char DevName[MAX_DEVICE_NAME_LENGTH + 1];		// название устройства не более 17 символов
																// включая null-terminating character
	LPVOID pDevice = NULL;

	// причешем название модуля
	DevNameLength = (WORD)strlen(DeviceName);
	if(!DevNameLength) return NULL;
	else if(DevNameLength > MAX_DEVICE_NAME_LENGTH) DevNameLength = MAX_DEVICE_NAME_LENGTH;
	strncpy(DevName, DeviceName, DevNameLength);
	DevName[DevNameLength] = '\0';

	// попробуем открыть интерфейс на требуемый модуль
	if(!strcmpi(DevName, "USBDETECT")) pDevice = static_cast<IRTUSBDETECT *>(new CRTUSBDETECT(hInstance));
	else if(!strcmpi(DevName, "USB2185")) pDevice = static_cast<IRTUSB2185 *>(new CRTUSB2185(hInstance));
	else if(!strcmpi(DevName, "USB3000")) pDevice = static_cast<IRTUSB3000 *>(new CRTUSB3000(hInstance));
	// что-то не так с названием устройства
	return pDevice;
}

// Maybe defined in your compiler headers. If so, please, comment this
typedef struct _OSVERSIONINFOEX {
  DWORD dwOSVersionInfoSize;
  DWORD dwMajorVersion;
  DWORD dwMinorVersion;
  DWORD dwBuildNumber;
  DWORD dwPlatformId;
  TCHAR szCSDVersion[128];
  WORD wServicePackMajor;
  WORD wServicePackMinor;
  WORD wSuiteMask;
  BYTE wProductType;
  BYTE wReserved;
} OSVERSIONINFOEX, *POSVERSIONINFOEX, *LPOSVERSIONINFOEX;

//------------------------------------------------------------------------
// определение версии Windows
//------------------------------------------------------------------------
DWORD GetSystemVersionMy(void)
{
	OSVERSIONINFOEX osvi;

	ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

	if(!GetVersionEx((OSVERSIONINFO *)&osvi))
	{
		osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
		if(!GetVersionEx((OSVERSIONINFO *)&osvi)) return 0;
	}

	switch (osvi.dwPlatformId)
	{
		case VER_PLATFORM_WIN32_NT:
			if ( osvi.dwMajorVersion <= 4 ) return 0x00000003; // WinNT
			else if ( osvi.dwMajorVersion == 5 ) return 0x00010003; // Win2000 или WinXP

		case VER_PLATFORM_WIN32_WINDOWS:
			if((osvi.dwMajorVersion>4)||((osvi.dwMajorVersion==4)&&(osvi.dwMinorVersion>0))) return 0x00020001; // Win98
			else return 0x00010001; // Win95

		case VER_PLATFORM_WIN32s: return 0x00010000; // Win32s
	}
	return 0;
}

