copie (2) de rwtigl.c

来自「TUSB3410 win9x和win xp 驱动源代码,包含开发测试工具」· C语言 代码 · 共 464 行

C
464
字号
// 
// TiglUsb driver for Windows 98/Me & 2000/XP
// Test program (and example)
//
// Copyright (c) 2001-2002 Romain Li関in
// roms@lpg.ticalc.org
// http://lpg.ticalc.org/prj_usb
//
// August the 23th, 2002
//

/*++

Copyright (c) 2001 Romain Li関in. All rights reserved.

Module Name:

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

Abstract:

    Console test app for TiglUsb.sys driver. This program can be considered as an
	example for direct talking with the driver.
	Depending on the NONBLOCKING constant, normal (blocking) or overlapped (non-blocking)
	I/O operations are performed.
	
	This program shows how to open, read, write, close, flush and configure the driver.

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) 1997-1998 Microsoft Corporation.  All Rights Reserved.


Revision History:

	11/17/97: created
	04/10/01: modified
	28/12/01: modified
	02/07/02: fixed errors with GetOverlapped
	23/08/02: timeout pb fixed (test)

--*/

#include <windows.h>

#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <time.h>

#include "devioctl.h"

#include <setupapi.h>
#include <basetyps.h>
#include "BulkUsr.h"

#include "usbdi.h"

#include "../api/tiglusb.h"

#define NOISY(_x_) printf _x_ ;

char inPipe[32] = "PIPE00";			// pipe name for bulk input pipe on our test board
char outPipe[32] = "PIPE01";		// pipe name for bulk output pipe on our test board

BOOL fDumpUsbConfig = FALSE;		// flags set in response to console command line switches
BOOL fDumpReadData  = FALSE;

int WriteLen = 0;					// #bytes to write
int ReadLen  = 0;					// #bytes to read

OVERLAPPED oOverlap = { 0 };		// Overlapped structure for non-blocking I/O
OVERLAPPED oOverlap2 = { 0 };		// Overlapped structure for non-blocking I/O

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

/*++
Routine Description:

    Convert an error code into a more human readable message.

Arguments:

    None

Return Value:

    None

--*/
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 );
	printf("Win32 error: %i -> %s\n", GetLastError(), lpMsgBuf);
}

/*++
Routine Description:

    Called by main() to dump usage info to the console when
    the app is called with no parms or with an invalid parm

Arguments:

    None

Return Value:

    None

--*/
void
usage()
{
    static int i=1;

    if (i) {
        printf("Usage for Read/Write test:\n");
        printf("-i [s] where s is the input pipe\n");
        printf("-o [s] where s is the output pipe\n");
        printf("-v verbose -- dumps read data\n");

        printf("\nUsage for USB and Endpoint info:\n");
        printf("-u to dump USB configuration and pipe info \n");
        i = 0;
    }
	exit(0);
}


/*++
Routine Description:

    Called by main() to parse command line parms

Arguments:

    argc and argv that was passed to main()

Return Value:

    Sets global flags as per user function request

--*/
void
parse(
    int argc,
    char *argv[] )
{
    int i;

	if ( argc < 2 ) // give usage if invoked with no parms
		usage();

    for (i=0; i<argc; i++) {
        if (argv[i][0] == '-' ||
            argv[i][0] == '/') {
            switch(argv[i][1]) {
            case 'i':
            case 'I':
                strcpy(inPipe, &argv[i+1][0]);
                i++;
                break;
            case 'u':
            case 'U':
                fDumpUsbConfig = TRUE;
				i++;
                break;
            case 'v':
            case 'V':
                fDumpReadData = TRUE;
				i++;
                break;
			 case 'o':
             case 'O':
                strcpy(outPipe, &argv[i+1][0]);
                i++;
                break;                    
            default:
                usage();
            }
        }
    }
}


/*++
Routine Description:

    Entry point to rwtigl.exe
    Parses cmdline, performs user-requested tests

Arguments:

    argc, argv  standard console  'c' app arguments

Return Value:

    Zero

--*/
int _cdecl main(
    int argc,
	char *argv[])
{
	HANDLE hRead  = INVALID_HANDLE_VALUE;
	HANDLE hWrite = INVALID_HANDLE_VALUE;	
    char *pinBuf  = NULL;
	char *poutBuf = NULL;
    int nBytesRead, nBytesWrite, nBytes;
	DWORD dwWait, dwError;
	BOOL bResult;
	UINT success;
	ULONG i=1;
	int j;
	//char buf[1024];
  
    parse(argc, argv );

	// dump USB configuation and pipe info
	if( fDumpUsbConfig ) 
	{
		dumpUsbConfig();
		return 0;
	}

	// open IN & OUT pipes
	hRead = open_file( inPipe);
    hWrite = open_file( outPipe);

	// allocate buffers
	pinBuf = malloc(TIGLUSB_MAX_PACKET_SIZE);
    poutBuf = malloc(4);

	// reset both pipes
	resetPipes();

	/* 
		Check if calc is ready (TI89/92+) : method 1
	*/

//isready:
	// send a packet
	printf("Send an 'Is ready ?' packet\n");
	if (poutBuf && hWrite != INVALID_HANDLE_VALUE) 
	{
		WriteLen = 4;
		poutBuf[0] = 0x00;
		poutBuf[1] = 0x56;
		poutBuf[2] = 0x00;
		poutBuf[3] = 0x00;

		printf("Send packet...\n");
#ifndef NONBLOCKING
	    WriteFile(hWrite, poutBuf, WriteLen, &nBytesWrite, NULL);
		if(!nBytesWrite) { printf("Write Error: timeout\n"); goto end; }
#else
		memset(&oOverlap, 0, sizeof(OVERLAPPED));	// clear struct
		oOverlap.hEvent = CreateEvent( 
         NULL,    // no security attribute 
         TRUE,    // manual-reset event 
         TRUE,    // initial state = signaled 
         NULL);   // unnamed event object 
		bResult = WriteFile(hWrite, poutBuf, WriteLen, &nBytesWrite, &oOverlap);
		if(!bResult)
		{
			switch(dwError = GetLastError())
			{
			case ERROR_IO_PENDING:
				printf("I/O is still pending...\n");
				dwWait  = WaitForSingleObject(oOverlap.hEvent, 15);
				if(dwWait == WAIT_FAILED) {
					printf("Wait failed !\n");
					print_last_error();
				}
				printf("I/O elapsed !\n");
				bResult = GetOverlappedResult(hWrite, &oOverlap, &nBytesWrite, FALSE);
				if(!bResult)
				{
					dwError = GetLastError();
					printf("GetOverlapResult error !\n");
				} 
				else
					printf("GetOverlappedResult ok\n");
				break;

			}

		}
#endif

		printf("<%s> W (%04.4d) : request %06.6d bytes -- %06.6d bytes written\n", 
	                    outPipe, i, WriteLen, nBytesWrite);
        assert(nBytesWrite == WriteLen);
	}

	// receive answer
	if (pinBuf) 
	{
		TIME clk;

		printf("Receive packet...\n");
		ReadLen = TIGLUSB_MAX_PACKET_SIZE;
#ifndef NONBLOCKING
		ReadFile(hRead, pinBuf, ReadLen, &nBytesRead, NULL);
		if(!nBytesRead) { printf("Read Error: timeout\n"); goto end; }
#else
		memset(&oOverlap2, 0, sizeof(OVERLAPPED));							// clear struct
		oOverlap2.hEvent = CreateEvent( 
         NULL,    // no security attribute 
         TRUE,    // manual-reset event 
         TRUE,    // initial state = signaled 
         NULL);   // unnamed event object 
	    bResult = ReadFile(hRead, pinBuf, ReadLen, &nBytesRead, &oOverlap2);
		if(!bResult)
		{
			switch(dwError = GetLastError())
			{
			case ERROR_IO_PENDING:
				printf("I/O is still pending...\n");
				dwWait  = WaitForSingleObject(oOverlap2.hEvent, 15);
				if(dwWait == WAIT_FAILED) {
					printf("Wait failed !\n");
					print_last_error();
				}
				printf("I/O elapsed !\n");
				bResult = GetOverlappedResult(hRead, &oOverlap2, &nBytesRead, FALSE);
				if(!bResult)
				{
					printf("GetOverlapResult error !\n");
					print_last_error();
				}
				else
					printf("GetOverlappedResult ok\n");
				break;

			}

		}
#endif

        printf("<%s> R (%04.4d) : request %06.6d bytes -- %06.6d bytes read\n", 
               inPipe, i, ReadLen, nBytesRead);
		for(j=0; j<nBytesRead; j++) printf("0x%02x ", pinBuf[j] & 0x000000ff);
		printf("\n");
	}


	/* 
		Flush pipes 
	*/
	/*
#ifdef OVERLAP
	printf("Flushing...\n");
	ReadLen = 1024;
	memset(&oOverlap, 0, sizeof(OVERLAPPED));							// clear struct
	success = ReadFile(hRead, pinBuf, ReadLen, &nBytesRead, &oOverlap);
#endif
	*/

	goto end;
	resetPipes();	

	/* 
		Get a screensump (TI89) : method 2
	*/

//screendump:
	// send a packet
	printf("Get a screendump\n");
	if (poutBuf && hWrite != INVALID_HANDLE_VALUE) 
	{
		TIME clk;
		WriteLen = 4;
		poutBuf[0]=0x08;
		poutBuf[1]=0x6D;
		poutBuf[2]=0x00;
		poutBuf[3]=0x00;

#ifndef NONBLOCKING
		printf("Send packet...\n");
	    WriteFile(hWrite, poutBuf, WriteLen, &nBytesWrite, NULL);
		if(!nBytesWrite) { printf("Write Error: timeout\n"); goto end; }
#else
		memset(&oOverlap, 0, sizeof(OVERLAPPED));							// clear struct
		WriteFile(hWrite, poutBuf, WriteLen, &nBytesWrite, &oOverlap);
		toSTART(clk);
		do {
			if(toELAPSED(clk, 15)) { printf("Timeout !!!\n"); goto end; }
		} 
		while(HasOverlappedIoCompleted(&oOverlap) == FALSE);
#endif

		printf("<%s> W (%04.4d) : request %06.6d bytes -- %06.6d bytes written\n", 
	                    outPipe, i, WriteLen, nBytesWrite);
        assert(nBytesWrite == WriteLen);
	}

	// receive answer
	if (pinBuf) 
	{
		TIME clk;
		nBytesRead = 0;
		printf("Receive packet...\n");
		for(i=0, nBytesRead=0; i<4+4+3840+2; i+=nBytesRead)
		{
			do
			{
				ReadLen = TIGLUSB_MAX_PACKET_SIZE;
#ifndef NONBLOCKING
				ReadFile(hRead, pinBuf, ReadLen, &nBytesRead, NULL);
#else
				memset(&oOverlap, 0, sizeof(OVERLAPPED));							// clear struct
				success = ReadFile(hRead, pinBuf, ReadLen, &nBytesRead, &oOverlap);
				toSTART(clk);
				do {
					if(toELAPSED(clk, 15)) { printf("Timeout !!!\n"); goto end; }
				} 
				while(HasOverlappedIoCompleted(&oOverlap) == FALSE);
#endif
			}
			while(!nBytesRead);
			printf("%i ", nBytesRead);
		}
		printf("\n");
	}

end:
	// free memory
	if (pinBuf) free(pinBuf);
    if (poutBuf) free(poutBuf);

	// close devices if needed
	if(hRead != INVALID_HANDLE_VALUE)
		CloseHandle(hRead);
	if(hWrite != INVALID_HANDLE_VALUE)
		CloseHandle(hWrite);
	printf("All handles closed\n");

	printf("Program terminated\n");

	return 0;
}

⌨️ 快捷键说明

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