ndis(4): remove as previous announced

nids(4) was a clever idea in the early 2000's when the market was
flooded with 10/100 NICs with Windows-only drivers, but that hasn't been
the case for ages and the driver has had no meaningful maintenance in
ages. It only supports Windows-XP era drivers.

Also remove:
 - ndis support from wpa_supplicant
 - ndiscvt(8)

Reviewed By:	emaste, bcr (manpages)
Differential Revision:	https://reviews.freebsd.org/D27609
This commit is contained in:
Brooks Davis 2021-01-25 21:45:03 +00:00 committed by Brooks Davis
parent 1b109c69ed
commit bfc99943b0
53 changed files with 11 additions and 26392 deletions

View File

@ -36,6 +36,15 @@
# xargs -n1 | sort | uniq -d;
# done
# 20210125: ndis driver support removed
OLD_FILES+=usr/sbin/ndiscvt
OLD_FILES+=usr/sbin/ndisgen
OLD_FILES+=usr/share/man/man4/ndis.4.gz
OLD_FILES+=usr/share/man/man4/if_ndis.4.gz
OLD_FILES+=usr/share/man/man8/ndiscvt.8.gz
OLD_FILES+=usr/share/man/man8/ndisgen.8.gz
OLD_FILES+=usr/share/misc/windrv_stub.c
# 20210116: if_wl_wavelan.h removed
.if ${TARGET_ARCH} == "i386"
OLD_FILES+=usr/include/machine/if_wl_wavelan.h

View File

@ -325,7 +325,6 @@ MAN= aac.4 \
mx25l.4 \
mxge.4 \
my.4 \
${_ndis.4} \
net80211.4 \
netdump.4 \
netfpga10g_nf10bmac.4 \
@ -715,7 +714,6 @@ MLINKS+=msk.4 if_msk.4
MLINKS+=mwl.4 if_mwl.4
MLINKS+=mxge.4 if_mxge.4
MLINKS+=my.4 if_my.4
MLINKS+=${_ndis.4} ${_if_ndis.4}
MLINKS+=netfpga10g_nf10bmac.4 if_nf10bmac.4
MLINKS+=netintro.4 net.4 \
netintro.4 networking.4
@ -815,7 +813,6 @@ _hwpstate_intel.4= hwpstate_intel.4
_i8254.4= i8254.4
_ichwd.4= ichwd.4
_if_bxe.4= if_bxe.4
_if_ndis.4= if_ndis.4
_if_nfe.4= if_nfe.4
_if_urtw.4= if_urtw.4
_if_vmx.4= if_vmx.4
@ -826,7 +823,6 @@ _io.4= io.4
_itwd.4= itwd.4
_linux.4= linux.4
_nda.4= nda.4
_ndis.4= ndis.4
_nfe.4= nfe.4
_nfsmb.4= nfsmb.4
_if_ntb.4= if_ntb.4

View File

@ -1,155 +0,0 @@
.\" Copyright (c) 2003
.\" Bill Paul <wpaul@windriver.com>. All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Bill Paul.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd March 14, 2010
.Dt NDIS 4
.Os
.Sh NAME
.Nm ndis
.Nd NDIS miniport driver wrapper
.Sh SYNOPSIS
.Cd "options NDISAPI"
.Cd "device ndis"
.Cd "device wlan"
.Sh DESCRIPTION
The
.Nm
driver is a wrapper designed to allow binary
.Tn Windows\[rg]
NDIS miniport
network drivers to be used with
.Fx .
The
.Nm
driver is provided in source code form and must be combined with
the
.Tn Windows\[rg]
driver supplied with your network adapter.
The
.Nm
driver uses the
.Nm ndisapi
kernel subsystem to relocate and link the
.Tn Windows\[rg]
binary so
that it can be used in conjunction with native code.
The
.Nm ndisapi
subsystem provides an interface between the NDIS API and the
.Fx
networking infrastructure.
The
.Tn Windows\[rg]
driver is essentially
fooled into thinking it is running on
.Tn Windows\[rg] .
Note that this
means the
.Nm
driver is only useful on x86 machines.
.Pp
To build a functional driver, the user must have a copy of the
driver distribution media for his or her card.
From this distribution,
the user must extract two files: the
.Pa .SYS
file containing the driver
binary code, and its companion
.Pa .INF
file, which contains the
definitions for driver-specific registry keys and other installation
data such as device identifiers.
These two files can be converted
into a kernel module file using the
.Xr ndisgen 8
utility.
This file contains a binary image of the driver plus
registry key data.
When the
.Nm
driver loads, it will create
.Xr sysctl 3
nodes for each registry key extracted from the
.Pa .INF
file.
.Pp
The
.Nm
driver is designed to support mainly Ethernet and wireless
network devices with PCI and USB bus attachments.
(Cardbus devices are also supported as PCI.)
It can
support many different media types and speeds.
One limitation
however, is that there is no consistent way to learn if an
Ethernet device is operating in full or half duplex mode.
The NDIS API allows for a generic means for determining link
state and speed, but not the duplex setting.
There may be
driver-specific registry keys to control the media setting
which can be configured via the
.Xr sysctl 8
command.
.Sh DEPRECATION NOTICE
This driver is scheduled for removal prior to the release of
.Fx 14.0
.Sh DIAGNOSTICS
.Bl -diag
.It "ndis%d: watchdog timeout"
A packet was queued for transmission and a transmit command was
issued, however the device failed to acknowledge the transmission
before a timeout expired.
.El
.Sh SEE ALSO
.Xr altq 4 ,
.Xr arp 4 ,
.Xr netintro 4 ,
.Xr ng_ether 4 ,
.Xr ifconfig 8 ,
.Xr ndis_events 8 ,
.Xr ndiscvt 8 ,
.Xr ndisgen 8 ,
.Xr wpa_supplicant 8
.Rs
.%T "NDIS 5.1 specification"
.%U http://www.microsoft.com
.Re
.Sh HISTORY
The
.Nm
device driver first appeared in
.Fx 5.3 .
.Sh AUTHORS
The
.Nm
driver was written by
.An Bill Paul Aq Mt wpaul@windriver.com .

View File

@ -1,49 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _CFG_VAR_H_
#define _CFG_VAR_H_
struct ndis_cfg {
char *nc_cfgkey;
char *nc_cfgdesc;
char nc_val[256];
int nc_idx;
};
typedef struct ndis_cfg ndis_cfg;
#endif /* _CFG_VAR_H_ */

View File

@ -1,55 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _HAL_VAR_H_
#define _HAL_VAR_H_
#define NDIS_BUS_SPACE_IO X86_BUS_SPACE_IO
#define NDIS_BUS_SPACE_MEM X86_BUS_SPACE_MEM
extern image_patch_table hal_functbl[];
__BEGIN_DECLS
extern int hal_libinit(void);
extern int hal_libfini(void);
extern uint8_t KfAcquireSpinLock(kspin_lock *);
extern void KfReleaseSpinLock(kspin_lock *, uint8_t);
extern uint8_t KfRaiseIrql(uint8_t);
extern void KfLowerIrql(uint8_t);
extern uint8_t KeGetCurrentIrql(void);
__END_DECLS
#endif /* _HAL_VAR_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,555 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _PE_VAR_H_
#define _PE_VAR_H_
/*
* Image Format
*/
#define IMAGE_DOS_SIGNATURE 0x5A4D /* MZ */
#define IMAGE_OS2_SIGNATURE 0x454E /* NE */
#define IMAGE_OS2_SIGNATURE_LE 0x454C /* LE */
#define IMAGE_VXD_SIGNATURE 0x454C /* LE */
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
/*
* All PE files have one of these, just so if you attempt to
* run them, they'll print out a message telling you they can
* only be run in Windows.
*/
struct image_dos_header {
uint16_t idh_magic; /* Magic number */
uint16_t idh_cblp; /* Bytes on last page of file */
uint16_t idh_cp; /* Pages in file */
uint16_t idh_crlc; /* Relocations */
uint16_t idh_cparhdr; /* Size of header in paragraphs */
uint16_t idh_minalloc; /* Minimum extra paragraphs needed */
uint16_t idh_maxalloc; /* Maximum extra paragraphs needed */
uint16_t idh_ss; /* Initial (relative) SS value */
uint16_t idh_sp; /* Initial SP value */
uint16_t idh_csum; /* Checksum */
uint16_t idh_ip; /* Initial IP value */
uint16_t idh_cs; /* Initial (relative) CS value */
uint16_t idh_lfarlc; /* File address of relocation table */
uint16_t idh_ovno; /* Overlay number */
uint16_t idh_rsvd1[4]; /* Reserved words */
uint16_t idh_oemid; /* OEM identifier (for idh_oeminfo) */
uint16_t idh_oeminfo; /* OEM information; oemid specific */
uint16_t idh_rsvd2[10]; /* Reserved words */
uint32_t idh_lfanew; /* File address of new exe header */
};
typedef struct image_dos_header image_dos_header;
/*
* File header format.
*/
struct image_file_header {
uint16_t ifh_machine; /* Machine type */
uint16_t ifh_numsections; /* # of sections */
uint32_t ifh_timestamp; /* Date/time stamp */
uint32_t ifh_symtblptr; /* Offset to symbol table */
uint32_t ifh_numsyms; /* # of symbols */
uint16_t ifh_optionalhdrlen; /* Size of optional header */
uint16_t ifh_characteristics; /* Characteristics */
};
typedef struct image_file_header image_file_header;
/* Machine types */
#define IMAGE_FILE_MACHINE_UNKNOWN 0
#define IMAGE_FILE_MACHINE_I860 0x014d
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_R3000 0x0162
#define IMAGE_FILE_MACHINE_R4000 0x0166
#define IMAGE_FILE_MACHINE_R10000 0x0168
#define IMAGE_FILE_MACHINE_WCEMIPSV2 0x0169
#define IMAGE_FILE_MACHINE_ALPHA 0x0184
#define IMAGE_FILE_MACHINE_SH3 0x01a2
#define IMAGE_FILE_MACHINE_SH3DSP 0x01a3
#define IMAGE_FILE_MACHINE_SH3E 0x01a4
#define IMAGE_FILE_MACHINE_SH4 0x01a6
#define IMAGE_FILE_MACHINE_SH5 0x01a8
#define IMAGE_FILE_MACHINE_ARM 0x01c0
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
#define IMAGE_FILE_MACHINE_AM33 0x01d3
#define IMAGE_FILE_MACHINE_POWERPC 0x01f0
#define IMAGE_FILE_MACHINE_POWERPCFP 0x01f1
#define IMAGE_FILE_MACHINE_MIPS16 0x0266
#define IMAGE_FILE_MACHINE_ALPHA64 0x0284
#define IMAGE_FILE_MACHINE_MIPSFPU 0x0366
#define IMAGE_FILE_MACHINE_MIPSFPU16 0x0466
#define IMAGE_FILE_MACHINE_AXP64 IMAGE_FILE_MACHINE_ALPHA64
#define IMAGE_FILE_MACHINE_TRICORE 0x0520
#define IMAGE_FILE_MACHINE_CEF 0x0cef
#define IMAGE_FILE_MACHINE_EBC 0x0ebc
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_M32R 0x9041
#define IMAGE_FILE_MACHINE_CEE 0xc0ee
/* Characteristics */
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001 /* No relocation info */
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
#define IMAGE_FILE_AGGRESIVE_WS_TRIM 0x0010
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
#define IMAGE_FILE_16BIT_MACHINE 0x0040
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
#define IMAGE_FILE_32BIT_MACHINE 0x0100
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
#define IMAGE_FILE_SYSTEM 0x1000
#define IMAGE_FILE_DLL 0x2000
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
#define IMAGE_SIZEOF_FILE_HEADER 20
/*
* Directory format.
*/
struct image_data_directory {
uint32_t idd_vaddr; /* virtual address */
uint32_t idd_size; /* size */
};
typedef struct image_data_directory image_data_directory;
#define IMAGE_DIRECTORY_ENTRIES_MAX 16
/*
* Optional header format.
*/
struct image_optional_header {
/* Standard fields */
uint16_t ioh_magic;
uint8_t ioh_linkerver_major;
uint8_t ioh_linkerver_minor;
uint32_t ioh_codesize;
uint32_t ioh_datasize;
uint32_t ioh_bsssize;
uint32_t ioh_entryaddr;
uint32_t ioh_codebaseaddr;
#ifndef __amd64__
uint32_t ioh_databaseaddr;
#endif
/* NT-specific fields */
uintptr_t ioh_imagebase;
uint32_t ioh_sectalign;
uint32_t ioh_filealign;
uint16_t ioh_osver_major;
uint16_t ioh_osver_minor;
uint16_t ioh_imagever_major;
uint16_t ioh_imagever_minor;
uint16_t ioh_subsys_major;
uint16_t ioh_subsys_minor;
uint32_t ioh_win32ver;
uint32_t ioh_imagesize;
uint32_t ioh_headersize;
uint32_t ioh_csum;
uint16_t ioh_subsys;
uint16_t ioh_dll_characteristics;
uintptr_t ioh_stackreservesize;
uintptr_t ioh_stackcommitsize;
uintptr_t ioh_heapreservesize;
uintptr_t ioh_heapcommitsize;
uint16_t ioh_loaderflags;
uint32_t ioh_rva_size_cnt;
image_data_directory ioh_datadir[IMAGE_DIRECTORY_ENTRIES_MAX];
};
typedef struct image_optional_header image_optional_header;
struct image_nt_header {
uint32_t inh_signature;
image_file_header inh_filehdr;
image_optional_header inh_optionalhdr;
};
typedef struct image_nt_header image_nt_header;
#define IMAGE_SIZEOF_NT_HEADER(nthdr) \
(offsetof(image_nt_header, inh_optionalhdr) + \
((image_nt_header *)(nthdr))->inh_filehdr.ifh_optionalhdrlen)
/* Directory Entries */
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 /* Export Directory */
#define IMAGE_DIRECTORY_ENTRY_IMPORT 1 /* Import Directory */
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 /* Resource Directory */
#define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 /* Exception Directory */
#define IMAGE_DIRECTORY_ENTRY_SECURITY 4 /* Security Directory */
#define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 /* Base Relocation Table */
#define IMAGE_DIRECTORY_ENTRY_DEBUG 6 /* Debug Directory */
#define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 /* Description String */
#define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 /* Machine Value (MIPS GP) */
#define IMAGE_DIRECTORY_ENTRY_TLS 9 /* TLS Directory */
#define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 /* Load Configuration Directory */
#define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 /* Bound Import Directory in headers */
#define IMAGE_DIRECTORY_ENTRY_IAT 12 /* Import Address Table */
#define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13
#define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
/* Resource types */
#define RT_CURSOR 1
#define RT_BITMAP 2
#define RT_ICON 3
#define RT_MENU 4
#define RT_DIALOG 5
#define RT_STRING 6
#define RT_FONTDIR 7
#define RT_FONT 8
#define RT_ACCELERATOR 9
#define RT_RCDATA 10
#define RT_MESSAGETABLE 11
#define RT_GROUP_CURSOR 12
#define RT_GROUP_ICON 14
#define RT_VERSION 16
#define RT_DLGINCLUDE 17
#define RT_PLUGPLAY 19
#define RT_VXD 20
#define RT_ANICURSOR 21
#define RT_ANIICON 22
#define RT_HTML 23
/*
* Section header format.
*/
#define IMAGE_SHORT_NAME_LEN 8
struct image_section_header {
uint8_t ish_name[IMAGE_SHORT_NAME_LEN];
union {
uint32_t ish_paddr;
uint32_t ish_vsize;
} ish_misc;
uint32_t ish_vaddr;
uint32_t ish_rawdatasize;
uint32_t ish_rawdataaddr;
uint32_t ish_relocaddr;
uint32_t ish_linenumaddr;
uint16_t ish_numrelocs;
uint16_t ish_numlinenums;
uint32_t ish_characteristics;
};
typedef struct image_section_header image_section_header;
#define IMAGE_SIZEOF_SECTION_HEADER 40
#define IMAGE_FIRST_SECTION(nthdr) \
((image_section_header *)((vm_offset_t)(nthdr) + \
offsetof(image_nt_header, inh_optionalhdr) + \
((image_nt_header *)(nthdr))->inh_filehdr.ifh_optionalhdrlen))
/*
* Import format
*/
struct image_import_by_name {
uint16_t iibn_hint;
uint8_t iibn_name[1];
};
#define IMAGE_ORDINAL_FLAG 0x80000000
#define IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
struct image_import_descriptor {
uint32_t iid_import_name_table_addr;
uint32_t iid_timestamp;
uint32_t iid_forwardchain;
uint32_t iid_nameaddr;
uint32_t iid_import_address_table_addr;
};
typedef struct image_import_descriptor image_import_descriptor;
struct image_base_reloc {
uint32_t ibr_vaddr;
uint32_t ibr_blocksize;
uint16_t ibr_rel[1];
};
typedef struct image_base_reloc image_base_reloc;
#define IMR_RELTYPE(x) ((x >> 12) & 0xF)
#define IMR_RELOFFSET(x) (x & 0xFFF)
/* generic relocation types */
#define IMAGE_REL_BASED_ABSOLUTE 0
#define IMAGE_REL_BASED_HIGH 1
#define IMAGE_REL_BASED_LOW 2
#define IMAGE_REL_BASED_HIGHLOW 3
#define IMAGE_REL_BASED_HIGHADJ 4
#define IMAGE_REL_BASED_MIPS_JMPADDR 5
#define IMAGE_REL_BASED_SECTION 6
#define IMAGE_REL_BASED_REL 7
#define IMAGE_REL_BASED_MIPS_JMPADDR16 9
#define IMAGE_REL_BASED_DIR64 10
#define IMAGE_REL_BASED_HIGH3ADJ 11
struct image_resource_directory_entry {
uint32_t irde_name;
uint32_t irde_dataoff;
};
typedef struct image_resource_directory_entry image_resource_directory_entry;
#define RESOURCE_NAME_STR 0x80000000
#define RESOURCE_DIR_FLAG 0x80000000
struct image_resource_directory {
uint32_t ird_characteristics;
uint32_t ird_timestamp;
uint16_t ird_majorver;
uint16_t ird_minorver;
uint16_t ird_named_entries;
uint16_t ird_id_entries;
#ifdef notdef
image_resource_directory_entry ird_entries[1];
#endif
};
typedef struct image_resource_directory image_resource_directory;
struct image_resource_directory_string {
uint16_t irds_len;
char irds_name[1];
};
typedef struct image_resource_directory_string image_resource_directory_string;
struct image_resource_directory_string_u {
uint16_t irds_len;
char irds_name[1];
};
typedef struct image_resource_directory_string_u
image_resource_directory_string_u;
struct image_resource_data_entry {
uint32_t irde_offset;
uint32_t irde_size;
uint32_t irde_codepage;
uint32_t irde_rsvd;
};
typedef struct image_resource_data_entry image_resource_data_entry;
struct message_resource_data {
uint32_t mrd_numblocks;
#ifdef notdef
message_resource_block mrd_blocks[1];
#endif
};
typedef struct message_resource_data message_resource_data;
struct message_resource_block {
uint32_t mrb_lowid;
uint32_t mrb_highid;
uint32_t mrb_entryoff;
};
typedef struct message_resource_block message_resource_block;
struct message_resource_entry {
uint16_t mre_len;
uint16_t mre_flags;
char mre_text[];
};
typedef struct message_resource_entry message_resource_entry;
#define MESSAGE_RESOURCE_UNICODE 0x0001
struct image_patch_table {
char *ipt_name;
void (*ipt_func)(void);
void (*ipt_wrap)(void);
int ipt_argcnt;
int ipt_ftype;
};
typedef struct image_patch_table image_patch_table;
/*
* AMD64 support. Microsoft uses a different calling convention
* than everyone else on the amd64 platform. Sadly, gcc has no
* built-in support for it (yet).
*
* The three major differences we're concerned with are:
*
* - The first 4 register-sized arguments are passed in the
* %rcx, %rdx, %r8 and %r9 registers, and the rest are pushed
* onto the stack. (The ELF ABI uses 6 registers, not 4).
*
* - The caller must reserve space on the stack for the 4
* register arguments in case the callee has to spill them.
*
* - The stack myst be 16-byte aligned by the time the callee
* executes. A call instruction implicitly pushes an 8 byte
* return address onto the stack. We have to make sure that
* the amount of space we consume, plus the return address,
* is a multiple of 16 bytes in size. This means that in
* some cases, we may need to chew up an extra 8 bytes on
* the stack that will be unused.
*
* On the bright side, Microsoft seems to be using just the one
* calling convention for all functions on amd64, unlike x86 where
* they use a mix of _stdcall, _fastcall and _cdecl.
*/
#ifdef __amd64__
extern uint64_t x86_64_call1(void *, uint64_t);
extern uint64_t x86_64_call2(void *, uint64_t, uint64_t);
extern uint64_t x86_64_call3(void *, uint64_t, uint64_t, uint64_t);
extern uint64_t x86_64_call4(void *, uint64_t, uint64_t, uint64_t, uint64_t);
extern uint64_t x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t);
extern uint64_t x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t);
uint64_t _x86_64_call1(void *, uint64_t);
uint64_t _x86_64_call2(void *, uint64_t, uint64_t);
uint64_t _x86_64_call3(void *, uint64_t, uint64_t, uint64_t);
uint64_t _x86_64_call4(void *, uint64_t, uint64_t, uint64_t, uint64_t);
uint64_t _x86_64_call5(void *, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t);
uint64_t _x86_64_call6(void *, uint64_t, uint64_t, uint64_t, uint64_t,
uint64_t, uint64_t);
#define MSCALL1(fn, a) \
_x86_64_call1((fn), (uint64_t)(a))
#define MSCALL2(fn, a, b) \
_x86_64_call2((fn), (uint64_t)(a), (uint64_t)(b))
#define MSCALL3(fn, a, b, c) \
_x86_64_call3((fn), (uint64_t)(a), (uint64_t)(b), \
(uint64_t)(c))
#define MSCALL4(fn, a, b, c, d) \
_x86_64_call4((fn), (uint64_t)(a), (uint64_t)(b), \
(uint64_t)(c), (uint64_t)(d))
#define MSCALL5(fn, a, b, c, d, e) \
_x86_64_call5((fn), (uint64_t)(a), (uint64_t)(b), \
(uint64_t)(c), (uint64_t)(d), (uint64_t)(e))
#define MSCALL6(fn, a, b, c, d, e, f) \
_x86_64_call6((fn), (uint64_t)(a), (uint64_t)(b), \
(uint64_t)(c), (uint64_t)(d), (uint64_t)(e), (uint64_t)(f))
#endif /* __amd64__ */
#ifdef __i386__
extern uint32_t x86_stdcall_call(void *, int, ...);
#define MSCALL1(fn, a) x86_stdcall_call(fn, 1, (a))
#define MSCALL2(fn, a, b) x86_stdcall_call(fn, 2, (a), (b))
#define MSCALL3(fn, a, b, c) x86_stdcall_call(fn, 3, (a), (b), (c))
#define MSCALL4(fn, a, b, c, d) x86_stdcall_call(fn, 4, (a), (b), (c), (d))
#define MSCALL5(fn, a, b, c, d, e) \
x86_stdcall_call(fn, 5, (a), (b), (c), (d), (e))
#define MSCALL6(fn, a, b, c, d, e, f) \
x86_stdcall_call(fn, 6, (a), (b), (c), (d), (e), (f))
#endif /* __i386__ */
#define FUNC void(*)(void)
#ifdef __i386__
#define IMPORT_SFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_STDCALL }
#define IMPORT_SFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_STDCALL }
#define IMPORT_FFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_FASTCALL }
#define IMPORT_FFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_FASTCALL }
#define IMPORT_RFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_REGPARM }
#define IMPORT_RFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_REGPARM }
#define IMPORT_CFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_CDECL }
#define IMPORT_CFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_CDECL }
#endif /* __i386__ */
#ifdef __amd64__
#define IMPORT_SFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 }
#define IMPORT_SFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 }
#define IMPORT_FFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 }
#define IMPORT_FFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 }
#define IMPORT_RFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 }
#define IMPORT_RFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 }
#define IMPORT_CFUNC(x, y) { #x, (FUNC)x, NULL, y, WINDRV_WRAP_AMD64 }
#define IMPORT_CFUNC_MAP(x, y, z) \
{ #x, (FUNC)y, NULL, z, WINDRV_WRAP_AMD64 }
#endif /* __amd64__ */
__BEGIN_DECLS
extern int pe_get_dos_header(vm_offset_t, image_dos_header *);
extern int pe_is_nt_image(vm_offset_t);
extern int pe_get_optional_header(vm_offset_t, image_optional_header *);
extern int pe_get_file_header(vm_offset_t, image_file_header *);
extern int pe_get_section_header(vm_offset_t, image_section_header *);
extern int pe_numsections(vm_offset_t);
extern vm_offset_t pe_imagebase(vm_offset_t);
extern vm_offset_t pe_directory_offset(vm_offset_t, uint32_t);
extern vm_offset_t pe_translate_addr (vm_offset_t, vm_offset_t);
extern int pe_get_section(vm_offset_t, image_section_header *, const char *);
extern int pe_relocate(vm_offset_t);
extern int pe_get_import_descriptor(vm_offset_t, image_import_descriptor *, char *);
extern int pe_patch_imports(vm_offset_t, char *, image_patch_table *);
extern int pe_get_messagetable(vm_offset_t, message_resource_data **);
extern int pe_get_message(vm_offset_t, uint32_t, char **, int *, uint16_t *);
__END_DECLS
#endif /* _PE_VAR_H_ */

View File

@ -1,201 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _RESOURCE_VAR_H_
#define _RESOURCE_VAR_H_
typedef int cm_resource_type;
struct physaddr {
uint64_t np_quad;
#ifdef notdef
uint32_t np_low;
uint32_t np_high;
#endif
};
typedef struct physaddr physaddr;
enum interface_type {
InterfaceTypeUndefined = -1,
Internal,
Isa,
Eisa,
MicroChannel,
TurboChannel,
PCIBus,
VMEBus,
NuBus,
PCMCIABus,
CBus,
MPIBus,
MPSABus,
ProcessorInternal,
InternalPowerBus,
PNPISABus,
PNPBus,
MaximumInterfaceType
};
typedef enum interface_type interface_type;
#define CmResourceTypeNull 0 /* ResType_All or ResType_None (0x0000) */
#define CmResourceTypePort 1 /* ResType_IO (0x0002) */
#define CmResourceTypeInterrupt 2 /* ResType_IRQ (0x0004) */
#define CmResourceTypeMemory 3 /* ResType_Mem (0x0001) */
#define CmResourceTypeDma 4 /* ResType_DMA (0x0003) */
#define CmResourceTypeDeviceSpecific 5 /* ResType_ClassSpecific (0xFFFF) */
#define CmResourceTypeBusNumber 6 /* ResType_BusNumber (0x0006) */
#define CmResourceTypeMaximum 7
#define CmResourceTypeNonArbitrated 128 /* Not arbitrated if 0x80 bit set */
#define CmResourceTypeConfigData 128 /* ResType_Reserved (0x8000) */
#define CmResourceTypeDevicePrivate 129 /* ResType_DevicePrivate (0x8001) */
#define CmResourceTypePcCardConfig 130 /* ResType_PcCardConfig (0x8002) */
enum cm_share_disposition {
CmResourceShareUndetermined = 0, /* Reserved */
CmResourceShareDeviceExclusive,
CmResourceShareDriverExclusive,
CmResourceShareShared
};
typedef enum cm_share_disposition cm_share_disposition;
/* Define the bit masks for Flags when type is CmResourceTypeInterrupt */
#define CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE 0
#define CM_RESOURCE_INTERRUPT_LATCHED 1
/* Define the bit masks for Flags when type is CmResourceTypeMemory */
#define CM_RESOURCE_MEMORY_READ_WRITE 0x0000
#define CM_RESOURCE_MEMORY_READ_ONLY 0x0001
#define CM_RESOURCE_MEMORY_WRITE_ONLY 0x0002
#define CM_RESOURCE_MEMORY_PREFETCHABLE 0x0004
#define CM_RESOURCE_MEMORY_COMBINEDWRITE 0x0008
#define CM_RESOURCE_MEMORY_24 0x0010
#define CM_RESOURCE_MEMORY_CACHEABLE 0x0020
/* Define the bit masks for Flags when type is CmResourceTypePort */
#define CM_RESOURCE_PORT_MEMORY 0x0000
#define CM_RESOURCE_PORT_IO 0x0001
#define CM_RESOURCE_PORT_10_BIT_DECODE 0x0004
#define CM_RESOURCE_PORT_12_BIT_DECODE 0x0008
#define CM_RESOURCE_PORT_16_BIT_DECODE 0x0010
#define CM_RESOURCE_PORT_POSITIVE_DECODE 0x0020
#define CM_RESOURCE_PORT_PASSIVE_DECODE 0x0040
#define CM_RESOURCE_PORT_WINDOW_DECODE 0x0080
/* Define the bit masks for Flags when type is CmResourceTypeDma */
#define CM_RESOURCE_DMA_8 0x0000
#define CM_RESOURCE_DMA_16 0x0001
#define CM_RESOURCE_DMA_32 0x0002
#define CM_RESOURCE_DMA_8_AND_16 0x0004
#define CM_RESOURCE_DMA_BUS_MASTER 0x0008
#define CM_RESOURCE_DMA_TYPE_A 0x0010
#define CM_RESOURCE_DMA_TYPE_B 0x0020
#define CM_RESOURCE_DMA_TYPE_F 0x0040
struct cm_partial_resource_desc {
uint8_t cprd_type;
uint8_t cprd_sharedisp;
uint16_t cprd_flags;
union {
struct {
physaddr cprd_start;
uint32_t cprd_len;
} cprd_generic;
struct {
physaddr cprd_start;
uint32_t cprd_len;
} cprd_port;
struct {
uint32_t cprd_level;
uint32_t cprd_vector;
uint32_t cprd_affinity;
} cprd_intr;
struct {
physaddr cprd_start;
uint32_t cprd_len;
} cprd_mem;
struct {
uint32_t cprd_chan;
uint32_t cprd_port;
uint32_t cprd_rsvd;
} cprd_dmachan;
struct {
uint32_t cprd_data[3];
} cprd_devpriv;
struct {
uint32_t cprd_datasize;
uint32_t cprd_rsvd1;
uint32_t cprd_rsvd2;
} cprd_devspec;
} u __attribute__((packed));
};
typedef struct cm_partial_resource_desc cm_partial_resource_desc;
struct cm_partial_resource_list {
uint16_t cprl_version;
uint16_t cprl_revision;
uint32_t cprl_count;
cm_partial_resource_desc cprl_partial_descs[1];
};
typedef struct cm_partial_resource_list cm_partial_resource_list;
struct cm_full_resource_list {
interface_type cfrl_type;
uint32_t cfrl_busnum;
cm_partial_resource_desc cfrl_partiallist;
};
typedef struct cm_full_resource_list cm_full_resource_list;
struct cm_resource_list {
uint32_t crl_count;
cm_full_resource_list crl_rlist;
};
typedef struct cm_resource_list cm_resource_list;
typedef cm_partial_resource_list ndis_resource_list;
#endif /* _RESOURCE_VAR_H_ */

View File

@ -1,482 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/types.h>
#include <sys/errno.h>
#include <sys/callout.h>
#include <sys/kernel.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <sys/sched.h>
#include <sys/module.h>
#include <sys/systm.h>
#include <machine/bus.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <compat/ndis/pe_var.h>
#include <compat/ndis/resource_var.h>
#include <compat/ndis/cfg_var.h>
#include <compat/ndis/ntoskrnl_var.h>
#include <compat/ndis/hal_var.h>
static void KeStallExecutionProcessor(uint32_t);
static void WRITE_PORT_BUFFER_ULONG(uint32_t *,
uint32_t *, uint32_t);
static void WRITE_PORT_BUFFER_USHORT(uint16_t *,
uint16_t *, uint32_t);
static void WRITE_PORT_BUFFER_UCHAR(uint8_t *,
uint8_t *, uint32_t);
static void WRITE_PORT_ULONG(uint32_t *, uint32_t);
static void WRITE_PORT_USHORT(uint16_t *, uint16_t);
static void WRITE_PORT_UCHAR(uint8_t *, uint8_t);
static uint32_t READ_PORT_ULONG(uint32_t *);
static uint16_t READ_PORT_USHORT(uint16_t *);
static uint8_t READ_PORT_UCHAR(uint8_t *);
static void READ_PORT_BUFFER_ULONG(uint32_t *,
uint32_t *, uint32_t);
static void READ_PORT_BUFFER_USHORT(uint16_t *,
uint16_t *, uint32_t);
static void READ_PORT_BUFFER_UCHAR(uint8_t *,
uint8_t *, uint32_t);
static uint64_t KeQueryPerformanceCounter(uint64_t *);
static void _KeLowerIrql(uint8_t);
static uint8_t KeRaiseIrqlToDpcLevel(void);
static void dummy (void);
#define NDIS_MAXCPUS 64
static struct mtx disp_lock[NDIS_MAXCPUS];
int
hal_libinit()
{
image_patch_table *patch;
int i;
for (i = 0; i < NDIS_MAXCPUS; i++)
mtx_init(&disp_lock[i], "HAL preemption lock",
"HAL lock", MTX_RECURSE|MTX_DEF);
patch = hal_functbl;
while (patch->ipt_func != NULL) {
windrv_wrap((funcptr)patch->ipt_func,
(funcptr *)&patch->ipt_wrap,
patch->ipt_argcnt, patch->ipt_ftype);
patch++;
}
return (0);
}
int
hal_libfini()
{
image_patch_table *patch;
int i;
for (i = 0; i < NDIS_MAXCPUS; i++)
mtx_destroy(&disp_lock[i]);
patch = hal_functbl;
while (patch->ipt_func != NULL) {
windrv_unwrap(patch->ipt_wrap);
patch++;
}
return (0);
}
static void
KeStallExecutionProcessor(usecs)
uint32_t usecs;
{
DELAY(usecs);
}
static void
WRITE_PORT_ULONG(port, val)
uint32_t *port;
uint32_t val;
{
bus_space_write_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val);
}
static void
WRITE_PORT_USHORT(uint16_t *port, uint16_t val)
{
bus_space_write_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val);
}
static void
WRITE_PORT_UCHAR(uint8_t *port, uint8_t val)
{
bus_space_write_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port, val);
}
static void
WRITE_PORT_BUFFER_ULONG(port, val, cnt)
uint32_t *port;
uint32_t *val;
uint32_t cnt;
{
bus_space_write_multi_4(NDIS_BUS_SPACE_IO, 0x0,
(bus_size_t)port, val, cnt);
}
static void
WRITE_PORT_BUFFER_USHORT(port, val, cnt)
uint16_t *port;
uint16_t *val;
uint32_t cnt;
{
bus_space_write_multi_2(NDIS_BUS_SPACE_IO, 0x0,
(bus_size_t)port, val, cnt);
}
static void
WRITE_PORT_BUFFER_UCHAR(port, val, cnt)
uint8_t *port;
uint8_t *val;
uint32_t cnt;
{
bus_space_write_multi_1(NDIS_BUS_SPACE_IO, 0x0,
(bus_size_t)port, val, cnt);
}
static uint16_t
READ_PORT_USHORT(port)
uint16_t *port;
{
return (bus_space_read_2(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
}
static uint32_t
READ_PORT_ULONG(port)
uint32_t *port;
{
return (bus_space_read_4(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
}
static uint8_t
READ_PORT_UCHAR(port)
uint8_t *port;
{
return (bus_space_read_1(NDIS_BUS_SPACE_IO, 0x0, (bus_size_t)port));
}
static void
READ_PORT_BUFFER_ULONG(port, val, cnt)
uint32_t *port;
uint32_t *val;
uint32_t cnt;
{
bus_space_read_multi_4(NDIS_BUS_SPACE_IO, 0x0,
(bus_size_t)port, val, cnt);
}
static void
READ_PORT_BUFFER_USHORT(port, val, cnt)
uint16_t *port;
uint16_t *val;
uint32_t cnt;
{
bus_space_read_multi_2(NDIS_BUS_SPACE_IO, 0x0,
(bus_size_t)port, val, cnt);
}
static void
READ_PORT_BUFFER_UCHAR(port, val, cnt)
uint8_t *port;
uint8_t *val;
uint32_t cnt;
{
bus_space_read_multi_1(NDIS_BUS_SPACE_IO, 0x0,
(bus_size_t)port, val, cnt);
}
/*
* The spinlock implementation in Windows differs from that of FreeBSD.
* The basic operation of spinlocks involves two steps: 1) spin in a
* tight loop while trying to acquire a lock, 2) after obtaining the
* lock, disable preemption. (Note that on uniprocessor systems, you're
* allowed to skip the first step and just lock out pre-emption, since
* it's not possible for you to be in contention with another running
* thread.) Later, you release the lock then re-enable preemption.
* The difference between Windows and FreeBSD lies in how preemption
* is disabled. In FreeBSD, it's done using critical_enter(), which on
* the x86 arch translates to a cli instruction. This masks off all
* interrupts, and effectively stops the scheduler from ever running
* so _nothing_ can execute except the current thread. In Windows,
* preemption is disabled by raising the processor IRQL to DISPATCH_LEVEL.
* This stops other threads from running, but does _not_ block device
* interrupts. This means ISRs can still run, and they can make other
* threads runable, but those other threads won't be able to execute
* until the current thread lowers the IRQL to something less than
* DISPATCH_LEVEL.
*
* There's another commonly used IRQL in Windows, which is APC_LEVEL.
* An APC is an Asynchronous Procedure Call, which differs from a DPC
* (Defered Procedure Call) in that a DPC is queued up to run in
* another thread, while an APC runs in the thread that scheduled
* it (similar to a signal handler in a UNIX process). We don't
* actually support the notion of APCs in FreeBSD, so for now, the
* only IRQLs we're interested in are DISPATCH_LEVEL and PASSIVE_LEVEL.
*
* To simulate DISPATCH_LEVEL, we raise the current thread's priority
* to PI_REALTIME, which is the highest we can give it. This should,
* if I understand things correctly, prevent anything except for an
* interrupt thread from preempting us. PASSIVE_LEVEL is basically
* everything else.
*
* Be aware that, at least on the x86 arch, the Windows spinlock
* functions are divided up in peculiar ways. The actual spinlock
* functions are KfAcquireSpinLock() and KfReleaseSpinLock(), and
* they live in HAL.dll. Meanwhile, KeInitializeSpinLock(),
* KefAcquireSpinLockAtDpcLevel() and KefReleaseSpinLockFromDpcLevel()
* live in ntoskrnl.exe. Most Windows source code will call
* KeAcquireSpinLock() and KeReleaseSpinLock(), but these are just
* macros that call KfAcquireSpinLock() and KfReleaseSpinLock().
* KefAcquireSpinLockAtDpcLevel() and KefReleaseSpinLockFromDpcLevel()
* perform the lock acquisition/release functions without doing the
* IRQL manipulation, and are used when one is already running at
* DISPATCH_LEVEL. Make sense? Good.
*
* According to the Microsoft documentation, any thread that calls
* KeAcquireSpinLock() must be running at IRQL <= DISPATCH_LEVEL. If
* we detect someone trying to acquire a spinlock from DEVICE_LEVEL
* or HIGH_LEVEL, we panic.
*
* Alternate sleep-lock-based spinlock implementation
* --------------------------------------------------
*
* The earlier spinlock implementation was arguably a bit of a hack
* and presented several problems. It was basically designed to provide
* the functionality of spinlocks without incurring the wrath of
* WITNESS. We could get away with using both our spinlock implementation
* and FreeBSD sleep locks at the same time, but if WITNESS knew what
* we were really up to, it would have spanked us rather severely.
*
* There's another method we can use based entirely on sleep locks.
* First, it's important to realize that everything we're locking
* resides inside Project Evil itself: any critical data being locked
* by drivers belongs to the drivers, and should not be referenced
* by any other OS code outside of the NDISulator. The priority-based
* locking scheme has system-wide effects, just like real spinlocks
* (blocking preemption affects the whole CPU), but since we keep all
* our critical data private, we can use a simpler mechanism that
* affects only code/threads directly related to Project Evil.
*
* The idea is to create a sleep lock mutex for each CPU in the system.
* When a CPU running in the NDISulator wants to acquire a spinlock, it
* does the following:
* - Pin ourselves to the current CPU
* - Acquire the mutex for the current CPU
* - Spin on the spinlock variable using atomic test and set, just like
* a real spinlock.
* - Once we have the lock, we execute our critical code
*
* To give up the lock, we do:
* - Clear the spinlock variable with an atomic op
* - Release the per-CPU mutex
* - Unpin ourselves from the current CPU.
*
* On a uniprocessor system, this means all threads that access protected
* data are serialized through the per-CPU mutex. After one thread
* acquires the 'spinlock,' any other thread that uses a spinlock on the
* current CPU will block on the per-CPU mutex, which has the same general
* effect of blocking pre-emption, but _only_ for those threads that are
* running NDISulator code.
*
* On a multiprocessor system, threads on different CPUs all block on
* their respective per-CPU mutex, and the atomic test/set operation
* on the spinlock variable provides inter-CPU synchronization, though
* only for threads running NDISulator code.
*
* This method solves an important problem. In Windows, you're allowed
* to do an ExAllocatePoolWithTag() with a spinlock held, provided you
* allocate from NonPagedPool. This implies an atomic heap allocation
* that will not cause the current thread to sleep. (You can't sleep
* while holding real spinlock: clowns will eat you.) But in FreeBSD,
* malloc(9) _always_ triggers the acquisition of a sleep lock, even
* when you use M_NOWAIT. This is not a problem for FreeBSD native
* code: you're allowed to sleep in things like interrupt threads. But
* it is a problem with the old priority-based spinlock implementation:
* even though we get away with it most of the time, we really can't
* do a malloc(9) after doing a KeAcquireSpinLock() or KeRaiseIrql().
* With the new implementation, it's not a problem: you're allowed to
* acquire more than one sleep lock (as long as you avoid lock order
* reversals).
*
* The one drawback to this approach is that now we have a lot of
* contention on one per-CPU mutex within the NDISulator code. Whether
* or not this is preferable to the expected Windows spinlock behavior
* of blocking pre-emption is debatable.
*/
uint8_t
KfAcquireSpinLock(lock)
kspin_lock *lock;
{
uint8_t oldirql;
KeRaiseIrql(DISPATCH_LEVEL, &oldirql);
KeAcquireSpinLockAtDpcLevel(lock);
return (oldirql);
}
void
KfReleaseSpinLock(kspin_lock *lock, uint8_t newirql)
{
KeReleaseSpinLockFromDpcLevel(lock);
KeLowerIrql(newirql);
}
uint8_t
KeGetCurrentIrql()
{
if (mtx_owned(&disp_lock[curthread->td_oncpu]))
return (DISPATCH_LEVEL);
return (PASSIVE_LEVEL);
}
static uint64_t
KeQueryPerformanceCounter(freq)
uint64_t *freq;
{
if (freq != NULL)
*freq = hz;
return ((uint64_t)ticks);
}
uint8_t
KfRaiseIrql(uint8_t irql)
{
uint8_t oldirql;
sched_pin();
oldirql = KeGetCurrentIrql();
/* I am so going to hell for this. */
if (oldirql > irql)
panic("IRQL_NOT_LESS_THAN_OR_EQUAL");
if (oldirql != DISPATCH_LEVEL)
mtx_lock(&disp_lock[curthread->td_oncpu]);
else
sched_unpin();
/*printf("RAISE IRQL: %d %d\n", irql, oldirql);*/
return (oldirql);
}
void
KfLowerIrql(uint8_t oldirql)
{
if (oldirql == DISPATCH_LEVEL)
return;
if (KeGetCurrentIrql() != DISPATCH_LEVEL)
panic("IRQL_NOT_GREATER_THAN");
mtx_unlock(&disp_lock[curthread->td_oncpu]);
sched_unpin();
}
static uint8_t
KeRaiseIrqlToDpcLevel(void)
{
uint8_t irql;
KeRaiseIrql(DISPATCH_LEVEL, &irql);
return (irql);
}
static void
_KeLowerIrql(uint8_t oldirql)
{
KeLowerIrql(oldirql);
}
static void dummy()
{
printf("hal dummy called...\n");
}
image_patch_table hal_functbl[] = {
IMPORT_SFUNC(KeStallExecutionProcessor, 1),
IMPORT_SFUNC(WRITE_PORT_ULONG, 2),
IMPORT_SFUNC(WRITE_PORT_USHORT, 2),
IMPORT_SFUNC(WRITE_PORT_UCHAR, 2),
IMPORT_SFUNC(WRITE_PORT_BUFFER_ULONG, 3),
IMPORT_SFUNC(WRITE_PORT_BUFFER_USHORT, 3),
IMPORT_SFUNC(WRITE_PORT_BUFFER_UCHAR, 3),
IMPORT_SFUNC(READ_PORT_ULONG, 1),
IMPORT_SFUNC(READ_PORT_USHORT, 1),
IMPORT_SFUNC(READ_PORT_UCHAR, 1),
IMPORT_SFUNC(READ_PORT_BUFFER_ULONG, 3),
IMPORT_SFUNC(READ_PORT_BUFFER_USHORT, 3),
IMPORT_SFUNC(READ_PORT_BUFFER_UCHAR, 3),
IMPORT_FFUNC(KfAcquireSpinLock, 1),
IMPORT_FFUNC(KfReleaseSpinLock, 1),
IMPORT_SFUNC(KeGetCurrentIrql, 0),
IMPORT_SFUNC(KeQueryPerformanceCounter, 1),
IMPORT_FFUNC(KfLowerIrql, 1),
IMPORT_FFUNC(KfRaiseIrql, 1),
IMPORT_SFUNC(KeRaiseIrqlToDpcLevel, 0),
#undef KeLowerIrql
IMPORT_SFUNC_MAP(KeLowerIrql, _KeLowerIrql, 1),
/*
* This last entry is a catch-all for any function we haven't
* implemented yet. The PE import list patching routine will
* use it for any function that doesn't have an explicit match
* in this table.
*/
{ NULL, (FUNC)dummy, NULL, 0, WINDRV_WRAP_STDCALL },
/* End of list. */
{ NULL, NULL, NULL }
};

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,644 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* This file contains routines for relocating and dynamically linking
* executable object code files in the Windows(r) PE (Portable Executable)
* format. In Windows, anything with a .EXE, .DLL or .SYS extension is
* considered an executable, and all such files have some structures in
* common. The PE format was apparently based largely on COFF but has
* mutated significantly over time. We are mainly concerned with .SYS files,
* so this module implements only enough routines to be able to parse the
* headers and sections of a .SYS object file and perform the necessary
* relocations and jump table patching to allow us to call into it
* (and to have it call back to us). Note that while this module
* can handle fixups for imported symbols, it knows nothing about
* exporting them.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/errno.h>
#ifdef _KERNEL
#include <sys/systm.h>
#else
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#endif
#include <compat/ndis/pe_var.h>
static vm_offset_t pe_functbl_match(image_patch_table *, char *);
/*
* Check for an MS-DOS executable header. All Windows binaries
* have a small MS-DOS executable prepended to them to print out
* the "This program requires Windows" message. Even .SYS files
* have this header, in spite of the fact that you're can't actually
* run them directly.
*/
int
pe_get_dos_header(imgbase, hdr)
vm_offset_t imgbase;
image_dos_header *hdr;
{
uint16_t signature;
if (imgbase == 0 || hdr == NULL)
return (EINVAL);
signature = *(uint16_t *)imgbase;
if (signature != IMAGE_DOS_SIGNATURE)
return (ENOEXEC);
bcopy ((char *)imgbase, (char *)hdr, sizeof(image_dos_header));
return (0);
}
/*
* Verify that this image has a Windows NT PE signature.
*/
int
pe_is_nt_image(imgbase)
vm_offset_t imgbase;
{
uint32_t signature;
image_dos_header *dos_hdr;
if (imgbase == 0)
return (EINVAL);
signature = *(uint16_t *)imgbase;
if (signature == IMAGE_DOS_SIGNATURE) {
dos_hdr = (image_dos_header *)imgbase;
signature = *(uint32_t *)(imgbase + dos_hdr->idh_lfanew);
if (signature == IMAGE_NT_SIGNATURE)
return (0);
}
return (ENOEXEC);
}
/*
* Return a copy of the optional header. This contains the
* executable entry point and the directory listing which we
* need to find the relocations and imports later.
*/
int
pe_get_optional_header(imgbase, hdr)
vm_offset_t imgbase;
image_optional_header *hdr;
{
image_dos_header *dos_hdr;
image_nt_header *nt_hdr;
if (imgbase == 0 || hdr == NULL)
return (EINVAL);
if (pe_is_nt_image(imgbase))
return (EINVAL);
dos_hdr = (image_dos_header *)(imgbase);
nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
bcopy ((char *)&nt_hdr->inh_optionalhdr, (char *)hdr,
nt_hdr->inh_filehdr.ifh_optionalhdrlen);
return (0);
}
/*
* Return a copy of the file header. Contains the number of
* sections in this image.
*/
int
pe_get_file_header(imgbase, hdr)
vm_offset_t imgbase;
image_file_header *hdr;
{
image_dos_header *dos_hdr;
image_nt_header *nt_hdr;
if (imgbase == 0 || hdr == NULL)
return (EINVAL);
if (pe_is_nt_image(imgbase))
return (EINVAL);
dos_hdr = (image_dos_header *)imgbase;
nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
/*
* Note: the size of the nt_header is variable since it
* can contain optional fields, as indicated by ifh_optionalhdrlen.
* However it happens we're only interested in fields in the
* non-variant portion of the nt_header structure, so we don't
* bother copying the optional parts here.
*/
bcopy ((char *)&nt_hdr->inh_filehdr, (char *)hdr,
sizeof(image_file_header));
return (0);
}
/*
* Return the header of the first section in this image (usually
* .text).
*/
int
pe_get_section_header(imgbase, hdr)
vm_offset_t imgbase;
image_section_header *hdr;
{
image_dos_header *dos_hdr;
image_nt_header *nt_hdr;
image_section_header *sect_hdr;
if (imgbase == 0 || hdr == NULL)
return (EINVAL);
if (pe_is_nt_image(imgbase))
return (EINVAL);
dos_hdr = (image_dos_header *)imgbase;
nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
bcopy ((char *)sect_hdr, (char *)hdr, sizeof(image_section_header));
return (0);
}
/*
* Return the number of sections in this executable, or 0 on error.
*/
int
pe_numsections(imgbase)
vm_offset_t imgbase;
{
image_file_header file_hdr;
if (pe_get_file_header(imgbase, &file_hdr))
return (0);
return (file_hdr.ifh_numsections);
}
/*
* Return the base address that this image was linked for.
* This helps us calculate relocation addresses later.
*/
vm_offset_t
pe_imagebase(imgbase)
vm_offset_t imgbase;
{
image_optional_header optional_hdr;
if (pe_get_optional_header(imgbase, &optional_hdr))
return (0);
return (optional_hdr.ioh_imagebase);
}
/*
* Return the offset of a given directory structure within the
* image. Directories reside within sections.
*/
vm_offset_t
pe_directory_offset(imgbase, diridx)
vm_offset_t imgbase;
uint32_t diridx;
{
image_optional_header opt_hdr;
vm_offset_t dir;
if (pe_get_optional_header(imgbase, &opt_hdr))
return (0);
if (diridx >= opt_hdr.ioh_rva_size_cnt)
return (0);
dir = opt_hdr.ioh_datadir[diridx].idd_vaddr;
return (pe_translate_addr(imgbase, dir));
}
vm_offset_t
pe_translate_addr(imgbase, rva)
vm_offset_t imgbase;
vm_offset_t rva;
{
image_optional_header opt_hdr;
image_section_header *sect_hdr;
image_dos_header *dos_hdr;
image_nt_header *nt_hdr;
int i = 0, sections, fixedlen;
if (pe_get_optional_header(imgbase, &opt_hdr))
return (0);
sections = pe_numsections(imgbase);
dos_hdr = (image_dos_header *)imgbase;
nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
/*
* The test here is to see if the RVA falls somewhere
* inside the section, based on the section's start RVA
* and its length. However it seems sometimes the
* virtual length isn't enough to cover the entire
* area of the section. We fudge by taking into account
* the section alignment and rounding the section length
* up to a page boundary.
*/
while (i++ < sections) {
fixedlen = sect_hdr->ish_misc.ish_vsize;
fixedlen += ((opt_hdr.ioh_sectalign - 1) -
sect_hdr->ish_misc.ish_vsize) &
(opt_hdr.ioh_sectalign - 1);
if (sect_hdr->ish_vaddr <= (uint32_t)rva &&
(sect_hdr->ish_vaddr + fixedlen) >
(uint32_t)rva)
break;
sect_hdr++;
}
if (i > sections)
return (0);
return ((vm_offset_t)(imgbase + rva - sect_hdr->ish_vaddr +
sect_hdr->ish_rawdataaddr));
}
/*
* Get the section header for a particular section. Note that
* section names can be anything, but there are some standard
* ones (.text, .data, .rdata, .reloc).
*/
int
pe_get_section(imgbase, hdr, name)
vm_offset_t imgbase;
image_section_header *hdr;
const char *name;
{
image_dos_header *dos_hdr;
image_nt_header *nt_hdr;
image_section_header *sect_hdr;
int i, sections;
if (imgbase == 0 || hdr == NULL)
return (EINVAL);
if (pe_is_nt_image(imgbase))
return (EINVAL);
sections = pe_numsections(imgbase);
dos_hdr = (image_dos_header *)imgbase;
nt_hdr = (image_nt_header *)(imgbase + dos_hdr->idh_lfanew);
sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
for (i = 0; i < sections; i++) {
if (!strcmp ((char *)&sect_hdr->ish_name, name)) {
bcopy((char *)sect_hdr, (char *)hdr,
sizeof(image_section_header));
return (0);
} else
sect_hdr++;
}
return (ENOEXEC);
}
/*
* Apply the base relocations to this image. The relocation table
* resides within the .reloc section. Relocations are specified in
* blocks which refer to a particular page. We apply the relocations
* one page block at a time.
*/
int
pe_relocate(imgbase)
vm_offset_t imgbase;
{
image_section_header sect;
image_base_reloc *relhdr;
uint16_t rel, *sloc;
vm_offset_t base;
vm_size_t delta;
uint32_t *lloc;
uint64_t *qloc;
int i, count;
vm_offset_t txt;
base = pe_imagebase(imgbase);
pe_get_section(imgbase, &sect, ".text");
txt = pe_translate_addr(imgbase, sect.ish_vaddr);
delta = (uint32_t)(txt) - base - sect.ish_vaddr;
pe_get_section(imgbase, &sect, ".reloc");
relhdr = (image_base_reloc *)(imgbase + sect.ish_rawdataaddr);
do {
count = (relhdr->ibr_blocksize -
(sizeof(uint32_t) * 2)) / sizeof(uint16_t);
for (i = 0; i < count; i++) {
rel = relhdr->ibr_rel[i];
switch (IMR_RELTYPE(rel)) {
case IMAGE_REL_BASED_ABSOLUTE:
break;
case IMAGE_REL_BASED_HIGHLOW:
lloc = (uint32_t *)pe_translate_addr(imgbase,
relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
*lloc = pe_translate_addr(imgbase,
(*lloc - base));
break;
case IMAGE_REL_BASED_HIGH:
sloc = (uint16_t *)pe_translate_addr(imgbase,
relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
*sloc += (delta & 0xFFFF0000) >> 16;
break;
case IMAGE_REL_BASED_LOW:
sloc = (uint16_t *)pe_translate_addr(imgbase,
relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
*sloc += (delta & 0xFFFF);
break;
case IMAGE_REL_BASED_DIR64:
qloc = (uint64_t *)pe_translate_addr(imgbase,
relhdr->ibr_vaddr + IMR_RELOFFSET(rel));
*qloc = pe_translate_addr(imgbase,
(*qloc - base));
break;
default:
printf("[%d]reloc type: %d\n",i,
IMR_RELTYPE(rel));
break;
}
}
relhdr = (image_base_reloc *)((vm_offset_t)relhdr +
relhdr->ibr_blocksize);
} while (relhdr->ibr_blocksize);
return (0);
}
/*
* Return the import descriptor for a particular module. An image
* may be linked against several modules, typically HAL.dll, ntoskrnl.exe
* and NDIS.SYS. For each module, there is a list of imported function
* names and their addresses.
*
* Note: module names are case insensitive!
*/
int
pe_get_import_descriptor(imgbase, desc, module)
vm_offset_t imgbase;
image_import_descriptor *desc;
char *module;
{
vm_offset_t offset;
image_import_descriptor *imp_desc;
char *modname;
if (imgbase == 0 || module == NULL || desc == NULL)
return (EINVAL);
offset = pe_directory_offset(imgbase, IMAGE_DIRECTORY_ENTRY_IMPORT);
if (offset == 0)
return (ENOENT);
imp_desc = (void *)offset;
while (imp_desc->iid_nameaddr) {
modname = (char *)pe_translate_addr(imgbase,
imp_desc->iid_nameaddr);
if (!strncasecmp(module, modname, strlen(module))) {
bcopy((char *)imp_desc, (char *)desc,
sizeof(image_import_descriptor));
return (0);
}
imp_desc++;
}
return (ENOENT);
}
int
pe_get_messagetable(imgbase, md)
vm_offset_t imgbase;
message_resource_data **md;
{
image_resource_directory *rdir, *rtype;
image_resource_directory_entry *dent, *dent2;
image_resource_data_entry *rent;
vm_offset_t offset;
int i;
if (imgbase == 0)
return (EINVAL);
offset = pe_directory_offset(imgbase, IMAGE_DIRECTORY_ENTRY_RESOURCE);
if (offset == 0)
return (ENOENT);
rdir = (image_resource_directory *)offset;
dent = (image_resource_directory_entry *)(offset +
sizeof(image_resource_directory));
for (i = 0; i < rdir->ird_id_entries; i++){
if (dent->irde_name != RT_MESSAGETABLE) {
dent++;
continue;
}
dent2 = dent;
while (dent2->irde_dataoff & RESOURCE_DIR_FLAG) {
rtype = (image_resource_directory *)(offset +
(dent2->irde_dataoff & ~RESOURCE_DIR_FLAG));
dent2 = (image_resource_directory_entry *)
((uintptr_t)rtype +
sizeof(image_resource_directory));
}
rent = (image_resource_data_entry *)(offset +
dent2->irde_dataoff);
*md = (message_resource_data *)pe_translate_addr(imgbase,
rent->irde_offset);
return (0);
}
return (ENOENT);
}
int
pe_get_message(imgbase, id, str, len, flags)
vm_offset_t imgbase;
uint32_t id;
char **str;
int *len;
uint16_t *flags;
{
message_resource_data *md = NULL;
message_resource_block *mb;
message_resource_entry *me;
uint32_t i;
pe_get_messagetable(imgbase, &md);
if (md == NULL)
return (ENOENT);
mb = (message_resource_block *)((uintptr_t)md +
sizeof(message_resource_data));
for (i = 0; i < md->mrd_numblocks; i++) {
if (id >= mb->mrb_lowid && id <= mb->mrb_highid) {
me = (message_resource_entry *)((uintptr_t)md +
mb->mrb_entryoff);
for (i = id - mb->mrb_lowid; i > 0; i--)
me = (message_resource_entry *)((uintptr_t)me +
me->mre_len);
*str = me->mre_text;
*len = me->mre_len;
*flags = me->mre_flags;
return (0);
}
mb++;
}
return (ENOENT);
}
/*
* Find the function that matches a particular name. This doesn't
* need to be particularly speedy since it's only run when loading
* a module for the first time.
*/
static vm_offset_t
pe_functbl_match(functbl, name)
image_patch_table *functbl;
char *name;
{
image_patch_table *p;
if (functbl == NULL || name == NULL)
return (0);
p = functbl;
while (p->ipt_name != NULL) {
if (!strcmp(p->ipt_name, name))
return ((vm_offset_t)p->ipt_wrap);
p++;
}
printf("no match for %s\n", name);
/*
* Return the wrapper pointer for this routine.
* For x86, this is the same as the funcptr.
* For amd64, this points to a wrapper routine
* that does calling convention translation and
* then invokes the underlying routine.
*/
return ((vm_offset_t)p->ipt_wrap);
}
/*
* Patch the imported function addresses for a given module.
* The caller must specify the module name and provide a table
* of function pointers that will be patched into the jump table.
* Note that there are actually two copies of the jump table: one
* copy is left alone. In a .SYS file, the jump tables are usually
* merged into the INIT segment.
*/
int
pe_patch_imports(imgbase, module, functbl)
vm_offset_t imgbase;
char *module;
image_patch_table *functbl;
{
image_import_descriptor imp_desc;
char *fname;
vm_offset_t *nptr, *fptr;
vm_offset_t func;
if (imgbase == 0 || module == NULL || functbl == NULL)
return (EINVAL);
if (pe_get_import_descriptor(imgbase, &imp_desc, module))
return (ENOEXEC);
nptr = (vm_offset_t *)pe_translate_addr(imgbase,
imp_desc.iid_import_name_table_addr);
fptr = (vm_offset_t *)pe_translate_addr(imgbase,
imp_desc.iid_import_address_table_addr);
while (nptr != NULL && pe_translate_addr(imgbase, *nptr)) {
fname = (char *)pe_translate_addr(imgbase, (*nptr) + 2);
func = pe_functbl_match(functbl, fname);
if (func)
*fptr = func;
#ifdef notdef
if (*fptr == 0)
return (ENOENT);
#endif
nptr++;
fptr++;
}
return (0);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,224 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _USBD_VAR_H_
#define _USBD_VAR_H_
#define IOCTL_INTERNAL_USB_SUBMIT_URB 0x00220003
#define URB_FUNCTION_SELECT_CONFIGURATION 0x0000
#define URB_FUNCTION_ABORT_PIPE 0x0002
#define URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER 0x0009
#define URB_FUNCTION_GET_DESCRIPTOR_FROM_DEVICE 0x000B
#define URB_FUNCTION_VENDOR_DEVICE 0x0017
#define URB_FUNCTION_VENDOR_INTERFACE 0x0018
#define URB_FUNCTION_VENDOR_ENDPOINT 0x0019
#define URB_FUNCTION_CLASS_DEVICE 0x001A
#define URB_FUNCTION_CLASS_INTERFACE 0x001B
#define URB_FUNCTION_CLASS_ENDPOINT 0x001C
#define URB_FUNCTION_CLASS_OTHER 0x001F
#define URB_FUNCTION_VENDOR_OTHER 0x0020
#define USBD_STATUS_SUCCESS 0x00000000
#define USBD_STATUS_CANCELED 0x00010000
#define USBD_STATUS_PENDING 0x40000000
#define USBD_STATUS_NO_MEMORY 0x80000100
#define USBD_STATUS_REQUEST_FAILED 0x80000500
#define USBD_STATUS_INVALID_PIPE_HANDLE 0x80000600
#define USBD_STATUS_ERROR_SHORT_TRANSFER 0x80000900
#define USBD_STATUS_CRC 0xC0000001
#define USBD_STATUS_BTSTUFF 0xC0000002
#define USBD_STATUS_DATA_TOGGLE_MISMATCH 0xC0000003
#define USBD_STATUS_STALL_PID 0xC0000004
#define USBD_STATUS_DEV_NOT_RESPONDING 0xC0000005
#define USBD_STATUS_PID_CHECK_FAILURE 0xC0000006
#define USBD_STATUS_UNEXPECTED_PID 0xC0000007
#define USBD_STATUS_DATA_OVERRUN 0xC0000008
#define USBD_STATUS_DATA_UNDERRUN 0xC0000009
#define USBD_STATUS_RESERVED1 0xC000000A
#define USBD_STATUS_RESERVED2 0xC000000B
#define USBD_STATUS_BUFFER_OVERRUN 0xC000000C
#define USBD_STATUS_BUFFER_UNDERRUN 0xC000000D
#define USBD_STATUS_NOT_ACCESSED 0xC000000F
#define USBD_STATUS_FIFO 0xC0000010
#define USBD_STATUS_XACT_ERROR 0xC0000011
#define USBD_STATUS_BABBLE_DETECTED 0xC0000012
#define USBD_STATUS_DATA_BUFFER_ERROR 0xC0000013
#define USBD_STATUS_NOT_SUPPORTED 0xC0000E00
#define USBD_STATUS_TIMEOUT 0xC0006000
#define USBD_STATUS_DEVICE_GONE 0xC0007000
struct usbd_urb_header {
uint16_t uuh_len;
uint16_t uuh_func;
int32_t uuh_status;
void *uuh_handle;
uint32_t uuh_flags;
};
enum usbd_pipe_type {
UsbdPipeTypeControl = UE_CONTROL,
UsbdPipeTypeIsochronous = UE_ISOCHRONOUS,
UsbdPipeTypeBulk = UE_BULK,
UsbdPipeTypeInterrupt = UE_INTERRUPT
};
struct usbd_pipe_information {
uint16_t upi_maxpktsize;
uint8_t upi_epaddr;
uint8_t upi_interval;
enum usbd_pipe_type upi_type;
usb_endpoint_descriptor_t *upi_handle;
uint32_t upi_maxtxsize;
#define USBD_DEFAULT_MAXIMUM_TRANSFER_SIZE PAGE_SIZE
uint32_t upi_flags;
};
struct usbd_interface_information {
uint16_t uii_len;
uint8_t uii_intfnum;
uint8_t uii_altset;
uint8_t uii_intfclass;
uint8_t uii_intfsubclass;
uint8_t uii_intfproto;
uint8_t uii_reserved;
void *uii_handle;
uint32_t uii_numeps;
struct usbd_pipe_information uii_pipes[1];
};
struct usbd_urb_select_interface {
struct usbd_urb_header usi_hdr;
void *usi_handle;
struct usbd_interface_information uusi_intf;
};
struct usbd_urb_select_configuration {
struct usbd_urb_header usc_hdr;
usb_config_descriptor_t *usc_conf;
void *usc_handle;
struct usbd_interface_information usc_intf;
};
struct usbd_urb_pipe_request {
struct usbd_urb_header upr_hdr;
usb_endpoint_descriptor_t *upr_handle;
};
struct usbd_hcd_area {
void *reserved8[8];
};
struct usbd_urb_bulk_or_intr_transfer {
struct usbd_urb_header ubi_hdr;
usb_endpoint_descriptor_t *ubi_epdesc;
uint32_t ubi_trans_flags;
#define USBD_SHORT_TRANSFER_OK 0x00000002
uint32_t ubi_trans_buflen;
void *ubi_trans_buf;
struct mdl *ubi_mdl;
union usbd_urb *ubi_urblink;
struct usbd_hcd_area ubi_hca;
};
struct usbd_urb_control_descriptor_request {
struct usbd_urb_header ucd_hdr;
void *ucd_reserved0;
uint32_t ucd_reserved1;
uint32_t ucd_trans_buflen;
void *ucd_trans_buf;
struct mdl *ucd_mdl;
union nt_urb *ucd_urblink;
struct usbd_hcd_area ucd_hca;
uint16_t ucd_reserved2;
uint8_t ucd_idx;
uint8_t ucd_desctype;
uint16_t ucd_langid;
uint16_t ucd_reserved3;
};
struct usbd_urb_vendor_or_class_request {
struct usbd_urb_header uvc_hdr;
void *uvc_reserved0;
uint32_t uvc_trans_flags;
#define USBD_TRANSFER_DIRECTION_IN 1
uint32_t uvc_trans_buflen;
void *uvc_trans_buf;
struct mdl *uvc_mdl;
union nt_urb *uvc_urblink;
struct usbd_hcd_area uvc_hca;
uint8_t uvc_reserved1;
uint8_t uvc_req;
uint16_t uvc_value;
uint16_t uvc_idx;
uint16_t uvc_reserved2;
};
struct usbd_interface_list_entry {
usb_interface_descriptor_t *uil_intfdesc;
struct usbd_interface_information *uil_intf;
};
union usbd_urb {
struct usbd_urb_header uu_hdr;
struct usbd_urb_select_configuration uu_selconf;
struct usbd_urb_bulk_or_intr_transfer uu_bulkintr;
struct usbd_urb_control_descriptor_request uu_ctldesc;
struct usbd_urb_vendor_or_class_request uu_vcreq;
struct usbd_urb_pipe_request uu_pipe;
};
#define USBD_URB_STATUS(urb) ((urb)->uu_hdr.uuh_status)
#define USBDI_VERSION 0x00000500
#define USB_VER_1_1 0x00000110
#define USB_VER_2_0 0x00000200
struct usbd_version_info {
uint32_t uvi_usbdi_vers;
uint32_t uvi_supported_vers;
};
typedef struct usbd_version_info usbd_version_info;
extern image_patch_table usbd_functbl[];
__BEGIN_DECLS
extern int usbd_libinit(void);
extern int usbd_libfini(void);
__END_DECLS
#endif /* _USBD_VAR_H_ */

View File

@ -1,385 +0,0 @@
/*-
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
/* The 'ret' macro doesn't work in this file if GPROF is enabled. */
#ifdef GPROF
#undef GPROF
#endif
#include <machine/asmacros.h>
/*
* This file contains assembly language wrappers for the different
* calling conventions supported by Windows on the i386 architecture.
* In FreeBSD, the whole OS typically use same C calling convention
* everywhere, namely _cdecl. Windows, on the other hand, uses several
* different C calling conventions depending on the circumstances:
*
* _stdcall: Used for most ordinary Windows APIs. With _stdcall,
* arguments are passed on the stack, and the callee unwinds the stack
* before returning control to the caller. Not suitable for variadic
* functions.
*
* _fastcall: Used for some APIs that may be invoked frequently and
* where speed is a critical factor (e.g. KeAcquireSpinLock() and
* KeReleaseSpinLock()) Similar to _stdcall, except the first 2 32-bit
* or smaller arguments are passed in the %ecx and %edx registers
* instead of on the stack. Not suitable for variadic functions.
*
* _cdecl: Used for standard C library routines and for variadic
* functions.
*
* _regparm(3): Used for certain assembly routines. All arguments
* passed in %eax, %ecx and %edx.
*
* Furthermore, there is an additional wrinkle that's not obvious
* with all code: Microsoft supports the use of exceptions in C
* (__try/__except) both in user _and_ kernel mode. Sadly, Windows
* structured exception handling uses machine-specific features
* that conflict rather badly with FreeBSD. (See utility routines
* at the end of this module for more details.)
*
* We want to support these calling conventions in as portable a manner
* as possible. The trick is doing it not only with different versions
* of GNU C, but with compilers other than GNU C (e.g. the Solaris
* SunOne C compiler). The only sure fire method is with assembly
* language trampoline code which both fixes up the argument passing,
* stack unwinding and exception/thread context all at once.
*
* You'll notice that we call the thunk/unthunk routines in the
* *_wrap() functions in an awkward way. Rather than branching
* directly to the address, we load the address into a register
* first as a literal value, then we branch to it. This is done
* to insure that the assembler doesn't translate the branch into
* a relative branch. We use the *_wrap() routines here as templates
* and create the actual trampolines at run time, at which point
* we only know the absolute addresses of the thunk and unthunk
* routines. So we need to make sure the templates have enough
* room in them for the full address.
*
* Also note that when we call the a thunk/unthunk routine after
* invoking a wrapped function, we have to make sure to preserve
* the value returned from that function. Most functions return
* a 32-bit value in %eax, however some routines return 64-bit
* values, which span both %eax and %edx. Consequently, we have
* to preserve both registers.
*/
/*
* Handle _stdcall going from Windows to UNIX.
* This is frustrating, because to do it right you have to
* know how many arguments the called function takes, and there's
* no way to figure this out on the fly: you just have to be told
* ahead of time. We assume there will be 16 arguments. I don't
* think there are any Windows APIs that require this many.
*/
.globl x86_stdcall_wrap_call
.globl x86_stdcall_wrap_arg
.globl x86_stdcall_wrap_end
ENTRY(x86_stdcall_wrap)
push %esi
push %edi
sub $64,%esp
mov %esp,%esi
add $64+8+4,%esi
mov %esp,%edi
mov $16,%ecx # handle up to 16 args
rep
movsl
movl $ctxsw_wtou, %eax
call *%eax # unthunk
x86_stdcall_wrap_call:
movl $0,%eax
call *%eax # jump to routine
push %eax # preserve return val
push %edx
movl $ctxsw_utow, %eax
call *%eax # thunk
pop %edx
pop %eax # restore return val
add $64,%esp # clean the stack
pop %edi
pop %esi
x86_stdcall_wrap_arg:
ret $0xFF
x86_stdcall_wrap_end:
/*
* Handle _stdcall going from UNIX to Windows. This routine
* expects to be passed the function to be called, number of
* args and the arguments for the Windows function on the stack.
*/
ENTRY(x86_stdcall_call)
push %esi # must preserve %esi
push %edi # and %edi
mov 16(%esp),%eax # get arg cnt
mov %eax,%ecx # save as copy count
mov %esp,%esi # Set source address register to point to
add $20,%esi # first agument to be forwarded.
shl $2,%eax # turn arg cnt into offset
sub %eax,%esp # shift stack to new location
mov %esp,%edi # store dest copy addr
rep # do the copy
movsl
call ctxsw_utow # thunk
call *12(%edi) # branch to stdcall routine
push %eax # preserve return val
push %edx
call ctxsw_wtou # unthunk
pop %edx
pop %eax # restore return val
mov %edi,%esp # restore stack
pop %edi # restore %edi
pop %esi # and %esi
ret
/*
* Fastcall support. Similar to _stdcall, except the first
* two arguments are passed in %ecx and %edx. It happens we
* only support a small number of _fastcall APIs, none of them
* take more than three arguments. So to keep the code size
* and complexity down, we only handle 3 arguments here.
*/
/* Call _fastcall function going from Windows to UNIX. */
.globl x86_fastcall_wrap_call
.globl x86_fastcall_wrap_arg
.globl x86_fastcall_wrap_end
ENTRY(x86_fastcall_wrap)
mov 4(%esp),%eax
push %eax
push %edx
push %ecx
movl $ctxsw_wtou, %eax
call *%eax # unthunk
x86_fastcall_wrap_call:
mov $0,%eax
call *%eax # branch to fastcall routine
push %eax # preserve return val
push %edx
movl $ctxsw_utow, %eax
call *%eax # thunk
pop %edx
pop %eax # restore return val
add $12,%esp # clean the stack
x86_fastcall_wrap_arg:
ret $0xFF
x86_fastcall_wrap_end:
/*
* Call _fastcall function going from UNIX to Windows.
* This routine isn't normally used since NDIS miniport drivers
* only have _stdcall entry points, but it's provided anyway
* to round out the API, and for testing purposes.
*/
ENTRY(x86_fastcall_call)
mov 4(%esp),%eax
push 16(%esp)
call ctxsw_utow # thunk
mov 12(%esp),%ecx
mov 16(%esp),%edx
call *8(%esp) # branch to fastcall routine
push %eax # preserve return val
push %edx
call ctxsw_wtou # unthunk
pop %edx
pop %eax # restore return val
add $4,%esp # clean the stack
ret
/*
* Call regparm(3) function going from Windows to UNIX. Arguments
* are passed in %eax, %edx and %ecx. Note that while additional
* arguments are passed on the stack, we never bother when them,
* since the only regparm(3) routines we need to wrap never take
* more than 3 arguments.
*/
.globl x86_regparm_wrap_call
.globl x86_regparm_wrap_end
ENTRY(x86_regparm_wrap)
push %ecx
push %edx
push %eax
movl $ctxsw_wtou, %eax
call *%eax # unthunk
x86_regparm_wrap_call:
movl $0,%eax
call *%eax # jump to routine
push %eax # preserve return val
push %edx # preserve return val
movl $ctxsw_utow, %eax
call *%eax # thunk
pop %edx # restore return val
pop %eax # restore return val
add $12,%esp # restore stack
ret
x86_regparm_wrap_end:
/*
* Call regparm(3) function going from UNIX to Windows.
* This routine isn't normally used since NDIS miniport drivers
* only have _stdcall entry points, but it's provided anyway
* to round out the API, and for testing purposes.
*/
ENTRY(x86_regparm_call)
call ctxsw_utow # thunk
mov 8(%esp),%eax
mov 12(%esp),%edx
mov 16(%esp),%ecx
call *4(%esp) # branch to fastcall routine
push %eax # preserve return val
push %edx # preserve return val
call ctxsw_wtou # unthunk
pop %edx # restore return val
pop %eax # restore return val
ret
/*
* Ugly hack alert:
*
* On Win32/i386, using __try/__except results in code that tries to
* manipulate what's supposed to be the Windows Threada Environment
* Block (TEB), which one accesses via the %fs register. In particular,
* %fs:0 (the first DWORD in the TEB) points to the exception
* registration list. Unfortunately, FreeBSD uses %fs for the
* per-cpu data structure (pcpu), and we can't allow Windows code
* to muck with that. I don't even know what Solaris uses %fs for
* (or if it even uses it at all).
*
* Even worse, in 32-bit protected mode, %fs is a selector that
* refers to an entry in either the GDT or the LDT. Ideally, we would
* like to be able to temporarily point it at another descriptor
* while Windows code executes, but to do that we need a separate
* descriptor entry of our own to play with.
*
* Therefore, we go to some trouble to learn the existing layout of
* the GDT and update it to include an extra entry that we can use.
* We need the following utility routines to help us do that. On
* FreeBSD, index #7 in the GDT happens to be unused, so we turn
* this into our own data segment descriptor. It would be better
* if we could use a private LDT entry, but there's no easy way to
* do that in SMP mode because of the way FreeBSD handles user LDTs.
*
* Once we have a custom descriptor, we have to thunk/unthunk whenever
* we cross between FreeBSD code and Windows code. The thunking is
* based on the premise that when executing instructions in the
* Windows binary itself, we won't go to sleep. This is because in
* order to yield the CPU, the code has to call back out to a FreeBSD
* routine first, and when that happens we can unthunk in order to
* restore FreeBSD context. What we're desperately trying to avoid is
* being involuntarily pre-empted with the %fs register still pointing
* to our fake TIB: if FreeBSD code runs with %fs pointing at our
* Windows TIB instead of pcpu, we'll panic the kernel. Fortunately,
* the only way involuntary preemption can occur is if an interrupt
* fires, and the trap handler saves/restores %fs for us.
*
* The thunking routines themselves, ctxsw_utow() (Context SWitch UNIX
* to Windows) and ctxsw_wtou() (Context SWitch Windows to UNIX), are
* external to this module. This is done simply because it's easier
* to manipulate data structures in C rather than assembly.
*/
ENTRY(x86_getldt)
movl 4(%esp),%eax
sgdtl (%eax)
movl 8(%esp),%eax
sldt (%eax)
xor %eax,%eax
ret
ENTRY(x86_setldt)
movl 4(%esp),%eax
lgdt (%eax)
jmp 1f
nop
1:
movl 8(%esp),%eax
lldt %ax
xor %eax,%eax
ret
ENTRY(x86_getfs)
mov %fs,%ax
ret
ENTRY(x86_setfs)
mov 4(%esp),%fs
ret
ENTRY(x86_gettid)
mov %fs:12,%eax
ret
ENTRY(x86_critical_enter)
cli
ret
ENTRY(x86_critical_exit)
sti
ret

View File

@ -1,179 +0,0 @@
/*-
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* The x86_64 callback routines were written and graciously submitted
* by Ville-Pertti Keinonen <will@exomi.com>.
*
* $FreeBSD$
*/
#include <machine/asmacros.h>
/*
* Wrapper for handling up to 16 arguments. We can't really
* know how many arguments the caller will pass us. I'm taking an
* educated guess that we'll never get over 16. Handling too
* few arguments is bad. Handling too many is inefficient, but
* not fatal. If someone can think of a way to handle an arbitrary
* number of arguments with more elegant code, freel free to let
* me know.
*
* Standard amd64 calling conventions specify the following registers
* to be used for passing the first 6 arguments:
*
* %rdi, %rsi, %rdx, %rcx, %r8, %r9
*
* Further arguments are passed on the stack (the 7th argument is
* located immediately after the return address).
*
* Windows x86_64 calling conventions only pass the first 4
* arguments in registers:
*
* %rcx, %rdx, %r8, %r9
*
* Even when arguments are passed in registers, the stack must have
* space reserved for those arguments. Thus the 5th argument (the
* first non-register argument) is placed 32 bytes after the return
* address. Additionally, %rdi and %rsi must be preserved. (These
* two registers are not scratch registers in the standard convention.)
*
* Note that in this template, we load a contrived 64 bit address into
* %r11 to represent our jump address. This is to guarantee that the
* assembler leaves enough room to patch in an absolute 64-bit address
* later. The idea behind this code is that we want to avoid having to
* manually create all the wrapper functions at compile time with
* a bunch of macros. This is doable, but a) messy and b) requires
* us to maintain two separate tables (one for the UNIX function
* pointers and another with the wrappers). This means I'd have to
* update two different tables each time I added a function.
*
* To avoid this, we create the wrappers at runtime instead. The
* image patch tables now contain two pointers: one two the normal
* routine, and a blank one for the wrapper. To construct a wrapper,
* we allocate some memory and copy the template function into it,
* then patch the function pointer for the routine we want to wrap
* into the newly created wrapper. The subr_pe module can then
* simply patch the wrapper routine into the jump table into the
* windows image. As a bonus, the wrapper pointer not only serves
* as the wrapper entry point address, it's also a data pointer
* that we can pass to free() later when we unload the module.
*/
.globl x86_64_wrap_call
.globl x86_64_wrap_end
ENTRY(x86_64_wrap)
push %rbp # insure that the stack
mov %rsp,%rbp # is 16-byte aligned
and $-16,%rsp #
subq $96,%rsp # allocate space on stack
mov %rsi,96-8(%rsp) # save %rsi
mov %rdi,96-16(%rsp)# save %rdi
mov %rcx,%r10 # temporarily save %rcx in scratch
lea 56+8(%rbp),%rsi # source == old stack top (stack+56)
mov %rsp,%rdi # destination == new stack top
mov $10,%rcx # count == 10 quadwords
rep
movsq # copy old stack contents to new location
mov %r10,%rdi # set up arg0 (%rcx -> %rdi)
mov %rdx,%rsi # set up arg1 (%rdx -> %rsi)
mov %r8,%rdx # set up arg2 (%r8 -> %rdx)
mov %r9,%rcx # set up arg3 (%r9 -> %rcx)
mov 40+8(%rbp),%r8 # set up arg4 (stack+40 -> %r8)
mov 48+8(%rbp),%r9 # set up arg5 (stack+48 -> %r9)
xor %rax,%rax # clear return value
x86_64_wrap_call:
mov $0xFF00FF00FF00FF00,%r11
callq *%r11 # call routine
mov 96-16(%rsp),%rdi# restore %rdi
mov 96-8(%rsp),%rsi # restore %rsi
leave # delete space on stack
ret
x86_64_wrap_end:
/*
* Functions for invoking x86_64 callbacks. In each case, the first
* argument is a pointer to the function.
*/
ENTRY(x86_64_call1)
subq $40,%rsp
mov %rsi,%rcx
call *%rdi
addq $40,%rsp
ret
ENTRY(x86_64_call2)
subq $40,%rsp
mov %rsi,%rcx
/* %rdx is already correct */
call *%rdi
addq $40,%rsp
ret
ENTRY(x86_64_call3)
subq $40,%rsp
mov %rcx,%r8
mov %rsi,%rcx
call *%rdi
addq $40,%rsp
ret
ENTRY(x86_64_call4)
subq $40,%rsp
mov %r8,%r9
mov %rcx,%r8
mov %rsi,%rcx
call *%rdi
addq $40,%rsp
ret
ENTRY(x86_64_call5)
subq $48,%rsp
mov %r9,32(%rsp)
mov %r8,%r9
mov %rcx,%r8
mov %rsi,%rcx
call *%rdi
addq $48,%rsp
ret
ENTRY(x86_64_call6)
subq $56,%rsp
mov 56+8(%rsp),%rax
mov %r9,32(%rsp)
mov %rax,40(%rsp)
mov %r8,%r9
mov %rcx,%r8
mov %rsi,%rcx
call *%rdi
addq $56,%rsp
ret

View File

@ -438,7 +438,6 @@ compat/linux/linux.c optional compat_linux32
x86/linux/linux_dummy_x86.c optional compat_linux32
dev/amr/amr_linux.c optional compat_linux32 amr
dev/mfi/mfi_linux.c optional compat_linux32 mfi
compat/ndis/winx64_wrap.S optional ndisapi pci
#
# x86 real mode BIOS emulator, required by dpms/pci/vesa
#

View File

@ -75,7 +75,6 @@ compat/linux/linux_uid16.c optional compat_linux
compat/linux/linux_util.c optional compat_linux
compat/linux/linux_vdso.c optional compat_linux
compat/linux/linux.c optional compat_linux
compat/ndis/winx32_wrap.S optional ndisapi pci
crypto/aesni/aeskeys_i386.S optional aesni
crypto/des/arch/i386/des_enc.S optional netsmb
crypto/openssl/i386/sha1-586.S optional ossl

View File

@ -20,13 +20,6 @@ atkbdmap.h optional atkbd_dflt_keymap \
cddl/dev/fbt/x86/fbt_isa.c optional dtrace_fbt | dtraceall compile-with "${FBT_C}"
cddl/dev/dtrace/x86/dis_tables.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
cddl/dev/dtrace/x86/instr_size.c optional dtrace_fbt | dtraceall compile-with "${DTRACE_C}"
compat/ndis/kern_ndis.c optional ndisapi pci
compat/ndis/kern_windrv.c optional ndisapi pci
compat/ndis/subr_hal.c optional ndisapi pci
compat/ndis/subr_ndis.c optional ndisapi pci
compat/ndis/subr_ntoskrnl.c optional ndisapi pci
compat/ndis/subr_pe.c optional ndisapi pci
compat/ndis/subr_usbd.c optional ndisapi pci
crypto/aesni/aesni.c optional aesni
aesni_ghash.o optional aesni \
dependency "$S/crypto/aesni/aesni_ghash.c" \
@ -157,9 +150,6 @@ dev/hyperv/vmbus/vmbus_if.m optional hyperv
dev/hyperv/vmbus/vmbus_res.c optional hyperv
dev/hyperv/vmbus/vmbus_xact.c optional hyperv
dev/ichwd/ichwd.c optional ichwd
dev/if_ndis/if_ndis.c optional ndis
dev/if_ndis/if_ndis_pci.c optional ndis cardbus | ndis pci
dev/if_ndis/if_ndis_usb.c optional ndis usb
dev/imcsmb/imcsmb.c optional imcsmb
dev/imcsmb/imcsmb_pci.c optional imcsmb pci
dev/intel/spi.c optional intelspi

File diff suppressed because it is too large Load Diff

View File

@ -1,357 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/if_media.h>
#include <net/ethernet.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <net80211/ieee80211_var.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <compat/ndis/pe_var.h>
#include <compat/ndis/cfg_var.h>
#include <compat/ndis/resource_var.h>
#include <compat/ndis/ntoskrnl_var.h>
#include <compat/ndis/ndis_var.h>
#include <dev/if_ndis/if_ndisvar.h>
MODULE_DEPEND(ndis, pci, 1, 1, 1);
static int ndis_probe_pci (device_t);
static int ndis_attach_pci (device_t);
static struct resource_list *ndis_get_resource_list
(device_t, device_t);
static int ndis_devcompare (interface_type,
struct ndis_pci_type *, device_t);
extern int ndisdrv_modevent (module_t, int, void *);
extern int ndis_attach (device_t);
extern int ndis_shutdown (device_t);
extern int ndis_detach (device_t);
extern int ndis_suspend (device_t);
extern int ndis_resume (device_t);
static device_method_t ndis_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ndis_probe_pci),
DEVMETHOD(device_attach, ndis_attach_pci),
DEVMETHOD(device_detach, ndis_detach),
DEVMETHOD(device_shutdown, ndis_shutdown),
DEVMETHOD(device_suspend, ndis_suspend),
DEVMETHOD(device_resume, ndis_resume),
/* Bus interface */
DEVMETHOD(bus_get_resource_list, ndis_get_resource_list),
{ 0, 0 }
};
static driver_t ndis_driver = {
"ndis",
ndis_methods,
sizeof(struct ndis_softc)
};
static devclass_t ndis_devclass;
DRIVER_MODULE(ndis, pci, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
static int
ndis_devcompare(bustype, t, dev)
interface_type bustype;
struct ndis_pci_type *t;
device_t dev;
{
uint16_t vid, did;
uint32_t subsys;
if (bustype != PCIBus)
return(FALSE);
vid = pci_get_vendor(dev);
did = pci_get_device(dev);
subsys = pci_get_subdevice(dev);
subsys = (subsys << 16) | pci_get_subvendor(dev);
while(t->ndis_name != NULL) {
if ((t->ndis_vid == vid) && (t->ndis_did == did) &&
(t->ndis_subsys == subsys || t->ndis_subsys == 0)) {
device_set_desc(dev, t->ndis_name);
return(TRUE);
}
t++;
}
return(FALSE);
}
/*
* Probe for an NDIS device. Check the PCI vendor and device
* IDs against our list and return a device name if we find a match.
*/
static int
ndis_probe_pci(dev)
device_t dev;
{
driver_object *drv;
struct drvdb_ent *db;
drv = windrv_lookup(0, "PCI Bus");
if (drv == NULL)
return(ENXIO);
db = windrv_match((matchfuncptr)ndis_devcompare, dev);
if (db != NULL) {
/* Create PDO for this device instance */
windrv_create_pdo(drv, dev);
return(0);
}
return(ENXIO);
}
/*
* Attach the interface. Allocate softc structures, do ifmedia
* setup and ethernet/BPF attach.
*/
static int
ndis_attach_pci(dev)
device_t dev;
{
struct ndis_softc *sc;
int unit, error = 0, rid;
struct ndis_pci_type *t;
int devidx = 0, defidx = 0;
struct resource_list *rl;
struct resource_list_entry *rle;
struct drvdb_ent *db;
uint16_t vid, did;
uint32_t subsys;
sc = device_get_softc(dev);
unit = device_get_unit(dev);
sc->ndis_dev = dev;
db = windrv_match((matchfuncptr)ndis_devcompare, dev);
if (db == NULL)
return (ENXIO);
sc->ndis_dobj = db->windrv_object;
sc->ndis_regvals = db->windrv_regvals;
/*
* Map control/status registers.
*/
pci_enable_busmaster(dev);
rl = BUS_GET_RESOURCE_LIST(device_get_parent(dev), dev);
if (rl != NULL) {
STAILQ_FOREACH(rle, rl, link) {
switch (rle->type) {
case SYS_RES_IOPORT:
sc->ndis_io_rid = rle->rid;
sc->ndis_res_io = bus_alloc_resource_any(dev,
SYS_RES_IOPORT, &sc->ndis_io_rid,
RF_ACTIVE);
if (sc->ndis_res_io == NULL) {
device_printf(dev,
"couldn't map iospace\n");
error = ENXIO;
goto fail;
}
break;
case SYS_RES_MEMORY:
if (sc->ndis_res_altmem != NULL &&
sc->ndis_res_mem != NULL) {
device_printf(dev,
"too many memory resources\n");
error = ENXIO;
goto fail;
}
if (sc->ndis_res_mem) {
sc->ndis_altmem_rid = rle->rid;
sc->ndis_res_altmem =
bus_alloc_resource_any(dev,
SYS_RES_MEMORY,
&sc->ndis_altmem_rid,
RF_ACTIVE);
if (sc->ndis_res_altmem == NULL) {
device_printf(dev,
"couldn't map alt "
"memory\n");
error = ENXIO;
goto fail;
}
} else {
sc->ndis_mem_rid = rle->rid;
sc->ndis_res_mem =
bus_alloc_resource_any(dev,
SYS_RES_MEMORY,
&sc->ndis_mem_rid,
RF_ACTIVE);
if (sc->ndis_res_mem == NULL) {
device_printf(dev,
"couldn't map memory\n");
error = ENXIO;
goto fail;
}
}
break;
case SYS_RES_IRQ:
rid = rle->rid;
sc->ndis_irq = bus_alloc_resource_any(dev,
SYS_RES_IRQ, &rid,
RF_SHAREABLE | RF_ACTIVE);
if (sc->ndis_irq == NULL) {
device_printf(dev,
"couldn't map interrupt\n");
error = ENXIO;
goto fail;
}
break;
default:
break;
}
sc->ndis_rescnt++;
}
}
/*
* If the BIOS did not set up an interrupt for this device,
* the resource traversal code above will fail to set up
* an IRQ resource. This is usually a bad thing, so try to
* force the allocation of an interrupt here. If one was
* not assigned to us by the BIOS, bus_alloc_resource()
* should route one for us.
*/
if (sc->ndis_irq == NULL) {
rid = 0;
sc->ndis_irq = bus_alloc_resource_any(dev, SYS_RES_IRQ,
&rid, RF_SHAREABLE | RF_ACTIVE);
if (sc->ndis_irq == NULL) {
device_printf(dev, "couldn't route interrupt\n");
error = ENXIO;
goto fail;
}
sc->ndis_rescnt++;
}
/*
* Allocate the parent bus DMA tag appropriate for PCI.
*/
#define NDIS_NSEG_NEW 32
error = bus_dma_tag_create(bus_get_dma_tag(dev),/* PCI parent */
1, 0, /* alignment, boundary */
BUS_SPACE_MAXADDR_32BIT,/* lowaddr */
BUS_SPACE_MAXADDR, /* highaddr */
NULL, NULL, /* filter, filterarg */
DFLTPHYS, NDIS_NSEG_NEW,/* maxsize, nsegments */
BUS_SPACE_MAXSIZE_32BIT,/* maxsegsize */
BUS_DMA_ALLOCNOW, /* flags */
NULL, NULL, /* lockfunc, lockarg */
&sc->ndis_parent_tag);
if (error)
goto fail;
sc->ndis_iftype = PCIBus;
/* Figure out exactly which device we matched. */
vid = pci_get_vendor(dev);
did = pci_get_device(dev);
subsys = pci_get_subdevice(dev);
subsys = (subsys << 16) | pci_get_subvendor(dev);
t = db->windrv_devlist;
while(t->ndis_name != NULL) {
if (t->ndis_vid == vid && t->ndis_did == did) {
if (t->ndis_subsys == 0)
defidx = devidx;
else if (t->ndis_subsys == subsys)
break;
}
t++;
devidx++;
}
if (t->ndis_name == NULL)
sc->ndis_devidx = defidx;
else
sc->ndis_devidx = devidx;
error = ndis_attach(dev);
if (error == 0)
gone_in_dev(dev, 14, "ndis removed");
fail:
return(error);
}
static struct resource_list *
ndis_get_resource_list(dev, child)
device_t dev;
device_t child;
{
struct ndis_softc *sc;
sc = device_get_softc(dev);
return (BUS_GET_RESOURCE_LIST(device_get_parent(sc->ndis_dev), dev));
}

View File

@ -1,240 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sockio.h>
#include <sys/module.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_arp.h>
#include <net/ethernet.h>
#include <net/if_dl.h>
#include <net/if_media.h>
#include <net/bpf.h>
#include <sys/bus.h>
#include <machine/bus.h>
#include <dev/usb/usb.h>
#include <dev/usb/usbdi.h>
#include <net80211/ieee80211_var.h>
#include <compat/ndis/pe_var.h>
#include <compat/ndis/cfg_var.h>
#include <compat/ndis/resource_var.h>
#include <compat/ndis/ntoskrnl_var.h>
#include <compat/ndis/ndis_var.h>
#include <compat/ndis/usbd_var.h>
#include <dev/if_ndis/if_ndisvar.h>
SYSCTL_NODE(_hw, OID_AUTO, ndisusb, CTLFLAG_RD | CTLFLAG_MPSAFE, 0,
"NDIS USB driver parameters");
MODULE_DEPEND(ndis, usb, 1, 1, 1);
static device_probe_t ndisusb_match;
static device_attach_t ndisusb_attach;
static device_detach_t ndisusb_detach;
static bus_get_resource_list_t ndis_get_resource_list;
extern int ndisdrv_modevent (module_t, int, void *);
extern int ndis_attach (device_t);
extern int ndis_shutdown (device_t);
extern int ndis_detach (device_t);
extern int ndis_suspend (device_t);
extern int ndis_resume (device_t);
extern unsigned char drv_data[];
static device_method_t ndis_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, ndisusb_match),
DEVMETHOD(device_attach, ndisusb_attach),
DEVMETHOD(device_detach, ndisusb_detach),
DEVMETHOD(device_shutdown, ndis_shutdown),
/* bus interface */
DEVMETHOD(bus_get_resource_list, ndis_get_resource_list),
DEVMETHOD_END
};
static driver_t ndis_driver = {
"ndis",
ndis_methods,
sizeof(struct ndis_softc)
};
static devclass_t ndis_devclass;
DRIVER_MODULE(ndis, uhub, ndis_driver, ndis_devclass, ndisdrv_modevent, 0);
static int
ndisusb_devcompare(interface_type bustype, struct ndis_usb_type *t, device_t dev)
{
struct usb_attach_arg *uaa;
if (bustype != PNPBus)
return (FALSE);
uaa = device_get_ivars(dev);
while (t->ndis_name != NULL) {
if ((uaa->info.idVendor == t->ndis_vid) &&
(uaa->info.idProduct == t->ndis_did)) {
device_set_desc(dev, t->ndis_name);
return (TRUE);
}
t++;
}
return (FALSE);
}
static int
ndisusb_match(device_t self)
{
struct drvdb_ent *db;
struct usb_attach_arg *uaa = device_get_ivars(self);
if (uaa->usb_mode != USB_MODE_HOST)
return (ENXIO);
if (uaa->info.bConfigIndex != NDISUSB_CONFIG_NO)
return (ENXIO);
if (uaa->info.bIfaceIndex != NDISUSB_IFACE_INDEX)
return (ENXIO);
if (windrv_lookup(0, "USB Bus") == NULL)
return (ENXIO);
db = windrv_match((matchfuncptr)ndisusb_devcompare, self);
if (db == NULL)
return (ENXIO);
uaa->driver_ivar = db;
return (0);
}
static int
ndisusb_attach(device_t self)
{
const struct drvdb_ent *db;
struct ndisusb_softc *dummy = device_get_softc(self);
struct usb_attach_arg *uaa = device_get_ivars(self);
struct ndis_softc *sc;
struct ndis_usb_type *t;
driver_object *drv;
int devidx = 0;
device_set_usb_desc(self);
db = uaa->driver_ivar;
sc = (struct ndis_softc *)dummy;
sc->ndis_dev = self;
mtx_init(&sc->ndisusb_mtx, "NDIS USB", MTX_NETWORK_LOCK, MTX_DEF);
sc->ndis_dobj = db->windrv_object;
sc->ndis_regvals = db->windrv_regvals;
sc->ndis_iftype = PNPBus;
sc->ndisusb_dev = uaa->device;
/* Create PDO for this device instance */
drv = windrv_lookup(0, "USB Bus");
windrv_create_pdo(drv, self);
/* Figure out exactly which device we matched. */
t = db->windrv_devlist;
while (t->ndis_name != NULL) {
if ((uaa->info.idVendor == t->ndis_vid) &&
(uaa->info.idProduct == t->ndis_did)) {
sc->ndis_devidx = devidx;
break;
}
t++;
devidx++;
}
if (ndis_attach(self) != 0)
return (ENXIO);
gone_in_dev(self, 14, "ndis removed");
return (0);
}
static int
ndisusb_detach(device_t self)
{
int i;
struct ndis_softc *sc = device_get_softc(self);
struct ndisusb_ep *ne;
sc->ndisusb_status |= NDISUSB_STATUS_DETACH;
ndis_pnpevent_nic(self, NDIS_PNP_EVENT_SURPRISE_REMOVED);
if (sc->ndisusb_status & NDISUSB_STATUS_SETUP_EP) {
usbd_transfer_unsetup(sc->ndisusb_dread_ep.ne_xfer, 1);
usbd_transfer_unsetup(sc->ndisusb_dwrite_ep.ne_xfer, 1);
}
for (i = 0; i < NDISUSB_ENDPT_MAX; i++) {
ne = &sc->ndisusb_ep[i];
usbd_transfer_unsetup(ne->ne_xfer, 1);
}
(void)ndis_detach(self);
mtx_destroy(&sc->ndisusb_mtx);
return (0);
}
static struct resource_list *
ndis_get_resource_list(device_t dev, device_t child)
{
struct ndis_softc *sc;
sc = device_get_softc(dev);
return (BUS_GET_RESOURCE_LIST(device_get_parent(sc->ndis_dev), dev));
}

View File

@ -1,263 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#define NDIS_DEFAULT_NODENAME "FreeBSD NDIS node"
#define NDIS_NODENAME_LEN 32
/* For setting/getting OIDs from userspace. */
struct ndis_oid_data {
uint32_t oid;
uint32_t len;
#ifdef notdef
uint8_t data[1];
#endif
};
struct ndis_pci_type {
uint16_t ndis_vid;
uint16_t ndis_did;
uint32_t ndis_subsys;
char *ndis_name;
};
struct ndis_pccard_type {
const char *ndis_vid;
const char *ndis_did;
char *ndis_name;
};
struct ndis_usb_type {
uint16_t ndis_vid;
uint16_t ndis_did;
char *ndis_name;
};
struct ndis_shmem {
list_entry ndis_list;
bus_dma_tag_t ndis_stag;
bus_dmamap_t ndis_smap;
void *ndis_saddr;
ndis_physaddr ndis_paddr;
};
struct ndis_cfglist {
ndis_cfg ndis_cfg;
struct sysctl_oid *ndis_oid;
TAILQ_ENTRY(ndis_cfglist) link;
};
/*
* Helper struct to make parsing information
* elements easier.
*/
struct ndis_ie {
uint8_t ni_oui[3];
uint8_t ni_val;
};
TAILQ_HEAD(nch, ndis_cfglist);
#define NDIS_INITIALIZED(sc) (sc->ndis_block->nmb_devicectx != NULL)
#define NDIS_TXPKTS 64
#define NDIS_INC(x) \
(x)->ndis_txidx = ((x)->ndis_txidx + 1) % (x)->ndis_maxpkts
#define NDIS_EVENTS 4
#define NDIS_EVTINC(x) (x) = ((x) + 1) % NDIS_EVENTS
struct ndis_evt {
uint32_t ne_sts;
uint32_t ne_len;
char *ne_buf;
};
struct ndis_vap {
struct ieee80211vap vap;
int (*newstate)(struct ieee80211vap *,
enum ieee80211_state, int);
};
#define NDIS_VAP(vap) ((struct ndis_vap *)(vap))
#define NDISUSB_CONFIG_NO 0
#define NDISUSB_IFACE_INDEX 0
/* XXX at USB2 there's no USBD_NO_TIMEOUT macro anymore */
#define NDISUSB_NO_TIMEOUT 0
#define NDISUSB_INTR_TIMEOUT 1000
#define NDISUSB_TX_TIMEOUT 10000
struct ndisusb_xfer;
struct ndisusb_ep {
struct usb_xfer *ne_xfer[1];
list_entry ne_active;
list_entry ne_pending;
kspin_lock ne_lock;
uint8_t ne_dirin;
};
struct ndisusb_xfer {
struct ndisusb_ep *nx_ep;
void *nx_priv;
uint8_t *nx_urbbuf;
uint32_t nx_urbactlen;
uint32_t nx_urblen;
uint8_t nx_shortxfer;
list_entry nx_next;
};
struct ndisusb_xferdone {
struct ndisusb_xfer *nd_xfer;
usb_error_t nd_status;
list_entry nd_donelist;
};
struct ndisusb_task {
unsigned nt_type;
#define NDISUSB_TASK_TSTART 0
#define NDISUSB_TASK_IRPCANCEL 1
#define NDISUSB_TASK_VENDOR 2
void *nt_ctx;
list_entry nt_tasklist;
};
struct ndis_softc {
#define NDISUSB_GET_IFNET(ndis_softc) ( (ndis_softc)->ndis_80211 ? NULL : (ndis_softc)->ifp )
u_int ndis_80211:1,
ndis_link:1,
ndis_running:1;
union {
struct { /* Ethernet */
struct ifnet *ifp;
struct ifmedia ifmedia;
int ndis_if_flags;
};
struct { /* Wireless */
struct ieee80211com ndis_ic;
struct callout ndis_scan_callout;
int (*ndis_newstate)(struct ieee80211com *,
enum ieee80211_state, int);
};
};
u_long ndis_hwassist;
uint32_t ndis_v4tx;
uint32_t ndis_v4rx;
bus_space_handle_t ndis_bhandle;
bus_space_tag_t ndis_btag;
void *ndis_intrhand;
struct resource *ndis_irq;
struct resource *ndis_res;
struct resource *ndis_res_io;
int ndis_io_rid;
struct resource *ndis_res_mem;
int ndis_mem_rid;
struct resource *ndis_res_altmem;
int ndis_altmem_rid;
struct resource *ndis_res_am; /* attribute mem (pccard) */
int ndis_am_rid;
struct resource *ndis_res_cm; /* common mem (pccard) */
struct resource_list ndis_rl;
int ndis_rescnt;
struct mtx ndis_mtx;
uint8_t ndis_irql;
device_t ndis_dev;
int ndis_unit;
ndis_miniport_block *ndis_block;
ndis_miniport_characteristics *ndis_chars;
interface_type ndis_type;
struct callout ndis_stat_callout;
int ndis_maxpkts;
ndis_oid *ndis_oids;
int ndis_oidcnt;
int ndis_txidx;
int ndis_txpending;
ndis_packet **ndis_txarray;
ndis_handle ndis_txpool;
int ndis_sc;
ndis_cfg *ndis_regvals;
struct nch ndis_cfglist_head;
uint32_t ndis_sts;
uint32_t ndis_filter;
int ndis_skip;
int ndis_devidx;
interface_type ndis_iftype;
driver_object *ndis_dobj;
io_workitem *ndis_tickitem;
io_workitem *ndis_startitem;
io_workitem *ndis_resetitem;
io_workitem *ndis_inputitem;
kdpc ndis_rxdpc;
bus_dma_tag_t ndis_parent_tag;
list_entry ndis_shlist;
bus_dma_tag_t ndis_mtag;
bus_dma_tag_t ndis_ttag;
bus_dmamap_t *ndis_mmaps;
bus_dmamap_t *ndis_tmaps;
int ndis_mmapcnt;
struct ndis_evt ndis_evt[NDIS_EVENTS];
int ndis_evtpidx;
int ndis_evtcidx;
struct mbufq ndis_rxqueue;
kspin_lock ndis_rxlock;
int ndis_tx_timer;
int ndis_hang_timer;
struct usb_device *ndisusb_dev;
struct mtx ndisusb_mtx;
struct ndisusb_ep ndisusb_dread_ep;
struct ndisusb_ep ndisusb_dwrite_ep;
#define NDISUSB_GET_ENDPT(addr) \
((UE_GET_DIR(addr) >> 7) | (UE_GET_ADDR(addr) << 1))
#define NDISUSB_ENDPT_MAX ((UE_ADDR + 1) * 2)
struct ndisusb_ep ndisusb_ep[NDISUSB_ENDPT_MAX];
io_workitem *ndisusb_xferdoneitem;
list_entry ndisusb_xferdonelist;
kspin_lock ndisusb_xferdonelock;
io_workitem *ndisusb_taskitem;
list_entry ndisusb_tasklist;
kspin_lock ndisusb_tasklock;
int ndisusb_status;
#define NDISUSB_STATUS_DETACH 0x1
#define NDISUSB_STATUS_SETUP_EP 0x2
};
#define NDIS_LOCK(_sc) mtx_lock(&(_sc)->ndis_mtx)
#define NDIS_UNLOCK(_sc) mtx_unlock(&(_sc)->ndis_mtx)
#define NDIS_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndis_mtx, t)
#define NDISUSB_LOCK(_sc) mtx_lock(&(_sc)->ndisusb_mtx)
#define NDISUSB_UNLOCK(_sc) mtx_unlock(&(_sc)->ndisusb_mtx)
#define NDISUSB_LOCK_ASSERT(_sc, t) mtx_assert(&(_sc)->ndisusb_mtx, t)

View File

@ -159,7 +159,6 @@ SUBDIR= \
${_if_me} \
if_infiniband \
if_lagg \
${_if_ndis} \
${_if_stf} \
if_tuntap \
if_vlan \
@ -261,7 +260,6 @@ SUBDIR= \
mxge \
my \
${_nctgpio} \
${_ndis} \
${_netgraph} \
${_nfe} \
nfscl \
@ -634,7 +632,6 @@ _em= em
_et= et
_ftwd= ftwd
_exca= exca
_if_ndis= if_ndis
_io= io
_itwd= itwd
_ix= ix
@ -643,7 +640,6 @@ _ixv= ixv
_lio= lio
.endif
_nctgpio= nctgpio
_ndis= ndis
_ntb= ntb
_ocs_fc= ocs_fc
_pccard= pccard

View File

@ -1,10 +0,0 @@
# $FreeBSD$
.PATH: ${SRCTOP}/sys/dev/if_ndis
KMOD= if_ndis
SRCS= if_ndis.c if_ndis_pci.c if_ndis_usb.c
SRCS+= device_if.h bus_if.h pci_if.h
SRCS+= opt_bus.h opt_usb.h usb_if.h usbdevs.h
.include <bsd.kmod.mk>

View File

@ -737,7 +737,6 @@ DIRDEPS+= \
usr.sbin/wlandebug \
usr.sbin/wpa/hostapd \
usr.sbin/wpa/hostapd_cli \
usr.sbin/wpa/ndis_events \
usr.sbin/wpa/wpa_cli \
usr.sbin/wpa/wpa_passphrase \
usr.sbin/wpa/wpa_supplicant \
@ -788,7 +787,6 @@ DIRDEPS.amd64= \
usr.sbin/kgmon \
usr.sbin/lptcontrol \
usr.sbin/mptable \
usr.sbin/ndiscvt \
usr.sbin/spkrtest \
usr.sbin/sade \
usr.sbin/zzz
@ -814,7 +812,6 @@ DIRDEPS.i386= \
usr.sbin/kgmon \
usr.sbin/lptcontrol \
usr.sbin/mptable \
usr.sbin/ndiscvt \
usr.sbin/pnpinfo \
usr.sbin/sade \
usr.sbin/spkrtest \

View File

@ -5938,14 +5938,6 @@ OLD_FILES+=usr/share/man/whatis
OLD_FILES+=usr/share/openssl/man/whatis
.endif
.if ${MK_NDIS} == no
OLD_FILES+=usr/sbin/ndiscvt
OLD_FILES+=usr/sbin/ndisgen
OLD_FILES+=usr/share/man/man8/ndiscvt.8.gz
OLD_FILES+=usr/share/man/man8/ndisgen.8.gz
OLD_FILES+=usr/share/misc/windrv_stub.c
.endif
.if ${MK_NETCAT} == no
OLD_FILES+=rescue/nc
OLD_FILES+=usr/bin/nc

View File

@ -1,21 +0,0 @@
# Doxyfile 1.5.2
# $FreeBSD$
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
PROJECT_NAME = "FreeBSD kernel IF_NDIS device code"
OUTPUT_DIRECTORY = $(DOXYGEN_DEST_PATH)/dev_if_ndis/
EXTRACT_ALL = YES # for undocumented src, no warnings enabled
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = $(DOXYGEN_SRC_PATH)/dev/if_ndis/ \
$(NOTREVIEWED)
GENERATE_TAGFILE = dev_if_ndis/dev_if_ndis.tag
@INCLUDE_PATH = $(DOXYGEN_INCLUDE_PATH)
@INCLUDE = common-Doxyfile

View File

@ -24,8 +24,5 @@ SUBDIR+= hyperv
SUBDIR+= kgmon
SUBDIR+= lptcontrol
SUBDIR+= mptable
.if ${MK_NDIS} != "no"
SUBDIR+= ndiscvt
.endif
SUBDIR+= spkrtest
SUBDIR+= zzz

View File

@ -18,9 +18,6 @@ SUBDIR+= hyperv
SUBDIR+= kgmon
SUBDIR+= lptcontrol
SUBDIR+= mptable
.if ${MK_NDIS} != "no"
SUBDIR+= ndiscvt
.endif
SUBDIR+= pnpinfo
SUBDIR+= spkrtest
SUBDIR+= zzz

View File

@ -1,27 +0,0 @@
# $FreeBSD$
.PATH: ${SRCTOP}/sys/compat/ndis
PROG= ndiscvt
SRCS= ndiscvt.c
SRCS+= subr_pe.c
SRCS+= inf.c inf-token.l inf-parse.y y.tab.h
MAN= ndiscvt.8
MAN+= ndisgen.8
WARNS?= 4
NO_WCAST_ALIGN=
YFLAGS+=-v
CFLAGS+=-I. -I${.CURDIR} -I${SRCTOP}/sys
CLEANFILES= y.output
FILES= windrv_stub.c
FILESDIR= ${SHAREDIR}/misc
SCRIPTS= ndisgen.sh
.include <bsd.prog.mk>

View File

@ -1,19 +0,0 @@
# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
gnu/lib/csu \
include \
include/xlocale \
lib/${CSU_DIR} \
lib/libc \
lib/libcompiler_rt \
usr.bin/lex/lib \
usr.bin/yacc.host \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View File

@ -1,112 +0,0 @@
%{
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <sys/types.h>
#include <sys/queue.h>
#include "inf.h"
extern int yylex (void);
extern void yyerror(const char *);
%}
%token EQUALS COMMA EOL
%token <str> SECTION
%token <str> STRING
%token <str> WORD
%union {
char *str;
}
%%
inf_file
: inf_list
|
;
inf_list
: inf
| inf_list inf
;
inf
: SECTION EOL
{ section_add($1); }
| WORD EQUALS assign EOL
{ assign_add($1); }
| WORD COMMA regkey EOL
{ regkey_add($1); }
| WORD EOL
{ define_add($1); }
| EOL
;
assign
: WORD
{ push_word($1); }
| STRING
{ push_word($1); }
| WORD COMMA assign
{ push_word($1); }
| STRING COMMA assign
{ push_word($1); }
| COMMA assign
{ push_word(NULL); }
| COMMA
{ push_word(NULL); }
|
;
regkey
: WORD
{ push_word($1); }
| STRING
{ push_word($1); }
| WORD COMMA regkey
{ push_word($1); }
| STRING COMMA regkey
{ push_word($1); }
| COMMA regkey
{ push_word(NULL); }
| COMMA
{ push_word(NULL); }
;
%%

View File

@ -1,134 +0,0 @@
%{
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <regex.h>
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
int lineno = 1;
int yylex(void);
void yyerror(const char *);
static void
update_lineno(const char *cp)
{
while (*cp)
if (*cp++ == '\n')
lineno++;
}
%}
%option noyywrap
%option nounput
%option noinput
%%
[ \t]+ ;
\n { lineno++; return EOL; }
\r ;
;.*$ ;
\/\/.*$ ;
= { return EQUALS; }
, { return COMMA; }
\"(\\\"|[^"]|\"\")*\" {
int len = strlen(yytext) - 2;
int blen = len + 1;
char *walker;
int i;
update_lineno(yytext);
yylval.str = (char *)malloc(blen);
if (yylval.str == NULL)
goto out;
walker = yylval.str;
for (i = 1; i <= len; i++) {
if (yytext[i] == '\"') {
switch (yytext[i + 1]) {
case '\"':
i++;
break;
default:
break;
}
}
if (yytext[i] == '\\') {
switch (yytext[i + 1]) {
case '\n':
i += 2;
while(isspace(yytext[i]))
i++;
break;
case '\"':
i++;
break;
case '(':
i++;
break;
default:
break;
}
}
*walker++ = yytext[i];
}
*walker++ = '\0';
out:;
return STRING;
}
\[[a-zA-Z0-9%&\{\}\-\.\/_\\\*\ ]+\] {
int len = strlen(yytext);
yytext[len-1] = '\0';
yylval.str = strdup(yytext+1);
return SECTION;
}
[a-zA-Z0-9%&\{\}\-\.\/_\\\*]+ {
yylval.str = strdup(yytext);
return WORD;
}
%%
void
yyerror(const char *s)
{
errx(1, "line %d: %s%s %s.", lineno, yytext, yytext?":":"", s);
}

View File

@ -1,920 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/queue.h>
#include "inf.h"
extern FILE *yyin;
int yyparse (void);
const char *words[W_MAX]; /* More than we'll need. */
int idx;
static struct section_head sh;
static struct reg_head rh;
static struct assign_head ah;
static char *sstrdup (const char *);
static struct assign
*find_assign (const char *, const char *);
static struct assign
*find_next_assign
(struct assign *);
static struct section
*find_section (const char *);
static int dump_deviceids_pci (void);
static int dump_deviceids_pcmcia (void);
static int dump_deviceids_usb (void);
static void dump_pci_id (const char *);
static void dump_pcmcia_id (const char *);
static void dump_usb_id (const char *);
static void dump_regvals (void);
static void dump_paramreg (const struct section *,
const struct reg *, int);
static FILE *ofp;
int
inf_parse (FILE *fp, FILE *outfp)
{
TAILQ_INIT(&sh);
TAILQ_INIT(&rh);
TAILQ_INIT(&ah);
ofp = outfp;
yyin = fp;
yyparse();
if (dump_deviceids_pci() == 0 &&
dump_deviceids_pcmcia() == 0 &&
dump_deviceids_usb() == 0)
return (-1);
fprintf(outfp, "#ifdef NDIS_REGVALS\n");
dump_regvals();
fprintf(outfp, "#endif /* NDIS_REGVALS */\n");
return (0);
}
void
section_add (const char *s)
{
struct section *sec;
sec = malloc(sizeof(struct section));
bzero(sec, sizeof(struct section));
sec->name = s;
TAILQ_INSERT_TAIL(&sh, sec, link);
return;
}
static struct assign *
find_assign (const char *s, const char *k)
{
struct assign *assign;
char newkey[256];
/* Deal with string section lookups. */
if (k != NULL && k[0] == '%') {
bzero(newkey, sizeof(newkey));
strncpy(newkey, k + 1, strlen(k) - 2);
k = newkey;
}
TAILQ_FOREACH(assign, &ah, link) {
if (strcasecmp(assign->section->name, s) == 0) {
if (k == NULL)
return(assign);
else
if (strcasecmp(assign->key, k) == 0)
return(assign);
}
}
return(NULL);
}
static struct assign *
find_next_assign (struct assign *a)
{
struct assign *assign;
TAILQ_FOREACH(assign, &ah, link) {
if (assign == a)
break;
}
assign = assign->link.tqe_next;
if (assign == NULL || assign->section != a->section)
return(NULL);
return (assign);
}
static const char *
stringcvt(const char *s)
{
struct assign *manf;
manf = find_assign("strings", s);
if (manf == NULL)
return(s);
return(manf->vals[0]);
}
struct section *
find_section (const char *s)
{
struct section *section;
TAILQ_FOREACH(section, &sh, link) {
if (strcasecmp(section->name, s) == 0)
return(section);
}
return(NULL);
}
static void
dump_pcmcia_id(const char *s)
{
char *manstr, *devstr;
char *p0, *p;
p0 = __DECONST(char *, s);
p = strchr(p0, '\\');
if (p == NULL)
return;
p0 = p + 1;
p = strchr(p0, '-');
if (p == NULL)
return;
*p = '\0';
manstr = p0;
/* Convert any underscores to spaces. */
while (*p0 != '\0') {
if (*p0 == '_')
*p0 = ' ';
p0++;
}
p0 = p + 1;
p = strchr(p0, '-');
if (p == NULL)
return;
*p = '\0';
devstr = p0;
/* Convert any underscores to spaces. */
while (*p0 != '\0') {
if (*p0 == '_')
*p0 = ' ';
p0++;
}
fprintf(ofp, "\t\\\n\t{ \"%s\", \"%s\", ", manstr, devstr);
return;
}
static void
dump_pci_id(const char *s)
{
char *p;
char vidstr[7], didstr[7], subsysstr[14];
p = strcasestr(s, "VEN_");
if (p == NULL)
return;
p += 4;
strcpy(vidstr, "0x");
strncat(vidstr, p, 4);
p = strcasestr(s, "DEV_");
if (p == NULL)
return;
p += 4;
strcpy(didstr, "0x");
strncat(didstr, p, 4);
if (p == NULL)
return;
p = strcasestr(s, "SUBSYS_");
if (p == NULL)
strcpy(subsysstr, "0x00000000");
else {
p += 7;
strcpy(subsysstr, "0x");
strncat(subsysstr, p, 8);
}
fprintf(ofp, "\t\\\n\t{ %s, %s, %s, ", vidstr, didstr, subsysstr);
return;
}
static void
dump_usb_id(const char *s)
{
char *p;
char vidstr[7], pidstr[7];
p = strcasestr(s, "VID_");
if (p == NULL)
return;
p += 4;
strcpy(vidstr, "0x");
strncat(vidstr, p, 4);
p = strcasestr(s, "PID_");
if (p == NULL)
return;
p += 4;
strcpy(pidstr, "0x");
strncat(pidstr, p, 4);
if (p == NULL)
return;
fprintf(ofp, "\t\\\n\t{ %s, %s, ", vidstr, pidstr);
}
static int
dump_deviceids_pci()
{
struct assign *manf, *dev;
struct section *sec;
struct assign *assign;
char xpsec[256];
int first = 1, found = 0;
/* Find manufacturer name */
manf = find_assign("Manufacturer", NULL);
nextmanf:
/* Find manufacturer section */
if (manf->vals[1] != NULL &&
(strcasecmp(manf->vals[1], "NT.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTx86") == 0 ||
strcasecmp(manf->vals[1], "NTx86.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTamd64") == 0)) {
/* Handle Windows XP INF files. */
snprintf(xpsec, sizeof(xpsec), "%s.%s",
manf->vals[0], manf->vals[1]);
sec = find_section(xpsec);
} else
sec = find_section(manf->vals[0]);
/* See if there are any PCI device definitions. */
TAILQ_FOREACH(assign, &ah, link) {
if (assign->section == sec) {
dev = find_assign("strings", assign->key);
if (strcasestr(assign->vals[1], "PCI") != NULL) {
found++;
break;
}
}
}
if (found == 0)
goto done;
found = 0;
if (first == 1) {
/* Emit start of PCI device table */
fprintf (ofp, "#define NDIS_PCI_DEV_TABLE");
first = 0;
}
retry:
/*
* Now run through all the device names listed
* in the manufacturer section and dump out the
* device descriptions and vendor/device IDs.
*/
TAILQ_FOREACH(assign, &ah, link) {
if (assign->section == sec) {
dev = find_assign("strings", assign->key);
/* Emit device IDs. */
if (strcasestr(assign->vals[1], "PCI") != NULL)
dump_pci_id(assign->vals[1]);
else
continue;
/* Emit device description */
fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]);
found++;
}
}
/* Someone tried to fool us. Shame on them. */
if (!found) {
found++;
sec = find_section(manf->vals[0]);
goto retry;
}
/* Handle Manufacturer sections with multiple entries. */
manf = find_next_assign(manf);
if (manf != NULL)
goto nextmanf;
done:
/* Emit end of table */
fprintf(ofp, "\n\n");
return (found);
}
static int
dump_deviceids_pcmcia()
{
struct assign *manf, *dev;
struct section *sec;
struct assign *assign;
char xpsec[256];
int first = 1, found = 0;
/* Find manufacturer name */
manf = find_assign("Manufacturer", NULL);
nextmanf:
/* Find manufacturer section */
if (manf->vals[1] != NULL &&
(strcasecmp(manf->vals[1], "NT.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTx86") == 0 ||
strcasecmp(manf->vals[1], "NTx86.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTamd64") == 0)) {
/* Handle Windows XP INF files. */
snprintf(xpsec, sizeof(xpsec), "%s.%s",
manf->vals[0], manf->vals[1]);
sec = find_section(xpsec);
} else
sec = find_section(manf->vals[0]);
/* See if there are any PCMCIA device definitions. */
TAILQ_FOREACH(assign, &ah, link) {
if (assign->section == sec) {
dev = find_assign("strings", assign->key);
if (strcasestr(assign->vals[1], "PCMCIA") != NULL) {
found++;
break;
}
}
}
if (found == 0)
goto done;
found = 0;
if (first == 1) {
/* Emit start of PCMCIA device table */
fprintf (ofp, "#define NDIS_PCMCIA_DEV_TABLE");
first = 0;
}
retry:
/*
* Now run through all the device names listed
* in the manufacturer section and dump out the
* device descriptions and vendor/device IDs.
*/
TAILQ_FOREACH(assign, &ah, link) {
if (assign->section == sec) {
dev = find_assign("strings", assign->key);
/* Emit device IDs. */
if (strcasestr(assign->vals[1], "PCMCIA") != NULL)
dump_pcmcia_id(assign->vals[1]);
else
continue;
/* Emit device description */
fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]);
found++;
}
}
/* Someone tried to fool us. Shame on them. */
if (!found) {
found++;
sec = find_section(manf->vals[0]);
goto retry;
}
/* Handle Manufacturer sections with multiple entries. */
manf = find_next_assign(manf);
if (manf != NULL)
goto nextmanf;
done:
/* Emit end of table */
fprintf(ofp, "\n\n");
return (found);
}
static int
dump_deviceids_usb()
{
struct assign *manf, *dev;
struct section *sec;
struct assign *assign;
char xpsec[256];
int first = 1, found = 0;
/* Find manufacturer name */
manf = find_assign("Manufacturer", NULL);
nextmanf:
/* Find manufacturer section */
if (manf->vals[1] != NULL &&
(strcasecmp(manf->vals[1], "NT.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTx86") == 0 ||
strcasecmp(manf->vals[1], "NTx86.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTamd64") == 0)) {
/* Handle Windows XP INF files. */
snprintf(xpsec, sizeof(xpsec), "%s.%s",
manf->vals[0], manf->vals[1]);
sec = find_section(xpsec);
} else
sec = find_section(manf->vals[0]);
/* See if there are any USB device definitions. */
TAILQ_FOREACH(assign, &ah, link) {
if (assign->section == sec) {
dev = find_assign("strings", assign->key);
if (strcasestr(assign->vals[1], "USB") != NULL) {
found++;
break;
}
}
}
if (found == 0)
goto done;
found = 0;
if (first == 1) {
/* Emit start of USB device table */
fprintf (ofp, "#define NDIS_USB_DEV_TABLE");
first = 0;
}
retry:
/*
* Now run through all the device names listed
* in the manufacturer section and dump out the
* device descriptions and vendor/device IDs.
*/
TAILQ_FOREACH(assign, &ah, link) {
if (assign->section == sec) {
dev = find_assign("strings", assign->key);
/* Emit device IDs. */
if (strcasestr(assign->vals[1], "USB") != NULL)
dump_usb_id(assign->vals[1]);
else
continue;
/* Emit device description */
fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]);
found++;
}
}
/* Someone tried to fool us. Shame on them. */
if (!found) {
found++;
sec = find_section(manf->vals[0]);
goto retry;
}
/* Handle Manufacturer sections with multiple entries. */
manf = find_next_assign(manf);
if (manf != NULL)
goto nextmanf;
done:
/* Emit end of table */
fprintf(ofp, "\n\n");
return (found);
}
static void
dump_addreg(const char *s, int devidx)
{
struct section *sec;
struct reg *reg;
/* Find the addreg section */
sec = find_section(s);
/* Dump all the keys defined in it. */
TAILQ_FOREACH(reg, &rh, link) {
/*
* Keys with an empty subkey are very easy to parse,
* so just deal with them here. If a parameter key
* of the same name also exists, prefer that one and
* skip this one.
*/
if (reg->section == sec) {
if (reg->subkey == NULL) {
fprintf(ofp, "\n\t{ \"%s\",", reg->key);
fprintf(ofp,"\n\t\"%s \",", reg->key);
fprintf(ofp, "\n\t{ \"%s\" }, %d },",
reg->value == NULL ? "" :
stringcvt(reg->value), devidx);
} else if (strncasecmp(reg->subkey,
"Ndi\\params", strlen("Ndi\\params")-1) == 0 &&
(reg->key != NULL && strcasecmp(reg->key,
"ParamDesc") == 0))
dump_paramreg(sec, reg, devidx);
}
}
return;
}
static void
dump_enumreg(const struct section *s, const struct reg *r)
{
struct reg *reg;
char enumkey[256];
sprintf(enumkey, "%s\\enum", r->subkey);
TAILQ_FOREACH(reg, &rh, link) {
if (reg->section != s)
continue;
if (reg->subkey == NULL || strcasecmp(reg->subkey, enumkey))
continue;
fprintf(ofp, " [%s=%s]", reg->key,
stringcvt(reg->value));
}
return;
}
static void
dump_editreg(const struct section *s, const struct reg *r)
{
struct reg *reg;
TAILQ_FOREACH(reg, &rh, link) {
if (reg->section != s)
continue;
if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey))
continue;
if (reg->key == NULL)
continue;
if (strcasecmp(reg->key, "LimitText") == 0)
fprintf(ofp, " [maxchars=%s]", reg->value);
if (strcasecmp(reg->key, "Optional") == 0 &&
strcmp(reg->value, "1") == 0)
fprintf(ofp, " [optional]");
}
return;
}
/* Use this for int too */
static void
dump_dwordreg(const struct section *s, const struct reg *r)
{
struct reg *reg;
TAILQ_FOREACH(reg, &rh, link) {
if (reg->section != s)
continue;
if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey))
continue;
if (reg->key == NULL)
continue;
if (strcasecmp(reg->key, "min") == 0)
fprintf(ofp, " [min=%s]", reg->value);
if (strcasecmp(reg->key, "max") == 0)
fprintf(ofp, " [max=%s]", reg->value);
}
return;
}
static void
dump_defaultinfo(const struct section *s, const struct reg *r, int devidx)
{
struct reg *reg;
TAILQ_FOREACH(reg, &rh, link) {
if (reg->section != s)
continue;
if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey))
continue;
if (reg->key == NULL || strcasecmp(reg->key, "Default"))
continue;
fprintf(ofp, "\n\t{ \"%s\" }, %d },", reg->value == NULL ? "" :
stringcvt(reg->value), devidx);
return;
}
/* Default registry entry missing */
fprintf(ofp, "\n\t{ \"\" }, %d },", devidx);
return;
}
static void
dump_paramdesc(const struct section *s, const struct reg *r)
{
struct reg *reg;
TAILQ_FOREACH(reg, &rh, link) {
if (reg->section != s)
continue;
if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey))
continue;
if (reg->key == NULL || strcasecmp(reg->key, "ParamDesc"))
continue;
fprintf(ofp, "\n\t\"%s", stringcvt(r->value));
break;
}
return;
}
static void
dump_typeinfo(const struct section *s, const struct reg *r)
{
struct reg *reg;
TAILQ_FOREACH(reg, &rh, link) {
if (reg->section != s)
continue;
if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey))
continue;
if (reg->key == NULL)
continue;
if (strcasecmp(reg->key, "type"))
continue;
if (strcasecmp(reg->value, "dword") == 0 ||
strcasecmp(reg->value, "int") == 0)
dump_dwordreg(s, r);
if (strcasecmp(reg->value, "enum") == 0)
dump_enumreg(s, r);
if (strcasecmp(reg->value, "edit") == 0)
dump_editreg(s, r);
}
return;
}
static void
dump_paramreg(const struct section *s, const struct reg *r, int devidx)
{
const char *keyname;
keyname = r->subkey + strlen("Ndi\\params\\");
fprintf(ofp, "\n\t{ \"%s\",", keyname);
dump_paramdesc(s, r);
dump_typeinfo(s, r);
fprintf(ofp, "\",");
dump_defaultinfo(s, r, devidx);
return;
}
static void
dump_regvals(void)
{
struct assign *manf, *dev;
struct section *sec;
struct assign *assign;
char sname[256];
int found = 0, i, is_winxp = 0, is_winnt = 0, devidx = 0;
/* Find signature to check for special case of WinNT. */
assign = find_assign("version", "signature");
if (strcasecmp(assign->vals[0], "$windows nt$") == 0)
is_winnt++;
/* Emit start of block */
fprintf (ofp, "ndis_cfg ndis_regvals[] = {");
/* Find manufacturer name */
manf = find_assign("Manufacturer", NULL);
nextmanf:
/* Find manufacturer section */
if (manf->vals[1] != NULL &&
(strcasecmp(manf->vals[1], "NT.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTx86") == 0 ||
strcasecmp(manf->vals[1], "NTx86.5.1") == 0 ||
strcasecmp(manf->vals[1], "NTamd64") == 0)) {
is_winxp++;
/* Handle Windows XP INF files. */
snprintf(sname, sizeof(sname), "%s.%s",
manf->vals[0], manf->vals[1]);
sec = find_section(sname);
} else
sec = find_section(manf->vals[0]);
retry:
TAILQ_FOREACH(assign, &ah, link) {
if (assign->section == sec) {
found++;
/*
* Find all the AddReg sections.
* Look for section names with .NT, unless
* this is a WinXP .INF file.
*/
if (is_winxp) {
sprintf(sname, "%s.NTx86", assign->vals[0]);
dev = find_assign(sname, "AddReg");
if (dev == NULL) {
sprintf(sname, "%s.NT",
assign->vals[0]);
dev = find_assign(sname, "AddReg");
}
if (dev == NULL)
dev = find_assign(assign->vals[0],
"AddReg");
} else {
sprintf(sname, "%s.NT", assign->vals[0]);
dev = find_assign(sname, "AddReg");
if (dev == NULL && is_winnt)
dev = find_assign(assign->vals[0],
"AddReg");
}
/* Section not found. */
if (dev == NULL)
continue;
for (i = 0; i < W_MAX; i++) {
if (dev->vals[i] != NULL)
dump_addreg(dev->vals[i], devidx);
}
devidx++;
}
}
if (!found) {
sec = find_section(manf->vals[0]);
is_winxp = 0;
found++;
goto retry;
}
manf = find_next_assign(manf);
if (manf != NULL)
goto nextmanf;
fprintf(ofp, "\n\t{ NULL, NULL, { 0 }, 0 }\n};\n\n");
return;
}
void
assign_add (const char *a)
{
struct assign *assign;
int i;
assign = malloc(sizeof(struct assign));
bzero(assign, sizeof(struct assign));
assign->section = TAILQ_LAST(&sh, section_head);
assign->key = sstrdup(a);
for (i = 0; i < idx; i++)
assign->vals[(idx - 1) - i] = sstrdup(words[i]);
TAILQ_INSERT_TAIL(&ah, assign, link);
clear_words();
return;
}
void
define_add (const char *d __unused)
{
#ifdef notdef
fprintf(stderr, "define \"%s\"\n", d);
#endif
return;
}
static char *
sstrdup(const char *str)
{
if (str != NULL && strlen(str))
return (strdup(str));
return (NULL);
}
static int
satoi (const char *nptr)
{
if (nptr != NULL && strlen(nptr))
return (atoi(nptr));
return (0);
}
void
regkey_add (const char *r)
{
struct reg *reg;
reg = malloc(sizeof(struct reg));
bzero(reg, sizeof(struct reg));
reg->section = TAILQ_LAST(&sh, section_head);
reg->root = sstrdup(r);
reg->subkey = sstrdup(words[3]);
reg->key = sstrdup(words[2]);
reg->flags = satoi(words[1]);
reg->value = sstrdup(words[0]);
TAILQ_INSERT_TAIL(&rh, reg, link);
free(__DECONST(char *, r));
clear_words();
return;
}
void
push_word (const char *w)
{
if (idx == W_MAX) {
fprintf(stderr, "too many words; try bumping W_MAX in inf.h\n");
exit(1);
}
if (w && strlen(w))
words[idx++] = w;
else
words[idx++] = NULL;
return;
}
void
clear_words (void)
{
int i;
for (i = 0; i < idx; i++) {
if (words[i]) {
free(__DECONST(char *, words[i]));
}
}
idx = 0;
bzero(words, sizeof(words));
return;
}

View File

@ -1,61 +0,0 @@
/*
* $Id: inf.h,v 1.3 2003/11/30 21:58:16 winter Exp $
*
* $FreeBSD$
*/
#define W_MAX 32
struct section {
const char * name;
TAILQ_ENTRY(section) link;
};
TAILQ_HEAD(section_head, section);
struct assign {
struct section *section;
const char * key;
const char * vals[W_MAX];
TAILQ_ENTRY(assign) link;
};
TAILQ_HEAD(assign_head, assign);
struct reg {
struct section *section;
const char * root;
const char * subkey;
const char * key;
u_int flags;
const char * value;
TAILQ_ENTRY(reg) link;
};
TAILQ_HEAD(reg_head, reg);
#define FLG_ADDREG_TYPE_SZ 0x00000000
#define FLG_ADDREG_BINVALUETYPE 0x00000001
#define FLG_ADDREG_NOCLOBBER 0x00000002
#define FLG_ADDREG_DELVAL 0x00000004
#define FLG_ADDREG_APPEND 0x00000008
#define FLG_ADDREG_KEYONLY 0x00000010
#define FLG_ADDREG_OVERWRITEONLY 0x00000020
#define FLG_ADDREG_64BITKEY 0x00001000
#define FLG_ADDREG_KEYONLY_COMMON 0x00002000
#define FLG_ADDREG_32BITKEY 0x00004000
#define FLG_ADDREG_TYPE_MULTI_SZ 0x00010000
#define FLG_ADDREG_TYPE_EXPAND_SZ 0x00020000
#define FLG_ADDREG_TYPE_DWORD 0x00010001
#define FLG_ADDREG_TYPE_NONE 0x00020001
extern void section_add (const char *);
extern void assign_add (const char *);
extern void define_add (const char *);
extern void regkey_add (const char *);
extern void push_word (const char *);
extern void clear_words (void);
extern int inf_parse (FILE *, FILE *);

View File

@ -1,283 +0,0 @@
.\" Copyright (c) 2003
.\" Bill Paul <wpaul@windriver.com> All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Bill Paul.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd December 10, 2003
.Dt NDISCVT 8
.Os
.Sh NAME
.Nm ndiscvt
.Nd convert
.Tn Windows\[rg]
NDIS drivers for use with FreeBSD
.Sh SYNOPSIS
.Nm
.Op Fl O
.Op Fl i Ar inffile
.Fl s Ar sysfile
.Op Fl n Ar devname
.Op Fl o Ar outfile
.Nm
.Op Fl f Ar firmfile
.Sh DESCRIPTION
The
.Nm
utility transforms a
.Tn Windows\[rg]
NDIS driver into a data file which
is used to build an
.Xr ndis 4
compatibility driver module.
.Tn Windows\[rg]
drivers consist of two main parts: a
.Pa .SYS
file, which contains the actual driver executable code,
and an
.Pa .INF
file, which provides the
.Tn Windows\[rg]
installer with device
identifier information and a list of driver-specific registry keys.
The
.Nm
utility can convert these files into a header file that is compiled
into
.Pa if_ndis.c
to create an object code module that can be linked into
the
.Fx
kernel.
.Pp
The
.Pa .INF
file is typically required since only it contains device
identification data such as PCI vendor and device IDs or PCMCIA
identifier strings.
The
.Pa .INF
file may be optionally omitted however,
in which case the
.Nm
utility will only perform the conversion of the
.Pa .SYS
file.
This is useful for debugging purposes only.
.Sh OPTIONS
The options are as follows:
.Bl -tag -width indent
.It Fl i Ar inffile
Open and parse the specified
.Pa .INF
file when performing conversion.
The
.Nm
utility will parse this file and emit a device identification
structure and registry key configuration structures which will be
used by the
.Xr ndis 4
driver and
.Xr ndisapi 9
kernel subsystem.
If this is omitted,
.Nm
will emit a dummy configuration structure only.
.It Fl s Ar sysfile
Open and parse the specified
.Pa .SYS
file.
This file must contain a
.Tn Windows\[rg]
driver image.
The
.Nm
utility will perform some manipulation of the sections within the
executable file to make runtime linking within the kernel a little
easier and then convert the image into a data array.
.It Fl n Ar devname
Specify an alternate name for the network device/interface which will
be created when the driver is instantiated.
If you need to load more
than one NDIS driver into your system (i.e., if you have two different
network cards in your system which require NDIS driver support), each
module you create must have a unique name.
Device can not be larger than
.Dv IFNAMSIZ .
If no name is specified, the driver will use the
default a default name
.Pq Dq Li ndis .
.It Fl o Ar outfile
Specify the output file in which to place the resulting data.
This can be any file pathname.
If
.Ar outfile
is a single dash
.Pq Sq Fl ,
the data will be written to the standard output.
The
.Pa if_ndis.c
module expects to find the driver data in a file called
.Pa ndis_driver_data.h ,
so it is recommended that this name be used.
.It Fl O
Generate both an
.Pa ndis_driver_data.h
file and
an
.Pa ndis_driver.data.o
file.
The latter file will contain a copy of the
.Tn Windows\[rg]
.Pa .SYS
driver image encoded as a
.Fx
ELF object file
(created with
.Xr objcopy 1 ) .
Turning the
.Tn Windows\[rg]
driver image directly into an object code file saves disk space
and compilation time.
.It Fl f Ar firmfile
A few NDIS drivers come with additional files that the core
driver module will load during initialization time.
Typically,
these files contain firmware which the driver will transfer to
the device in order to make it fully operational.
In
.Tn Windows\[rg] ,
these files are usually just copied into one of the system
directories along with the driver itself.
.Pp
In
.Fx
there are two mechanism for loading these files.
If the driver
is built as a loadable kernel module which is loaded after the
kernel has finished booting
(and after the root file system has
been mounted),
the extra files can simply be copied to the
.Pa /compat/ndis
directory, and they will be loaded into the kernel on demand when the
driver needs them.
.Pp
If however the driver is required to bootstrap the system
(i.e., if
the NDIS-based network interface is to be used for diskless/PXE
booting),
the files need to be pre-loaded by the bootstrap
loader in order to be accessible, since the driver will need them
before the root file system has been mounted.
However, the bootstrap
loader is only able to load files that are shared
.Fx
binary objects.
.Pp
The
.Fl f
flag can be used to convert an arbitrary file
.Ar firmfile
into shared object format
(the actual conversion is done using
the
.Xr objcopy 1
and
.Xr ld 1
commands).
The resulting files can then be copied to the
.Pa /boot/kernel
directory, and can be pre-loaded directly from the boot loader
prompt, or automatically by editing the
.Xr loader.conf 5
file.
If desired, the files can also be loaded into memory
at runtime using the
.Xr kldload 8
command.
.Pp
When an NDIS driver tries to open an external file, the
.Xr ndisapi 9
code will first search for a loaded kernel module that matches the
name specified in the open request, and if that fails, it will then
try to open the file from the
.Pa /compat/ndis
directory as well.
Note that during kernel bootstrap, the ability
to open files from
.Pa /compat/ndis
is disabled: only the module search will be performed.
.Pp
When using the
.Fl f
flag,
.Nm
will generate both a relocatable object file
(with a
.Pa .o
extension)
and a shared object file
(with a
.Pa .ko
extension).
The shared object is the one that should be placed in
the
.Pa /boot/kernel
directory.
The relocatable object file is useful if the user wishes
to create a completely static kernel image: the object file can be
linked into the kernel directly along with the driver itself.
Some
editing of the kernel configuration files will be necessary in order
to have the extra object included in the build.
.El
.Sh SEE ALSO
.Xr ld 1 ,
.Xr objcopy 1 ,
.Xr ndis 4 ,
.Xr kldload 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Fx 5.3 .
.Sh AUTHORS
.An -nosplit
The
.Nm
utility was written by
.An Bill Paul Aq Mt wpaul@windriver.com .
The
.Xr lex 1
and
.Xr yacc 1
.Pa INF
file parser was written by
.An Matthew Dodd Aq Mt mdodd@FreeBSD.org .

View File

@ -1,436 +0,0 @@
/*
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2003
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/types.h>
#include <sys/queue.h>
#include <sys/socket.h>
#include <net/if.h>
#include <stdlib.h>
#include <stddef.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <libgen.h>
#include <err.h>
#include <ctype.h>
#include <compat/ndis/pe_var.h>
#include "inf.h"
static int insert_padding(void **, int *);
extern const char *__progname;
/*
* Sections within Windows PE files are defined using virtual
* and physical address offsets and virtual and physical sizes.
* The physical values define how the section data is stored in
* the executable file while the virtual values describe how the
* sections will look once loaded into memory. It happens that
* the linker in the Microsoft(r) DDK will tend to generate
* binaries where the virtual and physical values are identical,
* which means in most cases we can just transfer the file
* directly to memory without any fixups. This is not always
* the case though, so we have to be prepared to handle files
* where the in-memory section layout differs from the disk file
* section layout.
*
* There are two kinds of variations that can occur: the relative
* virtual address of the section might be different from the
* physical file offset, and the virtual section size might be
* different from the physical size (for example, the physical
* size of the .data section might be 1024 bytes, but the virtual
* size might be 1384 bytes, indicating that the data section should
* actually use up 1384 bytes in RAM and be padded with zeros). What we
* do is read the original file into memory and then make an in-memory
* copy with all of the sections relocated, re-sized and zero padded
* according to the virtual values specified in the section headers.
* We then emit the fixed up image file for use by the if_ndis driver.
* This way, we don't have to do the fixups inside the kernel.
*/
#define ROUND_DOWN(n, align) (((uintptr_t)n) & ~((align) - 1l))
#define ROUND_UP(n, align) ROUND_DOWN(((uintptr_t)n) + (align) - 1l, \
(align))
#define SET_HDRS(x) \
dos_hdr = (image_dos_header *)x; \
nt_hdr = (image_nt_header *)(x + dos_hdr->idh_lfanew); \
sect_hdr = IMAGE_FIRST_SECTION(nt_hdr);
static int
insert_padding(void **imgbase, int *imglen)
{
image_section_header *sect_hdr;
image_dos_header *dos_hdr;
image_nt_header *nt_hdr;
image_optional_header opt_hdr;
int i = 0, sections, curlen = 0;
int offaccum = 0, oldraddr, oldrlen;
uint8_t *newimg, *tmp;
newimg = malloc(*imglen);
if (newimg == NULL)
return(ENOMEM);
bcopy(*imgbase, newimg, *imglen);
curlen = *imglen;
if (pe_get_optional_header((vm_offset_t)newimg, &opt_hdr))
return(0);
sections = pe_numsections((vm_offset_t)newimg);
SET_HDRS(newimg);
for (i = 0; i < sections; i++) {
oldraddr = sect_hdr->ish_rawdataaddr;
oldrlen = sect_hdr->ish_rawdatasize;
sect_hdr->ish_rawdataaddr = sect_hdr->ish_vaddr;
offaccum += ROUND_UP(sect_hdr->ish_vaddr - oldraddr,
opt_hdr.ioh_filealign);
offaccum +=
ROUND_UP(sect_hdr->ish_misc.ish_vsize,
opt_hdr.ioh_filealign) -
ROUND_UP(sect_hdr->ish_rawdatasize,
opt_hdr.ioh_filealign);
tmp = realloc(newimg, *imglen + offaccum);
if (tmp == NULL) {
free(newimg);
return(ENOMEM);
}
newimg = tmp;
SET_HDRS(newimg);
sect_hdr += i;
bzero(newimg + sect_hdr->ish_rawdataaddr,
ROUND_UP(sect_hdr->ish_misc.ish_vsize,
opt_hdr.ioh_filealign));
bcopy((uint8_t *)(*imgbase) + oldraddr,
newimg + sect_hdr->ish_rawdataaddr, oldrlen);
sect_hdr++;
}
free(*imgbase);
*imgbase = newimg;
*imglen += offaccum;
return(0);
}
static void
usage(void)
{
fprintf(stderr, "Usage: %s [-O] [-i <inffile>] -s <sysfile> "
"[-n devname] [-o outfile]\n", __progname);
fprintf(stderr, " %s -f <firmfile>\n", __progname);
exit(1);
}
static void
bincvt(char *sysfile, char *outfile, void *img, int fsize)
{
char *ptr;
char tname[] = "/tmp/ndiscvt.XXXXXX";
char sysbuf[1024];
FILE *binfp;
mkstemp(tname);
binfp = fopen(tname, "a+");
if (binfp == NULL)
err(1, "opening %s failed", tname);
if (fwrite(img, fsize, 1, binfp) != 1)
err(1, "failed to output binary image");
fclose(binfp);
outfile = strdup(basename(outfile));
if (strchr(outfile, '.'))
*strchr(outfile, '.') = '\0';
snprintf(sysbuf, sizeof(sysbuf),
#ifdef __i386__
"objcopy -I binary -O elf32-i386-freebsd -B i386 %s %s.o\n",
#endif
#ifdef __amd64__
"objcopy -I binary -O elf64-x86-64-freebsd -B i386 %s %s.o\n",
#endif
tname, outfile);
printf("%s", sysbuf);
system(sysbuf);
unlink(tname);
ptr = tname;
while (*ptr) {
if (*ptr == '/' || *ptr == '.')
*ptr = '_';
ptr++;
}
snprintf(sysbuf, sizeof(sysbuf),
"objcopy --redefine-sym _binary_%s_start=ndis_%s_drv_data_start "
"--strip-symbol _binary_%s_size "
"--redefine-sym _binary_%s_end=ndis_%s_drv_data_end %s.o %s.o\n",
tname, sysfile, tname, tname, sysfile, outfile, outfile);
printf("%s", sysbuf);
system(sysbuf);
free(outfile);
return;
}
static void
firmcvt(char *firmfile)
{
char *basefile, *outfile, *ptr;
char sysbuf[1024];
outfile = strdup(basename(firmfile));
basefile = strdup(outfile);
snprintf(sysbuf, sizeof(sysbuf),
#ifdef __i386__
"objcopy -I binary -O elf32-i386-freebsd -B i386 %s %s.o\n",
#endif
#ifdef __amd64__
"objcopy -I binary -O elf64-x86-64-freebsd -B i386 %s %s.o\n",
#endif
firmfile, outfile);
printf("%s", sysbuf);
system(sysbuf);
ptr = firmfile;
while (*ptr) {
if (*ptr == '/' || *ptr == '.')
*ptr = '_';
ptr++;
}
ptr = basefile;
while (*ptr) {
if (*ptr == '/' || *ptr == '.')
*ptr = '_';
else
*ptr = tolower(*ptr);
ptr++;
}
snprintf(sysbuf, sizeof(sysbuf),
"objcopy --redefine-sym _binary_%s_start=%s_start "
"--strip-symbol _binary_%s_size "
"--redefine-sym _binary_%s_end=%s_end %s.o %s.o\n",
firmfile, basefile, firmfile, firmfile,
basefile, outfile, outfile);
ptr = sysbuf;
printf("%s", sysbuf);
system(sysbuf);
snprintf(sysbuf, sizeof(sysbuf),
"ld -Bshareable -d -warn-common -o %s.ko %s.o\n",
outfile, outfile);
printf("%s", sysbuf);
system(sysbuf);
free(basefile);
exit(0);
}
int
main(int argc, char *argv[])
{
FILE *fp, *outfp;
int i, bin = 0;
void *img;
int n, fsize, cnt;
unsigned char *ptr;
char *inffile = NULL, *sysfile = NULL;
char *outfile = NULL, *firmfile = NULL;
char *dname = NULL;
int ch;
while((ch = getopt(argc, argv, "i:s:o:n:f:O")) != -1) {
switch(ch) {
case 'f':
firmfile = optarg;
break;
case 'i':
inffile = optarg;
break;
case 's':
sysfile = optarg;
break;
case 'o':
outfile = optarg;
break;
case 'n':
dname = optarg;
break;
case 'O':
bin = 1;
break;
default:
usage();
break;
}
}
if (firmfile != NULL)
firmcvt(firmfile);
if (sysfile == NULL)
usage();
/* Open the .SYS file and load it into memory */
fp = fopen(sysfile, "r");
if (fp == NULL)
err(1, "opening .SYS file '%s' failed", sysfile);
fseek (fp, 0L, SEEK_END);
fsize = ftell (fp);
rewind (fp);
img = calloc(fsize, 1);
n = fread (img, fsize, 1, fp);
if (n == 0)
err(1, "reading .SYS file '%s' failed", sysfile);
fclose(fp);
if (insert_padding(&img, &fsize)) {
fprintf(stderr, "section relocation failed\n");
exit(1);
}
if (outfile == NULL || strcmp(outfile, "-") == 0)
outfp = stdout;
else {
outfp = fopen(outfile, "w");
if (outfp == NULL)
err(1, "opening output file '%s' failed", outfile);
}
fprintf(outfp, "\n/*\n");
fprintf(outfp, " * Generated from %s and %s (%d bytes)\n",
inffile == NULL ? "<notused>" : inffile, sysfile, fsize);
fprintf(outfp, " */\n\n");
if (dname != NULL) {
if (strlen(dname) > IFNAMSIZ)
err(1, "selected device name '%s' is "
"too long (max chars: %d)", dname, IFNAMSIZ);
fprintf (outfp, "#define NDIS_DEVNAME \"%s\"\n", dname);
fprintf (outfp, "#define NDIS_MODNAME %s\n\n", dname);
}
if (inffile == NULL) {
fprintf (outfp, "#ifdef NDIS_REGVALS\n");
fprintf (outfp, "ndis_cfg ndis_regvals[] = {\n");
fprintf (outfp, "\t{ NULL, NULL, { 0 }, 0 }\n");
fprintf (outfp, "#endif /* NDIS_REGVALS */\n");
fprintf (outfp, "};\n\n");
} else {
fp = fopen(inffile, "r");
if (fp == NULL)
err(1, "opening .INF file '%s' failed", inffile);
if (inf_parse(fp, outfp) != 0)
errx(1, "creating .INF file - no entries created, are you using the correct files?");
fclose(fp);
}
fprintf(outfp, "\n#ifdef NDIS_IMAGE\n");
if (bin) {
sysfile = strdup(basename(sysfile));
ptr = (unsigned char *)sysfile;
while (*ptr) {
if (*ptr == '.')
*ptr = '_';
ptr++;
}
fprintf(outfp,
"\nextern unsigned char ndis_%s_drv_data_start[];\n",
sysfile);
fprintf(outfp, "static unsigned char *drv_data = "
"ndis_%s_drv_data_start;\n\n", sysfile);
bincvt(sysfile, outfile, img, fsize);
goto done;
}
fprintf(outfp, "\nextern unsigned char drv_data[];\n\n");
fprintf(outfp, "__asm__(\".data\");\n");
fprintf(outfp, "__asm__(\".globl drv_data\");\n");
fprintf(outfp, "__asm__(\".type drv_data, @object\");\n");
fprintf(outfp, "__asm__(\".size drv_data, %d\");\n", fsize);
fprintf(outfp, "__asm__(\"drv_data:\");\n");
ptr = img;
cnt = 0;
while(cnt < fsize) {
fprintf (outfp, "__asm__(\".byte ");
for (i = 0; i < 10; i++) {
cnt++;
if (cnt == fsize) {
fprintf(outfp, "0x%.2X\");\n", ptr[i]);
goto done;
} else {
if (i == 9)
fprintf(outfp, "0x%.2X\");\n", ptr[i]);
else
fprintf(outfp, "0x%.2X, ", ptr[i]);
}
}
ptr += 10;
}
done:
fprintf(outfp, "#endif /* NDIS_IMAGE */\n");
if (fp != NULL)
fclose(fp);
fclose(outfp);
free(img);
exit(0);
}

View File

@ -1,86 +0,0 @@
.\" Copyright (c) 2005
.\" Bill Paul <wpaul@windriver.com> All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Bill Paul.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd April 24, 2005
.Dt NDISGEN 8
.Os
.Sh NAME
.Nm ndisgen
.Nd generate a FreeBSD driver module from a
.Tn Windows\[rg]
NDIS driver distribution
.Sh SYNOPSIS
.Nm
.Op Ar /path/to/INF /path/to/SYS
.Sh DESCRIPTION
The
.Nm
script uses the
.Xr ndiscvt 8
utility and other tools to generate a
.Fx
loadable driver module
and a static ELF object module from a
.Tn Windows\[rg]
NDIS driver, for use with the
.Xr ndis 4
compatibility module.
.Pp
The
.Nm
script is interactive and contains its own help section.
Unless the paths to both files are supplied on the command line,
the script will prompt the user for the
.Pa .INF
and
.Pa .SYS
files needed to generate the
.Fx
driver module.
The script will also prompt for
any firmware or other external files needed.
.Sh SEE ALSO
.Xr ld 1 ,
.Xr objcopy 1 ,
.Xr ndis 4 ,
.Xr kldload 8 ,
.Xr ndiscvt 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Fx 6.0 .
.Sh AUTHORS
The
.Nm
utility was written by
.An Bill Paul Aq Mt wpaul@windriver.com .

View File

@ -1,556 +0,0 @@
#!/bin/sh
#
# SPDX-License-Identifier: BSD-4-Clause
#
# Copyright (c) 2005
# Bill Paul <wpaul@windriver.com>. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. All advertising materials mentioning features or use of this software
# must display the following acknowledgement:
# This product includes software developed by Bill Paul.
# 4. Neither the name of the author nor the names of any co-contributors
# may be used to endorse or promote products derived from this software
# without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
# THE POSSIBILITY OF SUCH DAMAGE.
#
# $FreeBSD$
#
header () {
clear
echo " =================================================================="
echo " ------------------ Windows(r) driver converter -------------------"
echo " =================================================================="
echo ""
}
mainmenu() {
header
echo " This script is designed to guide you through the process"
echo " of converting a Windows(r) binary driver module and .INF"
echo " specification file into a FreeBSD ELF kernel module for use"
echo " with the NDIS compatibility system."
echo ""
echo " The following options are available:"
echo ""
echo " 1] Learn about the NDIS compatibility system"
echo " 2] Convert individual firmware files"
echo " 3] Convert driver"
echo " 4] Exit"
echo ""
echo -n " Enter your selection here and press return: "
read KEYPRESS
return
}
help1 () {
header
echo " General information"
echo ""
echo " The NDIS compatibility system is designed to let you use Windows(r)"
echo " binary drivers for networking devices with FreeBSD, in cases where"
echo " a native FreeBSD driver is not available due to hardware manufacturer"
echo " oversight or stupidity. NDIS stands for Network Driver Interface"
echo " Standard, and refers to the programming model used to write Windows(r)"
echo " network drivers. (These are often called \"NDIS miniport\" drivers.)"
echo ""
echo " In order to use your network device in NDIS compatibility mode,"
echo " you need the Windows(r) driver that goes with it. Also, the driver"
echo " must be compiled for the same architecture as the release of FreeBSD"
echo " you have installed. At this time, the i386 and amd64 architectures"
echo " are both supported. Note that you cannot use a Windows/i386 driver"
echo " with FreeBSD/amd64: you must obtain a Windows/amd64 driver."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
return
}
help2() {
header
echo " Where to get drivers"
echo ""
echo " If you purchased your network card separately from your computer,"
echo " there should have been a driver distribution CD included with the"
echo " card which contains Windows(r) drivers. The NDIS compatibility"
echo " system is designed to emulate the NDIS API of a couple of different"
echo " Windows(r) releases, however it works best with drivers designed"
echo " for NDIS 5.0 or later. Drivers distributed for Windows 2000 should"
echo " work; however, for best results you should use a driver designed"
echo " for Windows XP or Windows Server 2003."
echo ""
echo " If your card was supplied with your computer, or is a built-in device,"
echo " drivers may have been included on a special driver bundle CD shipped"
echo " with the computer."
echo ""
echo " If you don't have a driver CD, you should be able to find a driver"
echo " kit on the card or computer vendor's web site."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
return
}
help3 () {
header
echo " What files do I need?"
echo ""
echo " In most cases, you will need only two files: a .INF file and a .SYS"
echo " file. The .INF file is a text file used by the Windows(r) installer to"
echo " perform the driver installation. It contains information that tells"
echo " the installer what devices the driver supports and what registry keys"
echo " should be created to control driver configuration. The .SYS file"
echo " is the actual driver executable code in Windows(r) Portable Executable"
echo " (PE) format. Note that sometimes the .INF file is supplied in Unicode"
echo " format. Unicode .INF files must be converted to ASCII form with the"
echo " iconv(1) utility before this installer script can use them."
echo " Occasionally, a driver may require firmware or register setup"
echo " files that are external to the main .SYS file. These are provided"
echo " on the same CD with the driver itself, and sometimes have a .BIN"
echo " extension, though they can be named almost anything. You will need"
echo " these additional files to make your device work with the NDIS"
echo " compatibility system as well."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
return
}
help4 () {
header
echo " How does it all work?"
echo ""
echo " The installer script uses the ndiscvt(1) utility to convert the .INF,"
echo " .SYS and optional firmware files into a FreeBSD kernel loadable module"
echo " (.ko) file. This module can be loaded via the kldload(8) utility or"
echo " loaded automatically via the /boot/loader.conf file. The ndiscvt(1)"
echo " utility extracts the device ID information and registry key data"
echo " from the .INF file and converts it into a C header file. It also uses"
echo " the objcopy(1) utility to convert the .SYS file and optional firmware"
echo " files into ELF objects. The header file is compiled into a small C"
echo " stub file which contains a small amount of code to interface with"
echo " the FreeBSD module system. This stub is linked together with the"
echo " converted ELF objects to form a FreeBSD kernel module. A static ELF"
echo " object (.o) file is also created. This file can be linked into a"
echo " static kernel image for those who want/need a fully linked kernel"
echo " image (possibly for embedded bootstrap purposes, or just plain old"
echo " experimentation)."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
return
}
help5 () {
header
echo " Prerequisites"
echo ""
echo " Converting a driver requires the following utilities:"
echo ""
echo " - The FreeBSD C compiler, cc(1) (part of the base install)."
echo " - The FreeBSD linker, ld(1) (part of the base install)."
echo " - The objcopy(1) utility (part of the base install)."
echo " - The ndiscvt(1) utility (part of the base install)."
echo ""
echo " If you happen to end up with a .INF file that's in Unicode format,"
echo " then you'll also need:"
echo ""
echo " - The iconv(1) utility."
echo ""
echo " If you have installed the X Window system or some sort of desktop"
echo " environment, then iconv(1) should already be present. If not, you"
echo " will need to install the libiconv package or port."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
return
}
infconv () {
header
echo " INF file validation"
if [ -z "$INFPATH" ]; then
echo ""
echo ""
echo " A .INF file is most often provided as an ASCII file, however"
echo " files with multilanguage support are provided in Unicode format."
echo " Please type in the path to your .INF file now."
echo ""
echo -n " > "
read INFPATH
fi
if [ ${INFPATH} ] && [ -e ${INFPATH} ]; then
INFTYPE=`${EGREP} -i -c "Signature|.S.i.g.n.a.t.u.r.e" ${INFPATH}`
if [ ${INFTYPE} -le 0 ]; then
echo ""
echo " I don't recognize this file format. It may not be a valid .INF file."
echo ""
echo -n " Press enter to try again, or ^C to quit. "
read KEYPRESS
INFPATH=""
return
fi
INFTYPE=`${EGREP} -i -c "Class.*=.*Net" ${INFPATH}`
if [ ${INFTYPE} -gt 0 ]; then
echo ""
echo " This .INF file appears to be ASCII."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
return
fi
INFTYPE=`${EGREP} -i -c ".C.l.a.s.s.*=.*N.e.t" ${INFPATH}`
if [ ${INFTYPE} -gt 0 ]; then
echo ""
echo " This .INF file appears to be Unicode."
if [ -e ${ICONVPATH} ]; then
echo " Trying to convert to ASCII..."
${ICONVPATH} -f utf-16 -t utf-8 ${INFPATH} > ${INFFILE}
INFPATH=${INFFILE}
echo " Done."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
else
echo " The iconv(1) utility does not appear to be installed."
echo " Please install this utility or convert the .INF file"
echo " to ASCII and run this utility again."
echo ""
exit
fi
return
fi
echo ""
echo " I don't recognize this file format. It may not be a valid .INF file."
echo ""
echo -n " Press enter to try again, or ^C to quit. "
read KEYPRESS
INFPATH=""
else
echo ""
echo " The file '${INFPATH}' was not found."
echo ""
echo -n " Press enter to try again, or ^C to quit. "
read KEYPRESS
INFPATH=""
fi
return
}
sysconv() {
header
echo " Driver file validation"
if [ ! -r "$SYSPATH" ]; then
echo ""
echo ""
echo " Now you need to specify the name of the Windows(r) driver .SYS"
echo " file for your device. Note that if you are running FreeBSD/amd64,"
echo " then you must provide a driver that has been compiled for the"
echo " 64-bit Windows(r) platform. If a 64-bit driver is not available"
echo " for your device, you must install FreeBSD/i386 and use the"
echo " 32-bit driver instead."
echo ""
echo " Please type in the path to the Windows(r) driver .SYS file now."
echo ""
echo -n " > "
read SYSPATH
fi
if [ ${SYSPATH} ] && [ -e ${SYSPATH} ]; then
SYSTYPE=`${FILE} ${SYSPATH}`
case ${SYSTYPE} in
*Windows*)
echo ""
echo " This .SYS file appears to be in Windows(r) PE format."
echo ""
echo -n " Press return to continue... "
read KEYPRESS
SYSBASE=`${BASENAME} ${SYSPATH} | ${TR} '.' '_'`
;;
*)
echo ""
echo " I don't recognize this file format. It may not be a valid .SYS file."
echo ""
echo -n " Press enter to try again, or ^C to quit. "
read KEYPRESS
SYSPATH=""
;;
esac
else
echo ""
echo " The file '${SYSPATH}' was not found."
echo ""
echo -n " Press enter to try again, or ^C to quit. "
read KEYPRESS
SYSPATH=""
fi
return
}
ndiscvt() {
header
echo " Driver file conversion"
echo ""
echo " The script will now try to convert the .INF and .SYS files"
echo " using the ndiscvt(1) utility. This utility can handle most"
echo " .INF files; however, occasionally it can fail to parse some files"
echo " due to subtle syntax issues: the .INF syntax is very complex,"
echo " and the Windows(r) parser will sometimes allow files with small"
echo " syntax errors to be processed correctly which ndiscvt(1) will"
echo " not. If the conversion fails, you may have to edit the .INF"
echo " file by hand to remove the offending lines."
echo ""
echo -n " Press enter to try converting the files now: "
read KEYPRESS
if ! ${NDISCVT} -i ${INFPATH} -s ${SYSPATH} -O -o ${DNAME}.h > /dev/null; then
echo "CONVERSION FAILED"
exit
else
echo ""
echo " Conversion was successful."
echo ""
echo -n " Press enter to continue... "
read KEYPRESS
fi
return
}
firmcvt() {
while : ; do
header
echo " Firmware file conversion"
echo ""
echo " If your driver uses additional firmware files, please list them"
echo " below. When you're finished, just press enter to continue. (If your"
echo " driver doesn't need any extra firmware files, just press enter"
echo " to move to the next step.)"
echo ""
echo -n " > "
read FIRMPATH
if [ ${FIRMPATH} ]; then
if [ ! -e ${FIRMPATH} ]; then
echo ""
echo " The file '${FIRMPATH}' was not found"
echo ""
echo -n " Press enter to try again, or ^C to quit. "
read KEYPRESS
continue
fi
if ! ${NDISCVT} -f ${FIRMPATH} > /dev/null; then
echo ""
echo "CONVERSION FAILED"
else
echo ""
echo " Conversion was successful."
echo ""
FRMBASE=`${BASENAME} ${FIRMPATH}`
FRMBASE="${FRMBASE}.o"
FRMLIST="${FRMLIST} ${FRMBASE}"
fi
echo -n " Press enter to continue... "
read KEYPRESS
else
break
fi
done
header
echo ""
echo " List of files converted firmware files:"
echo ""
for i in ${FRMLIST}
do
echo " "$i
done
echo ""
echo -n " Press enter to continue... "
read KEYPRESS
return
}
drvgen () {
header
echo " Kernel module generation"
echo ""
echo ""
echo " The script will now try to generate the kernel driver module."
echo " This is the last step. Once this module is generated, you should"
echo " be able to load it just like any other FreeBSD driver module."
echo ""
echo " Press enter to compile the stub module and generate the driver"
echo -n " module now: "
read KEYPRESS
echo ""
echo -n " Generating Makefile... "
echo ".PATH: ${PWD} ${STUBPATH}" > ${MAKEFILE}
echo "KMOD= ${SYSBASE}" >> ${MAKEFILE}
echo "SRCS+= ${STUBFILE} ${DNAME}.h bus_if.h device_if.h" >> ${MAKEFILE}
echo "OBJS+=${FRMLIST} ${DNAME}.o" >> ${MAKEFILE}
echo "CFLAGS+= \\" >> ${MAKEFILE}
echo " -DDRV_DATA_START=ndis_${SYSBASE}_drv_data_start \\" >> ${MAKEFILE}
echo " -DDRV_NAME=ndis_${SYSBASE} \\" >> ${MAKEFILE}
echo " -DDRV_DATA_END=ndis_${SYSBASE}_drv_data_end" >> ${MAKEFILE}
echo "CLEANFILES+= \\" >> ${MAKEFILE}
echo " ${INFFILE} \\" >> ${MAKEFILE}
echo " ${DNAME}.h \\" >> ${MAKEFILE}
echo " ${DNAME}.o" >> ${MAKEFILE}
echo ".include <bsd.kmod.mk>" >> ${MAKEFILE}
if [ -f ${MAKEFILE} ]; then
echo "done."
else
echo "generating Makefile failed. Exiting."
echo ""
exit
fi
echo -n " Building kernel module... "
echo "" > bus_if.h
echo "" > device_if.h
if ! ${MAKE} -f ${MAKEFILE} all > /dev/null; then
echo "build failed. Exiting."
echo ""
exit
else
if [ -f ${SYSBASE}.ko ]; then
${MV} ${SYSBASE}.ko ${SYSBASE}.kmod
echo "done."
else
echo "build failed. Exiting."
echo ""
exit
fi
fi
echo -n " Cleaning up... "
if ! ${MAKE} -f ${MAKEFILE} clean cleandepend > /dev/null; then
echo "cleanup failed. Exiting."
echo ""
exit
else
echo "done."
fi
${RM} ${MAKEFILE}
${MV} ${SYSBASE}.kmod ${SYSBASE}.ko
echo ""
echo " The file ${SYSBASE}.ko has been successfully generated."
echo " You can kldload this module to get started."
echo ""
echo -n " Press return to exit. "
read KEYPRESS
echo ""
echo ""
return
}
convert_driver () {
while : ; do
infconv
if [ ${INFPATH} ]; then
break
fi
done
while : ; do
sysconv
if [ ${SYSPATH} ]; then
break
fi
done
ndiscvt
firmcvt
drvgen
return
}
ICONVPATH=/usr/bin/iconv
NDISCVT=/usr/sbin/ndiscvt
STUBPATH=/usr/share/misc
STUBFILE=windrv_stub.c
DNAME=windrv
CP=/bin/cp
MV=/bin/mv
RM=/bin/rm
TR=/usr/bin/tr
FILE=/usr/bin/file
EGREP=/usr/bin/egrep
MAKE=/usr/bin/make
BASENAME=/usr/bin/basename
TOUCH=/usr/bin/touch
MKTEMP=/usr/bin/mktemp
MAKEFILE=`${MKTEMP} /tmp/Makefile.XXXXXX`
INFFILE=`${MKTEMP} /tmp/ascii_inf.XXXXXX`
INFPATH=""
FRMLIST=""
SYSPATH=""
SYSBASE=""
FRMBASE=""
if [ -r "$1" -a -r "$2" ]; then
# Looks like the user supplied .INF and .SYS files on the command line
INFPATH=$1
SYSPATH=$2
convert_driver && exit 0
fi
while : ; do
mainmenu
case ${KEYPRESS} in
1)
help1
help2
help3
help4
help5
;;
2)
firmcvt
;;
3)
convert_driver
;;
4)
header
echo ""
echo " Be seeing you!"
echo ""
exit
;;
*)
header
echo ""
echo -n " Sorry, I didn't understand that. Press enter to try again: "
read KEYPRESS
;;
esac
done
exit

View File

@ -1,268 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/conf.h>
#include <machine/bus.h>
#include <machine/resource.h>
#include <sys/bus.h>
#define NDIS_REGVALS
struct ndis_cfg {
char *nc_cfgkey;
char *nc_cfgdesc;
char nc_val[256];
int nc_idx;
};
typedef struct ndis_cfg ndis_cfg;
#include "windrv.h"
struct ndis_pci_type {
uint16_t ndis_vid;
uint16_t ndis_did;
uint32_t ndis_subsys;
char *ndis_name;
};
struct ndis_pccard_type {
const char *ndis_vid;
const char *ndis_did;
char *ndis_name;
};
struct ndis_usb_type {
uint16_t ndis_vid;
uint16_t ndis_did;
char *ndis_name;
};
#ifdef NDIS_PCI_DEV_TABLE
static struct ndis_pci_type ndis_devs_pci[] = {
NDIS_PCI_DEV_TABLE
{ 0, 0, 0, NULL }
};
#endif
#ifdef NDIS_PCMCIA_DEV_TABLE
static struct ndis_pccard_type ndis_devs_pccard[] = {
NDIS_PCMCIA_DEV_TABLE
{ NULL, NULL, NULL }
};
#endif
#ifdef NDIS_USB_DEV_TABLE
static struct ndis_usb_type ndis_devs_usb[] = {
NDIS_USB_DEV_TABLE
{ 0, 0, NULL }
};
#endif
enum interface_type {
InterfaceTypeUndefined = -1,
Internal,
Isa,
Eisa,
MicroChannel,
TurboChannel,
PCIBus,
VMEBus,
NuBus,
PCMCIABus,
CBus,
MPIBus,
MPSABus,
ProcessorInternal,
InternalPowerBus,
PNPISABus,
PNPBus,
MaximumInterfaceType
};
typedef enum interface_type interface_type;
/*
* XXX
* Ordinarily, device_probe_desc is defined in device_if.h, which
* is created from device_if.m. The problem is, the latter file
* is only available if you have the kernel source code installed,
* and not all users choose to install it. I'd like to let people
* load Windows driver modules with the minimal amount of hassle
* and dependencies. <sys/bus.h> wants both device_if.h and bus_if.h
* to be defined, but it turns out the only thing we really need
* to get this module compiled is device_probe_desc, so we define
* that here, and let the build script create empty copies of
* device_if.h and bus_if.h to make the compiler happy.
*/
extern struct kobjop_desc device_probe_desc;
typedef int device_probe_t(device_t dev);
extern int windrv_load(module_t, vm_offset_t, size_t,
interface_type, void *, void *);
extern int windrv_unload(module_t, vm_offset_t, size_t);
#ifndef DRV_DATA_START
#define DRV_DATA_START UNDEF_START
#endif
#ifndef DRV_DATA_END
#define DRV_DATA_END UNDEF_END
#endif
#ifndef DRV_NAME
#define DRV_NAME UNDEF_NAME
#endif
extern uint8_t DRV_DATA_START;
extern uint8_t DRV_DATA_END;
/*
* The following is stub code that makes it look as though we want
* to be a child device of all the buses that our supported devices
* might want to attach to. Our probe routine always fails. The
* reason we need this code is so that loading an ELF-ified Windows
* driver module will trigger a bus reprobe.
*/
#define MODULE_DECL(x) \
MODULE_DEPEND(x, ndisapi, 1, 1, 1); \
MODULE_DEPEND(x, ndis, 1, 1, 1)
MODULE_DECL(DRV_NAME);
static int windrv_probe(device_t);
static int windrv_modevent(module_t, int, void *);
static int windrv_loaded = 0;
static device_method_t windrv_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, windrv_probe),
{ 0, 0 }
};
static driver_t windrv_driver = {
"windrv_stub",
windrv_methods,
0
};
static devclass_t windrv_devclass;
#define DRIVER_DECL(x) \
DRIVER_MODULE(x, pci, windrv_driver, \
windrv_devclass, windrv_modevent, NULL); \
DRIVER_MODULE(x, cardbus, windrv_driver, \
windrv_devclass, windrv_modevent, NULL); \
DRIVER_MODULE(x, pccard, windrv_driver, \
windrv_devclass, windrv_modevent, NULL); \
DRIVER_MODULE(x, uhub, windrv_driver, \
windrv_devclass, windrv_modevent, NULL); \
MODULE_VERSION(x, 1)
DRIVER_DECL(DRV_NAME);
static int
windrv_probe(dev)
device_t dev;
{
return (ENXIO);
}
static int
windrv_modevent(mod, cmd, arg)
module_t mod;
int cmd;
void *arg;
{
int drv_data_len;
int error = 0;
vm_offset_t drv_data_start;
vm_offset_t drv_data_end;
drv_data_start = (vm_offset_t)&DRV_DATA_START;
drv_data_end = (vm_offset_t)&DRV_DATA_END;
drv_data_len = drv_data_end - drv_data_start;
switch (cmd) {
case MOD_LOAD:
windrv_loaded++;
if (windrv_loaded > 1)
break;
#ifdef NDIS_PCI_DEV_TABLE
windrv_load(mod, drv_data_start, drv_data_len, PCIBus,
ndis_devs_pci, &ndis_regvals);
#endif
#ifdef NDIS_PCMCIA_DEV_TABLE
windrv_load(mod, drv_data_start, drv_data_len, PCMCIABus,
ndis_devs_pccard, &ndis_regvals);
#endif
#ifdef NDIS_USB_DEV_TABLE
windrv_load(mod, drv_data_start, drv_data_len, PNPBus,
ndis_devs_usb, &ndis_regvals);
#endif
break;
case MOD_UNLOAD:
windrv_loaded--;
if (windrv_loaded > 0)
break;
#ifdef NDIS_PCI_DEV_TABLE
windrv_unload(mod, drv_data_start, drv_data_len);
#endif
#ifdef NDIS_PCMCIA_DEV_TABLE
windrv_unload(mod, drv_data_start, drv_data_len);
#endif
#ifdef NDIS_USB_DEV_TABLE
windrv_unload(mod, drv_data_start, drv_data_len);
#endif
break;
case MOD_SHUTDOWN:
break;
default:
error = EINVAL;
break;
}
return (error);
}

View File

@ -2,7 +2,6 @@
SUBDIR= wpa_supplicant wpa_cli wpa_passphrase
SUBDIR+= hostapd hostapd_cli
SUBDIR+= ndis_events
SUBDIR_PARALLEL=
.include <bsd.subdir.mk>

View File

@ -1,8 +0,0 @@
# $FreeBSD$
PROG= ndis_events
SRCS+= ndis_events.c
MAN= ndis_events.8
.include <bsd.prog.mk>

View File

@ -1,18 +0,0 @@
# $FreeBSD$
# Autogenerated - do NOT edit!
DIRDEPS = \
gnu/lib/csu \
include \
include/arpa \
include/xlocale \
lib/${CSU_DIR} \
lib/libc \
lib/libcompiler_rt \
.include <dirdeps.mk>
.if ${DEP_RELDIR} == ${_DEP_RELDIR}
# local dependencies - needed for -jN in clean tree
.endif

View File

@ -1,135 +0,0 @@
.\" Copyright (c) 2005
.\" Bill Paul <wpaul@windriver.com> All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by Bill Paul.
.\" 4. Neither the name of the author nor the names of any co-contributors
.\" may be used to endorse or promote products derived from this software
.\" without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
.\" ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
.\" THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD$
.\"
.Dd August 30, 2007
.Dt NDIS_EVENTS 8
.Os
.Sh NAME
.Nm ndis_events
.Nd relay events from
.Xr ndis 4
drivers to
.Xr wpa_supplicant 8
.Sh SYNOPSIS
.Nm
.Op Fl a
.Op Fl d
.Op Fl v
.Sh DESCRIPTION
The
.Nm
utility listens for events generated by an
.Xr ndis 4
wireless network driver and relays them to
.Xr wpa_supplicant 8
for possible processing.
The three event types that can occur
are media connect and disconnect events, such as when a wireless
interface joins or leaves a network, and media-specific events.
In particular,
.Xr ndis 4
drivers that support WPA2 will generate media-specific events
containing PMKID candidate information which
.Xr wpa_supplicant 8
needs in order to properly associate with WPA2-capable access points.
.Pp
The
.Nm
daemon works by listening for interface information events via
a routing socket.
When it detects an event that was generated by an
.Xr ndis 4
interface, it transmits it via UDP packet on the loopback interface,
where
.Xr wpa_supplicant 8
is presumably listening.
The standard
.Xr wpa_supplicant 8
distribution includes its own version of this utility for use with
.Tn Windows\[rg] .
The
.Fx
version performs the same functions as the
.Tn Windows\[rg]
one, except that it uses an
.Xr ioctl 2
and routing socket interface instead of WMI.
.Pp
Note that a single instance of
.Nm
is sufficient to scan for events for any number of
.Xr ndis 4
interfaces in a system.
.Sh OPTIONS
The
.Nm
daemon supports the following options:
.Bl -tag -width indent
.It Fl a
Process all events.
By default,
.Nm
will only process and forward media-specific events, which contain
PMKID candidate information, and not bother forwarding connect and
disconnect events, since
.Xr wpa_supplicant 8
normally can determine the current link state on its own.
In some
cases, the additional connect and disconnect events only confuse it
and make the association and authentication process take longer.
.It Fl d
Run in debug mode.
This causes
.Nm
to run in the foreground and generate any output to the standard
error instead of using the
.Xr syslog 3
facility.
.It Fl v
Run in verbose mode.
This causes
.Nm
to emit notifications when it receives events.
.El
.Sh SEE ALSO
.Xr ndis 4 ,
.Xr wpa_supplicant 8
.Sh HISTORY
The
.Nm
utility first appeared in
.Fx 6.0 .
.Sh AUTHORS
The
.Nm
utility was written by
.An Bill Paul Aq Mt wpaul@windriver.com .

View File

@ -1,353 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* This program simulates the behavior of the ndis_events utility
* supplied with wpa_supplicant for Windows. The original utility
* is designed to translate Windows WMI events. We don't have WMI,
* but we need to supply certain event info to wpa_supplicant in
* order to make WPA2 work correctly, so we fake up the interface.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/route.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <syslog.h>
#include <stdarg.h>
static int verbose = 0;
static int debug = 0;
static int all_events = 0;
#define PROGNAME "ndis_events"
#define WPA_SUPPLICANT_PORT 9876
#define NDIS_INDICATION_LEN 2048
#define EVENT_CONNECT 0
#define EVENT_DISCONNECT 1
#define EVENT_MEDIA_SPECIFIC 2
#define NDIS_STATUS_MEDIA_CONNECT 0x4001000B
#define NDIS_STATUS_MEDIA_DISCONNECT 0x4001000C
#define NDIS_STATUS_MEDIA_SPECIFIC_INDICATION 0x40010012
struct ndis_evt {
uint32_t ne_sts;
uint32_t ne_len;
#ifdef notdef
char ne_buf[1];
#endif
};
static int find_ifname(int, char *);
static int announce_event(char *, int, struct sockaddr_in *);
static void usage(void);
static void
dbgmsg(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
if (debug)
vwarnx(fmt, ap);
else
vsyslog(LOG_ERR, fmt, ap);
va_end(ap);
return;
}
static int
find_ifname(idx, name)
int idx;
char *name;
{
int mib[6];
size_t needed;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
char *buf, *lim, *next;
needed = 0;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0; /* protocol */
mib[3] = 0; /* wildcard address family */
mib[4] = NET_RT_IFLIST;
mib[5] = 0; /* no flags */
if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0)
return(EIO);
buf = malloc (needed);
if (buf == NULL)
return(ENOMEM);
if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0) {
free(buf);
return(EIO);
}
lim = buf + needed;
next = buf;
while (next < lim) {
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO) {
sdl = (struct sockaddr_dl *)(ifm + 1);
if (ifm->ifm_index == idx) {
strncpy(name, sdl->sdl_data, sdl->sdl_nlen);
name[sdl->sdl_nlen] = '\0';
free (buf);
return (0);
}
}
next += ifm->ifm_msglen;
}
free (buf);
return(ENOENT);
}
static int
announce_event(ifname, sock, dst)
char *ifname;
int sock;
struct sockaddr_in *dst;
{
int s;
char indication[NDIS_INDICATION_LEN];
struct ifreq ifr;
struct ndis_evt *e;
char buf[512], *pos, *end;
int len, type, _type;
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
dbgmsg("socket creation failed");
return(EINVAL);
}
bzero((char *)&ifr, sizeof(ifr));
e = (struct ndis_evt *)indication;
e->ne_len = NDIS_INDICATION_LEN - sizeof(struct ndis_evt);
strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
ifr.ifr_data = indication;
if (ioctl(s, SIOCGPRIVATE_0, &ifr) < 0) {
close(s);
if (verbose) {
if (errno == ENOENT)
dbgmsg("drained all events from %s",
ifname, errno);
else
dbgmsg("failed to read event info from %s: %d",
ifname, errno);
}
return(ENOENT);
}
if (e->ne_sts == NDIS_STATUS_MEDIA_CONNECT) {
type = EVENT_CONNECT;
if (verbose)
dbgmsg("Received a connect event for %s", ifname);
if (!all_events) {
close(s);
return(0);
}
}
if (e->ne_sts == NDIS_STATUS_MEDIA_DISCONNECT) {
type = EVENT_DISCONNECT;
if (verbose)
dbgmsg("Received a disconnect event for %s", ifname);
if (!all_events) {
close(s);
return(0);
}
}
if (e->ne_sts == NDIS_STATUS_MEDIA_SPECIFIC_INDICATION) {
type = EVENT_MEDIA_SPECIFIC;
if (verbose)
dbgmsg("Received a media-specific event for %s",
ifname);
}
end = buf + sizeof(buf);
_type = (int) type;
memcpy(buf, &_type, sizeof(_type));
pos = buf + sizeof(_type);
len = snprintf(pos + 1, end - pos - 1, "%s", ifname);
if (len < 0) {
close(s);
return(ENOSPC);
}
if (len > 255)
len = 255;
*pos = (unsigned char) len;
pos += 1 + len;
if (e->ne_len) {
if (e->ne_len > 255 || 1 + e->ne_len > end - pos) {
dbgmsg("Not enough room for send_event data (%d)\n",
e->ne_len);
close(s);
return(ENOSPC);
}
*pos++ = (unsigned char) e->ne_len;
memcpy(pos, (indication) + sizeof(struct ndis_evt), e->ne_len);
pos += e->ne_len;
}
len = sendto(sock, buf, pos - buf, 0, (struct sockaddr *) dst,
sizeof(struct sockaddr_in));
close(s);
return(0);
}
static void
usage()
{
fprintf(stderr, "Usage: ndis_events [-a] [-d] [-v]\n");
exit(1);
}
int
main(argc, argv)
int argc;
char *argv[];
{
int s, r, n;
struct sockaddr_in sin;
char msg[NDIS_INDICATION_LEN];
struct rt_msghdr *rtm;
struct if_msghdr *ifm;
char ifname[IFNAMSIZ];
int ch;
while ((ch = getopt(argc, argv, "dva")) != -1) {
switch(ch) {
case 'd':
debug++;
break;
case 'v':
verbose++;
break;
case 'a':
all_events++;
break;
default:
usage();
break;
}
}
if (!debug && daemon(0, 0))
err(1, "failed to daemonize ourselves");
if (!debug)
openlog(PROGNAME, LOG_PID | LOG_CONS, LOG_DAEMON);
bzero((char *)&sin, sizeof(sin));
/* Create a datagram socket. */
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s < 0) {
dbgmsg("socket creation failed");
exit(1);
}
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = inet_addr("127.0.0.1");
sin.sin_port = htons(WPA_SUPPLICANT_PORT);
/* Create a routing socket. */
r = socket (PF_ROUTE, SOCK_RAW, 0);
if (r < 0) {
dbgmsg("routing socket creation failed");
exit(1);
}
/* Now sit and spin, waiting for events. */
if (verbose)
dbgmsg("Listening for events");
while (1) {
n = read(r, msg, NDIS_INDICATION_LEN);
rtm = (struct rt_msghdr *)msg;
if (rtm->rtm_type != RTM_IFINFO)
continue;
ifm = (struct if_msghdr *)msg;
if (find_ifname(ifm->ifm_index, ifname))
continue;
if (strstr(ifname, "ndis")) {
while(announce_event(ifname, s, &sin) == 0)
;
} else {
if (verbose)
dbgmsg("Skipping ifinfo message from %s",
ifname);
}
}
/* NOTREACHED */
exit(0);
}

View File

@ -15,7 +15,7 @@ SRCS= base64.c bitfield.c blacklist.c bss.c cli.c common.c \
config.c config_file.c \
ctrl_iface.c ctrl_iface_common.c ctrl_iface_unix.c \
driver_bsd.c driver_common.c \
driver_ndis.c driver_wired.c driver_wired_common.c drivers.c \
driver_wired.c driver_wired_common.c drivers.c \
eap_register.c eloop.c \
events.c gas.c gas_query.c \
http_client.c http_server.c \
@ -24,8 +24,7 @@ SRCS= base64.c bitfield.c blacklist.c bss.c cli.c common.c \
notify.c offchannel.c op_classes.c os_unix.c pmksa_cache.c preauth.c \
rrm.c scan.c upnp_xml.c \
wmm_ac.c wpa.c wpa_common.c wpa_ctrl.c \
wpa_debug.c wpa_ft.c wpa_ie.c wpa_supplicant.c wpabuf.c wpas_glue.c \
Packet32.c
wpa_debug.c wpa_ft.c wpa_ie.c wpa_supplicant.c wpabuf.c wpas_glue.c
MAN= wpa_supplicant.8 wpa_supplicant.conf.5
@ -38,7 +37,6 @@ FILES= wpa_supplicant.conf
CFLAGS+=-DCONFIG_BACKEND_FILE \
-DCONFIG_DEBUG_SYSLOG \
-DCONFIG_DRIVER_BSD \
-DCONFIG_DRIVER_NDIS \
-DCONFIG_DRIVER_WIRED \
-DCONFIG_GAS \
-DCONFIG_IEEE80211R \

View File

@ -1,415 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
/*
* This file implements a small portion of the Winpcap API for the
* Windows NDIS interface in wpa_supplicant. It provides just enough
* routines to fool wpa_supplicant into thinking it's really running
* in a Windows environment.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/sysctl.h>
#include <sys/fcntl.h>
#include <net/if.h>
#include <net/if_dl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <net/route.h>
#include <net80211/ieee80211_ioctl.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pcap.h>
#include "Packet32.h"
#define OID_802_11_ADD_KEY 0x0d01011D
typedef ULONGLONG NDIS_802_11_KEY_RSC;
typedef UCHAR NDIS_802_11_MAC_ADDRESS[6];
typedef struct NDIS_802_11_KEY {
ULONG Length;
ULONG KeyIndex;
ULONG KeyLength;
NDIS_802_11_MAC_ADDRESS BSSID;
NDIS_802_11_KEY_RSC KeyRSC;
UCHAR KeyMaterial[1];
} NDIS_802_11_KEY;
typedef struct NDIS_802_11_KEY_COMPAT {
ULONG Length;
ULONG KeyIndex;
ULONG KeyLength;
NDIS_802_11_MAC_ADDRESS BSSID;
UCHAR Pad[6]; /* Make struct layout match Windows. */
NDIS_802_11_KEY_RSC KeyRSC;
#ifdef notdef
UCHAR KeyMaterial[1];
#endif
} NDIS_802_11_KEY_COMPAT;
#define TRUE 1
#define FALSE 0
struct adapter {
int socket;
char name[IFNAMSIZ];
int prev_roaming;
};
PCHAR
PacketGetVersion(void)
{
return("FreeBSD WinPcap compatibility shim v1.0");
}
void *
PacketOpenAdapter(CHAR *iface)
{
struct adapter *a;
int s;
int ifflags;
struct ifreq ifr;
struct ieee80211req ireq;
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s == -1)
return(NULL);
a = malloc(sizeof(struct adapter));
if (a == NULL)
return(NULL);
a->socket = s;
if (strncmp(iface, "\\Device\\NPF_", 12) == 0)
iface += 12;
else if (strncmp(iface, "\\DEVICE\\", 8) == 0)
iface += 8;
snprintf(a->name, IFNAMSIZ, "%s", iface);
/* Turn off net80211 roaming */
bzero((char *)&ireq, sizeof(ireq));
strncpy(ireq.i_name, iface, sizeof (ifr.ifr_name));
ireq.i_type = IEEE80211_IOC_ROAMING;
if (ioctl(a->socket, SIOCG80211, &ireq) == 0) {
a->prev_roaming = ireq.i_val;
ireq.i_val = IEEE80211_ROAMING_MANUAL;
if (ioctl(a->socket, SIOCS80211, &ireq) < 0)
fprintf(stderr,
"Could not set IEEE80211_ROAMING_MANUAL\n");
}
bzero((char *)&ifr, sizeof(ifr));
strncpy(ifr.ifr_name, iface, sizeof (ifr.ifr_name));
if (ioctl(a->socket, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
free(a);
close(s);
return(NULL);
}
ifr.ifr_flags |= IFF_UP;
if (ioctl(a->socket, SIOCSIFFLAGS, (caddr_t)&ifr) < 0) {
free(a);
close(s);
return(NULL);
}
return(a);
}
int
PacketRequest(void *iface, BOOLEAN set, PACKET_OID_DATA *oid)
{
struct adapter *a;
uint32_t retval;
struct ifreq ifr;
NDIS_802_11_KEY *old;
NDIS_802_11_KEY_COMPAT *new;
PACKET_OID_DATA *o = NULL;
if (iface == NULL)
return(-1);
a = iface;
bzero((char *)&ifr, sizeof(ifr));
/*
* This hack is necessary to work around a difference
* betwee the GNU C and Microsoft C compilers. The NDIS_802_11_KEY
* structure has a uint64_t in it, right after an array of
* chars. The Microsoft compiler inserts padding right before
* the 64-bit value to align it on a 64-bit boundary, but
* GCC only aligns it on a 32-bit boundary. Trying to pass
* the GCC-formatted structure to an NDIS binary driver
* fails because some of the fields appear to be at the
* wrong offsets.
*
* To get around this, if we detect someone is trying to do
* a set operation on OID_802_11_ADD_KEY, we shuffle the data
* into a properly padded structure and pass that into the
* driver instead. This allows the driver_ndis.c code supplied
* with wpa_supplicant to work unmodified.
*/
if (set == TRUE && oid->Oid == OID_802_11_ADD_KEY) {
old = (NDIS_802_11_KEY *)&oid->Data;
o = malloc(sizeof(PACKET_OID_DATA) +
sizeof(NDIS_802_11_KEY_COMPAT) + old->KeyLength);
if (o == NULL)
return(0);
bzero((char *)o, sizeof(PACKET_OID_DATA) +
sizeof(NDIS_802_11_KEY_COMPAT) + old->KeyLength);
o->Oid = oid->Oid;
o->Length = sizeof(NDIS_802_11_KEY_COMPAT) + old->KeyLength;
new = (NDIS_802_11_KEY_COMPAT *)&o->Data;
new->KeyRSC = old->KeyRSC;
new->Length = o->Length;
new->KeyIndex = old->KeyIndex;
new->KeyLength = old->KeyLength;
bcopy(old->BSSID, new->BSSID, sizeof(NDIS_802_11_MAC_ADDRESS));
bcopy(old->KeyMaterial, (char *)new +
sizeof(NDIS_802_11_KEY_COMPAT), new->KeyLength);
ifr.ifr_data = (caddr_t)o;
} else
ifr.ifr_data = (caddr_t)oid;
strlcpy(ifr.ifr_name, a->name, sizeof(ifr.ifr_name));
if (set == TRUE)
retval = ioctl(a->socket, SIOCSDRVSPEC, &ifr);
else
retval = ioctl(a->socket, SIOCGDRVSPEC, &ifr);
if (o != NULL)
free(o);
if (retval)
return(0);
return(1);
}
int
PacketGetAdapterNames(CHAR *namelist, ULONG *len)
{
int mib[6];
size_t needed;
struct if_msghdr *ifm;
struct sockaddr_dl *sdl;
char *buf, *lim, *next;
char *plist;
int spc;
int i, ifcnt = 0;
plist = namelist;
spc = 0;
bzero(plist, *len);
needed = 0;
mib[0] = CTL_NET;
mib[1] = PF_ROUTE;
mib[2] = 0; /* protocol */
mib[3] = 0; /* wildcard address family */
mib[4] = NET_RT_IFLIST;
mib[5] = 0; /* no flags */
if (sysctl (mib, 6, NULL, &needed, NULL, 0) < 0)
return(FALSE);
buf = malloc (needed);
if (buf == NULL)
return(FALSE);
if (sysctl (mib, 6, buf, &needed, NULL, 0) < 0) {
free(buf);
return(FALSE);
}
lim = buf + needed;
/* Generate interface name list. */
next = buf;
while (next < lim) {
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO) {
sdl = (struct sockaddr_dl *)(ifm + 1);
if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) {
if ((spc + sdl->sdl_nlen) > *len) {
free(buf);
return(FALSE);
}
strncpy(plist, sdl->sdl_data, sdl->sdl_nlen);
plist += (sdl->sdl_nlen + 1);
spc += (sdl->sdl_nlen + 1);
ifcnt++;
}
}
next += ifm->ifm_msglen;
}
/* Insert an extra "" as a spacer */
plist++;
spc++;
/*
* Now generate the interface description list. There
* must be a unique description for each interface, and
* they have to match what the ndis_events program will
* feed in later. To keep this simple, we just repeat
* the interface list over again.
*/
next = buf;
while (next < lim) {
ifm = (struct if_msghdr *)next;
if (ifm->ifm_type == RTM_IFINFO) {
sdl = (struct sockaddr_dl *)(ifm + 1);
if (strnstr(sdl->sdl_data, "wlan", sdl->sdl_nlen)) {
if ((spc + sdl->sdl_nlen) > *len) {
free(buf);
return(FALSE);
}
strncpy(plist, sdl->sdl_data, sdl->sdl_nlen);
plist += (sdl->sdl_nlen + 1);
spc += (sdl->sdl_nlen + 1);
ifcnt++;
}
}
next += ifm->ifm_msglen;
}
free (buf);
*len = spc + 1;
return(TRUE);
}
void
PacketCloseAdapter(void *iface)
{
struct adapter *a;
struct ifreq ifr;
struct ieee80211req ireq;
if (iface == NULL)
return;
a = iface;
/* Reset net80211 roaming */
bzero((char *)&ireq, sizeof(ireq));
strncpy(ireq.i_name, a->name, sizeof (ifr.ifr_name));
ireq.i_type = IEEE80211_IOC_ROAMING;
ireq.i_val = a->prev_roaming;
ioctl(a->socket, SIOCS80211, &ireq);
bzero((char *)&ifr, sizeof(ifr));
strncpy(ifr.ifr_name, a->name, sizeof (ifr.ifr_name));
ioctl(a->socket, SIOCGIFFLAGS, (caddr_t)&ifr);
ifr.ifr_flags &= ~IFF_UP;
ioctl(a->socket, SIOCSIFFLAGS, (caddr_t)&ifr);
close(a->socket);
free(a);
return;
}
#if __FreeBSD_version < 600000
/*
* The version of libpcap in FreeBSD 5.2.1 doesn't have these routines.
* Call me insane if you will, but I still run 5.2.1 on my laptop, and
* I'd like to use WPA there.
*/
int
pcap_get_selectable_fd(pcap_t *p)
{
return(pcap_fileno(p));
}
/*
* The old version of libpcap opens its BPF descriptor in read-only
* mode. We need to temporarily create a new one we can write to.
*/
int
pcap_inject(pcap_t *p, const void *buf, size_t len)
{
int fd;
int res, n = 0;
char device[sizeof "/dev/bpf0000000000"];
struct ifreq ifr;
/*
* Go through all the minors and find one that isn't in use.
*/
do {
(void)snprintf(device, sizeof(device), "/dev/bpf%d", n++);
fd = open(device, O_RDWR);
} while (fd < 0 && errno == EBUSY);
if (fd == -1)
return(-1);
bzero((char *)&ifr, sizeof(ifr));
ioctl(pcap_fileno(p), BIOCGETIF, (caddr_t)&ifr);
ioctl(fd, BIOCSETIF, (caddr_t)&ifr);
res = write(fd, buf, len);
close(fd);
return(res);
}
#endif

View File

@ -1,69 +0,0 @@
/*-
* SPDX-License-Identifier: BSD-4-Clause
*
* Copyright (c) 2005
* Bill Paul <wpaul@windriver.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _PACKET32_H_
#define _PACKET32_H_
#include <sys/types.h>
#include <ntddndis.h>
struct PACKET_OID_DATA {
uint32_t Oid;
uint32_t Length;
uint8_t Data[1];
};
typedef struct PACKET_OID_DATA PACKET_OID_DATA;
extern PCHAR PacketGetVersion(void);
extern void *PacketOpenAdapter(CHAR *);
extern int PacketRequest(void *, BOOLEAN, PACKET_OID_DATA *);
extern int PacketGetAdapterNames(CHAR *, ULONG *);
extern void PacketCloseAdapter(void *);
/*
* This is for backwards compatibility on FreeBSD 5.
*/
#ifndef SIOCGDRVSPEC
#define SIOCSDRVSPEC _IOW('i', 123, struct ifreq) /* set driver-specific
parameters */
#define SIOCGDRVSPEC _IOWR('i', 123, struct ifreq) /* get driver-specific
parameters */
#endif
#endif /* _PACKET32_H_ */

View File

@ -1,31 +0,0 @@
#ifndef _NTDDNDIS_H_
#define _NTDDNDIS_H_
/*
* $FreeBSD$
*/
/*
* Fake up some of the Windows type definitions so that the NDIS
* interface module in wpa_supplicant will build.
*/
#define ULONG uint32_t
#define USHORT uint16_t
#define UCHAR uint8_t
#define LONG int32_t
#define SHORT int16_t
#define CHAR int8_t
#define ULONGLONG uint64_t
#define LONGLONG int64_t
#define BOOLEAN uint8_t
typedef void * LPADAPTER;
typedef char * PTSTR;
typedef char * PCHAR;
#define TRUE 1
#define FALSE 0
#define OID_802_3_CURRENT_ADDRESS 0x01010102
#endif /* _NTDDNDIS_H_ */