// This is a Sample Driver
#include "stdafx.h"
#include <windows.h>
DWORD BQD_Init(LPCTSTR pContext, LPCVOID lpvBusContext);
BOOL BQD_Deinit( DWORD hDeviceContext );
DWORD BQD_Open( DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode );
BOOL BQD_Close( DWORD hOpenContext );
BOOL BQD_IOControl( DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut );
void BQD_PowerUp( DWORD hDeviceContext );
void BQD_PowerDown( DWORD hDeviceContext );
DWORD BQD_Read( DWORD hOpenContext, LPVOID pBuffer, DWORD Count );
DWORD BQD_Write( DWORD hOpenContext, LPCVOID pBuffer, DWORD Count );
DWORD BQD_Seek( DWORD hOpenContext, long Amount, WORD Type );
BOOL CustomFunction(void);
BOOL CustomFunctionEx(LPTSTR lpBuffer);
void DBGOut(DWORD dwValue);

#define IOCTL_DRIVER_REVSTR 0x1000

HANDLE hMem;      // Storage for Inbound Strings
DWORD  dwCount;   // Size of current String
// ----------------------------------------------------

BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved )
{
    switch(ul_reason_for_call) {
        case DLL_PROCESS_ATTACH:
            OutputDebugString(L"BQDrv - DLL_PROCESS_ATTACH\n");
        break;
        case DLL_PROCESS_DETACH:
            OutputDebugString(L"BQDrv - DLL_PROCESS_DETACH\n");
        break;
        case DLL_THREAD_ATTACH:
            OutputDebugString(L"BQDrv - DLL_THREAD_ATTACH\n");
        break;
        case DLL_THREAD_DETACH:
            OutputDebugString(L"BQDrv - DLL_THREAD_DETACH\n");
        break;
        default:
        break;
    }
return TRUE;
}

BOOL GetBQStatus() {
	return TRUE;
}

// Driver Init...
DWORD BQD_Init( LPCTSTR pContext, LPCVOID lpvBusContext)
{
  OutputDebugString(L"BQDrv - BQD_Init - Context: ");
  OutputDebugString(pContext);
  OutputDebugString(L"\n");
  hMem=LocalAlloc(LPTR,0x2000);   // 0x1000 Unicode Characters

  OutputDebugString(L"BQDrv - ~ BQD_Init\n");
  return 0x1234;
}

BOOL BQD_Deinit( DWORD hDeviceContext )
{
OutputDebugString(L"BQDrv - BQD_Deinit\n");

OutputDebugString(L"BQDrv - ~ BQD_Deinit\n");
return TRUE;
}

// Driver Open
DWORD BQD_Open( DWORD hDeviceContext, DWORD AccessCode, DWORD ShareMode )
{
  OutputDebugString(L"BQDrv - BQD_Open\n");
  OutputDebugString(L"hDeviceContext - ");
  DBGOut(hDeviceContext);
  OutputDebugString(L"\n");
  OutputDebugString(L"BQDrv - ~ BQD_Open\n");
return 0x5678;
}
BOOL BQD_Close( DWORD hOpenContext )
{
  OutputDebugString(L"BQDrv - BQD_Close\n");
  OutputDebugString(L"hOpenContext - ");
  DBGOut(hOpenContext);
  OutputDebugString(L"\n");
  OutputDebugString(L"BQDrv - ~ BQD_Close\n");
return TRUE;
}
BOOL BQD_IOControl( DWORD hOpenContext, DWORD dwCode, PBYTE pBufIn, DWORD dwLenIn, PBYTE pBufOut, DWORD dwLenOut, PDWORD pdwActualOut )
{
  OutputDebugString(L"BQDrv - BQD_IOControl\n");
  OutputDebugString(L"hOpenContext - ");
  DBGOut(hOpenContext);
  OutputDebugString(L"\n");
  switch (dwCode) {
    case IOCTL_DRIVER_REVSTR:
    {
       OutputDebugString(L"DRIVER REVSTR IOCTL...\n");
       // reverse the string...
       HANDLE hTemp=LocalAlloc(LPTR,dwLenIn+sizeof(TCHAR));
       memset(hTemp,0x00,dwLenIn+1);
       TCHAR *tcOut=(TCHAR*)hTemp;
       TCHAR *tcIn=(TCHAR*)pBufIn;
       DWORD dwChars=dwLenIn/2;
       for (DWORD x=0;x < dwChars;x++) {
          tcOut[x]=tcIn[dwChars-x-1];
       }
       memcpy(pBufOut,hTemp,dwLenIn);
       LocalFree(hTemp);
       *pdwActualOut=dwLenIn;
    }
    break;
    default:
       OutputDebugString(L"Unknown IOCTL\n");
    break;
}
	HINSTANCE hCore = LoadLibrary(L"Coredll.dll");
	if(!hCore) {
		return TRUE;
	}
	typedef BOOL (*KernelIoControlptr)(DWORD, LPVOID, DWORD, LPVOID, DWORD, LPDWORD);

	KernelIoControlptr KernelIoControl = (KernelIoControlptr)GetProcAddress(hCore, L"KernelIoControl");



OutputDebugString(L"BQDrv - ~ BQD_IOControl\n");
return TRUE;
}
void BQD_PowerUp( DWORD hDeviceContext )
{
  OutputDebugString(L"BQDrv - BQD_PowerUp\n");
  OutputDebugString(L"hDeviceContext - ");
  DBGOut(hDeviceContext);
  OutputDebugString(L"\n");

  OutputDebugString(L"BQDrv - ~ BQD_PowerUp\n");
}

void BQD_PowerDown( DWORD hDeviceContext )
{
  OutputDebugString(L"BQDrv - BQD_PowerDown\n");
  OutputDebugString(L"hDeviceContext - ");
  DBGOut(hDeviceContext);
  OutputDebugString(L"\n");

  OutputDebugString(L"BQDrv - ~ BQD_PowerDown\n");
}

DWORD BQD_Read( DWORD hOpenContext, LPVOID pBuffer, DWORD Count )
{
  DWORD dwRetCount=0xffff;      // default to error
  OutputDebugString(L"BQDrv - BQD_Read\n");
  OutputDebugString(L"hOpenContext - ");
  DBGOut(hOpenContext);
  OutputDebugString(L"\n");
  if (NULL != hMem) {
     dwRetCount=dwCount;
     memcpy(pBuffer,hMem,dwCount);
  }
  OutputDebugString(L"BQDrv - ~ BQD_Read\n");

return dwRetCount;
}

DWORD BQD_Write( DWORD hOpenContext, LPCVOID pBuffer, DWORD Count )
{
  OutputDebugString(L"BQDrv - BQD_Write\n");
  OutputDebugString(L"hOpenContext - ");
  DBGOut(hOpenContext);
  OutputDebugString(L"\n");

  if (NULL != hMem) {
     LocalFree(hMem);
  }

  hMem=LocalAlloc(LPTR,Count);
  memcpy(hMem,pBuffer,Count);
  dwCount=Count;

  OutputDebugString(L"BQDrv - ~ BQD_Write\n");

return Count;
}

DWORD BQD_Seek( DWORD hOpenContext, long Amount, WORD Type )
{
  OutputDebugString(L"BQDrv - BQD_Seek\n");
  OutputDebugString(L"hOpenContext - ");
  DBGOut(hOpenContext);
  OutputDebugString(L"\n");

  OutputDebugString(L"BQDrv - ~ BQD_Seek\n");

return 0;
}
BOOL CustomFunction(void)
{
  OutputDebugString(L"BQDrv - CustomFunction\n");
  OutputDebugString(L"BQDrv - ~ CustomFunction\n");
return TRUE;
}
BOOL CustomFunctionEx(LPTSTR lpBuffer )
{
  OutputDebugString(L"BQDrv - CustomFunctionEx\n");
  TCHAR buffer[16];
  _tcscpy(buffer, lpBuffer);
  OutputDebugString(buffer);
  OutputDebugString(_T("\n"));
  OutputDebugString(L"BQDrv - ~ CustomFunctionEx\n");
return TRUE;
}

void DBGOut(DWORD dwValue)
{
  TCHAR tcTemp[10];
  wsprintf(tcTemp,L"%ld",dwValue);
  OutputDebugString(tcTemp);
}



