⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiglusb.cpp

📁 TUSB3410 win9x和win xp 驱动源代码,包含开发测试工具
💻 CPP
字号:
// 
// TiglUsb driver for Windows 9x/Me, NT4/2000/XP
// Library (user mode) for talking with the driver (kernel mode)
//
// Copyright (c) 2001-2002 Romain Li関in
// roms@lpg.ticalc.org
// http://lpg.ticalc.org/prj_usb
//
// July the 4th, 2002
//

/*++

Module Name:

    Device.c
	(this file is the same for both drivers (98DDK & XPDDK))

Abstract:

    Library (user mode) used for talking with the driver (kernel mode).
	This library contains a set of functions for:
	- opening/closing the driver
	- reading/writing with the driver
	- flushing buffers
	- setting/getting timeout
	- checking arrival of data (useful for emulators which need to monitor the linkport)

Environment:

    user mode only

Notes:

  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  PURPOSE.

  Copyright (c) 2001-2004 Romain Li関in.  All Rights Reserved.


Revision History:

	03/07/02: created
	23/08/02: overlapped I/O fixes
	06/10/02: added a function for polling data arrival & improvements
	21/12/02: added a function for retrieving library version
        11/04/04: improved to workaround the quirk (returns neither error nor data)

--*/

#include <stdio.h>

#include "stdafx.h"
#include "TiglUsb.h"

//
// DllMain : defines the entry point for the DLL application.
//
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    switch (ul_reason_for_call)
	{
		case DLL_PROCESS_ATTACH:
		case DLL_THREAD_ATTACH:
		case DLL_THREAD_DETACH:
		case DLL_PROCESS_DETACH:
			break;
    }
    return TRUE;
}

TIGLUSB_EXP char* TIGLUSB_API TiglUsbVersion(void)
{
	return "2.3";
}

//
// TiglUsb.cpp: DLL routines
//

typedef DWORD                   TIME;
# define  toSTART(ref)          { (ref)=GetTickCount(); }
# define  toELAPSED(ref, max)   ( (int)(GetTickCount()-(ref)) > (100*max) )

static OVERLAPPED olp = { 0 };	// Overlapped structure for non-blocking I/O

static HANDLE hRead  = INVALID_HANDLE_VALUE;
static HANDLE hWrite = INVALID_HANDLE_VALUE;

static UCHAR rBuf[TIGLUSB_MAX_PACKET_SIZE];
static DWORD nBytesRead = 0;

static int timeout = 15;		// default timeout: 1.5 seconds

static void print_last_error()
{
	LPVOID lpMsgBuf;
	
	FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
					FORMAT_MESSAGE_FROM_SYSTEM |
					FORMAT_MESSAGE_IGNORE_INSERTS,
					NULL, GetLastError(),
					MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
					(LPTSTR) &lpMsgBuf,    0,    NULL );
	fprintf(stdout, "TiglUsb.dll error: %i -> %s\n", GetLastError(), lpMsgBuf);
}

// Open the device
TIGLUSB_EXP int TIGLUSB_API TiglUsbOpen()
{
	if( (hRead != INVALID_HANDLE_VALUE) || (hWrite != INVALID_HANDLE_VALUE) )
		return TIGLERR_DEV_ALREADY_OPEN;

	// Open the USB device: 2 named pipes (endpoints)
	hWrite = open_file(OUT_PIPE_0);
	if(hWrite == INVALID_HANDLE_VALUE)
	{
		print_last_error();
		return TIGLERR_DEV_OPEN_FAILED;
	}

	hRead = open_file(IN_PIPE_0);
	if(hRead == INVALID_HANDLE_VALUE)
	{
		print_last_error();
		return TIGLERR_DEV_OPEN_FAILED;
	}

	return 0;
}


TIGLUSB_EXP int TIGLUSB_API TiglUsbFlush()
{
	nBytesRead = 0;

	return (resetPipes() ? TIGLERR_FLUSH_FAILED : 0);
}


TIGLUSB_EXP int TIGLUSB_API TiglUsbWrite(UCHAR data)
{
	BOOL fSuccess;
	DWORD nBytesWritten;
	TIME clk;

	// start operation
	memset(&olp, 0, sizeof(OVERLAPPED));
	fSuccess=WriteFile(hWrite, &data, 1, &nBytesWritten, &olp);
	if( (fSuccess == FALSE) && (GetLastError() != ERROR_IO_PENDING) )
			return TIGLERR_WRITE_ERROR;

	// and wait for completion (overlapped = asynchronous)
	toSTART(clk);
	do 
	{
		if(toELAPSED(clk, timeout)) 
		{ 
			fprintf(stdout, "TiglUsb.dll: Write timeout error.\n"); 
			return TIGLERR_WRITE_TIMEOUT; 
		}
	} 
	//while(!GetOverlappedResult(hRead, &olp, &nBytesWritten, FALSE));
	while(HasOverlappedIoCompleted(&olp) == FALSE);
	fSuccess = GetOverlappedResult(hWrite, &olp, &nBytesWritten, FALSE);
	
	if(fSuccess == FALSE)
		return TIGLERR_WRITE_ERROR;
	if(nBytesWritten == 0)
		return TIGLERR_WRITE_TIMEOUT;

	return 0;
}

static BOOL ioPending = FALSE;

TIGLUSB_EXP int TIGLUSB_API TiglUsbCheck(int *status)
{
	BOOL fSuccess;

	*status = 0;

	if(nBytesRead > 0)
	{
		*status = !0;
		return 0;
	}

	if(ioPending == FALSE)
	{
		// start operation
		memset(&olp, 0, sizeof(OVERLAPPED));
		fSuccess = ReadFile(hRead, rBuf, TIGLUSB_MAX_PACKET_SIZE, &nBytesRead, &olp);
		if( (fSuccess == FALSE) && (GetLastError() != ERROR_IO_PENDING) )
			return TIGLERR_READ_ERROR;

		ioPending = TRUE;
	}
	else
	{
		// and monitor completion
		if(HasOverlappedIoCompleted(&olp) == FALSE)
			*status = 0;
		else
			*status = !0;
	}
	
	return 0;
}

TIGLUSB_EXP int TIGLUSB_API TiglUsbRead(UCHAR *data)
{
	BOOL fSuccess;
	TIME clk;
	static UCHAR *rBufPtr;

	/* This routine try to read up to 32 bytes (BULKUSB_MAX_TRANSFER_SIZE) and store them
	in a buffer for subsequent accesses */
	if(nBytesRead == 0)
	{
retry:
		if(ioPending == FALSE)
		{
			// start operation
			memset(&olp, 0, sizeof(OVERLAPPED));
			fSuccess = ReadFile(hRead, rBuf, TIGLUSB_MAX_PACKET_SIZE, &nBytesRead, &olp);
			if( (fSuccess == FALSE) && (GetLastError() != ERROR_IO_PENDING) )
				return TIGLERR_READ_ERROR;

			// and wait for completion (overlapped = asynchronous)
			toSTART(clk);
			do 
			{
				if(toELAPSED(clk, timeout)) 
				{ 
					fprintf(stdout, "TiglUsb.dll: Read timeout error.\n"); 
					return TIGLERR_READ_TIMEOUT; 
				}
			} 
			//while(!GetOverlappedResult(hRead, &olp, &nBytesRead, FALSE));	//wait bytes are written
			while(HasOverlappedIoCompleted(&olp) == FALSE);
		}

		fSuccess = GetOverlappedResult(hRead, &olp, &nBytesRead, FALSE);
		ioPending = FALSE;

		if( (fSuccess == FALSE) && (GetLastError() != ERROR_IO_PENDING) )
			return TIGLERR_READ_ERROR;

                // This is the quirk: sometimes retunrs with no data and no error; retry !
		if(nBytesRead == 0)
		//	return TIGLERR_READ_TIMEOUT;
                        goto retry;

		rBufPtr = rBuf;
	}
	
	*data = *rBufPtr++;
	nBytesRead--;

	return 0;
}


TIGLUSB_EXP int TIGLUSB_API TiglUsbClose()
{
	if(hWrite != INVALID_HANDLE_VALUE)
	{
		CloseHandle(hWrite);
		hWrite = INVALID_HANDLE_VALUE;
	}

	if(hRead != INVALID_HANDLE_VALUE)
	{
		CloseHandle(hRead);
		hRead = INVALID_HANDLE_VALUE;
	}

	return 0;
}


TIGLUSB_EXP int TIGLUSB_API TiglUsbSetTimeout(int ts)
{
	timeout = ts;

	return 0;
}


TIGLUSB_EXP int TIGLUSB_API TiglUsbGetTimeout(int *ts)
{
	if(ts != NULL)
		*ts = timeout;

	return timeout;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -