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

📄 dhahelper.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
字号:
/*    Direct Hardware Access kernel helper        (C) 2002 Alex Beregszaszi <alex@fsn.hu>        Accessing hardware from userspace as USER (no root needed!)    Tested on 2.2.x (2.2.19) and 2.4.x (2.4.3,2.4.17).        License: GPL        WARNING! THIS MODULE VIOLATES SEVERAL SECURITY LINES! DON'T USE IT    ON PRODUCTION SYSTEMS, ONLY AT HOME, ON A "SINGLE-USER" SYSTEM.    NO WARRANTY!    Tech:	Communication between userspace and kernelspace goes over character	device using ioctl.    Usage:	mknod -m 666 /dev/dhahelper c 180 0		Also you can change the major number, setting the "dhahelper_major"	module parameter, the default is 180, specified in dhahelper.h.		Note: do not use other than minor==0, the module forbids it.    TODO:	* do memory mapping without fops:mmap	* implement unmap memory	* select (request?) a "valid" major number (from Linux project? ;)	* make security	* is pci handling needed? (libdha does this with lowlevel port funcs)	* is mttr handling needed?	* test on older kernels (2.0.x (?))*/#ifndef MODULE#define MODULE#endif#ifndef __KERNEL__#define __KERNEL__#endif#include <linux/config.h>#ifdef CONFIG_MODVERSION#define MODVERSION#include <linux/modversions.h>#endif#include <linux/version.h>#include <linux/module.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/string.h>#include <linux/errno.h>#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,10)#include <linux/malloc.h>#else#include <linux/slab.h>#endif#include <linux/pci.h>#include <linux/ioport.h>#include <linux/init.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/io.h>#include <linux/mman.h>#include <linux/fs.h>#include <linux/unistd.h>#include "dhahelper.h"MODULE_AUTHOR("Alex Beregszaszi <alex@fsn.hu>");MODULE_DESCRIPTION("Provides userspace access to hardware (security violation!)");#ifdef MODULE_LICENSEMODULE_LICENSE("GPL");#endifstatic int dhahelper_major = DEFAULT_MAJOR;MODULE_PARM(dhahelper_major, "i");MODULE_PARM_DESC(dhahelper_major, "Major number of dhahelper characterdevice");/* 0 = silent *//* 1 = report errors (default) *//* 2 = debug */static int dhahelper_verbosity = 1;MODULE_PARM(dhahelper_verbosity, "i");MODULE_PARM_DESC(dhahelper_verbosity, "Level of verbosity (0 = silent, 1 = only errors, 2 = debug)");static dhahelper_memory_t last_mem_request;static int dhahelper_open(struct inode *inode, struct file *file){    if (dhahelper_verbosity > 1)	printk(KERN_DEBUG "dhahelper: device opened\n");    if (MINOR(inode->i_rdev) != 0)	return(-ENXIO);    MOD_INC_USE_COUNT;    return(0);}static int dhahelper_release(struct inode *inode, struct file *file){    if (dhahelper_verbosity > 1)	printk(KERN_DEBUG "dhahelper: device released\n");    if (MINOR(inode->i_rdev) != 0)	return(-ENXIO);    MOD_DEC_USE_COUNT;    return(0);}static int dhahelper_ioctl(struct inode *inode, struct file *file,    unsigned int cmd, unsigned long arg){    if (dhahelper_verbosity > 1)	printk(KERN_DEBUG "dhahelper: ioctl(cmd=%x, arg=%lx)\n",	    cmd, arg);    if (MINOR(inode->i_rdev) != 0)	return(-ENXIO);    switch(cmd)    {	case DHAHELPER_GET_VERSION:	{	    int version = API_VERSION;	    if (copy_to_user((int *)arg, &version, sizeof(int)))	    {		if (dhahelper_verbosity > 0)		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");		return(-EFAULT);	    }	    break;	}	case DHAHELPER_PORT:	{	    dhahelper_port_t port;	    if (copy_from_user(&port, (dhahelper_port_t *)arg, sizeof(dhahelper_port_t)))	    {		if (dhahelper_verbosity > 0)		    printk(KERN_ERR "dhahelper: failed copy from userspace\n");		return(-EFAULT);	    }	    switch(port.operation)	    {		case PORT_OP_READ:		{		    switch(port.size)		    {			case 1:			    port.value = inb(port.addr);			    break;			case 2:			    port.value = inw(port.addr);			    break;			case 4:			    port.value = inl(port.addr);			    break;			default:			    if (dhahelper_verbosity > 0)				printk(KERN_ERR "dhahelper: invalid port read size (%d)\n",				    port.size);			    return(-EINVAL);		    }		    break;		}		case PORT_OP_WRITE:		{		    switch(port.size)		    {			case 1:			    outb(port.value, port.addr);			    break;			case 2:			    outw(port.value, port.addr);			    break;			case 4:			    outl(port.value, port.addr);			    break;			default:			    if (dhahelper_verbosity > 0)				printk(KERN_ERR "dhahelper: invalid port write size (%d)\n",				    port.size);			    return(-EINVAL);		    }		    break;		}		default:		    if (dhahelper_verbosity > 0)		        printk(KERN_ERR "dhahelper: invalid port operation (%d)\n",		    	    port.operation);		    return(-EINVAL);	    }	    /* copy back only if read was performed */	    if (port.operation == PORT_OP_READ)	    if (copy_to_user((dhahelper_port_t *)arg, &port, sizeof(dhahelper_port_t)))	    {		if (dhahelper_verbosity > 0)		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");		return(-EFAULT);	    }	    	    break;	}	case DHAHELPER_MEMORY:	{	    dhahelper_memory_t mem;	    if (copy_from_user(&mem, (dhahelper_memory_t *)arg, sizeof(dhahelper_memory_t)))	    {		if (dhahelper_verbosity > 0)		    printk(KERN_ERR "dhahelper: failed copy from userspace\n");		return(-EFAULT);	    }	    	    switch(mem.operation)	    {		case MEMORY_OP_MAP:		{#if 1		    memcpy(&last_mem_request, &mem, sizeof(dhahelper_memory_t));#else		    mem.ret = do_mmap(file, mem.start, mem.size, PROT_READ|PROT_WRITE,			MAP_SHARED, mem.offset);#endif		    break;		}		case MEMORY_OP_UNMAP:		    break;		default:		    if (dhahelper_verbosity > 0)			printk(KERN_ERR "dhahelper: invalid memory operation (%d)\n",			    mem.operation);		    return(-EINVAL);	    }	    	    if (copy_to_user((dhahelper_memory_t *)arg, &mem, sizeof(dhahelper_memory_t)))	    {		if (dhahelper_verbosity > 0)		    printk(KERN_ERR "dhahelper: failed copy to userspace\n");		return(-EFAULT);	    }	    	    break;	}	default:    	    if (dhahelper_verbosity > 0)		printk(KERN_ERR "dhahelper: invalid ioctl (%x)\n", cmd);	    return(-EINVAL);    }    return(0);}static int dhahelper_mmap(struct file *file, struct vm_area_struct *vma){    if (last_mem_request.operation != MEMORY_OP_MAP)    {	if (dhahelper_verbosity > 0)	    printk(KERN_ERR "dhahelper: mapping not requested before mmap\n");	return(-EFAULT);    }        if (dhahelper_verbosity > 1)	printk(KERN_INFO "dhahelper: mapping %x (size: %x)\n",	    last_mem_request.start+last_mem_request.offset, last_mem_request.size);        if (remap_page_range(0, last_mem_request.start + last_mem_request.offset,	last_mem_request.size, vma->vm_page_prot))    {	if (dhahelper_verbosity > 0)	    printk(KERN_ERR "dhahelper: error mapping memory\n");	return(-EFAULT);    }    return(0);}#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)static struct file_operations dhahelper_fops ={    /*llseek*/	NULL,    /*read*/	NULL,    /*write*/	NULL,    /*readdir*/	NULL,    /*poll*/	NULL,    /*ioctl*/	dhahelper_ioctl,    /*mmap*/	dhahelper_mmap,    /*open*/	dhahelper_open,    /*flush*/	NULL,    /*release*/	dhahelper_release,    /* zero out the last 5 entries too ? */};#elsestatic struct file_operations dhahelper_fops ={    owner:	THIS_MODULE,    ioctl:	dhahelper_ioctl,    mmap:	dhahelper_mmap,    open:	dhahelper_open,    release:	dhahelper_release};#endif#if KERNEL_VERSION < KERNEL_VERSION(2,4,0)int init_module(void)#else static int __init init_dhahelper(void)#endif{    printk(KERN_INFO "Direct Hardware Access kernel helper (C) Alex Beregszaszi\n");    if(register_chrdev(dhahelper_major, "dhahelper", &dhahelper_fops))    {    	if (dhahelper_verbosity > 0)	    printk(KERN_ERR "dhahelper: unable to register character device (major: %d)\n",		dhahelper_major);	return(-EIO);    }        return(0);}#if KERNEL_VERSION < KERNEL_VERSION(2,4,0)void cleanup_module(void)#elsestatic void __exit exit_dhahelper(void)#endif{    unregister_chrdev(dhahelper_major, "dhahelper");}EXPORT_NO_SYMBOLS;#if KERNEL_VERSION >= KERNEL_VERSION(2,4,0)module_init(init_dhahelper);module_exit(exit_dhahelper);#endif

⌨️ 快捷键说明

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