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

📄 rtdlibdrv.c

📁 用Ardence RTX SDK开发的EPP并口驱动程序.
💻 C
字号:
/*++
 *
 * Copyright (c) 1997-2007 Ardence, a Citrix Company.  All rights reserved.
 *
 * Module Name:
 *
 *	RtdLibDrv.c
 *
 * Abstract:
 *
 *	RTX device library driver-side library functions.
 *
 * Environment:
 *
 *	Win32 or RTSS static library.
 *
 * Revision History:
 *
--*/
#include "windows.h"
#include "rtapi.h"
#include "RtDriver.h"

#define HANDLE_ERROR	(HANDLE)0
//
// Internal data structure -- one per driver.
//
typedef struct {
    HANDLE	hShm;			// internal library handles
    HANDLE	hMutex;
    HANDLE	hEvent;
    HANDLE	hSem1;
    HANDLE	hSem2;
    ULONG	(_stdcall *DispatchRoutime)(PTRP);
    PCMD	pCmd;			// shared memory address of command
    CHAR	cName[4];		// room for name suffixes
} DRIVER, *PDRIVER;


//
// Internal prototypes.
//
VOID
RTFCNDCL
RtdDrvDispatch(PDRIVER pDriver);

//
// Register a RTX driver.
//
HANDLE
_stdcall
RtdDriverRegister(
    PCHAR	lpName,
    ULONG	(_stdcall *DispatchRoutime)(
			PTRP	TransferRequestPacket),
    ULONG	StackSize,            
    ULONG	Priority,
    DWORD	dwMaximumBufferSize,
    DWORD	dwFlags			// ignored for now
    )
{
    PDRIVER	pDriver;
    HANDLE	hThread;
    int		size;
    int		i;
	int		finished = 0;
	DWORD	dwMaximumSizeHigh = 0;
	LONG	lInitialCount = 0;
	LONG	lMaximumCount = 1;

    //
    // Count the size of the driver name and allocate a driver structure for it.
    //
    for (size=0; lpName[size]!=finished; size++)
	;

    pDriver = (PDRIVER) RtAllocateLockedMemory( sizeof(DRIVER) + size);
    if (pDriver==NULL)
    {
		SetLastError( ERROR_NOT_ENOUGH_MEMORY);
		return HANDLE_ERROR;
    }

    //
    // Fill in the driver structure with the driver name and dispatch routine.
    //
    for (i=0; (pDriver->cName[i] = lpName[i])!=finished; i++)
	;

    pDriver->DispatchRoutime = DispatchRoutime;

    //
    // Append suffix and create the shared memory object.
    //
    for (i = 0; (pDriver->cName[size + i] = EXT_SHM[i])!=finished; i++)
	;
   
    pDriver->hShm = RtCreateSharedMemory( PAGE_READWRITE, dwMaximumSizeHigh, sizeof(CMD) +
			dwMaximumBufferSize, pDriver->cName, &pDriver->pCmd);

    if (pDriver->hShm==NULL)
    {
		RtFreeLockedMemory( pDriver);
		SetLastError( ERROR_ALREADY_EXISTS);
		return HANDLE_ERROR;
    }

    //
    // Initialize shared memory.
    //
    pDriver->pCmd->dwMaximumBufferSize = dwMaximumBufferSize;
    pDriver->pCmd->dwStatus = STATUS_SUCCESS;

    //
    // Append suffix and create the two semaphore objects.
    //
    for (i = 0; (pDriver->cName[size + i] = EXT_SEM1[i])!=finished; i++)
	;
    pDriver->hSem1 = RtCreateSemaphore( NULL, lInitialCount, lMaximumCount, pDriver->cName);

    if (pDriver->hSem1==NULL)
    {
		RtCloseHandle( pDriver->hShm);
		RtFreeLockedMemory( pDriver);
		SetLastError( ERROR_PATH_NOT_FOUND);
		return HANDLE_ERROR;
    }

    for (i = 0; (pDriver->cName[size + i] = EXT_SEM2[i])!=finished; i++)
	;
    pDriver->hSem2 = RtCreateSemaphore( NULL, lInitialCount, lMaximumCount, pDriver->cName);

    if (pDriver->hSem2==NULL)
    {
		RtCloseHandle( pDriver->hSem1);
		RtCloseHandle( pDriver->hShm);
		RtFreeLockedMemory( pDriver);
		SetLastError( ERROR_PATH_NOT_FOUND);
		return HANDLE_ERROR;
    }

    //
    // Append 0 and create the mutex for this named driver.
    //
    pDriver->cName[size] = 0;

    pDriver->hMutex = RtCreateMutex( NULL, FALSE, lpName);

    if (pDriver->hMutex==NULL)
    {
		RtCloseHandle( pDriver->hSem2);
		RtCloseHandle( pDriver->hSem1);
		RtCloseHandle( pDriver->hShm);
		RtFreeLockedMemory( pDriver);
		SetLastError( ERROR_PATH_NOT_FOUND);
		return HANDLE_ERROR;
    }

    //
    // Create the driver event for notify the app
    //	
    pDriver->hEvent = RtCreateEvent(NULL,TRUE,FALSE,"PhantomEvent1");
    if (pDriver->hEvent==NULL)
    {
		RtCloseHandle( pDriver->hMutex);
		RtCloseHandle( pDriver->hSem2);
		RtCloseHandle( pDriver->hSem1);
		RtCloseHandle( pDriver->hShm);
		RtFreeLockedMemory( pDriver);
		SetLastError( ERROR_PATH_NOT_FOUND);
		return HANDLE_ERROR;
    }    

    //
    // Create the driver dispatch thread, set its priority and start it.
    //
    hThread = CreateThread(
				NULL,
				StackSize,
      (int (RTFCNDCL *)(PVOID)) RtdDrvDispatch,
				pDriver,
				CREATE_SUSPENDED,
				&i
				);

    if (hThread==NULL)
    {
		RtCloseHandle( pDriver->hMutex);
		RtCloseHandle( pDriver->hSem2);
		RtCloseHandle( pDriver->hSem1);
		RtCloseHandle( pDriver->hShm);
		RtFreeLockedMemory( pDriver);
		SetLastError( ERROR_PATH_NOT_FOUND);
		return HANDLE_ERROR;
    }

    if(!RtSetThreadPriority( hThread, Priority))
	{
		RtCloseHandle(hThread);
		RtCloseHandle( pDriver->hMutex);
		RtCloseHandle( pDriver->hSem2);
		RtCloseHandle( pDriver->hSem1);
		RtCloseHandle( pDriver->hShm);
		RtFreeLockedMemory( pDriver);
		SetLastError( ERROR_PATH_NOT_FOUND);
		return HANDLE_ERROR;
	}

    ResumeThread( hThread);

    //
    // Successful register.
    //
    return (HANDLE) pDriver;
}


//
// Unregister a RTX driver.
//
BOOL
_stdcall
RtdDriverUnregister(HANDLE hDriver)
{
	int errorflag = 0;
	LONG lReleaseCount = 1;
    //
    // Simple check of handle.
    //
    if (hDriver==NULL)
    {
		SetLastError( ERROR_INVALID_HANDLE);
		return FALSE;
    }

    //
    // Send the internal exit command.
    //
    if(RtWaitForSingleObject( ((PDRIVER)hDriver)->hMutex, INFINITE) == WAIT_FAILED)
    {
		SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
		return FALSE;
    }		
    ((PDRIVER) hDriver)->pCmd->TransferRequest.dwCommand = RTD_EXIT;
    if(!RtReleaseSemaphore(  ((PDRIVER) hDriver)->hSem1, lReleaseCount, NULL))
    {
		SetLastError( ERROR_INVALID_HANDLE);
		return FALSE;
    }	
    if(RtWaitForSingleObject( ((PDRIVER)hDriver)->hSem2, INFINITE)==WAIT_FAILED)
    {
		SetLastError( ERROR_CALL_NOT_IMPLEMENTED);
		return FALSE;
    }
    if(!RtReleaseMutex( ((PDRIVER)hDriver)->hMutex))
    {
		SetLastError( ERROR_INVALID_HANDLE);
		return FALSE;
    }

    //
    // Close all driver objects.
    //
    if(!RtCloseHandle( ((PDRIVER) hDriver)->hMutex))
		errorflag++;
    if(!RtCloseHandle( ((PDRIVER) hDriver)->hSem2))
		errorflag++;
    if(!RtCloseHandle( ((PDRIVER) hDriver)->hSem1))
		errorflag++;
    if(!RtCloseHandle( ((PDRIVER) hDriver)->hShm))
		errorflag++;
    if(!RtFreeLockedMemory( hDriver))
		errorflag++;

	if(errorflag != 0)
		return FALSE;
	else
		return TRUE;
}


//
// Internal driver dispatch loop.
//
VOID
RTFCNDCL
RtdDrvDispatch(
    PDRIVER	pDriver
    )
{
	LONG lReleaseCount = 1;
	DWORD	exitCode = 0;
    //
    // Loop on driver commands from applications.
    //
    for (;;)
    {
		RtWaitForSingleObject( pDriver->hSem1, INFINITE);

        if (pDriver->pCmd->TransferRequest.dwCommand==RTD_EXIT)
		{
		 //
		 // Driver has been unregistered -- so exit the thread.
		 //
		 if(!RtReleaseSemaphore( pDriver->hSem2, lReleaseCount, NULL))
			 ExitThread(exitCode++);

		 ExitThread( exitCode);
		}

		//
		// Setup the buffer pointer and dispatch the command.
		//
		pDriver->pCmd->TransferRequest.lpBuffer = pDriver->pCmd->Buffer;
	
        pDriver->pCmd->dwStatus =
	    (*pDriver->DispatchRoutime)(&(pDriver->pCmd->TransferRequest));

		//
		// Release the semaphore so the app can continue.
		//
		if(!RtReleaseSemaphore( pDriver->hSem2, lReleaseCount, NULL))
			ExitThread(exitCode++);

	}
}

HANDLE
_stdcall
RtdDriverGetEvent(
	HANDLE	hDriver
	)
{
	PDRIVER pDriver = (PDRIVER)hDriver;
	return pDriver->hEvent;
}

⌨️ 快捷键说明

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