Remove userland part of ndis

This commit is contained in:
martin 2018-08-25 11:06:00 +00:00
parent 2ce97679ef
commit 1ebe46fcad
8 changed files with 2 additions and 1910 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.276 2018/01/09 03:31:13 christos Exp $
# $NetBSD: Makefile,v 1.277 2018/08/25 11:06:00 martin Exp $
# from: @(#)Makefile 5.20 (Berkeley) 6/12/93
.include <bsd.own.mk>
@ -17,7 +17,7 @@ SUBDIR= ac accton acpitools altq apm apmd arp autofs \
lastlogin ldpd link lmcconfig lockstat lpr \
mailwrapper makefs map-mbone mdconfig memswitch mlxctl mmcformat \
mopd mountd moused mrinfo mrouted mscdlabel mtrace mtree \
ndbootd ndiscvt netgroup_mkdb nfsd \
ndbootd netgroup_mkdb nfsd \
ofctl \
paxctl pcictl perfused psrset pstat pwd_mkdb postinstall \
powerd puffs \

View File

@ -1,22 +0,0 @@
# $NetBSD: Makefile,v 1.11 2009/04/22 15:23:06 lukem Exp $
# $FreeBSD: src/usr.sbin/ndiscvt/Makefile,v 1.5 2004/02/23 20:21:21 johan Exp $
.PATH: ${.CURDIR}/../../sys/compat/ndis
.if ${MACHINE_ARCH} == "i386"
PROG= ndiscvt
.endif
MAN= ndiscvt.8
MANSUBDIR= /i386
SRCS= ndiscvt.c
SRCS+= subr_pe.c
SRCS+= inf.c inf-token.l inf-parse.y
CFLAGS+=-I. -I${.CURDIR} -I${.CURDIR}/../../sys
YHEADER=yes
YPREFIX=ndiscvt_
LPREFIX=${YPREFIX}
.include <bsd.prog.mk>

View File

@ -1,115 +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.
*/
#include <sys/cdefs.h>
#ifdef __FreeBSD__
__FBSDID("$FreeBSD: src/usr.sbin/ndiscvt/inf-parse.y,v 1.2 2004/01/02 04:31:06 wpaul Exp $");
#endif
#ifdef __NetBSD__
__RCSID("$NetBSD: inf-parse.y,v 1.6 2006/04/19 20:38:49 martin Exp $");
#endif
#include <stdio.h>
#include <sys/types.h>
#include <sys/queue.h>
#include "inf.h"
extern int yyparse(void);
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); }
|
;
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,206 +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.
*/
#include <sys/cdefs.h>
#ifdef __FreeBSD__
__FBSDID("$FreeBSD: src/usr.sbin/ndiscvt/inf-token.l,v 1.3 2004/01/11 21:10:35 mdodd Exp $");
#endif
#ifdef __NetBSD__
__RCSID("$NetBSD: inf-token.l,v 1.10 2011/11/25 13:18:22 joerg Exp $");
#endif
#include <regex.h>
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "inf-parse.h"
int lineno = 1;
int input_is_unicode = 0;
#define IS_UNICODE 1
#define ISNT_UNICODE 2
static size_t opt_unicode_input(char *buf, size_t max_size);
#define YY_INPUT(buf, result, max_size) \
result = opt_unicode_input(buf, max_size)
int yylex(void);
__dead void ndiscvt_error(const char *);
int ndiscvt_wrap(void);
static void
update_lineno(const char *cp)
{
while (*cp)
if (*cp++ == '\n')
lineno++;
}
%}
%option nounput 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);
ndiscvt_lval.str = (char *)malloc(blen);
if (ndiscvt_lval.str == NULL)
goto out;
walker = ndiscvt_lval.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(
(unsigned char)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';
ndiscvt_lval.str = strdup(yytext+1);
return SECTION;
}
[a-zA-Z0-9%&\{\}\-\.\/_\\\*]+ {
ndiscvt_lval.str = strdup(yytext);
return WORD;
}
%%
void
ndiscvt_error(const char *s)
{
errx(1, "line %d: %s%s %s.", lineno, yytext, yytext?":":"", s);
}
int
ndiscvt_wrap(void)
{
return 1;
}
static size_t
opt_unicode_input(char *buf, size_t max_size)
{
size_t i, rb;
char *t = buf;
if (feof(yyin)) return YY_NULL;
if (input_is_unicode == ISNT_UNICODE)
/* standard ASCII .inf file */
return fread(buf, 1, max_size, yyin);
if (input_is_unicode != IS_UNICODE) {
/* we don't know yet if this file is unicode */
if (max_size < 2) {
fprintf(stderr, "internal error: can not determine "
"unicode with max_size %zd\n", max_size);
return YY_NULL;
}
rb = fread(buf, 2, 1, yyin);
if (!rb)
return YY_NULL;
if ((unsigned char)buf[0] == 0xff
&& (unsigned char)buf[1] == 0xfe) {
input_is_unicode = IS_UNICODE;
} else {
input_is_unicode = ISNT_UNICODE;
return 2;
}
}
if (input_is_unicode != IS_UNICODE)
return YY_NULL;
if (max_size < 2) {
fprintf(stderr, "internal error: can not read small unicode "
"buffer\n");
return YY_NULL;
}
/*
* read unicode string and skip every second byte if it is zero,
* replace it by an innocent 'A' otherwise. Poor man's
* version of "iconv -f unicode -t ascii" - should be good enough
* for INF files (maybe besides comments, which we don't care
* about)
*/
rb = fread(buf, 1, max_size&~1, yyin);
for (i = 0; i < rb; i += 2) {
if (buf[i+1] != 0)
*t++ = 'A';
else
*t++ = buf[i];
}
return t-buf;
}

View File

@ -1,748 +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.
*/
#include <sys/cdefs.h>
#ifdef __FreeBSD__
__FBSDID("$FreeBSD: src/usr.sbin/ndiscvt/inf.c,v 1.13.2.1 2005/02/18 16:30:10 wpaul Exp $");
#endif
#ifdef __NetBSD__
__RCSID("$NetBSD: inf.c,v 1.4 2006/04/19 15:45:21 christos Exp $");
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#ifdef __NetBSD__
#include <sys/stdint.h>
#endif
#include <sys/queue.h>
#include "inf.h"
#ifndef __DECONST
#define __DECONST(type, var) ((type)(uintptr_t)(const void *)(var))
#endif
extern FILE *ndiscvt_in;
int ndiscvt_parse (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 section
*find_section (const char *);
static void dump_deviceids_pci (void);
static void dump_deviceids_pcmcia (void);
static void dump_pci_id (const char *);
static void dump_pcmcia_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;
ndiscvt_in = fp;
ndiscvt_parse();
dump_deviceids_pci();
dump_deviceids_pcmcia();
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 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_deviceids_pci()
{
struct assign *manf, *dev;
struct section *sec;
struct assign *assign;
char xpsec[256];
int found = 0;
/* Find manufacturer name */
manf = find_assign("Manufacturer", NULL);
/* 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)
return;
found = 0;
/* Emit start of PCI device table */
fprintf (ofp, "#define NDIS_PCI_DEV_TABLE");
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;
}
/* Emit end of table */
fprintf(ofp, "\n\n");
}
static void
dump_deviceids_pcmcia()
{
struct assign *manf, *dev;
struct section *sec;
struct assign *assign;
char xpsec[256];
int found = 0;
/* Find manufacturer name */
manf = find_assign("Manufacturer", NULL);
/* 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)
return;
found = 0;
/* Emit start of PCMCIA device table */
fprintf (ofp, "#define NDIS_PCMCIA_DEV_TABLE");
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;
}
/* Emit end of table */
fprintf(ofp, "\n\n");
}
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);
break;
}
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++;
/* Find manufacturer name */
manf = find_assign("Manufacturer", NULL);
/* 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]);
/* Emit start of block */
fprintf (ofp, "ndis_cfg ndis_regvals[] = {");
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;
}
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 (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 @@
/*
* $NetBSD: inf.h,v 1.3 2006/04/28 07:20:39 skrll Exp $
*
* $FreeBSD: src/usr.sbin/ndiscvt/inf.h,v 1.1 2003/12/11 22:38:14 wpaul Exp $
*/
#define W_MAX 16
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,294 +0,0 @@
.\" $NetBSD: ndiscvt.8,v 1.9 2014/03/18 18:20:47 riastradh Exp $
.\"
.\" 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: src/usr.sbin/ndiscvt/ndiscvt.8,v 1.5.2.1 2005/02/27 15:40:17 brueffer Exp $
.\"
.Dd December 24, 2007
.Dt NDISCVT 8 i386
.Os
.Sh NAME
.Nm ndiscvt
.Nd convert
.Tn Windows\[rg]
NDIS drivers for use with
.Nx
.Sh SYNOPSIS
.Nm
.Op Fl O
.Op Fl i Ar inffile
.Op Fl n Ar devname
.Op Fl o Ar outfile
.Fl s Ar sysfile
.\".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
ndis
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
.Nx
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
indentifier 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 -offset indent -width XfXfirmfileXX
.\"***************************************************************************
.\" The section describing the -f option for firmware has been commented out
.\" Because this is not currently supported on NetBSD.
.\"***************************************************************************
.\".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
.\".Nx
.\"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 filesystem 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
.\"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
.\".Nx
.\"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.
.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
ndis
driver and
.\".Xr ndisapi 9
ndisapi
kernel subsystem.
If this is omitted,
.Nm
will emit a dummy configuration structure only.
.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
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
.Nx
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 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 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.
.El
.Sh SEE ALSO
.Xr ld 1 ,
.Xr objcopy 1 ,
.Xr ndis 4
.\".Xr kldload 8 ,
.\".Xr ndisapi 9
.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,462 +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.
*/
#include <sys/cdefs.h>
#ifdef __FreeBSD__
__FBSDID("$FreeBSD: src/usr.sbin/ndiscvt/ndiscvt.c,v 1.9.2.2 2005/02/23 16:31:47 wpaul Exp $");
#endif
#ifdef __NetBSD__
__RCSID("$NetBSD: ndiscvt.c,v 1.12 2015/06/16 23:04:14 christos Exp $");
#endif
#include <sys/types.h>
#ifdef __NetBSD__
#include <sys/stdint.h>
#endif
#include <sys/queue.h>
#include <sys/socket.h>
#include <sys/lock.h>
#include <net/if.h>
#include <stdlib.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_section_header *)((vm_offset_t)nt_hdr + \
sizeof(image_nt_header));
static
int insert_padding(imgbase, imglen)
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;
int offaccum = 0, oldraddr, oldrlen;
uint8_t *newimg, *tmp;
newimg = malloc(*imglen);
if (newimg == NULL)
return(ENOMEM);
bcopy(*imgbase, newimg, *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);
}
__dead 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;
int fd;
fd = mkstemp(tname);
if (fd == -1)
err(1, "creating temp file %s failed", tname);
binfp = fdopen(fd, "a+");
if (binfp == NULL) {
unlink(tname);
err(1, "opening %s failed", tname);
}
if (fwrite(img, fsize, 1, binfp) != 1) {
unlink(tname);
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__
#ifdef __FreeBSD__
"objcopy -I binary -O elf32-i386-freebsd -B i386 %s %s.o\n",
#else
"objcopy -I binary -O elf32-i386 -B i386 %s %s.o\n",
#endif /* __FreeBSD__ */
#endif
#ifdef __amd64__
"objcopy -I binary -O elf64-x86-64 -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=%s_drv_data_start "
"--strip-symbol _binary_%s_size "
"--redefine-sym _binary_%s_end=%s_drv_data_end %s.o %s.o\n",
tname, sysfile, tname, tname, sysfile, outfile, outfile);
printf("%s", sysbuf);
system(sysbuf);
free(outfile);
return;
}
__dead 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__
#ifdef __FreeBSD__
"objcopy -I binary -O elf32-i386-freebsd -B i386 %s %s.o\n",
#else
"objcopy -I binary -O elf32-i386 -B i386 %s %s.o\n",
#endif /* __FreeBSD__ */
#endif
#ifdef __amd64__
"objcopy -I binary -O elf64-x86-64 -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((int)*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;
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);
if (fsize == -1)
err(1, "getting size of .SYS file '%s' failed", sysfile);
rewind (fp);
img = malloc(fsize);
n = fread (img, fsize, 1, fp);
if (n < 1)
err(1, "reading .SYS file '%s' failed", sysfile);
fclose(fp);
fp = NULL;
if (insert_padding(&img, &fsize)) {
errx(1, "section relocation failed");
}
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);
inf_parse(fp, outfp);
fclose(fp);
fp = NULL;
}
fprintf(outfp, "\n#ifdef NDIS_IMAGE\n");
if (bin) {
sysfile = strdup(basename(sysfile));
ptr = sysfile;
while (*ptr) {
if (*ptr == '.')
*ptr = '_';
ptr++;
}
fprintf(outfp,
"\nextern unsigned char %s_drv_data_start[];\n",
sysfile);
fprintf(outfp, "static unsigned char *drv_data = "
"%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);
}