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

📄 device.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************
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 + -