📄 rtdlibdrv.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 + -