3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __FBSDID("$FreeBSD$");
39 #include <sys/types.h>
41 #include <sys/queue.h>
48 const char *words
[W_MAX
]; /* More than we'll need. */
51 static struct section_head sh
;
52 static struct reg_head rh
;
53 static struct assign_head ah
;
55 static char *sstrdup (const char *);
57 *find_assign (const char *, const char *);
62 *find_section (const char *);
63 static void dump_deviceids_pci (void);
64 static void dump_deviceids_pcmcia (void);
65 static void dump_pci_id (const char *);
66 static void dump_pcmcia_id (const char *);
67 static void dump_regvals (void);
68 static void dump_paramreg (const struct section
*,
69 const struct reg
*, int);
74 inf_parse (FILE *fp
, FILE *outfp
)
85 dump_deviceids_pcmcia();
86 fprintf(outfp
, "#ifdef NDIS_REGVALS\n");
88 fprintf(outfp
, "#endif /* NDIS_REGVALS */\n");
94 section_add (const char *s
)
98 sec
= malloc(sizeof(struct section
));
99 bzero(sec
, sizeof(struct section
));
101 TAILQ_INSERT_TAIL(&sh
, sec
, link
);
106 static struct assign
*
107 find_assign (const char *s
, const char *k
)
109 struct assign
*assign
;
112 /* Deal with string section lookups. */
114 if (k
!= NULL
&& k
[0] == '%') {
115 bzero(newkey
, sizeof(newkey
));
116 strncpy(newkey
, k
+ 1, strlen(k
) - 2);
120 TAILQ_FOREACH(assign
, &ah
, link
) {
121 if (strcasecmp(assign
->section
->name
, s
) == 0) {
125 if (strcasecmp(assign
->key
, k
) == 0)
132 static struct assign
*
133 find_next_assign (struct assign
*a
)
135 struct assign
*assign
;
137 TAILQ_FOREACH(assign
, &ah
, link
) {
142 assign
= assign
->link
.tqe_next
;
144 if (assign
== NULL
|| assign
->section
!= a
->section
)
151 stringcvt(const char *s
)
155 manf
= find_assign("strings", s
);
158 return(manf
->vals
[0]);
162 find_section (const char *s
)
164 struct section
*section
;
166 TAILQ_FOREACH(section
, &sh
, link
) {
167 if (strcasecmp(section
->name
, s
) == 0)
174 dump_pcmcia_id(const char *s
)
176 char *manstr
, *devstr
;
179 p0
= __DECONST(char *, s
);
181 p
= strchr(p0
, '\\');
193 /* Convert any underscores to spaces. */
195 while (*p0
!= '\0') {
209 /* Convert any underscores to spaces. */
211 while (*p0
!= '\0') {
217 fprintf(ofp
, "\t\\\n\t{ \"%s\", \"%s\", ", manstr
, devstr
);
222 dump_pci_id(const char *s
)
225 char vidstr
[7], didstr
[7], subsysstr
[14];
227 p
= strcasestr(s
, "VEN_");
231 strcpy(vidstr
, "0x");
232 strncat(vidstr
, p
, 4);
233 p
= strcasestr(s
, "DEV_");
237 strcpy(didstr
, "0x");
238 strncat(didstr
, p
, 4);
241 p
= strcasestr(s
, "SUBSYS_");
243 strcpy(subsysstr
, "0x00000000");
246 strcpy(subsysstr
, "0x");
247 strncat(subsysstr
, p
, 8);
250 fprintf(ofp
, "\t\\\n\t{ %s, %s, %s, ", vidstr
, didstr
, subsysstr
);
257 struct assign
*manf
, *dev
;
259 struct assign
*assign
;
261 int first
= 1, found
= 0;
263 /* Find manufacturer name */
264 manf
= find_assign("Manufacturer", NULL
);
268 /* Find manufacturer section */
269 if (manf
->vals
[1] != NULL
&&
270 (strcasecmp(manf
->vals
[1], "NT.5.1") == 0 ||
271 strcasecmp(manf
->vals
[1], "NTx86") == 0 ||
272 strcasecmp(manf
->vals
[1], "NTx86.5.1") == 0 ||
273 strcasecmp(manf
->vals
[1], "NTamd64") == 0)) {
274 /* Handle Windows XP INF files. */
275 snprintf(xpsec
, sizeof(xpsec
), "%s.%s",
276 manf
->vals
[0], manf
->vals
[1]);
277 sec
= find_section(xpsec
);
279 sec
= find_section(manf
->vals
[0]);
281 /* See if there are any PCI device definitions. */
283 TAILQ_FOREACH(assign
, &ah
, link
) {
284 if (assign
->section
== sec
) {
285 dev
= find_assign("strings", assign
->key
);
286 if (strcasestr(assign
->vals
[1], "PCI") != NULL
) {
299 /* Emit start of PCI device table */
300 fprintf (ofp
, "#define NDIS_PCI_DEV_TABLE");
307 * Now run through all the device names listed
308 * in the manufacturer section and dump out the
309 * device descriptions and vendor/device IDs.
312 TAILQ_FOREACH(assign
, &ah
, link
) {
313 if (assign
->section
== sec
) {
314 dev
= find_assign("strings", assign
->key
);
315 /* Emit device IDs. */
316 if (strcasestr(assign
->vals
[1], "PCI") != NULL
)
317 dump_pci_id(assign
->vals
[1]);
320 /* Emit device description */
321 fprintf (ofp
, "\t\\\n\t\"%s\" },", dev
->vals
[0]);
326 /* Someone tried to fool us. Shame on them. */
329 sec
= find_section(manf
->vals
[0]);
333 /* Handle Manufacturer sections with multiple entries. */
334 manf
= find_next_assign(manf
);
340 /* Emit end of table */
342 fprintf(ofp
, "\n\n");
348 dump_deviceids_pcmcia()
350 struct assign
*manf
, *dev
;
352 struct assign
*assign
;
354 int first
= 1, found
= 0;
356 /* Find manufacturer name */
357 manf
= find_assign("Manufacturer", NULL
);
361 /* Find manufacturer section */
362 if (manf
->vals
[1] != NULL
&&
363 (strcasecmp(manf
->vals
[1], "NT.5.1") == 0 ||
364 strcasecmp(manf
->vals
[1], "NTx86") == 0 ||
365 strcasecmp(manf
->vals
[1], "NTx86.5.1") == 0 ||
366 strcasecmp(manf
->vals
[1], "NTamd64") == 0)) {
367 /* Handle Windows XP INF files. */
368 snprintf(xpsec
, sizeof(xpsec
), "%s.%s",
369 manf
->vals
[0], manf
->vals
[1]);
370 sec
= find_section(xpsec
);
372 sec
= find_section(manf
->vals
[0]);
374 /* See if there are any PCMCIA device definitions. */
376 TAILQ_FOREACH(assign
, &ah
, link
) {
377 if (assign
->section
== sec
) {
378 dev
= find_assign("strings", assign
->key
);
379 if (strcasestr(assign
->vals
[1], "PCMCIA") != NULL
) {
392 /* Emit start of PCMCIA device table */
393 fprintf (ofp
, "#define NDIS_PCMCIA_DEV_TABLE");
400 * Now run through all the device names listed
401 * in the manufacturer section and dump out the
402 * device descriptions and vendor/device IDs.
405 TAILQ_FOREACH(assign
, &ah
, link
) {
406 if (assign
->section
== sec
) {
407 dev
= find_assign("strings", assign
->key
);
408 /* Emit device IDs. */
409 if (strcasestr(assign
->vals
[1], "PCMCIA") != NULL
)
410 dump_pcmcia_id(assign
->vals
[1]);
413 /* Emit device description */
414 fprintf (ofp
, "\t\\\n\t\"%s\" },", dev
->vals
[0]);
419 /* Someone tried to fool us. Shame on them. */
422 sec
= find_section(manf
->vals
[0]);
426 /* Handle Manufacturer sections with multiple entries. */
427 manf
= find_next_assign(manf
);
433 /* Emit end of table */
435 fprintf(ofp
, "\n\n");
441 dump_addreg(const char *s
, int devidx
)
446 /* Find the addreg section */
447 sec
= find_section(s
);
449 /* Dump all the keys defined in it. */
450 TAILQ_FOREACH(reg
, &rh
, link
) {
452 * Keys with an empty subkey are very easy to parse,
453 * so just deal with them here. If a parameter key
454 * of the same name also exists, prefer that one and
457 if (reg
->section
== sec
) {
458 if (reg
->subkey
== NULL
) {
459 fprintf(ofp
, "\n\t{ \"%s\",", reg
->key
);
460 fprintf(ofp
,"\n\t\"%s \",", reg
->key
);
461 fprintf(ofp
, "\n\t{ \"%s\" }, %d },",
462 reg
->value
== NULL
? "" :
463 stringcvt(reg
->value
), devidx
);
464 } else if (strncasecmp(reg
->subkey
,
465 "Ndi\\params", strlen("Ndi\\params")-1) == 0 &&
466 (reg
->key
!= NULL
&& strcasecmp(reg
->key
,
468 dump_paramreg(sec
, reg
, devidx
);
476 dump_enumreg(const struct section
*s
, const struct reg
*r
)
481 sprintf(enumkey
, "%s\\enum", r
->subkey
);
482 TAILQ_FOREACH(reg
, &rh
, link
) {
483 if (reg
->section
!= s
)
485 if (reg
->subkey
== NULL
|| strcasecmp(reg
->subkey
, enumkey
))
487 fprintf(ofp
, " [%s=%s]", reg
->key
,
488 stringcvt(reg
->value
));
494 dump_editreg(const struct section
*s
, const struct reg
*r
)
498 TAILQ_FOREACH(reg
, &rh
, link
) {
499 if (reg
->section
!= s
)
501 if (reg
->subkey
== NULL
|| strcasecmp(reg
->subkey
, r
->subkey
))
503 if (reg
->key
== NULL
)
505 if (strcasecmp(reg
->key
, "LimitText") == 0)
506 fprintf(ofp
, " [maxchars=%s]", reg
->value
);
507 if (strcasecmp(reg
->key
, "Optional") == 0 &&
508 strcmp(reg
->value
, "1") == 0)
509 fprintf(ofp
, " [optional]");
514 /* Use this for int too */
516 dump_dwordreg(const struct section
*s
, const struct reg
*r
)
520 TAILQ_FOREACH(reg
, &rh
, link
) {
521 if (reg
->section
!= s
)
523 if (reg
->subkey
== NULL
|| strcasecmp(reg
->subkey
, r
->subkey
))
525 if (reg
->key
== NULL
)
527 if (strcasecmp(reg
->key
, "min") == 0)
528 fprintf(ofp
, " [min=%s]", reg
->value
);
529 if (strcasecmp(reg
->key
, "max") == 0)
530 fprintf(ofp
, " [max=%s]", reg
->value
);
536 dump_defaultinfo(const struct section
*s
, const struct reg
*r
, int devidx
)
539 TAILQ_FOREACH(reg
, &rh
, link
) {
540 if (reg
->section
!= s
)
542 if (reg
->subkey
== NULL
|| strcasecmp(reg
->subkey
, r
->subkey
))
544 if (reg
->key
== NULL
|| strcasecmp(reg
->key
, "Default"))
546 fprintf(ofp
, "\n\t{ \"%s\" }, %d },", reg
->value
== NULL
? "" :
547 stringcvt(reg
->value
), devidx
);
550 /* Default registry entry missing */
551 fprintf(ofp
, "\n\t{ \"\" }, %d },", devidx
);
556 dump_paramdesc(const struct section
*s
, const struct reg
*r
)
559 TAILQ_FOREACH(reg
, &rh
, link
) {
560 if (reg
->section
!= s
)
562 if (reg
->subkey
== NULL
|| strcasecmp(reg
->subkey
, r
->subkey
))
564 if (reg
->key
== NULL
|| strcasecmp(reg
->key
, "ParamDesc"))
566 fprintf(ofp
, "\n\t\"%s", stringcvt(r
->value
));
573 dump_typeinfo(const struct section
*s
, const struct reg
*r
)
576 TAILQ_FOREACH(reg
, &rh
, link
) {
577 if (reg
->section
!= s
)
579 if (reg
->subkey
== NULL
|| strcasecmp(reg
->subkey
, r
->subkey
))
581 if (reg
->key
== NULL
)
583 if (strcasecmp(reg
->key
, "type"))
585 if (strcasecmp(reg
->value
, "dword") == 0 ||
586 strcasecmp(reg
->value
, "int") == 0)
588 if (strcasecmp(reg
->value
, "enum") == 0)
590 if (strcasecmp(reg
->value
, "edit") == 0)
597 dump_paramreg(const struct section
*s
, const struct reg
*r
, int devidx
)
601 keyname
= r
->subkey
+ strlen("Ndi\\params\\");
602 fprintf(ofp
, "\n\t{ \"%s\",", keyname
);
603 dump_paramdesc(s
, r
);
606 dump_defaultinfo(s
, r
, devidx
);
614 struct assign
*manf
, *dev
;
616 struct assign
*assign
;
618 int found
= 0, i
, is_winxp
= 0, is_winnt
= 0, devidx
= 0;
620 /* Find signature to check for special case of WinNT. */
621 assign
= find_assign("version", "signature");
622 if (strcasecmp(assign
->vals
[0], "$windows nt$") == 0)
625 /* Emit start of block */
626 fprintf (ofp
, "ndis_cfg ndis_regvals[] = {");
628 /* Find manufacturer name */
629 manf
= find_assign("Manufacturer", NULL
);
633 /* Find manufacturer section */
634 if (manf
->vals
[1] != NULL
&&
635 (strcasecmp(manf
->vals
[1], "NT.5.1") == 0 ||
636 strcasecmp(manf
->vals
[1], "NTx86") == 0 ||
637 strcasecmp(manf
->vals
[1], "NTx86.5.1") == 0 ||
638 strcasecmp(manf
->vals
[1], "NTamd64") == 0)) {
640 /* Handle Windows XP INF files. */
641 snprintf(sname
, sizeof(sname
), "%s.%s",
642 manf
->vals
[0], manf
->vals
[1]);
643 sec
= find_section(sname
);
645 sec
= find_section(manf
->vals
[0]);
649 TAILQ_FOREACH(assign
, &ah
, link
) {
650 if (assign
->section
== sec
) {
653 * Find all the AddReg sections.
654 * Look for section names with .NT, unless
655 * this is a WinXP .INF file.
659 sprintf(sname
, "%s.NTx86", assign
->vals
[0]);
660 dev
= find_assign(sname
, "AddReg");
662 sprintf(sname
, "%s.NT",
664 dev
= find_assign(sname
, "AddReg");
667 dev
= find_assign(assign
->vals
[0],
670 sprintf(sname
, "%s.NT", assign
->vals
[0]);
671 dev
= find_assign(sname
, "AddReg");
672 if (dev
== NULL
&& is_winnt
)
673 dev
= find_assign(assign
->vals
[0],
676 /* Section not found. */
679 for (i
= 0; i
< W_MAX
; i
++) {
680 if (dev
->vals
[i
] != NULL
)
681 dump_addreg(dev
->vals
[i
], devidx
);
688 sec
= find_section(manf
->vals
[0]);
694 manf
= find_next_assign(manf
);
699 fprintf(ofp
, "\n\t{ NULL, NULL, { 0 }, 0 }\n};\n\n");
705 assign_add (const char *a
)
707 struct assign
*assign
;
710 assign
= malloc(sizeof(struct assign
));
711 bzero(assign
, sizeof(struct assign
));
712 assign
->section
= TAILQ_LAST(&sh
, section_head
);
713 assign
->key
= sstrdup(a
);
714 for (i
= 0; i
< idx
; i
++)
715 assign
->vals
[(idx
- 1) - i
] = sstrdup(words
[i
]);
716 TAILQ_INSERT_TAIL(&ah
, assign
, link
);
723 define_add (const char *d __unused
)
726 fprintf(stderr
, "define \"%s\"\n", d
);
732 sstrdup(const char *str
)
734 if (str
!= NULL
&& strlen(str
))
735 return (strdup(str
));
740 satoi (const char *nptr
)
742 if (nptr
!= NULL
&& strlen(nptr
))
748 regkey_add (const char *r
)
752 reg
= malloc(sizeof(struct reg
));
753 bzero(reg
, sizeof(struct reg
));
754 reg
->section
= TAILQ_LAST(&sh
, section_head
);
755 reg
->root
= sstrdup(r
);
756 reg
->subkey
= sstrdup(words
[3]);
757 reg
->key
= sstrdup(words
[2]);
758 reg
->flags
= satoi(words
[1]);
759 reg
->value
= sstrdup(words
[0]);
760 TAILQ_INSERT_TAIL(&rh
, reg
, link
);
762 free(__DECONST(char *, r
));
768 push_word (const char *w
)
782 for (i
= 0; i
< idx
; i
++) {
784 free(__DECONST(char *, words
[i
]));
788 bzero(words
, sizeof(words
));