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

📄 wrapper.c

📁 万能网卡驱动程序源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if(res)	{		printk(KERN_ERR "Unable to get MAC-addr from driver\n");		return -1;	}	dev->open = ndis_open;	dev->hard_start_xmit = ndis_start_xmit;	dev->stop = ndis_close;	dev->get_stats = ndis_get_stats;	dev->do_ioctl = ndis_ioctl;	dev->get_wireless_stats = ndis_get_wireless_stats;	dev->wireless_handlers	= (struct iw_handler_def *)&ndis_handler_def;		for(i = 0; i < 6; i++)	{		dev->dev_addr[i] = mac[i];	}	dev->irq = handle->irq;	dev->mem_start = handle->mem_start;			dev->mem_end = handle->mem_end;			return register_netdev(dev);}/* * Called by PCI-subsystem for each PCI-card found. */static int __devinit ndis_init_one(struct pci_dev *pdev,                                   const struct pci_device_id *ent){	int res;	struct ndis_driver *driver = (struct ndis_driver *) ent->driver_data;	struct ndis_handle *handle;	struct net_device *dev;	DBGTRACE("%s\n", __FUNCTION__);	dev = alloc_etherdev(sizeof(*handle));	if(!dev)	{		printk(KERN_ERR "Unable to alloc etherdev\n");		res = -ENOMEM;		goto out_nodev;	}	SET_MODULE_OWNER(dev);//	SET_NETDEV_DEV(dev, &pdev->dev);	handle = dev->priv;	handle->driver = driver;	handle->net_dev = dev;	spin_lock_init(&handle->query_lock);	pci_set_drvdata(pdev, handle);	/* Poision this because it may contain function pointers */	memset(&handle->fill1, 0x12, sizeof(handle->fill1));	memset(&handle->fill2, 0x13, sizeof(handle->fill2));	memset(&handle->fill3, 0x14, sizeof(handle->fill3));	memset(&handle->fill4, 0x15, sizeof(handle->fill4));	handle->indicate_receive_packet = &NdisMIndicateReceivePacket;	handle->send_complete = &NdisMSendComplete;	handle->indicate_status = &NdisIndicateStatus;		handle->indicate_status_complete = &NdisIndicateStatusComplete;		handle->query_complete = &NdisMQueryInformationComplete;		handle->set_complete = &NdisMSetInformationComplete;		handle->pci_dev = pdev;		res = pci_enable_device(pdev);	if(res)		goto out_enable;	res = pci_request_regions(pdev, driver->name);	if(res)		goto out_regions;	if(call_init(handle))	{		printk(KERN_ERR "ndiswrapper: Driver init returned error\n");		res = -EINVAL;		goto out_start;	}		if(setup_dev(handle->net_dev))	{		printk(KERN_ERR "ndiswrapper: Unable to set up driver\n");		res = -EINVAL;		goto out_start;	}	handle->driver->key_len = 0;	init_timer(&(handle->driver->timer_list));	add_scan_timer((unsigned long)handle);	return 0;out_start:	pci_release_regions(pdev);out_regions:	pci_disable_device(pdev);out_enable:	free_netdev(dev);out_nodev:	return res;}static void __devexit ndis_remove_one(struct pci_dev *pdev){	struct ndis_handle *handle = (struct ndis_handle *) pci_get_drvdata(pdev);	DBGTRACE("%s\n", __FUNCTION__);	del_timer(&(handle->driver->timer_list));#ifndef DEBUG_CRASH_ON_INIT	unregister_netdev(handle->net_dev);	call_halt(handle);	if(handle->net_dev)		free_netdev(handle->net_dev);#endif	pci_release_regions(pdev);	pci_disable_device(pdev);}static int misc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg);static struct file_operations wrapper_fops = {	.owner          = THIS_MODULE,	.ioctl		= misc_ioctl,};static struct miscdevice wrapper_misc = {	.name   = DRV_NAME,	.fops   = &wrapper_fops};/* * Register driver with pci subsystem. */static int start_driver(struct ndis_driver *driver){	int res = 0;	if(call_entry(driver))	{		printk(KERN_ERR "ndiswrapper: Driver entry return error\n");		return -EINVAL;	}	driver->pci_driver.name = driver->name;	driver->pci_driver.id_table = driver->pci_id;	driver->pci_driver.probe = ndis_init_one;	driver->pci_driver.remove = ndis_remove_one;		#ifndef DEBUG_CRASH_ON_INIT	res = pci_module_init(&driver->pci_driver);	if(!res)		driver->pci_registered = 1;#endif	return res;}/* * Load the driver from userspace. */static struct ndis_driver *load_driver(struct put_driver *put_driver){	void *entry;	struct ndis_driver *driver;	struct pci_dev *pdev = 0;	int namelen;	DBGTRACE("Putting driver size %d\n", put_driver->size);	driver = kmalloc(sizeof(struct ndis_driver), GFP_KERNEL);	if(!driver)	{		printk(KERN_ERR "Unable to alloc driver struct\n");		goto out_nodriver;	}	memset(driver, 0, sizeof(struct ndis_driver));		INIT_LIST_HEAD(&driver->settings);	namelen = sizeof(put_driver->name);	if(sizeof(driver->name) < namelen)		namelen = sizeof(driver->name);	strncpy(driver->name, put_driver->name, namelen-1);	driver->name[namelen-1] = 0;	driver->image = vmalloc(put_driver->size);	DBGTRACE("Image is at %08x\n", (int)driver->image);	if(!driver->image)	{		printk(KERN_ERR "Unable to allocate mem for driver\n");		goto out_vmalloc;	}	if(copy_from_user(driver->image, put_driver->data, put_driver->size))	{		printk(KERN_ERR "Failed to copy from user\n");		goto out_vmalloc;	}	if(prepare_coffpe_image(&entry, driver->image, put_driver->size))	{		printk(KERN_ERR "Unable to prepare driver\n");				goto out_baddriver;	}	/* Make sure PCI device is present */	pdev = pci_find_device(put_driver->pci_vendor, put_driver->pci_device, pdev);	if(!pdev)	{		printk(KERN_ERR "PCI device %04x:%04x not present\n", put_driver->pci_vendor, put_driver->pci_device);		goto out_baddriver;	}		driver->pci_id[0].vendor = put_driver->pci_vendor;	driver->pci_id[0].device = put_driver->pci_device;	driver->pci_id[0].subvendor = PCI_ANY_ID;	driver->pci_id[0].subdevice = PCI_ANY_ID;	driver->pci_id[0].class = 0;	driver->pci_id[0].class_mask = 0;	driver->pci_id[0].driver_data = (int)driver;		driver->entry = entry;	return driver;out_baddriver:	vfree(driver->image);out_vmalloc:	kfree(driver);out_nodriver:	return 0;}/* * Add driver to list of loaded driver but make sure this driver is * not loaded before. */static int add_driver(struct ndis_driver *driver){	struct ndis_driver *tmp;	int dup = 0;	spin_lock(&driverlist_lock);	list_for_each_entry(tmp, &driverlist, list)	{		if(tmp->pci_id[0].vendor == driver->pci_id[0].vendor &&		   tmp->pci_id[0].device == driver->pci_id[0].device)	   	{			dup = 1;			break;		}		if(strcmp(tmp->name, driver->name) == 0)		{			dup = 1;			break;		}			}	if(!dup)		list_add(&driver->list, &driverlist);	spin_unlock(&driverlist_lock);	if(dup)	{		printk(KERN_ERR "Cannot add duplicate driver\n");		return -EBUSY;	}		return 0;}/* * Add setting to the list of settings for the driver. */static int add_setting(struct ndis_driver *driver, struct put_setting *put_setting){	struct ndis_setting *setting;	char *name;	unsigned int val;		if(put_setting->payload_len != sizeof(val))	{		return -EINVAL;	}	if(copy_from_user(&val, put_setting->payload, sizeof(val)))		return -EINVAL;	name = kmalloc(put_setting->name_len+1, GFP_KERNEL);	if(!name)		return -ENOMEM;	setting = kmalloc(sizeof(*setting), GFP_KERNEL);	if(!setting)	{		kfree(name);		return -ENOMEM;	}	memset(setting, 0, sizeof(*setting));		if(copy_from_user(name, put_setting->name, put_setting->name_len))	{		kfree(name);		kfree(setting);		return -EINVAL;	}	name[put_setting->name_len] = 0;	setting->val.type = 0;	setting->name = name;	setting->val.type = 0;	setting->val.data.intval = val;			list_add(&setting->list, &driver->settings);	return 0;}/* * Delete a driver. This implies deleting all cards for the handle too. */static void unload_driver(struct ndis_driver *driver){	struct list_head *curr, *tmp2;	DBGTRACE("%s\n", __FUNCTION__);	if(driver->pci_registered)		pci_unregister_driver(&driver->pci_driver);#ifdef DEBUG_CRASH_ON_INIT	{		struct pci_dev *pdev = 0;		pdev = pci_find_device(driver->pci_id[0].vendor, driver->pci_id[0].device, pdev);		if(pdev)			ndis_remove_one(pdev);	}#endif	spin_lock(&driverlist_lock);	list_del(&driver->list);	spin_unlock(&driverlist_lock);	if(driver->image)		vfree(driver->image);	list_for_each_safe(curr, tmp2, &driver->settings)	{		struct ndis_setting *setting = (struct ndis_setting*) curr;		kfree(setting->name);		kfree(setting);	}	kfree(driver);}static int misc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){	struct put_setting put_setting;	struct put_driver put_driver;	struct ndis_driver *driver;	switch(cmd) {	case NDIS_PUTDRIVER:		if(copy_from_user(&put_driver, (void*)arg, sizeof(struct put_driver)))			return -EINVAL;		driver = load_driver(&put_driver);		if(!driver)			return -EINVAL;		file->private_data = driver;		return add_driver(driver);		break;	case NDIS_STARTDRIVER:		if(file->private_data)		{			struct ndis_driver *driver= file->private_data;			int res = start_driver(driver);#ifdef DEBUG_CRASH_ON_INIT			{				struct pci_dev *pdev = 0;				pdev = pci_find_device(driver->pci_id[0].vendor, driver->pci_id[0].device, pdev);				if(pdev)					ndis_init_one(pdev, &driver->pci_id[0]);			}#endif			file->private_data = NULL;			if(res)			{				unload_driver(driver);				return res;			}		}		break;	case NDIS_PUTSETTING:		if(file->private_data)		{			int res;			struct ndis_driver *driver = file->private_data;			if(copy_from_user(&put_setting, (void*)arg, sizeof(struct put_setting)))				return -EINVAL;			res = add_setting(driver, &put_setting);			if(res)				return res;		}			break;	case NDIS_CANCELLOAD:		if(file->private_data)		{			struct ndis_driver *driver = file->private_data;			unload_driver(driver);		}				break;		default:		printk(KERN_ERR "Unknown ioctl %08x\n", cmd);		return -EINVAL;		break;	}		return 0;}void init_ndis_work(void);static int __init wrapper_init(void){	int err;	printk(KERN_INFO "ndiswrapper version %s loaded\n", DRV_VERSION);        if ( (err = misc_register(&wrapper_misc)) < 0 ) {                printk(KERN_ERR "misc_register failed\n");		return err;        }	init_ndis_work();	return 0;}static void __exit wrapper_exit(void){	while(!list_empty(&driverlist))	{		struct ndis_driver *driver = (struct ndis_driver*) driverlist.next;		unload_driver(driver);	}		misc_deregister(&wrapper_misc);}module_init(wrapper_init);module_exit(wrapper_exit);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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