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

📄 loader.c

📁 改文件可以安装无线网卡在linux下的驱动,大家可以在网站上查找一下用法
💻 C
📖 第 1 页 / 共 2 页
字号:
	if (driver->num_bin_files < load_driver->nr_bin_files) {		for (i = 0; i < driver->num_bin_files; i++)			vfree(bin_files[i].data);		kfree(bin_files);		driver->num_bin_files = 0;		TRACEEXIT1(return -EINVAL);	} else {		driver->bin_files = bin_files;		TRACEEXIT1(return 0);	}}/* load settnigs for a device */static int load_settings(struct ndis_driver *ndis_driver,			 struct load_driver *load_driver){	int i, found, nr_settings;	struct ndis_device *ndis_device;	TRACEENTER1("");	found = 0;	kspin_lock(&loader_lock);	for (i = 0; i < num_ndis_devices; i++) {		if (strcmp(ndis_devices[i].conf_file_name,			   load_driver->conf_file_name) == 0) {			found = 1;			break;		}	}	kspin_unlock(&loader_lock);	if (!found) {		ERROR("conf file %s not found",		      ndis_devices[i].conf_file_name);		TRACEEXIT1(return -EINVAL);	}	nr_settings = 0;	ndis_device = &ndis_devices[i];	for (i = 0; i < load_driver->nr_settings; i++) {		struct load_device_setting *load_setting =			&load_driver->settings[i];		struct device_setting *setting;		setting = kmalloc(sizeof(*setting), GFP_KERNEL);		if (!setting) {			ERROR("couldn't allocate memory");			break;		}		memset(setting, 0, sizeof(*setting));		memcpy(setting->name, load_setting->name,		       MAX_NDIS_SETTING_NAME_LEN);		memcpy(setting->value, load_setting->value,		       MAX_NDIS_SETTING_VALUE_LEN);		DBGTRACE2("copied setting %s", load_setting->name);		setting->config_param.type = NDIS_CONFIG_PARAM_NONE;		if (strcmp(setting->name, "ndis_version") == 0)			memcpy(ndis_driver->version, setting->value,			       sizeof(ndis_driver->version));		kspin_lock(&loader_lock);		list_add(&setting->list, &ndis_device->settings);		kspin_unlock(&loader_lock);		nr_settings++;	}	/* it is not a fatal error if some settings couldn't be loaded */	if (nr_settings > 0)		TRACEEXIT1(return 0);	else		TRACEEXIT1(return -EINVAL);}/* this function is called while holding load_lock spinlock */static void unload_ndis_device(struct ndis_device *device){	TRACEENTER1("unloading device %04X:%04X:%04X:%04X, driver %s",		    device->vendor, device->device, device->subvendor,		    device->subdevice, device->driver_name);	while (!list_empty(&device->settings)) {		struct device_setting *setting;		struct ndis_config_param *param;		setting = list_entry(device->settings.next,				     struct device_setting, list);		param = &setting->config_param;		if (param->type == NDIS_CONFIG_PARAM_STRING)			RtlFreeUnicodeString(&param->data.ustring);		list_del(&setting->list);		kfree(setting);	}	TRACEEXIT1(return);}/* at the time this function is called, devices are deregistered, so * safe to remove the driver without any checks */static void unload_ndis_driver(struct ndis_driver *driver){	int i;	DBGTRACE1("freeing %d images", driver->num_pe_images);	if (driver->driver_unload)		driver->driver_unload(driver);	for (i = 0; i < driver->num_pe_images; i++)		if (driver->pe_images[i].image)			vfree(driver->pe_images[i].image);	DBGTRACE1("freeing %d bin files", driver->num_bin_files);	for (i = 0; i < driver->num_bin_files; i++)		vfree(driver->bin_files[i].data);	if (driver->bin_files)		kfree(driver->bin_files);	kfree(driver);	TRACEEXIT1(return);}/* call the entry point of the driver */static int start_driver(struct ndis_driver *driver){	int i, ret, res;	struct unicode_string reg_string;	char *reg_path = "0/0t0m0p0";	TRACEENTER1("");	reg_string.buf = (wchar_t *)reg_path;	reg_string.buflen = reg_string.len = strlen(reg_path);	for (ret = res = 0, i = 0; i < driver->num_pe_images; i++)		/* dlls are already started by loader */		if (driver->pe_images[i].type == IMAGE_FILE_EXECUTABLE_IMAGE) {			UINT (*entry)(void *obj,				      struct unicode_string *p2) STDCALL;			entry = driver->pe_images[i].entry;			DBGTRACE1("entry: %p, %p", entry, *entry);			res = LIN2WIN2(entry, (void *)driver, &reg_string);			ret |= res;			DBGTRACE1("entry returns %08X", res);			DBGTRACE1("driver version: %d.%d",				  driver->miniport_char.majorVersion,				  driver->miniport_char.minorVersion);			driver->entry = entry;		}	if (ret) {		ERROR("driver initialization failed: %08X", ret);		TRACEEXIT1(return -EINVAL);	}	TRACEEXIT1(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;	TRACEENTER1("");	kspin_lock(&loader_lock);	list_for_each_entry(tmp, &ndis_drivers, list) {		if (strcmp(tmp->name, driver->name) == 0) {			kspin_unlock(&loader_lock);			ERROR("cannot add duplicate driver");			TRACEEXIT1(return -EBUSY);		}	}	list_add(&driver->list, &ndis_drivers);	kspin_unlock(&loader_lock);	TRACEEXIT1(return 0);}/* load a driver from userspace and initialize it */static int load_ndis_driver(struct load_driver *load_driver){	struct ndis_driver *ndis_driver;	ndis_driver = kmalloc(sizeof(*ndis_driver), GFP_KERNEL);	if (!ndis_driver) {		ERROR("couldn't allocate memory");		TRACEEXIT1(return -EINVAL);	}	memset(ndis_driver, 0, sizeof(*ndis_driver));	ndis_driver->bustype = -1;	if (load_sys_files(ndis_driver, load_driver) ||	    load_bin_files(ndis_driver, load_driver) ||	    load_settings(ndis_driver, load_driver) ||	    start_driver(ndis_driver) ||	    add_driver(ndis_driver)) {		unload_ndis_driver(ndis_driver);		TRACEEXIT1(return -EINVAL);	} else {		printk(KERN_INFO "%s: driver %s (%s) loaded\n",		       DRIVER_NAME, ndis_driver->name, ndis_driver->version);#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,10)		add_taint(TAINT_PROPRIETARY_MODULE);		/* older kernels don't seem to have a way to set		 * tainted information */#endif		TRACEEXIT1(return 0);	}}/* register all devices (for all drivers) installed */static int register_devices(struct load_devices *load_devices){	int i, res, num_pci, num_usb;	struct load_device *devices;	devices = NULL;	ndiswrapper_pci_devices = NULL;	ndiswrapper_usb_devices = NULL;	ndis_devices = NULL;	devices = vmalloc(load_devices->count * sizeof(struct load_device));	if (!devices) {		ERROR("couldn't allocate memory");		TRACEEXIT1(return -ENOMEM);	}	if (copy_from_user(devices, load_devices->devices,			   load_devices->count * sizeof(struct load_device))) {		ERROR("couldn't copy from user space");		goto err;	}	num_pci = num_usb = 0;	for (i = 0; i < load_devices->count; i++)		if (devices[i].bustype == NDIS_PCI_BUS)			num_pci++;		else if (devices[i].bustype == NDIS_USB_BUS)			num_usb++;		else			WARNING("bus type %d is not valid",				devices[i].bustype);	num_ndis_devices = num_pci + num_usb;	if (num_pci > 0) {		ndiswrapper_pci_devices =			kmalloc((num_pci + 1) * sizeof(struct pci_device_id),				GFP_KERNEL);		if (!ndiswrapper_pci_devices) {			ERROR("couldn't allocate memory");			goto err;		}		memset(ndiswrapper_pci_devices, 0,		       (num_pci + 1) * sizeof(struct pci_device_id));	}	if (num_usb > 0) {		ndiswrapper_usb_devices =			kmalloc((num_usb + 1) * sizeof(struct usb_device_id),				GFP_KERNEL);		if (!ndiswrapper_usb_devices) {			ERROR("couldn't allocate memory");			goto err;		}		memset(ndiswrapper_usb_devices, 0,		       (num_usb + 1) * sizeof(struct usb_device_id));	}	ndis_devices = vmalloc(num_ndis_devices * sizeof(*ndis_devices));	if (!ndis_devices) {		ERROR("couldn't allocate memory");		goto err;	}	memset(ndis_devices, 0, num_ndis_devices * sizeof(*ndis_devices));	num_usb = num_pci = 0;	for (i = 0; i < load_devices->count; i++) {		struct load_device *device = &devices[i];		struct ndis_device *ndis_device;		ndis_device = &ndis_devices[num_pci + num_usb];		INIT_LIST_HEAD(&ndis_device->settings);		memcpy(&ndis_device->driver_name, device->driver_name,		       sizeof(ndis_device->driver_name));		memcpy(&ndis_device->conf_file_name, device->conf_file_name,		       sizeof(ndis_device->conf_file_name));		ndis_device->bustype = device->bustype;		ndis_device->vendor = device->vendor;		ndis_device->device = device->device;		ndis_device->subvendor = device->subvendor;		ndis_device->subdevice = device->subdevice;		memcpy(&ndis_device->driver_name, device->driver_name,		       sizeof(ndis_device->driver_name));		if (device->bustype == NDIS_PCI_BUS) {			ndiswrapper_pci_devices[num_pci].vendor =				device->vendor;			ndiswrapper_pci_devices[num_pci].device =				device->device;			if (device->subvendor == DEV_ANY_ID)				ndiswrapper_pci_devices[num_pci].subvendor =					PCI_ANY_ID;			else				ndiswrapper_pci_devices[num_pci].subvendor =					device->subvendor;			if (device->subdevice == DEV_ANY_ID)				ndiswrapper_pci_devices[num_pci].subdevice =					PCI_ANY_ID;			else				ndiswrapper_pci_devices[num_pci].subdevice =					device->subdevice;			ndiswrapper_pci_devices[num_pci].class = 0;			ndiswrapper_pci_devices[num_pci].class_mask = 0;			ndiswrapper_pci_devices[num_pci].driver_data =				num_pci + num_usb;			num_pci++;			DBGTRACE1("pci device %d added", num_pci);			DBGTRACE1("adding %04x:%04x:%04x:%04x to pci idtable",				  device->vendor, device->device,				  device->subvendor, device->subdevice);#ifdef CONFIG_USB		} else if (device->bustype == NDIS_USB_BUS) {			ndiswrapper_usb_devices[num_usb].idVendor =				device->vendor;			ndiswrapper_usb_devices[num_usb].idProduct =				device->device;			ndiswrapper_usb_devices[num_usb].match_flags =				USB_DEVICE_ID_MATCH_DEVICE;			ndiswrapper_usb_devices[num_usb].driver_info =				num_pci + num_usb;			num_usb++;			DBGTRACE1("usb device %d added", num_usb);			DBGTRACE1("adding %04x:%04x to usb idtable",				  device->vendor, device->device);#endif		} else {			ERROR("system doesn't support bus type %d",			      device->bustype);		}	}	if (ndiswrapper_pci_devices) {		memset(&ndiswrapper_pci_driver, 0,			       sizeof(ndiswrapper_pci_driver));		ndiswrapper_pci_driver.name = DRIVER_NAME;		ndiswrapper_pci_driver.id_table = ndiswrapper_pci_devices;		ndiswrapper_pci_driver.probe = ndiswrapper_add_one_pci_dev;		ndiswrapper_pci_driver.remove =			__devexit_p(ndiswrapper_remove_one_pci_dev);		ndiswrapper_pci_driver.suspend = ndiswrapper_suspend_pci;		ndiswrapper_pci_driver.resume = ndiswrapper_resume_pci;		res = pci_register_driver(&ndiswrapper_pci_driver);		if (res < 0) {			ERROR("couldn't register ndiswrapper pci driver");			goto err;		}	}#ifdef CONFIG_USB	if (ndiswrapper_usb_devices) {		memset(&ndiswrapper_usb_driver, 0,			       sizeof(ndiswrapper_usb_driver));		ndiswrapper_usb_driver.owner = THIS_MODULE;		ndiswrapper_usb_driver.name = DRIVER_NAME;		ndiswrapper_usb_driver.id_table = ndiswrapper_usb_devices;		ndiswrapper_usb_driver.probe = ndiswrapper_add_one_usb_dev;		ndiswrapper_usb_driver.disconnect =			ndiswrapper_remove_one_usb_dev;		res = usb_register(&ndiswrapper_usb_driver);		if (res < 0) {			ERROR("couldn't register ndiswrapper usb driver");			goto err;		}	}#endif	vfree(devices);	TRACEEXIT1(return 0);err:	if (ndis_devices)		vfree(ndis_devices);	ndis_devices = NULL;	if (ndiswrapper_usb_devices)		kfree(ndiswrapper_usb_devices);	ndiswrapper_usb_devices = NULL;	if (ndiswrapper_pci_devices)		kfree(ndiswrapper_pci_devices);	ndiswrapper_pci_devices = NULL;	if (devices)		vfree(devices);	TRACEEXIT1(return -EINVAL);}static int wrapper_ioctl(struct inode *inode, struct file *file,			 unsigned int cmd, unsigned long arg){	struct load_driver *load_driver;	struct load_devices devices;	int res;	TRACEENTER1("cmd: %u (%lu, %lu)", cmd,		    (unsigned long)NDIS_REGISTER_DEVICES,		    (unsigned long)NDIS_LOAD_DRIVER);	res = 0;	switch (cmd) {	case NDIS_REGISTER_DEVICES:		DBGTRACE1("adding devices at %p", (void *)arg);		res = copy_from_user(&devices, (void *)arg, sizeof(devices));		if (!res)			res = register_devices(&devices);		if (res)			TRACEEXIT1(return -EINVAL);		TRACEEXIT1(return 0);		break;	case NDIS_LOAD_DRIVER:		DBGTRACE1("loading driver at %p", (void *)arg);		load_driver = vmalloc(sizeof(*load_driver));		if (!load_driver)			TRACEEXIT1(return -ENOMEM);		res = copy_from_user(load_driver, (void *)arg,				     sizeof(*load_driver));		if (!res)			res = load_ndis_driver(load_driver);		vfree(load_driver);		if (res)			TRACEEXIT1(return -EINVAL);		else			TRACEEXIT1(return 0);		break;	default:		ERROR("Unknown ioctl %u", cmd);		TRACEEXIT1(return -EINVAL);		break;	}	TRACEEXIT1(return 0);}static int wrapper_ioctl_release(struct inode *inode, struct file *file){	TRACEENTER1("");	return 0;}static struct file_operations wrapper_fops = {	.owner          = THIS_MODULE,	.ioctl		= wrapper_ioctl,	.release	= wrapper_ioctl_release,};static struct miscdevice wrapper_misc = {	.name   = DRIVER_NAME,	.fops   = &wrapper_fops};int loader_init(void){	int err;	INIT_LIST_HEAD(&ndis_drivers);	kspin_lock_init(&loader_lock);	if ((err = misc_register(&wrapper_misc)) < 0 ) {		ERROR("couldn't register module (%d)", err);		TRACEEXIT1(return err);	}	TRACEEXIT1(return 0);}void loader_exit(void){	int i;	TRACEENTER1("");	misc_deregister(&wrapper_misc);#ifdef CONFIG_USB	if (ndiswrapper_usb_devices) {		usb_deregister(&ndiswrapper_usb_driver);		kfree(ndiswrapper_usb_devices);		ndiswrapper_usb_devices = NULL;	}#endif	if (ndiswrapper_pci_devices) {		pci_unregister_driver(&ndiswrapper_pci_driver);		kfree(ndiswrapper_pci_devices);		ndiswrapper_pci_devices = NULL;	}	kspin_lock(&loader_lock);	if (ndis_devices) {		for (i = 0; i < num_ndis_devices; i++)			unload_ndis_device(&ndis_devices[i]);		vfree(ndis_devices);		ndis_devices = NULL;	}	while (!list_empty(&ndis_drivers)) {		struct ndis_driver *driver;		driver = list_entry(ndis_drivers.next,				    struct ndis_driver, list);		list_del(&driver->list);		unload_ndis_driver(driver);	}	kspin_unlock(&loader_lock);	TRACEEXIT1(return);}

⌨️ 快捷键说明

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