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

📄 tmman32.c

📁 wince host 和 target PCI驱动程序
💻 C
📖 第 1 页 / 共 3 页
字号:
/*
	tmman32.dll
	
	provides services to Win32 clients for communicating with the DSP.

	HISTORY
	960417	TR	Created
	960620	TR	Started changes for release candicate 3.
	961015	TR	Adding ArgC & ArgV support to tmDSpLoadExecutable
*/

#include "windows.h"

#include "tmwincom.h"
#include "tmman32.h"
#include "tmif.h"
#include "tmmain.h"
#include "cqueue.h"

#include "verinfo.h"


#include "stdio.h"



//#undef	USE_LOADERCOPY
#define	USE_LOADERCOPY

#include "TMDownLoader.h"
#include "TMObj.h"


#define		DEFAULT_WINDOW_SIZE		50

TMMAN_GLOBAL	Global;
CHAR			szTemp[0x80];

//-----------------------------------------------------------------------------
//	PROTOTYPES
//-----------------------------------------------------------------------------

DWORD WINAPI MsgRecvThread ( PVOID pvContext );
BOOL WINAPI tmmanControlHandler ( DWORD dwCtrlType );
BOOL	tmDSPInterrupt ( PVOID pObject, DWORD dwCommand );
BOOL    halValidateAddress ( PTMSTD_MEMORY_BLOCK pMem, DWORD dwAddress );
BOOL    halValidateLength ( PTMSTD_MEMORY_BLOCK pMem, DWORD dwAddress,
    DWORD dwLength );
VOID	ErrorBox ( PCHAR pszErrorString );

//-----------------------------------------------------------------------------
//	TMMAN SUPPORTING FUNCTIONS
//-----------------------------------------------------------------------------

BOOL	WINAPI	DLLInitialize ( PVOID DllHandle,	DWORD dwReason, 
	PVOID pvContext )
{
	DWORD	dwBytesReturned;
	TMIF_REGISTERCLIENT	Client;
	TMIF_STRUCT_NEGOTIATEVERSION	Version;
	DWORD dwWindowsVersion, dwWindowsMajorVersion, dwWindowsMinorVersion; 

	switch ( dwReason )
	{
		case DLL_PROCESS_ATTACH :
		dwWindowsVersion = GetVersion();
 
		// Get major and minor version numbers of Windows

		dwWindowsMajorVersion =  (DWORD)(LOBYTE(LOWORD(dwWindowsVersion)));
		dwWindowsMinorVersion =  (DWORD)(HIBYTE(LOWORD(dwWindowsVersion)));

		// Get build numbers for Windows NT or Win32s
		if (dwWindowsVersion < 0x80000000)	// Windows NT
		{
			wsprintf ( szTemp,
			"tmman32:DLLInitialize:NTOS:NOT SUPPORTED\n" );
			OutputDebugString ( szTemp );
			ErrorBox  ( "NTOS : NOT SUPPORTED" );
			return FALSE;

		}
		else  // should be 95 or Win32s
		{
			if (dwWindowsMajorVersion < 4)        // Win32s
			{
				wsprintf ( szTemp,
					"tmman32:DLLInitialize:Win32s:NOT SUPPORTED\n" );
					OutputDebugString ( szTemp );
					ErrorBox  ( "Win32s : NOT SUPPORTED" );
					return FALSE;
			}
		}

		wsprintf ( szTemp, "\ntmman32:Version[%d.%d.%d]\n",
			verGetFileMajorVersion(),
			verGetFileMinorVersion(),
			verGetFileBuildVersion() );
		OutputDebugString ( szTemp );

		// initialize the values for PROCES_DETACH
		Global.hDevice = INVALID_HANDLE_VALUE;
		Global.hEvent = INVALID_HANDLE_VALUE;
		Global.hThread = INVALID_HANDLE_VALUE;
		Global.dwClientHandle = 0;
		Global.dwThreadID = 0;
		Global.pvAdvisoryQueue = NULL;
		Global.pOverlapped = NULL;

		//InitializeCriticalSection ( &Global.ISRMonitor );	

		if ( ( Global.hDevice = 
			CreateFile ( "\\\\.\\vtmman.vxd",0,0,0, CREATE_NEW , 
			FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_OVERLAPPED, 
			0 ) ) == INVALID_HANDLE_VALUE )
		{
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:CreateFile:vtmman.vxd:FAIL[%x]\n",
				GetLastError() );
			OutputDebugString ( szTemp );
			ErrorBox  ( "CreateFile Failed [vtmman.vxd]" );
			return FALSE;
		}
		Version.Version.dwMajor = verGetFileMajorVersion();
		Version.Version.dwMinor = verGetFileMinorVersion();

		// perform the version control 
		if ( DeviceIoControl ( Global.hDevice,
			(DWORD)(TMIF_DIOC_NEGOTIATEVERSION),
			(PVOID)&Version, sizeof (TMIF_STRUCT_NEGOTIATEVERSION),
			(PVOID)&Version, sizeof (TMIF_STRUCT_NEGOTIATEVERSION),
			&dwBytesReturned, NULL ) != TRUE )
		{
			/* this will fail if vxd does not support negotiate version */
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:DeviceIoControl:NEGOTIATEVERSION:FAIL[%x]\n",
				GetLastError() );
			OutputDebugString ( szTemp );
			ErrorBox  ( "Obsolete Version of [vtmman.vxd]" );
			return FALSE;	
		}

		if ( Version.Status != TMOK )
		{
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:NEGOTIATEVERSION:FAIL[%x]\n", Version.Status );
			OutputDebugString ( szTemp );
			ErrorBox  ( "Obsolete Version of [tmman32.dll]" );
			return FALSE;
		}

		if ( ( Version.Version.dwMajor < verGetFileMajorVersion() ) ||
			( Version.Version.dwMinor < verGetFileMinorVersion()) )
		{
			OutputDebugString(
				"tmman32:DLLInitialize:VersionCheck:vtmman.vxd:FAIL\n");
			ErrorBox  ( "Obsolete Version of [vtmman.vxd]" );
			return FALSE;
		}

		// register this client with the VxD, ensure that Global is a 
		// per-instance data structure

		if ( ( Global.hEvent =
			CreateEvent ( 0, TRUE , 0, NULL )) == NULL )
		{
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:CreateEvent:FAIL[%x]\n",
				GetLastError() );
			OutputDebugString ( szTemp );
			ErrorBox  ( "CreateEvent Failed" );

			return FALSE;
		}

		Client.dwModuleHandle = (DWORD)GetModuleHandle ("tmman32");

		if ( DeviceIoControl ( Global.hDevice,
			(DWORD)(TMIF_DIOC_REGISTERCLIENT),
			(PVOID)&Client, sizeof ( TMIF_REGISTERCLIENT ),
			(PVOID)&Client, sizeof ( TMIF_REGISTERCLIENT ),
			&dwBytesReturned, NULL ) != TRUE)
		{
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:DeviceIoControl:REGISTERCLIENT:FAIL[%x]\n",
				GetLastError() );
			OutputDebugString ( szTemp );
			ErrorBox  ( "DeviceIOControl Register Client Failed" );
			return FALSE;
		}

		if ( Client.Status != TMOK )
		{
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:REGISTERCLIENT:FAIL[%x]\n",
				Client.Status );
			OutputDebugString ( szTemp );
         ErrorBox  ( "Register Cleint Failed : Too Many Processes Using TMMan" );
			return FALSE;
		}

		// store the info returnd by the Ring 0 driver
		Global.dwClientHandle = Client.dwClientHandle;
		Global.pOverlapped = Client.pvOverlapped;
		Global.pvAdvisoryQueue = Client.pvAdvisoryQueue;

		// store the event handle in the overlapped object that
		// can be used later for blocking and signalling the thread.
		// NOTE : a ring 3 app is acessing kernel address space  - NT ??
		// possible in NT via ZwMappedViewOfSectionXXX
		Global.pOverlapped->hEvent = Global.hEvent;

		if ( SetConsoleCtrlHandler  ( tmmanControlHandler , TRUE ) != TRUE )
		{
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:SetConsoleCtrlHandler:FAIL[%x]\n",
				GetLastError() );
			OutputDebugString ( szTemp );
			ErrorBox  ( "SetConsoleCtrlHandler Failed" );
			return FALSE;
		}

		if ( ( Global.hThread = 
			CreateThread ( NULL,0, MsgRecvThread, &Global, 
			0, 
			&Global.dwThreadID ) ) == NULL )
		{
			wsprintf ( szTemp,
				"tmman32:DLLInitialize:CreateThread:FAIL[%x]\n",
				GetLastError() );
			OutputDebugString ( szTemp );
			ErrorBox  ( "CreateThread  Failed" );
			return FALSE;
		}
		break;

		case DLL_PROCESS_DETACH :
		//DeleteCriticalSection ( &Global.ISRMonitor );	
		OutputDebugString("1111111111111111\n\r");
		// terminate thread
		Global.fTerminateThread = TRUE;
		if ( Global.hEvent )
		{
			PulseEvent ( Global.hEvent );
		}

		//remove the console handler
		SetConsoleCtrlHandler  ( tmmanControlHandler, FALSE );

		if ( Global.dwClientHandle != 0 )
		{
			// unregister the client with the VxD.
			if ( DeviceIoControl ( Global.hDevice,
				(DWORD)(TMIF_DIOC_UNREGISTERCLIENT),
				(PVOID)&Global.dwClientHandle, sizeof ( DWORD ),
				(PVOID)NULL, 0,
				&dwBytesReturned, NULL ) != TRUE)
			{
				return FALSE;
			}
		}

		// release the thread object
		if ( Global.hDevice != INVALID_HANDLE_VALUE )
		{
			DWORD dwExitCode;
			//***This will terminate the thread properly
			while (!GetExitCodeThread(Global.hThread,&dwExitCode));
			TerminateThread(Global.hThread, dwExitCode);
			CloseHandle ( Global.hThread );
		}

		// release the event
		if ( Global.hEvent != INVALID_HANDLE_VALUE )
		{
			CloseHandle ( Global.hEvent );
		}

		// release the VxD
		if ( Global.hDevice != INVALID_HANDLE_VALUE)
		{
			CloseHandle ( Global.hDevice );
		}
#if 0
		if ( (Global.hThread != NULL))
		{
			DWORD dwExitCode;
			while (!GetExitCodeThread(Global.hThread,&dwExitCode));
			TerminateThread(Global.hThread, dwExitCode);
			CloseHandle(Global.hThread);
		}
#endif
		break;

		case DLL_THREAD_ATTACH :
		break;

		case DLL_THREAD_DETACH :
		break;
	}
	return TRUE;
}

/*
	MsgRecvThread

	This thread waits on an event to be set by the VxD.
	When the event is set it calls the respective tasks advisory notification
	function. A single instance of TMMAN may be loaded to deal with several
	tasks. For all these will signal the same event on the occurace of all
	events. Hence this function has to perform routing of the advisory 
	callback to the right owner.

	To pass information from the VxD to Ring 3, at the time of client 
	registration, the VxD allocates a buffer in linear address space, this 
	buffer can be accessed by the VxD and Ring 3 at callback time. However
	this approach is not portable over NT.

*/
DWORD WINAPI MsgRecvThread ( PVOID pvContext )
{
	DWORD	dwBytesReturned;
	BOOL	fInterruptPeer = FALSE;
	DWORD	dwInterruptCommand = 0;

	TMIF_ADVISORY_REQUEST	Advise;
	PTMIF_ADVISORY_REQUEST	pAdvise = &Advise;


	OutputDebugString ("tmman32:MsgRecvThread:Started\n");
	SetThreadPriority ( GetCurrentThread(),  THREAD_PRIORITY_TIME_CRITICAL );

	while ( ! Global.fTerminateThread )
	{

		// this call should result in an ERROR_IO_PENDING status
		DeviceIoControl ( Global.hDevice, (DWORD)(TMIF_DIOC_BLOCKONADVISE),
			(PVOID)&Global.dwClientHandle, sizeof( DWORD) ,
			(PVOID)NULL, 0,
			&dwBytesReturned, Global.pOverlapped );

		GetOverlappedResult( Global.hDevice, Global.pOverlapped,
			&dwBytesReturned, TRUE );

		if ( Global.fTerminateThread )
			break;
		// ignore this comment TR960812
		// after the device io ctrl call pAdvise points to the ring0
		// tmif allocated advise request structure that completely encapsulates
		// all the information requried to perform the callback.

		// main processing code starts here
		//pTask = (PTMMAN_TASK_STRUCT)pAdvise->pvTaskContext;

		// retrieve all items from the Advisory queue and make the callbacks.
		while ( ! cqueueIsEmpty ( Global.pvAdvisoryQueue )  )
		{

			cqueueDelete  ( Global.pvAdvisoryQueue, pAdvise );

			if ( pAdvise->dwCallback )
			{
				( (TMMAN_ADVISORY_NOTIFICATION)pAdvise->dwCallback ) ( 
					pAdvise->dwMessage, pAdvise->dwObjHandle,
					pAdvise->pContext, &pAdvise->Packet );
			}
			else
			{
				wsprintf(szTemp, 
					"\ntmman32:pAdvise->dwCallback != NULL:FAIL\n" );
				OutputDebugString( szTemp);
			}

		}


	}

	OutputDebugString ("\ntmman32:MsgRecvThread:Exiting");
	return TMOK;
}



BOOL WINAPI tmmanControlHandler ( DWORD dwCtrlType )
{
	
	wsprintf ( szTemp, "\ntmman32:tmmanControlHandler [%x]\n", dwCtrlType );
	OutputDebugString ( szTemp );
	switch ( dwCtrlType )
	{
		case	CTRL_C_EVENT :
		case	CTRL_BREAK_EVENT :
		case	CTRL_CLOSE_EVENT :
		case	CTRL_LOGOFF_EVENT :
		case	CTRL_SHUTDOWN_EVENT :
		Global.fTerminateThread = TRUE;
		SetEvent ( Global.hEvent );
		break;
	}
	return FALSE;
}



//-----------------------------------------------------------------------------
//	API IMPLEMENTATION 
//-----------------------------------------------------------------------------


// DSP related API.


STATUS	tmNegotiateVersion ( DWORD dwModuleID, PTMSTD_VERSION_INFO pVersion )
{
	STATUS	Status = TMOK;
	TMIF_STRUCT_NEGOTIATEVERSION	TMIF;
	TMSTD_VERSION_INFO				ReturnedVersion;
	DWORD		dwBytesReturned;


	switch ( dwModuleID )
	{
		case	TMMAN_MODULE_HOST_TMMAN32 :
		case	TMMAN_DEFAULT :

		ReturnedVersion.dwMajor = verGetFileMajorVersion();
		ReturnedVersion.dwMinor = verGetFileMinorVersion();
		ReturnedVersion.dwBuild = verGetFileBuildVersion();

		if ( pVersion->dwMajor < verGetFileMajorVersion()  )
		{
			Status = TM_STATUS ( TMMAN32_ERR_MAJVERSIONERROR );
			goto tmNegotiateVersionExit1;
		}

		if ( pVersion->dwMinor < verGetFileMinorVersion() )
		{
			Status = TM_STATUS ( TMMAN32_ERR_MINVERSIONERROR );
			goto tmNegotiateVersionExit1;
		}
		break;

		case TMMAN_MODULE_HOST_VTMMAN :
		case TMMAN_MODULE_DSP_TMMAN :
		TMIF.Version.dwMajor = pVersion->dwMajor;
		TMIF.Version.dwMinor = pVersion->dwMinor;
		TMIF.Version.dwBuild = pVersion->dwBuild;
		TMIF.ModuleID = dwModuleID;

		// perform the version control 
		if ( DeviceIoControl ( Global.hDevice,
			(DWORD)(TMIF_DIOC_NEGOTIATEVERSION),
			(PVOID)&TMIF, sizeof (TMIF_STRUCT_NEGOTIATEVERSION),
			(PVOID)&TMIF, sizeof (TMIF_STRUCT_NEGOTIATEVERSION),
			&dwBytesReturned, NULL ) != TRUE )
		{	
			Status = TM_STATUS ( TMMAN32_ERR_DEVIOCTLFAIL );
		}
		else
		{
			Status = TMIF.Status;
		}

		ReturnedVersion.dwMajor = TMIF.Version.dwMajor;
		ReturnedVersion.dwMinor = TMIF.Version.dwMinor;
		ReturnedVersion.dwBuild = TMIF.Version.dwBuild;
		break;

		default :
		Status  = TM_STATUS ( TMMAN32_ERR_UNKNOWNCOMPONENT );
		break;
	}


tmNegotiateVersionExit1:
	pVersion->dwMajor = ReturnedVersion.dwMajor;
	pVersion->dwMinor = ReturnedVersion.dwMinor;
	pVersion->dwBuild = ReturnedVersion.dwBuild;
	return Status;
}

STATUS	tmDSPGetNum ( PDWORD DSPCount )
{
	TMIF_STRUCT_DSPGETNUM	TMIF;
	DWORD		BytesReturned;

	TMIF.ClientHandle = Global.dwClientHandle;

	if ( DeviceIoControl ( Global.hDevice, (DWORD)(TMIF_DIOC_DSPGETNUM),
		(PVOID)&TMIF, sizeof( TMIF_STRUCT_DSPGETNUM) ,
		(PVOID)&TMIF, sizeof( TMIF_STRUCT_DSPGETNUM) ,
		&BytesReturned, NULL ) != TRUE )
	{
		return TM_STATUS ( TMMAN32_ERR_DEVIOCTLFAIL );
	}

	*DSPCount = TMIF.DSPCount;
	return TMIF.Status;
}

STATUS	tmDSPGetCaps ( DWORD dwHandle, PTMMAN_DSP_CAPS DSPCaps )
{
	TMIF_STRUCT_DSPGETCAPS	TMIF;
	DWORD		BytesReturned;

	TMIF.ClientHandle = Global.dwClientHandle;
	TMIF.DSPHandle = dwHandle;

	if ( DeviceIoControl ( Global.hDevice, (DWORD)(TMIF_DIOC_DSPGETCAPS),
		(PVOID)&TMIF, sizeof( TMIF_STRUCT_DSPGETCAPS) ,
		(PVOID)&TMIF, sizeof( TMIF_STRUCT_DSPGETCAPS) ,
		&BytesReturned, NULL ) != TRUE )
	{
		return TM_STATUS ( TMMAN32_ERR_DEVIOCTLFAIL );
	}

	*DSPCaps = TMIF.DSPCaps;
	Global.DSPCaps = TMIF.DSPCaps;
	return TMIF.Status;
}
	
STATUS	tmDSPOpen ( DWORD dwDSPNumber, PDWORD DSPHandle )

⌨️ 快捷键说明

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