📄 par4chkd.c
字号:
#elif defined( SROS_WIN95 ) || defined( SROS_MSDOS )
// MSDOS Helper Function
SRLOCAL int Msdos_NameToAddress( char *ParPortName );
/* The rest of the functions are declared in par4chkd.h so they can
be called directly by the par4ch.c code instead of by the OS
Msdos_DrvOpen
Msdos_DrvRead
Msdos_DrvIoctl
Msdos_DrvClose
Msdos_DrvGetLastError
*/
#elif defined( SROS_LINUX )
// Linux Helper Functions
SRLOCAL void Linux_GetParameters( void );
SRLOCAL void Linux_ResourceFree( int PortAddress, int DevMajor, char *PortName );
// Linux Functions called from the OS
int Linux_DrvOpen( struct inode *inode, struct file *filp );
close_t Linux_DrvClose( struct inode *inode, struct file *filp );
int Linux_DrvIoctl( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg );
#if defined (LINUX_USE_OLD_READ)
rw_t Linux_DrvRead( struct inode *inode, struct file *filp, char *buf, count_t count );
#else
ssize_t Linux_DrvRead( struct file *filp, char *buf, size_t count, loff_t *offset );
#endif // LINUX_USE_OLD_READ
void cleanup_module( void );
int init_module( void );
#endif // SROS_xxxxx
/* OS DEPENDENT HELPER FUNCTIONS AND MACROS:
In order to protect the rest of the code from having lots of
conditional sections, several helper functions and macros have been
defined. The helper names are repeated once for each OS, but the
SROS_xxxxx define is used to select the one correct set to include at
compile time.
These helper functions include the in and out port I/O functions,
Atomic (ie non-interruptible) functions, and etc. For example, under
WinNT and Linux, in and out are best called through macros provided
by the system, while under DOS inline assembler suffices.
*/
#if defined( SROS_WINNT )
// Lowest level PC I/O functions
SRLOCAL void OsPortIn( int port, unsigned char *value ) {
*value = READ_PORT_UCHAR( (UCHAR *)port );
}
SRLOCAL void OsPortOut( int port, unsigned char value ) {
WRITE_PORT_UCHAR( (UCHAR *)port, value );
}
// Functions to transfer data between user and kernel space
SRLOCAL unsigned long OsCopyToUser( void *UserBuff, const void *KernelBuff, unsigned long Nbytes ) {
RtlCopyMemory( UserBuff, KernelBuff, Nbytes );
return( Nbytes );
}
SRLOCAL unsigned long CopyFromUser( void *KernelBuff, const void *UserBuff, unsigned long Nbytes ) {
RtlCopyMemory( KernelBuff, UserBuff, Nbytes );
return( Nbytes );
}
// Misc functions
SRLOCAL void OsIrpFinish( IRP *Irp, long Status, unsigned long Info ) {
Irp->IoStatus.Status = (NTSTATUS)Status;
Irp->IoStatus.Information = Info;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
}
SRLOCAL long OsSetReadParms( IRP *Irp, unsigned long *OutBufferSize, long **IOBuffer ) {
IO_STACK_LOCATION *IrpStack;
unsigned long DevFlags;
// Set up variables
IrpStack = IoGetCurrentIrpStackLocation( Irp );
DevFlags = IrpStack->DeviceObject->Flags;
*OutBufferSize = IrpStack->Parameters.Read.Length;
// Get appropriate pointer for buffer
if (DevFlags & DO_DIRECT_IO) {
if (Irp->MdlAddress)
*IOBuffer = (long *)MmGetSystemAddressForMdl(Irp->MdlAddress);
else
*IOBuffer = NULL;
}
else if (DevFlags & DO_BUFFERED_IO)
*IOBuffer = (long *)Irp->AssociatedIrp.SystemBuffer;
else // Must be NEITHER_IO
*IOBuffer = (long *)Irp->UserBuffer;
// Verify buffer pointer
if ( (*OutBufferSize == 0) || (!(*IOBuffer)) )
return( STATUS_INVALID_PARAMETER );
else
return( STATUS_SUCCESS );
}
SRLOCAL void OsSetIoctlCommand( IRP *Irp, unsigned long *Command ) {
IO_STACK_LOCATION *IrpStack;
IrpStack = IoGetCurrentIrpStackLocation( Irp );
*Command = IrpStack->Parameters.DeviceIoControl.IoControlCode;
}
SRLOCAL long OsSetIoctlBuffers( IRP *Irp,
unsigned long Command,
int **InBuffer,
int **OutBuffer ) {
// Assign buffers
*InBuffer = (int *)Irp->AssociatedIrp.SystemBuffer;
*OutBuffer = (int *)Irp->AssociatedIrp.SystemBuffer;
// Check that buffer exists since all commands pass (or get) data
if ( !(*InBuffer) )
return( STATUS_INVALID_USER_BUFFER );
// No filling needed for InBuffer since OS functions do that
return( STATUS_SUCCESS );
}
SRLOCAL void OsReturnIoctlBuffer( IRP *Irp,
unsigned long Command,
int *OutBuffer ) {
// No filling needed for OutBuffer since OS functions do that
return;
}
#define OsModuleUseCountInc
#define OsModuleUseCountDec
// Atomic operation functions
#define OsAtomicSet( pAtom, Value ) InterlockedExchange( (pAtom), (Value) )
#define OsAtomicInc( pAtom ) InterlockedIncrement( (pAtom) )
#define OsAtomicDec( pAtom ) InterlockedDecrement( (pAtom) )
#define OsAtomicAdd( pAtom, Amount ) InterlockedExchangeAdd( (pAtom), (Amount) )
#define OsAtomicSub( pAtom, Amount ) InterlockedExchangeAdd( (pAtom), -(Amount) )
#define OsAtomicRead( pAtom ) *(pAtom)
#elif defined( SROS_WIN95 ) || defined( SROS_MSDOS )
// Lowest level PC I/O functions
SRLOCAL void OsPortIn( int port, unsigned char *value) {
unsigned char temp;
_asm {
mov dx,WORD PTR port
in al,dx
mov BYTE PTR temp,al
}
*value = temp;
}
SRLOCAL void OsPortOut( int port, unsigned char value) {
_asm {
mov dx,WORD PTR port
mov al,BYTE PTR value
out dx,al
}
}
// Functions to transfer data between user and kernel space
SRLOCAL unsigned long OsCopyToUser( void *UserBuff, const void *KernelBuff, unsigned long Nbytes ) {
int i;
unsigned char *userptr;
unsigned char *kernelptr;
userptr = (unsigned char *)UserBuff;
kernelptr = (unsigned char *)KernelBuff;
for ( i = 0 ; i < Nbytes ; i++ )
*userptr++ = *kernelptr++;
return( Nbytes );
}
SRLOCAL unsigned long OsCopyFromUser( void *KernelBuff, const void *UserBuff, unsigned long Nbytes ) {
int i;
unsigned char *userptr;
unsigned char *kernelptr;
userptr = (unsigned char *)UserBuff;
kernelptr = (unsigned char *)KernelBuff;
for ( i = 0 ; i < Nbytes ; i++ )
*userptr++ = *kernelptr++;
return( Nbytes );
}
// Misc functions
SRLOCAL void OsIrpFinish( IRP *Irp, long Status, unsigned long Info ) {
if (Irp)
Irp->Nbytes = Info;
}
SRLOCAL long OsSetReadParms( IRP *Irp, unsigned long *OutBufferSize, long **IOBuffer ) {
// Set parameters
*OutBufferSize = Irp->Nbytes;
*IOBuffer = (long *)Irp->OutBuffer;
// Verify buffer pointer
if ( (*OutBufferSize == 0) || !(*IOBuffer) )
return( STATUS_INVALID_PARAMETER );
else
return( STATUS_SUCCESS );
}
SRLOCAL void OsSetIoctlCommand( IRP *Irp, unsigned long *Command ) {
*Command = Irp->Command;
}
SRLOCAL long OsSetIoctlBuffers( IRP *Irp,
unsigned long Command,
int **InBuffer,
int **OutBuffer ) {
// Assign buffers
*InBuffer = (int *)Irp->InBuffer;
*OutBuffer = (int *)Irp->OutBuffer;
// Check that a buffer exists since all commands pass (or get) data
if ( !(*OutBuffer) && !(*InBuffer) )
return( STATUS_INVALID_USER_BUFFER );
// No filling needed for InBuffer since "kernel" space is user space
return( STATUS_SUCCESS );
}
SRLOCAL void OsReturnIoctlBuffer( IRP *Irp,
unsigned long Command,
int *OutBuffer ) {
// No filling needed for OutBuffer since "kernel" space is user space
return;
}
#define OsModuleUseCountInc
#define OsModuleUseCountDec
// Atomic operation functions
#define OsAtomicSet( pAtom, Value ) *(pAtom) = (Value)
#define OsAtomicInc( pAtom ) *(pAtom) += 1
#define OsAtomicDec( pAtom ) *(pAtom) -= 1
#define OsAtomicAdd( pAtom, Amount ) *(pAtom) += (Amount)
#define OsAtomicSub( pAtom, Amount ) *(pAtom) -= (Amount)
#define OsAtomicRead( pAtom ) *(pAtom)
#elif defined( SROS_LINUX )
// Lowest level PC I/O functions
SRLOCAL void OsPortIn( int port, unsigned char *value) {
*value = inb( port );
}
SRLOCAL void OsPortOut( int port, unsigned char value) {
outb( value, port );
}
// Functions to transfer data between user and kernel space
SRLOCAL unsigned long OsCopyToUser( void *UserBuff, const void *KernelBuff, unsigned long Nbytes ) {
unsigned long result;
result = __copy_to_user( UserBuff, KernelBuff, Nbytes );
return( result );
}
SRLOCAL unsigned long OsCopyFromUser( void *KernelBuff, const void *UserBuff, unsigned long Nbytes ) {
unsigned long result;
result = __copy_from_user( KernelBuff, UserBuff, Nbytes );
return( result );
}
// Misc functions
SRLOCAL void OsIrpFinish( IRP *Irp, long Status, unsigned long Info ) {
if (Irp)
Irp->Nbytes = Info;
}
SRLOCAL long OsSetReadParms( IRP *Irp, unsigned long *OutBufferSize, long **IOBuffer ) {
// Set parameters
*OutBufferSize = Irp->Nbytes;
*IOBuffer = (long *)Irp->OutBuffer;
// Verify buffer pointer
if ( (*OutBufferSize == 0) ||
(!(*IOBuffer)) ||
(!access_ok( VERIFY_WRITE, (void*)(*IOBuffer), *OutBufferSize)) )
return( STATUS_INVALID_PARAMETER );
else
return( STATUS_SUCCESS );
}
SRLOCAL void OsSetIoctlCommand( IRP *Irp, unsigned long *Command ) {
*Command = Irp->Command;
}
SRLOCAL long OsSetIoctlBuffers( IRP *Irp,
unsigned long Command,
int **InBuffer,
int **OutBuffer ) {
// BufferArea is defined at maximum size needed for any command
static unsigned char BufferArea[sizeof(INIT4CHPARMS)];
int ReadCopy, WriteCopy, Err;
/* _IOC type is user-oriented, verify_area is kernel-oriented
* so read/write are reversed. VERIFY_WRITE handles R/W.
* eg _IOC_READ means read from the device, so driver must write
* to user space.
*/
*InBuffer = *OutBuffer = (int *)BufferArea;
// Check if driver must write to user space
if ( _IOC_DIR(Command) & _IOC_READ )
WriteCopy = 1;
else
WriteCopy = 0;
// Check if driver must read from user space
if ( _IOC_DIR(Command) & _IOC_WRITE )
ReadCopy = 1;
else
ReadCopy = 0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -