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

📄 loadndisdriver.c

📁 ndis在linux下的无线网卡驱动源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  Copyright (C) 2003-2005 Pontus Fuchs, Giridhar Pemmasani * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *  GNU General Public License for more details. * */#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <string.h>#include <libgen.h>#include <sys/mman.h>#include <sys/types.h>#include <sys/ioctl.h>#include <sys/stat.h>#include <unistd.h>#include <fcntl.h>#include <limits.h>#include <ctype.h>#include <dirent.h>#include <syslog.h>#include <stdlib.h>#include <linux/major.h>#include <linux/ioctl.h>#include "loader.h"#define PROG_NAME "loadndisdriver"#define SETTING_LEN (MAX_SETTING_NAME_LEN + MAX_SETTING_VALUE_LEN + 2)static const char confdir[] = "/etc/ndiswrapper";static const char ioctl_file[] = "/dev/ndiswrapper";static int debug;#ifndef UTILS_VERSION#error compile this file with 'make' in the 'utils' \	directory only#endif#define LOG_MSG(where, fmt, ...)					\	syslog(LOG_KERN | where, "%s: %s(%d): " fmt "\n",		\	       PROG_NAME, __FUNCTION__, __LINE__ , ## __VA_ARGS__)#define ERROR(fmt, ...) LOG_MSG(LOG_INFO, fmt, ## __VA_ARGS__)#define INFO(fmt, ...) LOG_MSG(LOG_INFO, fmt, ## __VA_ARGS__)#define DBG(fmt, ...) do {					\		if (debug > 0)					\			LOG_MSG(LOG_INFO, fmt, ## __VA_ARGS__); \	} while (0)#define WARN(fmt, ...) LOG_MSG(LOG_INFO, fmt, ## __VA_ARGS__)/* load .sys or .bin file */static int load_file(char *filename, struct load_driver_file *driver_file){	int fd;	size_t size;	void *image = NULL;	struct stat statbuf;	char *file_basename = basename(filename);	fd = open(filename, O_RDONLY);	if (fd == -1) {		ERROR("unable to open file: %s", strerror(errno));		return -EINVAL;	}	if (fstat(fd, &statbuf)) {		ERROR("incorrect driver file '%s'", filename);		close(fd);		return -EINVAL;	}	size = statbuf.st_size;	image = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0);	if (image == MAP_FAILED) {		ERROR("unable to mmap driver: %s", strerror(errno));		close(fd);		return -EINVAL;	}	strncpy(driver_file->name, file_basename, sizeof(driver_file->name));	driver_file->name[sizeof(driver_file->name)-1] = 0;	driver_file->size = size;	driver_file->data = image;	return 0;}/* split setting into name and value pair */static int parse_setting_line(const char *setting_line, char *setting_name,			      char *setting_val){	const char *s;	char *val, *end;	int i;	// We try to be really paranoid parsing settings	for (s = setting_line; isspace(*s); s++)		;	// ignore comments and blank lines	if (*s == '#' || *s == ';' || *s == '\0')		return 0;	if ((val = strchr(s, '|')) == NULL ||	    (end = strchr(s, '\n')) == NULL) {		ERROR("invalid setting: %s", setting_line);		return -EINVAL;	}	for (i = 0; s != val && i < MAX_SETTING_NAME_LEN; s++, i++)		setting_name[i] = *s;	setting_name[i] = 0;	if (*s != '|') {		ERROR("invalid setting: %s", setting_line);		return -EINVAL;	}	for (i = 0, s++; s != end && i < MAX_SETTING_VALUE_LEN ; s++, i++)		setting_val[i] = *s;	setting_val[i] = 0;	if (*s != '\n') {		ERROR("invalid setting: %s", setting_line);		return -EINVAL;	}	DBG("Found setting: name=%s, val=\"%s\"", setting_name, setting_val);	// setting_val can be empty, but not name	if (strlen(setting_name) == 0) {		ERROR("invalid setting: \"%s\"", setting_line);		return -EINVAL;	}	return 1;}/* read .conf file and store info in driver */static int read_conf_file(char *conf_file_name, struct load_driver *driver){	char setting_line[SETTING_LEN];	struct stat statbuf;	FILE *config;	char setting_name[MAX_SETTING_NAME_LEN];	char setting_value[MAX_SETTING_VALUE_LEN];	int ret, nr_settings;	int i, vendor, device, subvendor, subdevice, bus;	if (lstat(conf_file_name, &statbuf)) {		ERROR("unable to open config file %s: %s",		      conf_file_name, strerror(errno));		return -EINVAL;	}	if (sscanf(conf_file_name, "%04X:%04X.%X.conf",		   &vendor, &device, &bus) == 3) {		DBG("bus: %X", bus);	} else if (sscanf(conf_file_name, "%04X:%04X:%04X:%04X.%X.conf",			  &vendor, &device, &subvendor, &subdevice,			  &bus) == 5) {		DBG("bus: %X", bus);	} else {		ERROR("unable to parse conf file name %s (%d)",		      conf_file_name, i);		return -EINVAL;	}	nr_settings = 0;	driver->nr_settings = 0;	if ((config = fopen(conf_file_name, "r")) == NULL) {		ERROR("unable to open config file: %s", strerror(errno));		return -EINVAL;	}	while (fgets(setting_line, SETTING_LEN-1, config)) {		struct load_device_setting *setting;		setting_line[SETTING_LEN-1] = 0;		ret = parse_setting_line(setting_line, setting_name,					 setting_value);		if (ret == 0)			continue;		if (ret < 0)			return -EINVAL;		setting = &driver->settings[nr_settings];		strncpy(setting->name, setting_name, MAX_SETTING_NAME_LEN);		strncpy(setting->value, setting_value, MAX_SETTING_VALUE_LEN);		nr_settings++;		if (nr_settings >= MAX_DEVICE_SETTINGS) {			ERROR("too many settings");			return -EINVAL;		}					}	fclose(config);	driver->nr_settings = nr_settings;	return 0;}static int load_bin_file(int ioctl_device, char *driver_name, char *file_name){	struct load_driver_file driver_file;	char lc_file_name[MAX_DRIVER_NAME_LEN];	int i;	DBG("loading driver %s", driver_name);	for (i = 0; file_name[i] && i < sizeof(lc_file_name); i++)		lc_file_name[i] = tolower(file_name[i]);	lc_file_name[i] = 0;	if (chdir(confdir) || chdir(driver_name)) {		ERROR("couldn't change to directory %s: %s",		      driver_name, strerror(errno));		return -EINVAL;	}	if (load_file(lc_file_name, &driver_file)) {		ERROR("couldn't open file %s", file_name);		return -EINVAL;	}	strncpy(driver_file.driver_name, driver_name,		sizeof(driver_file.driver_name));	if (ioctl(ioctl_device, WRAP_IOCTL_LOAD_BIN_FILE, &driver_file)) {		ERROR("couldn't upload bin file: %s", file_name);		return -EINVAL;	}	return 0;}/* * open a windows driver and pass it to the kernel module. * returns 0: on success, -1 on error */static int load_driver(int ioctl_device, char *driver_name, char *conf_file_name){	int i;	struct dirent *dirent;	struct load_driver *driver;	int nr_sys_files, nr_bin_files;	DIR *driver_dir;	driver_dir = NULL;	nr_sys_files = 0;	nr_bin_files = 0;	DBG("loading driver %s", driver_name);	if (chdir(confdir) || chdir(driver_name)) {		ERROR("couldn't change to directory %s: %s",		      driver_name, strerror(errno));		return -EINVAL;	}	if ((driver_dir = opendir(".")) == NULL) {		ERROR("couldn't open driver directory %s: %s",		      driver_name, strerror(errno));		return -EINVAL;	}			if ((driver = malloc(sizeof(*driver))) == NULL) {		ERROR("couldn't allocate memory for driver %s", driver_name);		goto err;	}	memset(driver, 0, sizeof(*driver));	strncpy(driver->name, driver_name, MAX_DRIVER_NAME_LEN);	if (read_conf_file(conf_file_name, driver) ||	    driver->nr_settings == 0) {		ERROR("couldn't read conf file %s for driver %s",		      conf_file_name, driver_name);		goto err;	}	while ((dirent = readdir(driver_dir))) {		int len;		struct stat statbuf;		if (dirent->d_name[0] == '.')			continue;		if (stat(dirent->d_name, &statbuf) ||		    !S_ISREG(statbuf.st_mode)) {			ERROR("%s in %s is not a valid file: %s",			      dirent->d_name, driver_name, strerror(errno));			continue;		}		len = strlen(dirent->d_name);		if (len > 4 &&		     strcasecmp(&dirent->d_name[len-4], ".inf") == 0)			continue;

⌨️ 快捷键说明

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