From 02fe5479e30781ae670ce5635ac78d8d4de9779c Mon Sep 17 00:00:00 2001 From: Automatic Build System Date: Sat, 6 Jan 2024 07:34:31 +0100 Subject: [PATCH] automatic version update by autodist [release 1.59-1mamba;Sun Dec 01 2013] --- README.md | 4 + ndiswrapper-1.58-kernel-3.10.patch | 701 +++++++++++++++++++++++++++++ ndiswrapper.spec | 163 +++++++ 3 files changed, 868 insertions(+) create mode 100644 ndiswrapper-1.58-kernel-3.10.patch create mode 100644 ndiswrapper.spec diff --git a/README.md b/README.md index 68dfdb7..9b94b7a 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # ndiswrapper +Some vendors do not release specifications of the hardware or provide a linux driver for their wireless network cards. +This project implements Windows kernel API and NDIS (Network Driver Interface Specification) API within Linux kernel. +A Windows driver for wireless network card is then linked to this implementation so that the driver runs natively, as though it is in Windows, without binary emulation. + diff --git a/ndiswrapper-1.58-kernel-3.10.patch b/ndiswrapper-1.58-kernel-3.10.patch new file mode 100644 index 0000000..10b7339 --- /dev/null +++ b/ndiswrapper-1.58-kernel-3.10.patch @@ -0,0 +1,701 @@ +From 89857ddd1aecc262c03b00e66baa1126707a962d Mon Sep 17 00:00:00 2001 +From: Christian Weber +Date: Sat, 3 Aug 2013 22:11:04 +0200 +Subject: [PATCH] - API change of 'add_taint()' as of kernel 3.9 - procfs API + change as of kernel 3.10 + +TODO: + - 'proc.c':443 and 'wrapndis.c':1775 + Are wnd->net_dev->name and wnd->procfs_iface->name always equal? + - 'proc.c': + Commented out error checking in procfs-callback-functions. + Seem to make no sense to me with the new API, maybe they are handled by seq_file internally? +--- + driver/loader.c | 2 +- + driver/proc.c | 355 ++++++++++++++++++++++++++++++------------------------ + driver/wrapndis.c | 7 +- + driver/wrapper.c | 2 +- + 4 files changed, 208 insertions(+), 158 deletions(-) + +diff --git a/driver/loader.c b/driver/loader.c +index 406e6ba..8ae53c1 100644 +--- a/driver/loader.c ++++ b/driver/loader.c +@@ -575,7 +575,7 @@ static int load_user_space_driver(struct load_driver *load_driver) + } else { + printk(KERN_INFO "%s: driver %s (%s) loaded\n", + DRIVER_NAME, wrap_driver->name, wrap_driver->version); +- add_taint(TAINT_PROPRIETARY_MODULE); ++ add_taint(TAINT_PROPRIETARY_MODULE, LOCKDEP_STILL_OK); + EXIT1(return 0); + } + } +diff --git a/driver/proc.c b/driver/proc.c +index 60ed0e0..11f0f8b 100644 +--- a/driver/proc.c ++++ b/driver/proc.c +@@ -13,6 +13,7 @@ + * + */ + #include ++#include + #include + #include + +@@ -24,116 +25,144 @@ + + #define MAX_PROC_STR_LEN 32 + +-static struct proc_dir_entry *wrap_procfs_entry; ++static struct proc_dir_entry *procfs_hw, ++ *procfs_stats, ++ *procfs_encr, ++ *procfs_settings, ++ *procfs_debug, ++ *wrap_procfs_entry; + +-static int procfs_read_ndis_stats(char *page, char **start, off_t off, +- int count, int *eof, void *data) ++/* stats */ ++ ++static int procfs_ndis_stats_show( struct seq_file *seqf, void *data) + { +- char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct ndis_wireless_stats stats; + NDIS_STATUS res; + ndis_rssi rssi; + +- if (off != 0) { ++ /*if (off != 0) { + *eof = 1; + return 0; +- } ++ }*/ + + res = mp_query(wnd, OID_802_11_RSSI, &rssi, sizeof(rssi)); + if (!res) +- p += sprintf(p, "signal_level=%d dBm\n", (s32)rssi); ++ seq_printf(seqf, "signal_level=%d dBm\n", (s32)rssi); + + res = mp_query(wnd, OID_802_11_STATISTICS, &stats, sizeof(stats)); + if (!res) { + +- p += sprintf(p, "tx_frames=%llu\n", stats.tx_frag); +- p += sprintf(p, "tx_multicast_frames=%llu\n", +- stats.tx_multi_frag); +- p += sprintf(p, "tx_failed=%llu\n", stats.failed); +- p += sprintf(p, "tx_retry=%llu\n", stats.retry); +- p += sprintf(p, "tx_multi_retry=%llu\n", stats.multi_retry); +- p += sprintf(p, "tx_rtss_success=%llu\n", stats.rtss_succ); +- p += sprintf(p, "tx_rtss_fail=%llu\n", stats.rtss_fail); +- p += sprintf(p, "ack_fail=%llu\n", stats.ack_fail); +- p += sprintf(p, "frame_duplicates=%llu\n", stats.frame_dup); +- p += sprintf(p, "rx_frames=%llu\n", stats.rx_frag); +- p += sprintf(p, "rx_multicast_frames=%llu\n", +- stats.rx_multi_frag); +- p += sprintf(p, "fcs_errors=%llu\n", stats.fcs_err); ++ seq_printf(seqf, "tx_frames=%llu\n", stats.tx_frag); ++ seq_printf(seqf, "tx_multicast_frames=%llu\n", stats.tx_multi_frag); ++ seq_printf(seqf, "tx_failed=%llu\n", stats.failed); ++ seq_printf(seqf, "tx_retry=%llu\n", stats.retry); ++ seq_printf(seqf, "tx_multi_retry=%llu\n", stats.multi_retry); ++ seq_printf(seqf, "tx_rtss_success=%llu\n", stats.rtss_succ); ++ seq_printf(seqf, "tx_rtss_fail=%llu\n", stats.rtss_fail); ++ seq_printf(seqf, "ack_fail=%llu\n", stats.ack_fail); ++ seq_printf(seqf, "frame_duplicates=%llu\n", stats.frame_dup); ++ seq_printf(seqf, "rx_frames=%llu\n", stats.rx_frag); ++ seq_printf(seqf, "rx_multicast_frames=%llu\n", stats.rx_multi_frag); ++ seq_printf(seqf, "fcs_errors=%llu\n", stats.fcs_err); + } + +- if (p - page > count) { ++ /* if (p - page > count) { + ERROR("wrote %td bytes (limit is %u)\n", + p - page, count); + *eof = 1; +- } ++ }*/ + +- return p - page; ++ return 0; + } + +-static int procfs_read_ndis_encr(char *page, char **start, off_t off, +- int count, int *eof, void *data) ++static int procfs_ndis_stats_open( struct inode *ino, struct file *f) ++{ ++ return single_open( f, procfs_ndis_stats_show, PDE_DATA( ino)); ++}; ++ ++static struct file_operations procfs_ndis_stats_ops = { ++ .open = procfs_ndis_stats_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release ++}; ++ ++ ++/* encr */ ++static int procfs_ndis_encr_show( struct seq_file *seqf, void *data) + { +- char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + int i, encr_status, auth_mode, infra_mode; + NDIS_STATUS res; + struct ndis_essid essid; + mac_address ap_address; + +- if (off != 0) { ++ /*if (off != 0) { + *eof = 1; + return 0; +- } ++ }*/ + + res = mp_query(wnd, OID_802_11_BSSID, + &ap_address, sizeof(ap_address)); + if (res) + memset(ap_address, 0, ETH_ALEN); +- p += sprintf(p, "ap_address=%2.2X", ap_address[0]); ++ seq_printf(seqf, "ap_address=%2.2X", ap_address[0]); + for (i = 1; i < ETH_ALEN; i++) +- p += sprintf(p, ":%2.2X", ap_address[i]); +- p += sprintf(p, "\n"); ++ seq_printf(seqf, ":%2.2X", ap_address[i]); ++ seq_printf(seqf, "\n"); + + res = mp_query(wnd, OID_802_11_SSID, &essid, sizeof(essid)); + if (!res) +- p += sprintf(p, "essid=%.*s\n", essid.length, essid.essid); ++ seq_printf(seqf, "essid=%.*s\n", essid.length, essid.essid); + + res = mp_query_int(wnd, OID_802_11_ENCRYPTION_STATUS, &encr_status); + if (!res) { + typeof(&wnd->encr_info.keys[0]) tx_key; +- p += sprintf(p, "tx_key=%u\n", wnd->encr_info.tx_key_index); +- p += sprintf(p, "key="); ++ seq_printf(seqf, "tx_key=%u\n", wnd->encr_info.tx_key_index); ++ seq_printf(seqf, "key="); + tx_key = &wnd->encr_info.keys[wnd->encr_info.tx_key_index]; + if (tx_key->length > 0) + for (i = 0; i < tx_key->length; i++) +- p += sprintf(p, "%2.2X", tx_key->key[i]); ++ seq_printf(seqf, "%2.2X", tx_key->key[i]); + else +- p += sprintf(p, "off"); +- p += sprintf(p, "\n"); +- p += sprintf(p, "encr_mode=%d\n", encr_status); ++ seq_printf(seqf, "off"); ++ seq_printf(seqf, "\n"); ++ seq_printf(seqf, "encr_mode=%d\n", encr_status); + } + res = mp_query_int(wnd, OID_802_11_AUTHENTICATION_MODE, &auth_mode); + if (!res) +- p += sprintf(p, "auth_mode=%d\n", auth_mode); ++ seq_printf(seqf, "auth_mode=%d\n", auth_mode); + res = mp_query_int(wnd, OID_802_11_INFRASTRUCTURE_MODE, &infra_mode); +- p += sprintf(p, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ? ++ seq_printf(seqf, "mode=%s\n", (infra_mode == Ndis802_11IBSS) ? + "adhoc" : (infra_mode == Ndis802_11Infrastructure) ? + "managed" : "auto"); +- if (p - page > count) { ++ /*if (p - page > count) { + WARNING("wrote %td bytes (limit is %u)", + p - page, count); + *eof = 1; +- } ++ }*/ + +- return p - page; ++ return 0; + } + +-static int procfs_read_ndis_hw(char *page, char **start, off_t off, +- int count, int *eof, void *data) ++static int procfs_ndis_encr_open( struct inode *ino, struct file *f) ++{ ++ return single_open( f, procfs_ndis_encr_show, PDE_DATA( ino)); ++}; ++ ++static struct file_operations procfs_ndis_encr_ops = { ++ .open = procfs_ndis_encr_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release ++}; ++ ++ ++/* hw */ ++ ++static int procfs_ndis_hw_show( struct seq_file *seqf, void *data) + { +- char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct ndis_configuration config; + enum ndis_power power_mode; +@@ -149,54 +178,51 @@ static int procfs_read_ndis_hw(char *page, char **start, off_t off, + char *hw_status[] = {"ready", "initializing", "resetting", "closing", + "not ready"}; + +- if (off != 0) { ++ /*if (off != 0) { + *eof = 1; + return 0; +- } ++ }*/ + + res = mp_query_int(wnd, OID_GEN_HARDWARE_STATUS, &n); + if (res == NDIS_STATUS_SUCCESS && n >= 0 && n < ARRAY_SIZE(hw_status)) +- p += sprintf(p, "status=%s\n", hw_status[n]); ++ seq_printf(seqf, "status=%s\n", hw_status[n]); + + res = mp_query(wnd, OID_802_3_CURRENT_ADDRESS, mac, sizeof(mac)); + if (!res) +- p += sprintf(p, "mac: " MACSTRSEP "\n", MAC2STR(mac)); ++ seq_printf(seqf, "mac: " MACSTRSEP "\n", MAC2STR(mac)); + res = mp_query(wnd, OID_802_11_CONFIGURATION, &config, sizeof(config)); + if (!res) { +- p += sprintf(p, "beacon_period=%u msec\n", ++ seq_printf(seqf, "beacon_period=%u msec\n", + config.beacon_period); +- p += sprintf(p, "atim_window=%u msec\n", config.atim_window); +- p += sprintf(p, "frequency=%u kHz\n", config.ds_config); +- p += sprintf(p, "hop_pattern=%u\n", +- config.fh_config.hop_pattern); +- p += sprintf(p, "hop_set=%u\n", +- config.fh_config.hop_set); +- p += sprintf(p, "dwell_time=%u msec\n", +- config.fh_config.dwell_time); ++ seq_printf(seqf, "atim_window=%u msec\n", config.atim_window); ++ seq_printf(seqf, "frequency=%u kHz\n", config.ds_config); ++ seq_printf(seqf, "hop_pattern=%u\n", config.fh_config.hop_pattern); ++ seq_printf(seqf, "hop_set=%u\n", config.fh_config.hop_set); ++ seq_printf(seqf, "dwell_time=%u msec\n", config.fh_config.dwell_time); + } + + res = mp_query(wnd, OID_802_11_TX_POWER_LEVEL, + &tx_power, sizeof(tx_power)); + if (!res) +- p += sprintf(p, "tx_power=%u mW\n", tx_power); ++ seq_printf(seqf, "tx_power=%u mW\n", tx_power); + + res = mp_query(wnd, OID_GEN_LINK_SPEED, &bit_rate, sizeof(bit_rate)); + if (!res) +- p += sprintf(p, "bit_rate=%u kBps\n", (u32)bit_rate / 10); ++ seq_printf(seqf, "bit_rate=%u kBps\n", (u32)bit_rate / 10); + + res = mp_query(wnd, OID_802_11_RTS_THRESHOLD, + &rts_threshold, sizeof(rts_threshold)); + if (!res) +- p += sprintf(p, "rts_threshold=%u bytes\n", rts_threshold); ++ seq_printf(seqf, "rts_threshold=%u bytes\n", rts_threshold); + + res = mp_query(wnd, OID_802_11_FRAGMENTATION_THRESHOLD, + &frag_threshold, sizeof(frag_threshold)); + if (!res) +- p += sprintf(p, "frag_threshold=%u bytes\n", frag_threshold); ++ seq_printf(seqf, "frag_threshold=%u bytes\n", frag_threshold); + + res = mp_query_int(wnd, OID_802_11_POWER_MODE, &power_mode); + if (!res) +- p += sprintf(p, "power_mode=%s\n", ++ seq_printf(seqf, "power_mode=%s\n", + (power_mode == NDIS_POWER_OFF) ? "always_on" : + (power_mode == NDIS_POWER_MAX) ? + "max_savings" : "min_savings"); +@@ -204,19 +230,19 @@ static int procfs_read_ndis_hw(char *page, char **start, off_t off, + res = mp_query(wnd, OID_802_11_NUMBER_OF_ANTENNAS, + &antenna, sizeof(antenna)); + if (!res) +- p += sprintf(p, "num_antennas=%u\n", antenna); ++ seq_printf(seqf, "num_antennas=%u\n", antenna); + + res = mp_query(wnd, OID_802_11_TX_ANTENNA_SELECTED, + &antenna, sizeof(antenna)); + if (!res) +- p += sprintf(p, "tx_antenna=%u\n", antenna); ++ seq_printf(seqf, "tx_antenna=%u\n", antenna); + + res = mp_query(wnd, OID_802_11_RX_ANTENNA_SELECTED, + &antenna, sizeof(antenna)); + if (!res) +- p += sprintf(p, "rx_antenna=%u\n", antenna); ++ seq_printf(seqf, "rx_antenna=%u\n", antenna); + +- p += sprintf(p, "encryption_modes=%s%s%s%s%s%s%s\n", ++ seq_printf(seqf, "encryption_modes=%s%s%s%s%s%s%s\n", + test_bit(Ndis802_11Encryption1Enabled, &wnd->capa.encr) ? + "WEP" : "none", + +@@ -239,57 +265,70 @@ static int procfs_read_ndis_hw(char *page, char **start, off_t off, + if (packet_filter != wnd->packet_filter) + WARNING("wrong packet_filter? 0x%08x, 0x%08x\n", + packet_filter, wnd->packet_filter); +- p += sprintf(p, "packet_filter: 0x%08x\n", packet_filter); ++ seq_printf(seqf, "packet_filter: 0x%08x\n", packet_filter); + } +- if (p - page > count) { ++ /*if (p - page > count) { + WARNING("wrote %td bytes (limit is %u)", + p - page, count); + *eof = 1; +- } ++ }*/ + +- return p - page; ++ return 0; + } + +-static int procfs_read_ndis_settings(char *page, char **start, off_t off, +- int count, int *eof, void *data) ++static int procfs_ndis_hw_open( struct inode *ino, struct file *f) ++{ ++ return single_open( f, procfs_ndis_hw_show, PDE_DATA( ino)); ++}; ++ ++static struct file_operations procfs_ndis_hw_ops = { ++ .open = procfs_ndis_hw_open, ++ .read = seq_read, ++ .llseek = seq_lseek, ++ .release = seq_release ++}; ++ ++ ++/* settings */ ++ ++static int procfs_ndis_settings_show( struct seq_file *seqf, void *data) + { +- char *p = page; + struct ndis_device *wnd = (struct ndis_device *)data; + struct wrap_device_setting *setting; + +- if (off != 0) { ++ /*if (off != 0) { + *eof = 1; + return 0; +- } ++ }*/ + +- p += sprintf(p, "hangcheck_interval=%d\n", ++ seq_printf(seqf, "hangcheck_interval=%d\n", + hangcheck_interval == 0 ? + (wnd->hangcheck_interval / HZ) : -1); + + list_for_each_entry(setting, &wnd->wd->settings, list) { +- p += sprintf(p, "%s=%s\n", setting->name, setting->value); ++ seq_printf(seqf, "%s=%s\n", setting->name, setting->value); + } + + list_for_each_entry(setting, &wnd->wd->driver->settings, list) { +- p += sprintf(p, "%s=%s\n", setting->name, setting->value); ++ seq_printf(seqf, "%s=%s\n", setting->name, setting->value); + } + +- return p - page; ++ return 0; + } + + static int procfs_write_ndis_settings(struct file *file, const char __user *buf, +- unsigned long count, void *data) ++ size_t size, loff_t *ppos) + { +- struct ndis_device *wnd = (struct ndis_device *)data; ++ struct ndis_device *wnd = (struct ndis_device *)PDE_DATA( file->f_inode); + char setting[MAX_PROC_STR_LEN], *p; + unsigned int i; + NDIS_STATUS res; + +- if (count > MAX_PROC_STR_LEN) ++ if (size > MAX_PROC_STR_LEN) + return -EINVAL; + + memset(setting, 0, sizeof(setting)); +- if (copy_from_user(setting, buf, count)) ++ if (copy_from_user(setting, buf, size)) + return -EFAULT; + + if ((p = strchr(setting, '\n'))) +@@ -377,18 +416,35 @@ static int procfs_write_ndis_settings(struct file *file, const char __user *buf, + if (res != NDIS_STATUS_SUCCESS) + return -EFAULT; + } +- return count; ++ return size; + } + +-int wrap_procfs_add_ndis_device(struct ndis_device *wnd) ++static int procfs_ndis_settings_open( struct inode *ino, struct file *f) + { +- struct proc_dir_entry *procfs_entry; ++ return single_open( f, procfs_ndis_settings_show, PDE_DATA( ino)); ++}; ++ ++static struct file_operations procfs_ndis_settings_ops = { ++ .open = procfs_ndis_settings_open, ++ .read = seq_read, ++ .write = procfs_write_ndis_settings, ++ .llseek = seq_lseek, ++ .release = seq_release ++}; ++ + ++int wrap_procfs_add_ndis_device(struct ndis_device *wnd) ++{ + if (wrap_procfs_entry == NULL) + return -ENOMEM; + + if (wnd->procfs_iface) { +- ERROR("%s already registered?", wnd->procfs_iface->name); ++ ERROR("%s already registered?", wnd->net_dev->name); ++/* NEEDS CLARIFICATION: ++ * 'wnd->procfs_iface->name' changed to 'wnd->net_dev_name', as the 'proc_dir_entry'-struct ++ * is now opaque. ++ * Are they always the same? ++ */ + return -EINVAL; + } + wnd->procfs_iface = proc_mkdir(wnd->net_dev->name, wrap_procfs_entry); +@@ -396,68 +452,51 @@ int wrap_procfs_add_ndis_device(struct ndis_device *wnd) + ERROR("couldn't create proc directory"); + return -ENOMEM; + } +- wnd->procfs_iface->uid = proc_uid; +- wnd->procfs_iface->gid = proc_gid; ++ proc_set_user( wnd->procfs_iface, proc_uid, proc_gid); + +- procfs_entry = create_proc_entry("hw", S_IFREG | S_IRUSR | S_IRGRP, +- wnd->procfs_iface); +- if (procfs_entry == NULL) { ++ procfs_hw = proc_create_data("hw", S_IFREG | S_IRUSR | S_IRGRP, wnd->procfs_iface, &procfs_ndis_hw_ops, wnd); ++ if (procfs_hw == NULL) { + ERROR("couldn't create proc entry for 'hw'"); + goto err_hw; + } else { +- procfs_entry->uid = proc_uid; +- procfs_entry->gid = proc_gid; +- procfs_entry->data = wnd; +- procfs_entry->read_proc = procfs_read_ndis_hw; ++ proc_set_user( procfs_hw, proc_uid, proc_gid); + } + +- procfs_entry = create_proc_entry("stats", S_IFREG | S_IRUSR | S_IRGRP, +- wnd->procfs_iface); +- if (procfs_entry == NULL) { ++ procfs_stats = proc_create_data("stats", S_IFREG | S_IRUSR | S_IRGRP, wnd->procfs_iface, &procfs_ndis_stats_ops, wnd); ++ if (procfs_stats == NULL) { + ERROR("couldn't create proc entry for 'stats'"); + goto err_stats; + } else { +- procfs_entry->uid = proc_uid; +- procfs_entry->gid = proc_gid; +- procfs_entry->data = wnd; +- procfs_entry->read_proc = procfs_read_ndis_stats; ++ proc_set_user( procfs_stats, proc_uid, proc_gid); + } + +- procfs_entry = create_proc_entry("encr", S_IFREG | S_IRUSR | S_IRGRP, +- wnd->procfs_iface); +- if (procfs_entry == NULL) { ++ procfs_encr = proc_create_data("encr", S_IFREG | S_IRUSR | S_IRGRP, wnd->procfs_iface, &procfs_ndis_encr_ops, wnd); ++ if (procfs_encr == NULL) { + ERROR("couldn't create proc entry for 'encr'"); + goto err_encr; + } else { +- procfs_entry->uid = proc_uid; +- procfs_entry->gid = proc_gid; +- procfs_entry->data = wnd; +- procfs_entry->read_proc = procfs_read_ndis_encr; ++ proc_set_user( procfs_encr, proc_uid, proc_gid); + } + +- procfs_entry = create_proc_entry("settings", S_IFREG | ++ procfs_settings = proc_create_data("settings", S_IFREG | + S_IRUSR | S_IRGRP | +- S_IWUSR | S_IWGRP, wnd->procfs_iface); +- if (procfs_entry == NULL) { ++ S_IWUSR | S_IWGRP, wnd->procfs_iface, &procfs_ndis_settings_ops, wnd); ++ if (procfs_settings == NULL) { + ERROR("couldn't create proc entry for 'settings'"); + goto err_settings; + } else { +- procfs_entry->uid = proc_uid; +- procfs_entry->gid = proc_gid; +- procfs_entry->data = wnd; +- procfs_entry->read_proc = procfs_read_ndis_settings; +- procfs_entry->write_proc = procfs_write_ndis_settings; ++ proc_set_user( procfs_settings, proc_uid, proc_gid); + } + return 0; + + err_settings: +- remove_proc_entry("encr", wnd->procfs_iface); ++ proc_remove( procfs_encr); + err_encr: +- remove_proc_entry("stats", wnd->procfs_iface); ++ proc_remove( procfs_stats); + err_stats: +- remove_proc_entry("hw", wnd->procfs_iface); ++ proc_remove( procfs_hw); + err_hw: +- remove_proc_entry(wnd->procfs_iface->name, wrap_procfs_entry); ++ proc_remove( wnd->procfs_iface); + wnd->procfs_iface = NULL; + return -ENOMEM; + } +@@ -468,46 +507,45 @@ void wrap_procfs_remove_ndis_device(struct ndis_device *wnd) + + if (procfs_iface == NULL) + return; +- remove_proc_entry("hw", procfs_iface); +- remove_proc_entry("stats", procfs_iface); +- remove_proc_entry("encr", procfs_iface); +- remove_proc_entry("settings", procfs_iface); ++ proc_remove( procfs_hw); ++ proc_remove( procfs_stats); ++ proc_remove( procfs_encr); ++ proc_remove( procfs_settings); + if (wrap_procfs_entry) +- remove_proc_entry(procfs_iface->name, wrap_procfs_entry); ++ proc_remove( procfs_iface); + } + +-static int procfs_read_debug(char *page, char **start, off_t off, +- int count, int *eof, void *data) ++/* debug */ ++static int procfs_debug_show( struct seq_file *seqf, void *data) + { +- char *p = page; + #if ALLOC_DEBUG + enum alloc_type type; + #endif + +- if (off != 0) { ++ /*if (off != 0) { + *eof = 1; + return 0; +- } +- p += sprintf(p, "%d\n", debug); ++ }*/ ++ seq_printf(seqf, "%d\n", debug); + #if ALLOC_DEBUG + for (type = 0; type < ALLOC_TYPE_MAX; type++) +- p += sprintf(p, "total size of allocations in %s: %d\n", ++ seq_printf(seqf, "total size of allocations in %s: %d\n", + alloc_type_name[type], alloc_size(type)); + #endif +- return p - page; ++ return 0; + } + + static int procfs_write_debug(struct file *file, const char __user *buf, +- unsigned long count, void *data) ++ size_t size, loff_t *ppos) + { + int i; + char setting[MAX_PROC_STR_LEN], *p; + +- if (count > MAX_PROC_STR_LEN) ++ if (size > MAX_PROC_STR_LEN) + return -EINVAL; + + memset(setting, 0, sizeof(setting)); +- if (copy_from_user(setting, buf, count)) ++ if (copy_from_user(setting, buf, size)) + return -EFAULT; + + if ((p = strchr(setting, '\n'))) +@@ -521,31 +559,38 @@ static int procfs_write_debug(struct file *file, const char __user *buf, + debug = i; + else + return -EINVAL; +- return count; ++ return size; + } + +-int wrap_procfs_init(void) ++static int procfs_debug_open( struct inode *ino, struct file *f) + { +- struct proc_dir_entry *procfs_entry; ++ return single_open( f, procfs_debug_show, NULL); ++}; ++ ++static struct file_operations procfs_debug_ops = { ++ .open = procfs_debug_open, ++ .read = seq_read, ++ .write = procfs_write_debug, ++ .llseek = seq_lseek, ++ .release = seq_release ++}; + ++int wrap_procfs_init(void) ++{ + wrap_procfs_entry = proc_mkdir(DRIVER_NAME, proc_net_root); + if (wrap_procfs_entry == NULL) { + ERROR("couldn't create procfs directory"); + return -ENOMEM; + } +- wrap_procfs_entry->uid = proc_uid; +- wrap_procfs_entry->gid = proc_gid; ++ proc_set_user( wrap_procfs_entry, proc_uid, proc_gid); + +- procfs_entry = create_proc_entry("debug", S_IFREG | S_IRUSR | S_IRGRP, +- wrap_procfs_entry); +- if (procfs_entry == NULL) { ++ procfs_debug = proc_create("debug", S_IFREG | S_IRUSR | S_IRGRP, ++ wrap_procfs_entry, &procfs_debug_ops); ++ if (procfs_debug == NULL) { + ERROR("couldn't create proc entry for 'debug'"); + return -ENOMEM; + } else { +- procfs_entry->uid = proc_uid; +- procfs_entry->gid = proc_gid; +- procfs_entry->read_proc = procfs_read_debug; +- procfs_entry->write_proc = procfs_write_debug; ++ proc_set_user( procfs_debug, proc_uid, proc_gid); + } + return 0; + } +@@ -554,6 +599,6 @@ void wrap_procfs_remove(void) + { + if (wrap_procfs_entry == NULL) + return; +- remove_proc_entry("debug", wrap_procfs_entry); +- remove_proc_entry(DRIVER_NAME, proc_net_root); ++ proc_remove( procfs_debug); ++ proc_remove( wrap_procfs_entry); + } +diff --git a/driver/wrapndis.c b/driver/wrapndis.c +index 7bb9568..43074f4 100644 +--- a/driver/wrapndis.c ++++ b/driver/wrapndis.c +@@ -1771,7 +1771,12 @@ static int notifier_event(struct notifier_block *notifier, unsigned long event, + if (likely(wnd->procfs_iface)) { + printk(KERN_INFO "%s: changing interface name from " + "'%s' to '%s'\n", DRIVER_NAME, +- wnd->procfs_iface->name, net_dev->name); ++ wnd->net_dev->name, net_dev->name); ++/* NEEDS CLARIFICATION: ++ * 'wnd->procfs_iface->name' changed to 'wnd->net_dev_name', as the 'proc_dir_entry'-struct ++ * is now opaque. ++ * Are they always the same? ++ */ + wrap_procfs_remove_ndis_device(wnd); + wrap_procfs_add_ndis_device(wnd); + } +diff --git a/driver/wrapper.c b/driver/wrapper.c +index f77c879..19a3249 100644 +--- a/driver/wrapper.c ++++ b/driver/wrapper.c +@@ -72,7 +72,7 @@ static void module_cleanup(void) + static int __init wrapper_init(void) + { + #ifdef TAINT_OOT_MODULE +- add_taint(TAINT_OOT_MODULE); ++ add_taint(TAINT_OOT_MODULE, LOCKDEP_STILL_OK); + #endif + printk(KERN_INFO "%s version %s loaded (smp=%s, preempt=%s)\n", + DRIVER_NAME, DRIVER_VERSION, +-- +1.8.3.4 + diff --git a/ndiswrapper.spec b/ndiswrapper.spec new file mode 100644 index 0000000..c0ce5a0 --- /dev/null +++ b/ndiswrapper.spec @@ -0,0 +1,163 @@ +Name: ndiswrapper +Epoch: 5 +Version: 1.59 +Release: 1mamba +Summary: Ndis driver wrapper for the Linux kernel +Group: System/Kernel and Hardware +Vendor: openmamba +Distribution: openmamba +Packager: Silvan Calarco +URL: http://ndiswrapper.sourceforge.net/ +Source: http://downloads.sourceforge.net/ndiswrapper/ndiswrapper-%{version}.tar.gz +Patch0: ndiswrapper-1.58-kernel-3.10.patch +License: GPL +## AUTOBUILDREQ-BEGIN +BuildRequires: glibc-devel +BuildRequires: perl-devel +## AUTOBUILDREQ-END +Requires(post):dkms +Obsoletes: kernel-mamba-64GB-nongpl-ndiswrapper +Obsoletes: kernel-mamba-64GB-rt-nongpl-ndiswrapper +Obsoletes: kernel-mamba-nongpl-ndiswrapper +Obsoletes: kernel-mamba-rt-nongpl-ndiswrapper +Provides: kernelwireless +BuildRoot: %{_tmppath}/%{name}-%{version}-root + +%description +Some vendors do not release specifications of the hardware or provide a linux driver for their wireless network cards. +This project implements Windows kernel API and NDIS (Network Driver Interface Specification) API within Linux kernel. +A Windows driver for wireless network card is then linked to this implementation so that the driver runs natively, as though it is in Windows, without binary emulation. + +%prep +%setup -q +#%patch0 -p1 + +%build +%make -C utils + +%install +[ "%{buildroot}" != / ] && rm -rf "%{buildroot}" +# build/install ndiswrapper driver and tools +# FIXME: +# WARNING: This kernel seems to use 4K stack size option (CONFIG_4KSTACKS); +# any Windows drivers will not work with this option enabled. +# Disable CONFIG_4KSTACKS option, recompile and install kernel + +%makeinstall -C utils +#% makeinstall \ +# %{BUILD_OPTS} \ +# DIST_DESTDIR=%{buildroot} \ +# KVERS=%{kernel_version}%{?KERNEL_TARGET} \ +# KBUILD=%{_prefix}/src/linux-%{kernel_version}%{?KERNEL_TARGET} \ +# INST_DIR=/lib/modules/%{kernel_version}%{?KERNEL_TARGET}/kernel/drivers/net/wireless + +# dkms +install -d -m0755 %{buildroot}%{_prefix}/src/%{name}-%{version} +cp -a driver/* %{buildroot}%{_prefix}/src/%{name}-%{version} +cat > %{buildroot}%{_prefix}/src/%{name}-%{version}/dkms.conf << _EOF +PACKAGE_NAME=%{name} +PACKAGE_VERSION=%{version} +MAKE="make -C \${kernel_source_dir} SUBDIRS=\${dkms_tree}/\${PACKAGE_NAME}/\${PACKAGE_VERSION}/build modules" +CLEAN="make -C \${kernel_source_dir} SUBDIRS=\${dkms_tree}/\${PACKAGE_NAME}/\${PACKAGE_VERSION}/build clean" +BUILT_MODULE_NAME=\${PACKAGE_NAME} +BUILT_MODULE_LOCATION=. +DEST_MODULE_LOCATION=/extra/drivers/net/ +REMAKE_INITRD=no +AUTOINSTALL=yes +_EOF + +install -D -m 644 ndiswrapper.8 %{buildroot}%{_mandir}/man8/ndiswrapper.8 +install -D -m 644 loadndisdriver.8 %{buildroot}%{_mandir}/man8/loadndisdriver.8 + +#install -m 0755 -d %{buildroot}%{_sysconfdir}/modules.d +#echo "ndiswrapper" > %{buildroot}%{_sysconfdir}/modules.d/ndiswrapper.conf + +%clean +[ "%{buildroot}" != / ] && rm -rf "%{buildroot}" + +%preun +dkms remove -q -m %{name} -v %{version} --all --rpm_safe_upgrade +: + +%posttrans +if [ $1 -ge 1 ]; then + # clean any legacy alternatives symlink + dkms remove -q -m %{name} -v %{version} --all --rpm_safe_upgrade + dkms add -q -m %{name} -v %{version} + dkms install -q -m %{name} -v %{version} +fi +: + +%files +%defattr(-,root,root) +%dir %{_prefix}/src/%{name}-%{version} +%{_prefix}/src/%{name}-%{version}/* +/sbin/loadndisdriver +%{_sbindir}/ndiswrapper +%{_sbindir}/ndiswrapper-buginfo +%{_mandir}/man8/loadndisdriver.8* +%{_mandir}/man8/ndiswrapper.8* +%doc AUTHORS +# ChangeLog README + +%changelog +* Sun Dec 01 2013 Automatic Build System 1.59-1mamba +- automatic version update by autodist + +* Sun Sep 15 2013 Silvan Calarco 1.58-1mamba +- update to 1.58 +- dkms switch + +* Fri Jan 04 2013 Silvan Calarco 1.58rc1-3mamba +- kernel 3.4 rebuild + +* Sat Oct 27 2012 Silvan Calarco 1.58rc1-2mamba +- kernel 3.6 rebuild + +* Sat Sep 08 2012 Silvan Calarco 1.58rc1-1mamba +- update to 1.58rc1 + +* Sun Feb 12 2012 Silvan Calarco 1.57-2mamba +- automatic update by autodist + +* Wed Jan 25 2012 Silvan Calarco 1.57-1mamba +- update to 1.57 + +* Sun Sep 04 2011 Silvan Calarco 1.56-8mamba +- automatic update by autodist + +* Fri Aug 19 2011 Silvan Calarco 1.56-7mamba +- automatic update by autodist + +* Wed Apr 20 2011 Silvan Calarco 1.56-6mamba +- kernel 2.6.38 rebuild + +* Mon Feb 07 2011 Silvan Calarco 1.56-5mamba +- automatic update by autodist + +* Thu Dec 16 2010 Silvan Calarco 1.56-4mamba +- automatic rebuild by autodist + +* Wed Jun 30 2010 Silvan Calarco 1.56-3mamba +- automatic rebuild by autodist + +* Sun Apr 18 2010 Automatic Build System 1.56-2mamba +- automatic update to 1.56 by autodist + +* Fri Mar 12 2010 Automatic Build System 1.56-1mamba +- automatic update to 1.56 by autodist + +* Sat Dec 26 2009 Silvan Calarco 1.55-5mamba +- automatic rebuild by autodist + +* Sat Nov 14 2009 Automatic Build System 1.55-4mamba +- automatic update to 1.55 by autodist + +* Wed Nov 04 2009 Silvan Calarco 1.55-3mamba +- epoch incremented for update from old package version 2.6.30 + +* Tue Sep 01 2009 Automatic Build System 1.55-2mamba +- automatic update to 1.55 by autodist + +* Sun Aug 02 2009 Silvan Calarco 1.55-1mamba +- first build as standalone package