📄 tiglusb.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 + -