📄 device.c
字号:
/******************************************************
Copyright(c) 版权所有,1998-2003微逻辑。保留所有权利。
******************************************************/
/*****************************************************
文件说明:设备管理
版本号:2.0.0
开发时期:2000
作者:李林
修改记录:
******************************************************/
#include <eframe.h>
#include <edevice.h>
#include <efile.h>
#include <eapisrv.h>
#include <eobjlist.h>
#include <epdev.h>
#include <devsrv.h>
// struct define
// 文件设备结构
typedef struct _DEVFSD
{
struct _DEVFSD * lpNext;
LPFSDINITDRV lpFSDInitDrv;
HANDLE hFSDRegister;
LPTSTR lpszFSDName;
int iRefCount;
}DEVFSD, FAR * LPDEVFSD;
// 设备注册结构
typedef struct _DEVICE_DATA
{
OBJLIST obj;
LPTSTR lpszName;
BYTE index;
BYTE bFree;
WORD wReserve;
const DEVICE_DRIVER * lpDriver;
DWORD hDevInit; // init handle
// file sys
LPDEVFSD lpfsd;
HANDLE hFSDAttach;
}DEVICE_DATA, FAR * LPDEVICE_DATA;
// 设备打开结构
typedef struct _DEVICE_OPEN_DATA
{
OBJLIST obj;
LPDEVICE_DATA lpDev;
DWORD hDevOpen;
HANDLE hProcess;
}DEVICE_OPEN_DATA, FAR * LPDEVICE_OPEN_FILE;
// 全局数据
static LPDEVICE_DATA lpDeviceObjList = NULL; //已注册设备列式
static LPDEVICE_OPEN_FILE lpDeviceOpenObjList = NULL; //已打开设备列式
static CRITICAL_SECTION csDeviceObjList; //临界段
static const TCHAR szDll[]= "Dll";
static const TCHAR szIndex[] = "Index";
static const TCHAR szPrefix[] = "Prefix";
static const TCHAR szFlags[] = "Flags";
static const TCHAR szActiveKey[] = "Drivers\\Active";
static const TCHAR szBuiltInKey[] = "Drivers\\BuiltIn";
static const TCHAR szHandle[] = "handle";
// 函数声名
static LPOBJLIST FindDevice( LPCTSTR lpszName, UINT index );
//
// *****************************************************************
//声明:static LPDEVICE_DATA _GetHDEVPtr( HANDLE handle )
//参数:
// IN handle-设备句柄
//返回值:
// 成功,返回设备数据指针;失败,返回NULL
//功能描述:要访问设备数据,必须调用该函数以得到设备数据
//引用: 要访问设备数据的代码
// *****************************************************************
static LPDEVICE_DATA _GetHDEVPtr( HANDLE handle )
{
DEVICE_DATA * lp = handle;
if( lp && lp->obj.objType == OBJ_DEV )
return lp;
ASSERT_NOTIFY( 0, "Invalid device handle\r\n" );
return NULL;
}
// *****************************************************************
//声明:static LPDEVICE_OPEN_FILE _GetHDEVFilePtr( HANDLE hFile )
//参数:
// IN hFile-设备打开句柄
//返回值:
// 成功,返回设备打开数据指针;失败,返回NULL
//功能描述:
// 要访问设备打开数据,必须调用该函数以得到设备打开数据
//引用:
// 要访问设备打开数据的代码
// *****************************************************************
static LPDEVICE_OPEN_FILE _GetHDEVFilePtr( HANDLE hFile )
{
LPDEVICE_OPEN_FILE lpFile = (HANDLE)hFile;
if( lpFile && lpFile->lpDev && lpFile->obj.objType == OBJ_DEVOPEN )
{
return lpFile;
}
return NULL;
}
// *****************************************************************
//声明:HANDLE DoRegisterDriver( LPCTSTR lpDevName,
// int index,
// const DEVICE_DRIVER FAR * lpDriver,
// LPVOID lpParam )
//参数:
// IN lpDevName-设备类型名
// IN index-设备索引号
// IN lpDriver-设备调用界面指针
// IN lpParam-调用该设备的Init函数时将传递该参数
//返回值:
// 成功,返回设备句柄;失败,返回NULL
//功能描述:
// 调用设备驱动程序的初始化函数,假如成功,将该设备接口加入设备链表。
//引用:
// *****************************************************************
#define DEBUG_DOREGISTERDRIVER 0
static HANDLE DoRegisterDriver( LPCTSTR lpDevName, UINT index, const DEVICE_DRIVER FAR * lpDriver, LPVOID lpParam, BOOL bFreeStruct )
{
int s;
DEVICE_DATA * lpdd;
if( index < 0 || index > 9 )
return NULL;
DEBUGMSG( DEBUG_DOREGISTERDRIVER, ( "Device_Register:%s,lpDriver=%x.\r\n", lpDevName, lpDriver ) );
s = strlen( lpDevName );
lpdd = malloc( sizeof( DEVICE_DATA ) + s + 2 );
if( lpdd )
{
memset( lpdd, 0, sizeof( DEVICE_DATA ) + s + 2 );
lpdd->hDevInit = lpDriver->lpInit( (DWORD)lpParam ); // 调用设备驱动程序接口的初始化函数
if( lpdd->hDevInit ) // 初始化成功 ?
{ // 是,将该设备加入设备链表
lpdd->lpszName = (LPTSTR)(lpdd + 1);
strcpy( lpdd->lpszName, lpDevName );
*(lpdd->lpszName + s) = '0' + index;
*(lpdd->lpszName + s + 1) = 0;
lpdd->index = index;
lpdd->lpDriver = lpDriver;
lpdd->hFSDAttach = NULL;
lpdd->lpfsd = NULL;
lpdd->bFree = bFreeStruct;
EnterCriticalSection( &csDeviceObjList );
ObjList_Init( (LPOBJLIST*)&lpDeviceObjList, &lpdd->obj, OBJ_DEV, (ULONG)GetCurrentProcess() );//(ULONG)GetCurrentProcessId() );
LeaveCriticalSection( &csDeviceObjList );
return (HANDLE)lpdd;
}
else
{
WARNMSG( DEBUG_DOREGISTERDRIVER, ( "Device_Register: Device(%s) Index(%d) Init failure!.\r\n.", lpDevName, index ) );
}
free( lpdd );
}
return NULL;
}
// *****************************************************************
//声明:HANDLE WINAPI Device_RegisterDriver( LPCTSTR lpDevName,
// int index,
// const DEVICE_DRIVER FAR * lpDriver,
// LPVOID lpParam )
//参数:
// IN lpDevName-设备类型名
// IN index-设备索引号
// IN lpDriver-设备调用界面指针
// IN lpParam-调用该设备的Init函数时将传递该参数
//返回值:
// 成功,返回设备句柄;失败,返回NULL
//功能描述:
// 注册设备驱动程序。静态连接版本
//引用:
// 系统API
// *****************************************************************
HANDLE WINAPI Dev_RegisterDriver( LPCTSTR lpDevName, UINT index, const DEVICE_DRIVER FAR * lpDriver, LPVOID lpParam )
{
return DoRegisterDriver( lpDevName, index, lpDriver, lpParam, FALSE );
}
// *****************************************************************
//声明:HANDLE WINAPI Device_RegisterDevice( LPCTSTR lpDevName, UINT index, LPCTSTR lpszLib, LPVOID lpParam )
//参数:
// IN lpDevName - 设备名
// IN index - 设备索引名
// IN lpszLib - 动态连接库文件名
// IN lpParam - 传递给设备初始化函数的参数
//返回值:
// 假如成功返回非NULL的句柄,否则,返回NULL
//功能描述:
// 注册设备驱动程序。动态连接库版本
//引用:
// 系统API
// *****************************************************************
HANDLE WINAPI Device_RegisterDevice( LPCTSTR lpDevName, UINT index, LPCTSTR lpszLib, LPVOID lpParam )
{
HANDLE handle = NULL;
//check param
if( strlen( lpDevName ) != 3 || index <= 9 )
{
HMODULE hModule = LoadLibrary( lpszLib );
if( hModule )
{
const LPCTSTR szDrvName[] = { "_Init",
"_Deinit",
"_IOControl",
"_Open",
"_Close",
"_Read",
"_Write",
"_Seek",
"_PowerUp",
"_PowerDown" };
DEVICE_DRIVER * lpDriver = malloc( sizeof(DEVICE_DRIVER) );
if( lpDriver )
{
int i;
PFNVOID * lppFun = (PFNVOID *)lpDriver;
TCHAR bufName[32];
memset( lpDriver, 0, sizeof(DEVICE_DRIVER) );
for( i = 0; i < sizeof(szDrvName) / sizeof(LPCTSTR); i++, lppFun++ )
{
strcpy( bufName, lpDevName );
strcat( bufName, szDrvName[i] );
*lppFun = (PFNVOID)GetProcAddress( hModule, bufName );
if( *lppFun == 0 )
{
goto _error_return;
}
}
//ok
if( (handle = DoRegisterDriver( lpDevName, index, lpDriver, lpParam, TRUE )) == NULL )
{
free( lpDriver );
}
}
}
}
else
{
SetLastError( ERROR_INVALID_PARAMETER );
}
_error_return:
return handle;
}
// *****************************************************************
// 声明:BOOL WINAPI Device_Deregister( HANDLE handle )
// 参数:
// IN handle - 设备句柄(由RegisterDevice 或 RegisterDriver返回的句柄)
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 注销设备驱动程序
// 引用:
// 系统API
// *****************************************************************
BOOL WINAPI Device_Deregister( HANDLE handle )
{
DEVICE_DATA * lpdd = _GetHDEVPtr( handle ); // 由句柄得到设备数据结构指针
LPOBJLIST lpDevOpen;
BOOL bRetv = FALSE;
if( lpdd )
{
EnterCriticalSection( &csDeviceObjList ); // 进入冲突段
lpDevOpen = (LPOBJLIST)lpDeviceOpenObjList; //全局设备打开/引用对象链表
// 查找已打开该设备的对象,如果有则注销它
for( ; lpDevOpen; lpDevOpen = lpDevOpen->lpNext )
{
if( ( (LPDEVICE_OPEN_FILE)lpDevOpen )->lpDev == lpdd ) //
{ // 找到该对象
( (LPDEVICE_OPEN_FILE)lpDevOpen )->lpDev = NULL; // 不许再用
Interlock_Decrement( (LPLONG)&lpdd->obj.iRefCount ); // 减少引用
}
}
// 该对象是否与某文件系统关联 ?
if( lpdd->hFSDAttach && lpdd->lpfsd )
{ //是,通知该文件系统去注销它
RETAILMSG( 1, ( "Detach device.\r\n." ) );
lpdd->lpfsd->lpFSDInitDrv->lpDetachDevice( lpdd->hFSDAttach );
--lpdd->lpfsd->iRefCount;// 减少对该文件系统的引用
}
// 将该设备对象从系统对象链表去掉
if( ObjList_Remove( (LPOBJLIST*)&lpDeviceObjList, &lpdd->obj ) )
{ // 通知设备驱动程序的释放函数并释放该设备对象
lpdd->lpDriver->lpDeinit( lpdd->hDevInit );
lpdd->obj.objType = OBJ_NULL;
if( lpdd->bFree )
free( (LPVOID)lpdd->lpDriver );
free( lpdd );
bRetv = TRUE;
}
LeaveCriticalSection( &csDeviceObjList ); // 离开冲突段
}
return bRetv;
}
// *****************************************************************
// 声明:static DWORD FASTCALL EnumDevice( LPDEVICE_ENUM_PROC lpEnumFunc, LPVOID lpParam )
// 参数:
// IN lpEnumFunc - 枚举回调函数入口
// IN lpParam - 传递给回调函数的参数
// 返回值:
// 0
// 功能描述:
// 枚举所有设备对象
// 引用:
// *****************************************************************
typedef BOOL ( CALLBACK * LPDEVICE_ENUM_PROC )( LPDEVICE_DATA lpDev, LPVOID lpParam );
static DWORD FASTCALL EnumDevice( LPDEVICE_ENUM_PROC lpEnumFunc, LPVOID lpParam )
{
LPDEVICE_DATA lpDevList;
lpDevList = lpDeviceObjList;
for( ; lpDevList ; lpDevList = (LPDEVICE_DATA)lpDevList->obj.lpNext )
{
if( lpEnumFunc( lpDevList, lpParam ) == FALSE )
break;
}
return 0;
}
// *****************************************************************
// 声明:DWORD WINAPI Device_Enum( LPTSTR lpszDevList, LPDWORD lpdwBuflen )
// 参数:
// OUT lpszDevList – 用于接受设备名列式的缓存,返回的数据的格式为:“COM0:\0PRN1:\0USB5\0\0”。
// IN lpdwBufLen - lpszDevList缓存的大小,假如缓存不足以保存数据,则填入需要的缓存大小
// 返回值:
// ERROR_SUCCESS - 成功
// ERROR_INSUFFICIENT_BUFFER - 缓存的大小不足以保存任何一个数据
// ERROR_INVALID_PARAMETER - 无效的参数
// ERROR_MORE_DATA - 缓存的大小不足以保存所有的数据
// ERROR_NO_MORE_DEVICES - 没有设备
// 功能描述:
// 枚举当前系统的设备,返回其设备名
// 引用:
// 系统API
// *****************************************************************
DWORD WINAPI Device_Enum( LPTSTR lpszDevList, LPDWORD lpdwBuflen )
{
LPDEVICE_DATA lpDevList;
DWORD dwBuflen;
DWORD dwDeviceLen;
DWORD dwRetv;
LPTSTR lpstrBuf;
// 检查参数
if( lpdwBuflen == NULL || lpszDevList == NULL )
{
return ERROR_INVALID_PARAMETER;
}
dwDeviceLen = 0;
dwRetv = ERROR_SUCCESS;
lpstrBuf = lpszDevList;
dwBuflen = *lpdwBuflen - 1; // 减一是为最后的\0结束符
EnterCriticalSection( &csDeviceObjList );
lpDevList = lpDeviceObjList;
// 搜索所有的设备对象,并将它们的名字添入lpszDevList
for( ; lpDevList ; lpDevList = (LPDEVICE_DATA)lpDevList->obj.lpNext )
{
// 2 one is null char , one is ':'. because the lpDevList->lpszName no ':', example:"COM1"
UINT len = strlen( lpDevList->lpszName ) + 2;
dwDeviceLen += len;
if( dwDeviceLen < dwBuflen )// 用户给的内存够吗 ?
{ //够
strcpy( lpstrBuf, lpDevList->lpszName );
*(lpstrBuf+len-2) = ':';
*(lpstrBuf+len-1) = 0;
lpstrBuf += len;
}
else
dwRetv = !ERROR_SUCCESS; // 不够,继续循环已得到真实的内存长度
}
if( *lpdwBuflen )
*lpstrBuf = 0;
dwDeviceLen++; // 总需要的长度(包括最后的'\0')
if( lpstrBuf != lpszDevList )
{ // 已经保存了数据。has data in lpstrbuf, but may be not all data
if( dwRetv == !ERROR_SUCCESS ) // 是否保存完所有的数据 ?
{ //否,设置需要的长度和返回值
*lpdwBuflen = dwDeviceLen;
dwRetv = ERROR_MORE_DATA;
}
}
else
{ // 没有保存任何数据。maybe ERROR_INSUFFICIENT_BUFFER or ERROR_NO_MORE_DEVICES
if( lpDeviceOpenObjList == NULL )
dwRetv = ERROR_NO_MORE_DEVICES; // 没有如何设备
else
{
*lpdwBuflen = dwDeviceLen;
dwRetv = ERROR_INSUFFICIENT_BUFFER; // 内存长度不足以保存任何数据
}
}
LeaveCriticalSection( &csDeviceObjList ); // 离开冲突段
return dwRetv;
}
// *****************************************************************
// 声明:HANDLE WINAPI Device_CreateFile(
// LPCTSTR lpszName,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -