Test.C
资源名称:虚拟串口驱动程序.rar [点击查看]
上传用户:zanmei2
上传日期:2010-03-06
资源大小:775k
文件大小:11k
源码类别:
通讯编程文档
开发平台:
C/C++
- #include <windows.h>
- #include <initguid.h>
- #include "winioctl.h"
- #include <stdio.h>
- #include "tchar.h"
- #include <setupapi.h>
- #include "objbase.h"
- #include "..incwdmioctl.h"
- #include "conio.h"
- #include "test.h"
- /*++
- 打印使用信息
- --*/
- void Usage()
- {
- printf("Usage: test [-e] [-r IP:Port] [-n N] serial device numbern");
- printf(" -e: enumerate serial devicen");
- printf(" -r: set remote IP address and Portn");
- printf(" -n: create virtual device DOS name, eg. COM5n");
- printf(" -d: delete virtual device DOS namen");
- }
- /*++
- 格式化输入的参数
- argc - 参数个数
- argv - 参数字符串数组
- lpCmd - 格式化后的命令结构
- Return value:
- >=0: Success, 返回将要操作的目标设备序号
- -1: Error, 输入参数格式错误
- -2: Success, 没有返回特定的目标设备号
- --*/
- int Parse( int argc, char* argv[], PCMDS lpCmd )
- {
- int n;
- int nCmd;
- int Ret;
- nCmd = 0;
- Ret = -2;
- lpCmd->TargetDevice = -1;
- for ( n = 1; n < argc; n++)
- {
- if ( argv[ n ][ 0 ] == '-' )
- {
- switch ( argv[ n ][ 1 ] )
- {
- case 'e':
- lpCmd->bIsEnum = TRUE;
- break;
- case 'd':
- lpCmd->bDeleteDosName = TRUE;
- break;
- case 'r':
- n++;
- if ( n >= argc )
- return -1;
- if ( -1 == ParseAddress ( argv[ n ], &lpCmd->IPAddress, &lpCmd->Port ) )
- {
- printf("IPAddress and Port errorn");
- return -1;
- }
- lpCmd->bSetRmt = TRUE;
- break;
- case 'n':
- n++;
- if ( n >= argc )
- return -1;
- {
- int ComX;
- ComX = atoi ( argv[ n ] );
- if ( ComX > 255 )
- {
- printf("-n: create DOS name: Com%dn", ComX );
- printf(" ~~--> error!n");
- return -1;
- }
- lpCmd->ComX = ComX;
- lpCmd->bCreateDosName = TRUE;
- }
- break;
- default:
- return -1;
- }
- }else
- {
- if ( Ret == -2 )
- {
- Ret = atoi( argv[ n ] );
- if ( Ret < 0 )
- return -1;
- else
- lpCmd->TargetDevice = Ret;
- }else
- return -1;
- }
- }
- return Ret;
- }
- /*++
- 格式化IP地址和端口参数字符串
- szAddress - 输入的IP地址和端口参数字符串,形如:192.168.0.3:1025
- IPAddress - 输出的IP地址,符合网络字节序,即 0x0301a8c0
- Port - 输出的端口,符合网络字节序,即 0x0104
- --*/
- int ParseAddress( const char* szAddress, PULONG IPAddress, PUSHORT Port)
- {
- int Ret;
- char* pdest;
- char buf[ 16 ];
- int length;
- PUCHAR pa;
- UCHAR temp;
- int i, n, lastdot;
- Ret = -1;
- memset ( buf, 0, 16 );
- pdest = strchr ( szAddress, ':' );
- if ( pdest == NULL )
- return Ret;
- if ( pdest != strrchr ( szAddress, ':' ) )
- return Ret;
- strcpy ( buf, (const char* )( pdest + 1 ) );
- *Port = (USHORT)atoi( (const char*)buf );
- // change *Port from Intel order to Network Order
- pa = (PUCHAR)Port;
- temp = pa[ 0 ];
- pa[ 0 ] = pa[ 1 ];
- pa[ 1 ] = temp;
- if( ( pdest - szAddress ) > 15 )
- return Ret;
- memset ( buf, 0, 16 );
- strncpy ( buf, szAddress, ( pdest - szAddress ) );
- length = strlen ( buf );
- n = 0;
- lastdot = -1;
- if ( buf[ length - 1 ] == '.' )
- return Ret;
- for ( i = 0; i < length; i++)
- {
- if ( buf[ i ] == '.' )
- {
- if (( ( i - lastdot ) > 4 ) || ( ( i - lastdot ) < 2 ) )
- return Ret;
- buf[ i ] = 0;
- lastdot = i;
- n++;
- }
- }
- if ( n != 3 )
- return Ret;
- pdest = buf;
- pa = (PUCHAR)IPAddress;
- for ( i = 0; i < 4; i++ )
- {
- length = strlen ( pdest );
- if ( length > 3 )
- return Ret;
- n = atoi ( pdest );
- if ( n > 255 )
- return Ret;
- pa[ i ] = (UCHAR)n;
- pdest += strlen ( pdest ) + 1;
- }
- return 0;
- }
- int main(int argc, char* argv[])
- {
- CMDS cmd;
- int nDevice;
- if ( argc == 1 )
- {
- Usage();
- return 0;
- }
- memset ( (void*)&cmd, 0, sizeof ( CMDS ) );
- nDevice = Parse( argc, argv, &cmd );
- if ( nDevice == -1 )
- {
- printf("Error parameters!nn");
- Usage();
- return 0;
- }
- if ( cmd.bIsEnum )
- {
- printf("n- Serial ports classn--------------n");
- EnumDevice ( (LPGUID)&GUID_CLASS_COMPORT );
- printf("nn");
- }
- if ( cmd.bDeleteDosName && ( cmd.TargetDevice >= 0 ) )
- {
- printf("- Delete DOS namen-------------n");
- DeleteDosName ( (GUID*)&GUID_CLASS_COMPORT, (int)cmd.TargetDevice );
- printf("nn");
- }
- if( ( cmd.bCreateDosName ) && ( cmd.TargetDevice >= 0 ) )
- {
- printf("- Create DOS namen-------------n");
- CreateDosName( (GUID*)&GUID_CLASS_COMPORT, (int)cmd.TargetDevice, (ULONG)cmd.ComX );
- printf("nn");
- }
- if( ( cmd.bSetRmt ) && ( cmd.TargetDevice >= 0 ) )
- {
- printf("- Set remote IP infon-------------n");
- printf("IPAddress = 0x%x, Port = 0x%xn", cmd.IPAddress, cmd.Port );
- SetRmt( (LPGUID) &GUID_CLASS_COMPORT, cmd.TargetDevice, cmd.IPAddress, cmd.Port );
- printf("nn");
- }
- return 0;
- }
- /*++
- 向虚拟串口设备发送命令,要求创建指定的DOS name,即 ComX
- lpGuid - 设备类GUID, 此处传入 GUID_CLASS_COMPORT
- TargetDevice- 目标设备的序号,此序号由 EnumDevice函数枚举设备类得来。
- ComX - 指定的DOS name的序列号,若要创建COM10,则ComX = 10
- --*/
- void CreateDosName( LPGUID lpGuid, int TargetDevice, ULONG ComX )
- {
- HANDLE hfile;
- BOOL bRet;
- DWORD dwRet;
- hfile = OpenDevice( lpGuid, TargetDevice );
- if ( hfile == INVALID_HANDLE_VALUE )
- return;
- bRet = DeviceIoControl( hfile,
- IOCTL_CREATE_DOS_NAME,
- &ComX, sizeof ( ULONG ), NULL, 0, &dwRet, NULL );
- if ( !bRet )
- printf("IOCTL_CREATE_DOS_NAME Failed (0x%x)n", GetLastError() );
- else
- printf("IOCTL_CREATE_DOS_NAME OKn");
- CloseHandle ( hfile );
- }
- /*++
- 向虚拟串口设备发送命令,要求删除DOS name
- lpGuid - 设备类GUID, 此处传入 GUID_CLASS_COMPORT
- TargetDevice- 目标设备的序号,此序号由 EnumDevice函数枚举设备类得来。
- --*/
- void DeleteDosName ( LPGUID lpGuid, int TargetDevice )
- {
- HANDLE hfile;
- BOOL bRet;
- DWORD dwRet;
- hfile = OpenDevice( lpGuid, TargetDevice );
- if ( hfile == INVALID_HANDLE_VALUE )
- return;
- bRet = DeviceIoControl( hfile,
- IOCTL_DELETE_DOS_NAME,
- NULL, 0, NULL, 0, &dwRet, NULL );
- if ( !bRet )
- printf("IOCTL_DELETE_DOS_NAME Failed (0x%x)n", GetLastError() );
- else
- printf("IOCTL_DELETE_DOS_NAME OKn");
- CloseHandle ( hfile );
- }
- /*++
- 向虚拟串口设备发送命令,指定远端目标机器的地址和端口,用于以后发送UDP数据。
- lpGuid - 设备类GUID, 此处传入 GUID_CLASS_COMPORT
- TargetDevice- 目标设备的序号,此序号由 EnumDevice函数枚举设备类得来
- IPAddress - 远端目标机器的IP地址
- Port - 远端目标机器的端口
- --*/
- void SetRmt( LPGUID lpGuid, int TargetDevice, ULONG IPAddress, USHORT Port )
- {
- HANDLE hfile;
- BOOL bRet;
- DWORD dwRet;
- ULONG buf[ 2 ];
- hfile = OpenDevice( lpGuid, TargetDevice );
- if ( hfile == INVALID_HANDLE_VALUE )
- return;
- buf[ 0 ] = IPAddress;
- buf[ 1 ] = (ULONG)Port;
- bRet = DeviceIoControl( hfile,
- IOCTL_SET_REMOTE_INFO,
- buf, sizeof ( ULONG ) * 2, NULL, 0, &dwRet, NULL );
- if ( !bRet )
- printf("IOCTL_SET_REMOTE_INFO Failed (0x%x)n", GetLastError() );
- else
- printf("IOCTL_SET_REMOTE_INFO OKn");
- CloseHandle ( hfile );
- }
- /*++
- 打开TargetDevice指定的设备
- lpGuid - 设备类GUID, 此处传入 GUID_CLASS_COMPORT
- TargetDevice- 目标设备的序号,此序号由 EnumDevice函数枚举设备类得来。
- --*/
- HANDLE OpenDevice( LPGUID lpGuid , int TargetDevice)
- {
- HANDLE hfile;
- TCHAR szDevName[ MAX_PATH ];
- hfile = INVALID_HANDLE_VALUE;
- if ( TRUE != GetDeviceName( lpGuid, TargetDevice, szDevName ) )
- {
- return hfile;
- }
- hfile = CreateFile(
- szDevName,
- GENERIC_READ | GENERIC_WRITE,
- 0,
- NULL,
- OPEN_EXISTING,
- FILE_ATTRIBUTE_NORMAL, //FILE_FLAG_OVERLAPPED ,
- NULL
- );
- if (hfile == INVALID_HANDLE_VALUE)
- printf("Open serial device Failed (0x%x)n", GetLastError());
- else
- printf("Open serial device OKn", hfile );
- return hfile;
- }
- /*++
- 枚举lpGuid指定的设备类下面所有当前存在的设备,并且打印出来
- lpGuid - 设备类GUID, 此处传入 GUID_CLASS_COMPORT
- --*/
- BOOL EnumDevice( const LPGUID lpGUID )
- {
- HDEVINFO info;
- SP_INTERFACE_DEVICE_DATA ifdata;
- DWORD needed;
- PSP_INTERFACE_DEVICE_DETAIL_DATA detail;
- BYTE buf[ 4096 ];
- int i;
- info = SetupDiGetClassDevs( lpGUID,
- NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
- if( info == INVALID_HANDLE_VALUE ){
- printf("Enumeration device Failed (0x%x)n", GetLastError() );
- return 0;
- }
- detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA )buf;
- for( i = 0;; i++)
- {
- memset( &ifdata, 0, sizeof ( SP_INTERFACE_DEVICE_DATA ) );
- memset ( detail, 0, 4096 );
- ifdata.cbSize = sizeof(ifdata);
- if (!SetupDiEnumDeviceInterfaces(info, NULL, (LPGUID) &GUID_CLASS_COMPORT,
- i, &ifdata))
- {
- SetupDiDestroyDeviceInfoList(info);
- return 1;
- }
- detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
- needed = 4096;
- if (!SetupDiGetDeviceInterfaceDetail(info, &ifdata, detail, needed, NULL, NULL))
- {
- printf("Error %d getting interface detailn", GetLastError());
- SetupDiDestroyDeviceInfoList(info);
- return FALSE;
- }
- printf("No. %d %sn", i, detail->DevicePath );
- }
- SetupDiDestroyDeviceInfoList( info );
- return TRUE;
- }
- /*++
- 得到指定设备的访问路径
- lpGuid - 设备类GUID, 此处传入 GUID_CLASS_COMPORT
- TargetDevice- 目标设备的序号,此序号由 EnumDevice函数枚举设备类得来。
- szDevName - 输出目标设备的访问路径,以后可以使用CreateFile来打开该设备
- --*/
- BOOL GetDeviceName( LPGUID lpGuid, int TargetDevice, TCHAR* szDevName )
- {
- HDEVINFO info;
- SP_INTERFACE_DEVICE_DATA ifdata;
- DWORD needed;
- PSP_INTERFACE_DEVICE_DETAIL_DATA detail;
- info = SetupDiGetClassDevs( lpGuid,
- NULL, NULL, DIGCF_PRESENT | DIGCF_INTERFACEDEVICE);
- if( info == INVALID_HANDLE_VALUE ){
- printf("Enumeration device Failed (0x%x)n", GetLastError() );
- return FALSE;
- }
- ifdata.cbSize = sizeof(ifdata);
- if (!SetupDiEnumDeviceInterfaces(info, NULL, lpGuid,
- TargetDevice, &ifdata))
- {
- printf("Enumerate interfaces Failed (0x%x)n", GetLastError());
- SetupDiDestroyDeviceInfoList(info);
- return FALSE;
- }
- SetupDiGetDeviceInterfaceDetail(info, &ifdata, NULL, 0, &needed, NULL);
- detail = (PSP_INTERFACE_DEVICE_DETAIL_DATA) malloc(needed);
- if (!detail)
- {
- printf("Error %d trying to get memory for interface detailn", GetLastError());
- SetupDiDestroyDeviceInfoList(info);
- exit(1);
- }
- detail->cbSize = sizeof(SP_INTERFACE_DEVICE_DETAIL_DATA);
- if (!SetupDiGetDeviceInterfaceDetail(info, &ifdata, detail, needed, NULL, NULL))
- {
- printf("Error %d getting interface detailn", GetLastError());
- free((PVOID) detail);
- SetupDiDestroyDeviceInfoList(info);
- return FALSE;
- }
- _tcscpy( szDevName, detail->DevicePath );
- free( (PVOID)detail );
- SetupDiDestroyDeviceInfoList( info );
- return TRUE;
- }