1123475Swpaul/* 2124060Swpaul * Copyright (c) 2003 3124060Swpaul * Bill Paul <wpaul@windriver.com>. All rights reserved. 4124060Swpaul * 5124060Swpaul * Redistribution and use in source and binary forms, with or without 6124060Swpaul * modification, are permitted provided that the following conditions 7124060Swpaul * are met: 8124060Swpaul * 1. Redistributions of source code must retain the above copyright 9124060Swpaul * notice, this list of conditions and the following disclaimer. 10124060Swpaul * 2. Redistributions in binary form must reproduce the above copyright 11124060Swpaul * notice, this list of conditions and the following disclaimer in the 12124060Swpaul * documentation and/or other materials provided with the distribution. 13124060Swpaul * 3. All advertising materials mentioning features or use of this software 14124060Swpaul * must display the following acknowledgement: 15124060Swpaul * This product includes software developed by Bill Paul. 16124060Swpaul * 4. Neither the name of the author nor the names of any co-contributors 17124060Swpaul * may be used to endorse or promote products derived from this software 18124060Swpaul * without specific prior written permission. 19124060Swpaul * 20124060Swpaul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 21124060Swpaul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22124060Swpaul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 23124060Swpaul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD 24124060Swpaul * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25124060Swpaul * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26124060Swpaul * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27124060Swpaul * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28124060Swpaul * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29124060Swpaul * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30124060Swpaul * THE POSSIBILITY OF SUCH DAMAGE. 31123475Swpaul */ 32123475Swpaul 33123475Swpaul#include <sys/cdefs.h> 34123475Swpaul__FBSDID("$FreeBSD: stable/10/usr.sbin/ndiscvt/inf.c 343730 2019-02-04 03:44:07Z avos $"); 35123475Swpaul 36123475Swpaul#include <stdio.h> 37123475Swpaul#include <stdlib.h> 38123475Swpaul#include <string.h> 39123475Swpaul#include <sys/types.h> 40123475Swpaul 41123475Swpaul#include <sys/queue.h> 42123475Swpaul 43123475Swpaul#include "inf.h" 44123475Swpaul 45123475Swpaulextern FILE *yyin; 46123475Swpaulint yyparse (void); 47123475Swpaul 48123475Swpaulconst char *words[W_MAX]; /* More than we'll need. */ 49123475Swpaulint idx; 50123475Swpaul 51123475Swpaulstatic struct section_head sh; 52123475Swpaulstatic struct reg_head rh; 53123475Swpaulstatic struct assign_head ah; 54123475Swpaul 55123475Swpaulstatic char *sstrdup (const char *); 56123475Swpaulstatic struct assign 57123475Swpaul *find_assign (const char *, const char *); 58146243Swpaulstatic struct assign 59146243Swpaul *find_next_assign 60146243Swpaul (struct assign *); 61123475Swpaulstatic struct section 62123475Swpaul *find_section (const char *); 63343730Savosstatic int dump_deviceids_pci (void); 64343730Savosstatic int dump_deviceids_pcmcia (void); 65343730Savosstatic int dump_deviceids_usb (void); 66123475Swpaulstatic void dump_pci_id (const char *); 67126706Swpaulstatic void dump_pcmcia_id (const char *); 68186507Sweongyostatic void dump_usb_id (const char *); 69141981Swpaulstatic void dump_regvals (void); 70123620Swpaulstatic void dump_paramreg (const struct section *, 71123620Swpaul const struct reg *, int); 72123475Swpaul 73123475Swpaulstatic FILE *ofp; 74123475Swpaul 75123475Swpaulint 76123475Swpaulinf_parse (FILE *fp, FILE *outfp) 77123475Swpaul{ 78123475Swpaul TAILQ_INIT(&sh); 79123475Swpaul TAILQ_INIT(&rh); 80123475Swpaul TAILQ_INIT(&ah); 81123475Swpaul 82123475Swpaul ofp = outfp; 83123475Swpaul yyin = fp; 84123475Swpaul yyparse(); 85123475Swpaul 86343730Savos if (dump_deviceids_pci() == 0 && 87343730Savos dump_deviceids_pcmcia() == 0 && 88343730Savos dump_deviceids_usb() == 0) 89343730Savos return (-1); 90343730Savos 91126706Swpaul fprintf(outfp, "#ifdef NDIS_REGVALS\n"); 92123475Swpaul dump_regvals(); 93126706Swpaul fprintf(outfp, "#endif /* NDIS_REGVALS */\n"); 94123475Swpaul 95123475Swpaul return (0); 96123475Swpaul} 97123475Swpaul 98123475Swpaulvoid 99123475Swpaulsection_add (const char *s) 100123475Swpaul{ 101123475Swpaul struct section *sec; 102123475Swpaul 103123475Swpaul sec = malloc(sizeof(struct section)); 104123475Swpaul bzero(sec, sizeof(struct section)); 105123475Swpaul sec->name = s; 106123475Swpaul TAILQ_INSERT_TAIL(&sh, sec, link); 107123475Swpaul 108123475Swpaul return; 109123475Swpaul} 110123475Swpaul 111123475Swpaulstatic struct assign * 112123475Swpaulfind_assign (const char *s, const char *k) 113123475Swpaul{ 114123475Swpaul struct assign *assign; 115123475Swpaul char newkey[256]; 116123475Swpaul 117123475Swpaul /* Deal with string section lookups. */ 118123475Swpaul 119123475Swpaul if (k != NULL && k[0] == '%') { 120123475Swpaul bzero(newkey, sizeof(newkey)); 121123475Swpaul strncpy(newkey, k + 1, strlen(k) - 2); 122123475Swpaul k = newkey; 123123475Swpaul } 124123475Swpaul 125123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 126123475Swpaul if (strcasecmp(assign->section->name, s) == 0) { 127123475Swpaul if (k == NULL) 128123475Swpaul return(assign); 129123475Swpaul else 130123475Swpaul if (strcasecmp(assign->key, k) == 0) 131123475Swpaul return(assign); 132123475Swpaul } 133123475Swpaul } 134123475Swpaul return(NULL); 135123475Swpaul} 136123475Swpaul 137146243Swpaulstatic struct assign * 138146243Swpaulfind_next_assign (struct assign *a) 139146243Swpaul{ 140146243Swpaul struct assign *assign; 141146243Swpaul 142146243Swpaul TAILQ_FOREACH(assign, &ah, link) { 143146243Swpaul if (assign == a) 144146243Swpaul break; 145146243Swpaul } 146146243Swpaul 147146243Swpaul assign = assign->link.tqe_next; 148146243Swpaul 149146243Swpaul if (assign == NULL || assign->section != a->section) 150146243Swpaul return(NULL); 151146243Swpaul 152146243Swpaul return (assign); 153146243Swpaul} 154146243Swpaul 155123475Swpaulstatic const char * 156123475Swpaulstringcvt(const char *s) 157123475Swpaul{ 158123475Swpaul struct assign *manf; 159123475Swpaul 160123475Swpaul manf = find_assign("strings", s); 161123475Swpaul if (manf == NULL) 162123475Swpaul return(s); 163123475Swpaul return(manf->vals[0]); 164123475Swpaul} 165123475Swpaul 166123475Swpaulstruct section * 167123475Swpaulfind_section (const char *s) 168123475Swpaul{ 169123475Swpaul struct section *section; 170123475Swpaul 171123475Swpaul TAILQ_FOREACH(section, &sh, link) { 172123475Swpaul if (strcasecmp(section->name, s) == 0) 173123475Swpaul return(section); 174123475Swpaul } 175123475Swpaul return(NULL); 176123475Swpaul} 177123475Swpaul 178123475Swpaulstatic void 179126706Swpauldump_pcmcia_id(const char *s) 180126706Swpaul{ 181126706Swpaul char *manstr, *devstr; 182126706Swpaul char *p0, *p; 183126706Swpaul 184126706Swpaul p0 = __DECONST(char *, s); 185126706Swpaul 186126706Swpaul p = strchr(p0, '\\'); 187126706Swpaul if (p == NULL) 188126706Swpaul return; 189126706Swpaul p0 = p + 1; 190126706Swpaul 191126706Swpaul p = strchr(p0, '-'); 192126706Swpaul if (p == NULL) 193126706Swpaul return; 194126706Swpaul *p = '\0'; 195126706Swpaul 196126706Swpaul manstr = p0; 197126706Swpaul 198126706Swpaul /* Convert any underscores to spaces. */ 199126706Swpaul 200126706Swpaul while (*p0 != '\0') { 201126706Swpaul if (*p0 == '_') 202126706Swpaul *p0 = ' '; 203126706Swpaul p0++; 204126706Swpaul } 205126706Swpaul 206126706Swpaul p0 = p + 1; 207126706Swpaul p = strchr(p0, '-'); 208126706Swpaul if (p == NULL) 209126706Swpaul return; 210126706Swpaul *p = '\0'; 211126706Swpaul 212126706Swpaul devstr = p0; 213126706Swpaul 214126706Swpaul /* Convert any underscores to spaces. */ 215126706Swpaul 216126706Swpaul while (*p0 != '\0') { 217126706Swpaul if (*p0 == '_') 218126706Swpaul *p0 = ' '; 219126706Swpaul p0++; 220126706Swpaul } 221126706Swpaul 222126706Swpaul fprintf(ofp, "\t\\\n\t{ \"%s\", \"%s\", ", manstr, devstr); 223126706Swpaul return; 224126706Swpaul} 225126706Swpaul 226126706Swpaulstatic void 227123475Swpauldump_pci_id(const char *s) 228123475Swpaul{ 229123475Swpaul char *p; 230123620Swpaul char vidstr[7], didstr[7], subsysstr[14]; 231123475Swpaul 232123475Swpaul p = strcasestr(s, "VEN_"); 233123475Swpaul if (p == NULL) 234123475Swpaul return; 235123475Swpaul p += 4; 236123475Swpaul strcpy(vidstr, "0x"); 237123475Swpaul strncat(vidstr, p, 4); 238123475Swpaul p = strcasestr(s, "DEV_"); 239123475Swpaul if (p == NULL) 240123475Swpaul return; 241123475Swpaul p += 4; 242123475Swpaul strcpy(didstr, "0x"); 243123475Swpaul strncat(didstr, p, 4); 244123475Swpaul if (p == NULL) 245123475Swpaul return; 246123620Swpaul p = strcasestr(s, "SUBSYS_"); 247123620Swpaul if (p == NULL) 248123620Swpaul strcpy(subsysstr, "0x00000000"); 249123620Swpaul else { 250123620Swpaul p += 7; 251123620Swpaul strcpy(subsysstr, "0x"); 252123620Swpaul strncat(subsysstr, p, 8); 253123620Swpaul } 254123475Swpaul 255123620Swpaul fprintf(ofp, "\t\\\n\t{ %s, %s, %s, ", vidstr, didstr, subsysstr); 256123475Swpaul return; 257123475Swpaul} 258123475Swpaul 259123475Swpaulstatic void 260186507Sweongyodump_usb_id(const char *s) 261186507Sweongyo{ 262186507Sweongyo char *p; 263186507Sweongyo char vidstr[7], pidstr[7]; 264186507Sweongyo 265186507Sweongyo p = strcasestr(s, "VID_"); 266186507Sweongyo if (p == NULL) 267186507Sweongyo return; 268186507Sweongyo p += 4; 269186507Sweongyo strcpy(vidstr, "0x"); 270186507Sweongyo strncat(vidstr, p, 4); 271186507Sweongyo p = strcasestr(s, "PID_"); 272186507Sweongyo if (p == NULL) 273186507Sweongyo return; 274186507Sweongyo p += 4; 275186507Sweongyo strcpy(pidstr, "0x"); 276186507Sweongyo strncat(pidstr, p, 4); 277186507Sweongyo if (p == NULL) 278186507Sweongyo return; 279186507Sweongyo 280186507Sweongyo fprintf(ofp, "\t\\\n\t{ %s, %s, ", vidstr, pidstr); 281186507Sweongyo} 282186507Sweongyo 283343730Savosstatic int 284126706Swpauldump_deviceids_pci() 285123475Swpaul{ 286123475Swpaul struct assign *manf, *dev; 287123475Swpaul struct section *sec; 288123475Swpaul struct assign *assign; 289123483Swpaul char xpsec[256]; 290179855Sweongyo int first = 1, found = 0; 291123475Swpaul 292123475Swpaul /* Find manufacturer name */ 293123475Swpaul manf = find_assign("Manufacturer", NULL); 294123475Swpaul 295146243Swpaulnextmanf: 296146243Swpaul 297123475Swpaul /* Find manufacturer section */ 298123483Swpaul if (manf->vals[1] != NULL && 299123511Swpaul (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 300124094Swpaul strcasecmp(manf->vals[1], "NTx86") == 0 || 301141963Swpaul strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 302141963Swpaul strcasecmp(manf->vals[1], "NTamd64") == 0)) { 303123483Swpaul /* Handle Windows XP INF files. */ 304123483Swpaul snprintf(xpsec, sizeof(xpsec), "%s.%s", 305123483Swpaul manf->vals[0], manf->vals[1]); 306123483Swpaul sec = find_section(xpsec); 307123483Swpaul } else 308123483Swpaul sec = find_section(manf->vals[0]); 309123475Swpaul 310126706Swpaul /* See if there are any PCI device definitions. */ 311123475Swpaul 312126706Swpaul TAILQ_FOREACH(assign, &ah, link) { 313126706Swpaul if (assign->section == sec) { 314126706Swpaul dev = find_assign("strings", assign->key); 315126706Swpaul if (strcasestr(assign->vals[1], "PCI") != NULL) { 316126706Swpaul found++; 317126706Swpaul break; 318126706Swpaul } 319126706Swpaul } 320126706Swpaul } 321126706Swpaul 322126706Swpaul if (found == 0) 323146243Swpaul goto done; 324126706Swpaul 325126706Swpaul found = 0; 326126706Swpaul 327179855Sweongyo if (first == 1) { 328179855Sweongyo /* Emit start of PCI device table */ 329179855Sweongyo fprintf (ofp, "#define NDIS_PCI_DEV_TABLE"); 330179855Sweongyo first = 0; 331179855Sweongyo } 332179855Sweongyo 333125073Swpaulretry: 334125073Swpaul 335123475Swpaul /* 336123475Swpaul * Now run through all the device names listed 337123475Swpaul * in the manufacturer section and dump out the 338123475Swpaul * device descriptions and vendor/device IDs. 339123475Swpaul */ 340123475Swpaul 341123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 342123475Swpaul if (assign->section == sec) { 343123475Swpaul dev = find_assign("strings", assign->key); 344123475Swpaul /* Emit device IDs. */ 345123475Swpaul if (strcasestr(assign->vals[1], "PCI") != NULL) 346123475Swpaul dump_pci_id(assign->vals[1]); 347126706Swpaul else 348124886Swpaul continue; 349126706Swpaul /* Emit device description */ 350126706Swpaul fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); 351126706Swpaul found++; 352126706Swpaul } 353126706Swpaul } 354126706Swpaul 355126706Swpaul /* Someone tried to fool us. Shame on them. */ 356126706Swpaul if (!found) { 357126706Swpaul found++; 358126706Swpaul sec = find_section(manf->vals[0]); 359126706Swpaul goto retry; 360126706Swpaul } 361126706Swpaul 362146243Swpaul /* Handle Manufacturer sections with multiple entries. */ 363146243Swpaul manf = find_next_assign(manf); 364146243Swpaul 365146243Swpaul if (manf != NULL) 366146243Swpaul goto nextmanf; 367146243Swpaul 368146243Swpauldone: 369126706Swpaul /* Emit end of table */ 370126706Swpaul 371126706Swpaul fprintf(ofp, "\n\n"); 372126706Swpaul 373343730Savos return (found); 374126706Swpaul} 375126706Swpaul 376343730Savosstatic int 377126706Swpauldump_deviceids_pcmcia() 378126706Swpaul{ 379126706Swpaul struct assign *manf, *dev; 380126706Swpaul struct section *sec; 381126706Swpaul struct assign *assign; 382126706Swpaul char xpsec[256]; 383179855Sweongyo int first = 1, found = 0; 384126706Swpaul 385126706Swpaul /* Find manufacturer name */ 386126706Swpaul manf = find_assign("Manufacturer", NULL); 387126706Swpaul 388146243Swpaulnextmanf: 389146243Swpaul 390126706Swpaul /* Find manufacturer section */ 391126706Swpaul if (manf->vals[1] != NULL && 392126706Swpaul (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 393126706Swpaul strcasecmp(manf->vals[1], "NTx86") == 0 || 394141963Swpaul strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 395141963Swpaul strcasecmp(manf->vals[1], "NTamd64") == 0)) { 396126706Swpaul /* Handle Windows XP INF files. */ 397126706Swpaul snprintf(xpsec, sizeof(xpsec), "%s.%s", 398126706Swpaul manf->vals[0], manf->vals[1]); 399126706Swpaul sec = find_section(xpsec); 400126706Swpaul } else 401126706Swpaul sec = find_section(manf->vals[0]); 402126706Swpaul 403126706Swpaul /* See if there are any PCMCIA device definitions. */ 404126706Swpaul 405126706Swpaul TAILQ_FOREACH(assign, &ah, link) { 406126706Swpaul if (assign->section == sec) { 407126706Swpaul dev = find_assign("strings", assign->key); 408126706Swpaul if (strcasestr(assign->vals[1], "PCMCIA") != NULL) { 409126706Swpaul found++; 410126706Swpaul break; 411126706Swpaul } 412126706Swpaul } 413126706Swpaul } 414126706Swpaul 415126706Swpaul if (found == 0) 416146243Swpaul goto done; 417126706Swpaul 418126706Swpaul found = 0; 419126706Swpaul 420179855Sweongyo if (first == 1) { 421179855Sweongyo /* Emit start of PCMCIA device table */ 422179855Sweongyo fprintf (ofp, "#define NDIS_PCMCIA_DEV_TABLE"); 423179855Sweongyo first = 0; 424179855Sweongyo } 425126706Swpaul 426126706Swpaulretry: 427126706Swpaul 428126706Swpaul /* 429126706Swpaul * Now run through all the device names listed 430126706Swpaul * in the manufacturer section and dump out the 431126706Swpaul * device descriptions and vendor/device IDs. 432126706Swpaul */ 433126706Swpaul 434126706Swpaul TAILQ_FOREACH(assign, &ah, link) { 435126706Swpaul if (assign->section == sec) { 436126706Swpaul dev = find_assign("strings", assign->key); 437126706Swpaul /* Emit device IDs. */ 438126706Swpaul if (strcasestr(assign->vals[1], "PCMCIA") != NULL) 439123475Swpaul dump_pcmcia_id(assign->vals[1]); 440126706Swpaul else 441126706Swpaul continue; 442123475Swpaul /* Emit device description */ 443123480Swpaul fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); 444125073Swpaul found++; 445123475Swpaul } 446123475Swpaul } 447123475Swpaul 448125073Swpaul /* Someone tried to fool us. Shame on them. */ 449125073Swpaul if (!found) { 450125073Swpaul found++; 451125073Swpaul sec = find_section(manf->vals[0]); 452125073Swpaul goto retry; 453125073Swpaul } 454125073Swpaul 455146243Swpaul /* Handle Manufacturer sections with multiple entries. */ 456146243Swpaul manf = find_next_assign(manf); 457146243Swpaul 458146243Swpaul if (manf != NULL) 459146243Swpaul goto nextmanf; 460146243Swpaul 461146243Swpauldone: 462123475Swpaul /* Emit end of table */ 463123475Swpaul 464123480Swpaul fprintf(ofp, "\n\n"); 465123480Swpaul 466343730Savos return (found); 467123475Swpaul} 468123475Swpaul 469343730Savosstatic int 470186507Sweongyodump_deviceids_usb() 471186507Sweongyo{ 472186507Sweongyo struct assign *manf, *dev; 473186507Sweongyo struct section *sec; 474186507Sweongyo struct assign *assign; 475186507Sweongyo char xpsec[256]; 476186507Sweongyo int first = 1, found = 0; 477186507Sweongyo 478186507Sweongyo /* Find manufacturer name */ 479186507Sweongyo manf = find_assign("Manufacturer", NULL); 480186507Sweongyo 481186507Sweongyonextmanf: 482186507Sweongyo 483186507Sweongyo /* Find manufacturer section */ 484186507Sweongyo if (manf->vals[1] != NULL && 485186507Sweongyo (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 486186507Sweongyo strcasecmp(manf->vals[1], "NTx86") == 0 || 487186507Sweongyo strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 488186507Sweongyo strcasecmp(manf->vals[1], "NTamd64") == 0)) { 489186507Sweongyo /* Handle Windows XP INF files. */ 490186507Sweongyo snprintf(xpsec, sizeof(xpsec), "%s.%s", 491186507Sweongyo manf->vals[0], manf->vals[1]); 492186507Sweongyo sec = find_section(xpsec); 493186507Sweongyo } else 494186507Sweongyo sec = find_section(manf->vals[0]); 495186507Sweongyo 496186507Sweongyo /* See if there are any USB device definitions. */ 497186507Sweongyo 498186507Sweongyo TAILQ_FOREACH(assign, &ah, link) { 499186507Sweongyo if (assign->section == sec) { 500186507Sweongyo dev = find_assign("strings", assign->key); 501186507Sweongyo if (strcasestr(assign->vals[1], "USB") != NULL) { 502186507Sweongyo found++; 503186507Sweongyo break; 504186507Sweongyo } 505186507Sweongyo } 506186507Sweongyo } 507186507Sweongyo 508186507Sweongyo if (found == 0) 509186507Sweongyo goto done; 510186507Sweongyo 511186507Sweongyo found = 0; 512186507Sweongyo 513186507Sweongyo if (first == 1) { 514186507Sweongyo /* Emit start of USB device table */ 515186507Sweongyo fprintf (ofp, "#define NDIS_USB_DEV_TABLE"); 516186507Sweongyo first = 0; 517186507Sweongyo } 518186507Sweongyo 519186507Sweongyoretry: 520186507Sweongyo 521186507Sweongyo /* 522186507Sweongyo * Now run through all the device names listed 523186507Sweongyo * in the manufacturer section and dump out the 524186507Sweongyo * device descriptions and vendor/device IDs. 525186507Sweongyo */ 526186507Sweongyo 527186507Sweongyo TAILQ_FOREACH(assign, &ah, link) { 528186507Sweongyo if (assign->section == sec) { 529186507Sweongyo dev = find_assign("strings", assign->key); 530186507Sweongyo /* Emit device IDs. */ 531186507Sweongyo if (strcasestr(assign->vals[1], "USB") != NULL) 532186507Sweongyo dump_usb_id(assign->vals[1]); 533186507Sweongyo else 534186507Sweongyo continue; 535186507Sweongyo /* Emit device description */ 536186507Sweongyo fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); 537186507Sweongyo found++; 538186507Sweongyo } 539186507Sweongyo } 540186507Sweongyo 541186507Sweongyo /* Someone tried to fool us. Shame on them. */ 542186507Sweongyo if (!found) { 543186507Sweongyo found++; 544186507Sweongyo sec = find_section(manf->vals[0]); 545186507Sweongyo goto retry; 546186507Sweongyo } 547186507Sweongyo 548186507Sweongyo /* Handle Manufacturer sections with multiple entries. */ 549186507Sweongyo manf = find_next_assign(manf); 550186507Sweongyo 551186507Sweongyo if (manf != NULL) 552186507Sweongyo goto nextmanf; 553186507Sweongyo 554186507Sweongyodone: 555186507Sweongyo /* Emit end of table */ 556186507Sweongyo 557186507Sweongyo fprintf(ofp, "\n\n"); 558186507Sweongyo 559343730Savos return (found); 560186507Sweongyo} 561186507Sweongyo 562186507Sweongyostatic void 563123620Swpauldump_addreg(const char *s, int devidx) 564123475Swpaul{ 565123475Swpaul struct section *sec; 566123475Swpaul struct reg *reg; 567123475Swpaul 568123475Swpaul /* Find the addreg section */ 569123475Swpaul sec = find_section(s); 570123475Swpaul 571123475Swpaul /* Dump all the keys defined in it. */ 572123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 573123475Swpaul /* 574123475Swpaul * Keys with an empty subkey are very easy to parse, 575123475Swpaul * so just deal with them here. If a parameter key 576123475Swpaul * of the same name also exists, prefer that one and 577123475Swpaul * skip this one. 578123475Swpaul */ 579123475Swpaul if (reg->section == sec) { 580123475Swpaul if (reg->subkey == NULL) { 581123475Swpaul fprintf(ofp, "\n\t{ \"%s\",", reg->key); 582123475Swpaul fprintf(ofp,"\n\t\"%s \",", reg->key); 583123620Swpaul fprintf(ofp, "\n\t{ \"%s\" }, %d },", 584123475Swpaul reg->value == NULL ? "" : 585123620Swpaul stringcvt(reg->value), devidx); 586124452Swpaul } else if (strncasecmp(reg->subkey, 587124452Swpaul "Ndi\\params", strlen("Ndi\\params")-1) == 0 && 588124886Swpaul (reg->key != NULL && strcasecmp(reg->key, 589124886Swpaul "ParamDesc") == 0)) 590123620Swpaul dump_paramreg(sec, reg, devidx); 591123475Swpaul } 592123475Swpaul } 593123475Swpaul 594123475Swpaul return; 595123475Swpaul} 596123475Swpaul 597123475Swpaulstatic void 598123475Swpauldump_enumreg(const struct section *s, const struct reg *r) 599123475Swpaul{ 600123475Swpaul struct reg *reg; 601123475Swpaul char enumkey[256]; 602123475Swpaul 603123475Swpaul sprintf(enumkey, "%s\\enum", r->subkey); 604123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 605123475Swpaul if (reg->section != s) 606123475Swpaul continue; 607123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, enumkey)) 608123475Swpaul continue; 609123483Swpaul fprintf(ofp, " [%s=%s]", reg->key, 610123483Swpaul stringcvt(reg->value)); 611123475Swpaul } 612123475Swpaul return; 613123475Swpaul} 614123475Swpaul 615123475Swpaulstatic void 616123475Swpauldump_editreg(const struct section *s, const struct reg *r) 617123475Swpaul{ 618123475Swpaul struct reg *reg; 619123475Swpaul 620123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 621123475Swpaul if (reg->section != s) 622123475Swpaul continue; 623123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 624123475Swpaul continue; 625124886Swpaul if (reg->key == NULL) 626124886Swpaul continue; 627123475Swpaul if (strcasecmp(reg->key, "LimitText") == 0) 628123475Swpaul fprintf(ofp, " [maxchars=%s]", reg->value); 629123475Swpaul if (strcasecmp(reg->key, "Optional") == 0 && 630123475Swpaul strcmp(reg->value, "1") == 0) 631123475Swpaul fprintf(ofp, " [optional]"); 632123475Swpaul } 633123475Swpaul return; 634123475Swpaul} 635123475Swpaul 636123475Swpaul/* Use this for int too */ 637123475Swpaulstatic void 638123475Swpauldump_dwordreg(const struct section *s, const struct reg *r) 639123475Swpaul{ 640123475Swpaul struct reg *reg; 641123475Swpaul 642123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 643123475Swpaul if (reg->section != s) 644123475Swpaul continue; 645123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 646123475Swpaul continue; 647124886Swpaul if (reg->key == NULL) 648124886Swpaul continue; 649123475Swpaul if (strcasecmp(reg->key, "min") == 0) 650123475Swpaul fprintf(ofp, " [min=%s]", reg->value); 651123475Swpaul if (strcasecmp(reg->key, "max") == 0) 652123475Swpaul fprintf(ofp, " [max=%s]", reg->value); 653123475Swpaul } 654123475Swpaul return; 655123475Swpaul} 656123475Swpaul 657123475Swpaulstatic void 658123620Swpauldump_defaultinfo(const struct section *s, const struct reg *r, int devidx) 659123475Swpaul{ 660123475Swpaul struct reg *reg; 661123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 662123475Swpaul if (reg->section != s) 663123475Swpaul continue; 664123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 665123475Swpaul continue; 666124886Swpaul if (reg->key == NULL || strcasecmp(reg->key, "Default")) 667123475Swpaul continue; 668123620Swpaul fprintf(ofp, "\n\t{ \"%s\" }, %d },", reg->value == NULL ? "" : 669123977Swpaul stringcvt(reg->value), devidx); 670178214Sthompsa return; 671123475Swpaul } 672178214Sthompsa /* Default registry entry missing */ 673178214Sthompsa fprintf(ofp, "\n\t{ \"\" }, %d },", devidx); 674123475Swpaul return; 675123475Swpaul} 676123475Swpaul 677123475Swpaulstatic void 678123475Swpauldump_paramdesc(const struct section *s, const struct reg *r) 679123475Swpaul{ 680123475Swpaul struct reg *reg; 681123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 682123475Swpaul if (reg->section != s) 683123475Swpaul continue; 684123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 685123475Swpaul continue; 686124886Swpaul if (reg->key == NULL || strcasecmp(reg->key, "ParamDesc")) 687123475Swpaul continue; 688123475Swpaul fprintf(ofp, "\n\t\"%s", stringcvt(r->value)); 689123475Swpaul break; 690123475Swpaul } 691123475Swpaul return; 692123475Swpaul} 693123475Swpaul 694123475Swpaulstatic void 695123475Swpauldump_typeinfo(const struct section *s, const struct reg *r) 696123475Swpaul{ 697123475Swpaul struct reg *reg; 698123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 699123475Swpaul if (reg->section != s) 700123475Swpaul continue; 701123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 702123475Swpaul continue; 703124886Swpaul if (reg->key == NULL) 704124886Swpaul continue; 705123475Swpaul if (strcasecmp(reg->key, "type")) 706123475Swpaul continue; 707123475Swpaul if (strcasecmp(reg->value, "dword") == 0 || 708123475Swpaul strcasecmp(reg->value, "int") == 0) 709123475Swpaul dump_dwordreg(s, r); 710123475Swpaul if (strcasecmp(reg->value, "enum") == 0) 711123475Swpaul dump_enumreg(s, r); 712123475Swpaul if (strcasecmp(reg->value, "edit") == 0) 713123475Swpaul dump_editreg(s, r); 714123475Swpaul } 715123475Swpaul return; 716123475Swpaul} 717123475Swpaul 718123475Swpaulstatic void 719123620Swpauldump_paramreg(const struct section *s, const struct reg *r, int devidx) 720123475Swpaul{ 721123475Swpaul const char *keyname; 722123475Swpaul 723123475Swpaul keyname = r->subkey + strlen("Ndi\\params\\"); 724123475Swpaul fprintf(ofp, "\n\t{ \"%s\",", keyname); 725123475Swpaul dump_paramdesc(s, r); 726123475Swpaul dump_typeinfo(s, r); 727123475Swpaul fprintf(ofp, "\","); 728123620Swpaul dump_defaultinfo(s, r, devidx); 729123475Swpaul 730123475Swpaul return; 731123475Swpaul} 732123475Swpaul 733141981Swpaulstatic void 734123475Swpauldump_regvals(void) 735123475Swpaul{ 736123620Swpaul struct assign *manf, *dev; 737123475Swpaul struct section *sec; 738123475Swpaul struct assign *assign; 739123475Swpaul char sname[256]; 740125073Swpaul int found = 0, i, is_winxp = 0, is_winnt = 0, devidx = 0; 741123475Swpaul 742124085Swpaul /* Find signature to check for special case of WinNT. */ 743124085Swpaul assign = find_assign("version", "signature"); 744124085Swpaul if (strcasecmp(assign->vals[0], "$windows nt$") == 0) 745124085Swpaul is_winnt++; 746124085Swpaul 747146243Swpaul /* Emit start of block */ 748146243Swpaul fprintf (ofp, "ndis_cfg ndis_regvals[] = {"); 749146243Swpaul 750123475Swpaul /* Find manufacturer name */ 751123475Swpaul manf = find_assign("Manufacturer", NULL); 752123475Swpaul 753146243Swpaulnextmanf: 754146243Swpaul 755123475Swpaul /* Find manufacturer section */ 756123483Swpaul if (manf->vals[1] != NULL && 757123511Swpaul (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 758124094Swpaul strcasecmp(manf->vals[1], "NTx86") == 0 || 759141963Swpaul strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 760141963Swpaul strcasecmp(manf->vals[1], "NTamd64") == 0)) { 761123483Swpaul is_winxp++; 762123483Swpaul /* Handle Windows XP INF files. */ 763123483Swpaul snprintf(sname, sizeof(sname), "%s.%s", 764123483Swpaul manf->vals[0], manf->vals[1]); 765123483Swpaul sec = find_section(sname); 766123483Swpaul } else 767123483Swpaul sec = find_section(manf->vals[0]); 768123475Swpaul 769125073Swpaulretry: 770125073Swpaul 771123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 772123475Swpaul if (assign->section == sec) { 773125073Swpaul found++; 774123483Swpaul /* 775123483Swpaul * Find all the AddReg sections. 776123483Swpaul * Look for section names with .NT, unless 777123483Swpaul * this is a WinXP .INF file. 778123483Swpaul */ 779141963Swpaul 780123511Swpaul if (is_winxp) { 781123511Swpaul sprintf(sname, "%s.NTx86", assign->vals[0]); 782123511Swpaul dev = find_assign(sname, "AddReg"); 783141963Swpaul if (dev == NULL) { 784141963Swpaul sprintf(sname, "%s.NT", 785141963Swpaul assign->vals[0]); 786141963Swpaul dev = find_assign(sname, "AddReg"); 787141963Swpaul } 788123511Swpaul if (dev == NULL) 789123511Swpaul dev = find_assign(assign->vals[0], 790123511Swpaul "AddReg"); 791123511Swpaul } else { 792123483Swpaul sprintf(sname, "%s.NT", assign->vals[0]); 793123483Swpaul dev = find_assign(sname, "AddReg"); 794124085Swpaul if (dev == NULL && is_winnt) 795124085Swpaul dev = find_assign(assign->vals[0], 796124085Swpaul "AddReg"); 797123483Swpaul } 798123483Swpaul /* Section not found. */ 799123483Swpaul if (dev == NULL) 800123483Swpaul continue; 801123475Swpaul for (i = 0; i < W_MAX; i++) { 802123475Swpaul if (dev->vals[i] != NULL) 803123620Swpaul dump_addreg(dev->vals[i], devidx); 804123475Swpaul } 805123620Swpaul devidx++; 806123475Swpaul } 807123475Swpaul } 808123475Swpaul 809125073Swpaul if (!found) { 810125073Swpaul sec = find_section(manf->vals[0]); 811125073Swpaul is_winxp = 0; 812125073Swpaul found++; 813125073Swpaul goto retry; 814125073Swpaul } 815125073Swpaul 816146243Swpaul manf = find_next_assign(manf); 817146243Swpaul 818146243Swpaul if (manf != NULL) 819146243Swpaul goto nextmanf; 820146243Swpaul 821123620Swpaul fprintf(ofp, "\n\t{ NULL, NULL, { 0 }, 0 }\n};\n\n"); 822123475Swpaul 823123475Swpaul return; 824123475Swpaul} 825123475Swpaul 826123475Swpaulvoid 827123475Swpaulassign_add (const char *a) 828123475Swpaul{ 829123475Swpaul struct assign *assign; 830123475Swpaul int i; 831123475Swpaul 832123475Swpaul assign = malloc(sizeof(struct assign)); 833123475Swpaul bzero(assign, sizeof(struct assign)); 834123475Swpaul assign->section = TAILQ_LAST(&sh, section_head); 835123475Swpaul assign->key = sstrdup(a); 836123475Swpaul for (i = 0; i < idx; i++) 837123475Swpaul assign->vals[(idx - 1) - i] = sstrdup(words[i]); 838123475Swpaul TAILQ_INSERT_TAIL(&ah, assign, link); 839123475Swpaul 840123475Swpaul clear_words(); 841123475Swpaul return; 842123475Swpaul} 843123475Swpaul 844123475Swpaulvoid 845123475Swpauldefine_add (const char *d __unused) 846123475Swpaul{ 847123475Swpaul#ifdef notdef 848123475Swpaul fprintf(stderr, "define \"%s\"\n", d); 849123475Swpaul#endif 850123475Swpaul return; 851123475Swpaul} 852123475Swpaul 853123475Swpaulstatic char * 854123475Swpaulsstrdup(const char *str) 855123475Swpaul{ 856123475Swpaul if (str != NULL && strlen(str)) 857123475Swpaul return (strdup(str)); 858123475Swpaul return (NULL); 859123475Swpaul} 860123475Swpaul 861123475Swpaulstatic int 862123475Swpaulsatoi (const char *nptr) 863123475Swpaul{ 864123475Swpaul if (nptr != NULL && strlen(nptr)) 865123475Swpaul return (atoi(nptr)); 866123475Swpaul return (0); 867123475Swpaul} 868123475Swpaul 869123475Swpaulvoid 870123475Swpaulregkey_add (const char *r) 871123475Swpaul{ 872123475Swpaul struct reg *reg; 873123475Swpaul 874123475Swpaul reg = malloc(sizeof(struct reg)); 875123475Swpaul bzero(reg, sizeof(struct reg)); 876123475Swpaul reg->section = TAILQ_LAST(&sh, section_head); 877123475Swpaul reg->root = sstrdup(r); 878123475Swpaul reg->subkey = sstrdup(words[3]); 879123475Swpaul reg->key = sstrdup(words[2]); 880123475Swpaul reg->flags = satoi(words[1]); 881123475Swpaul reg->value = sstrdup(words[0]); 882123475Swpaul TAILQ_INSERT_TAIL(&rh, reg, link); 883123475Swpaul 884123475Swpaul free(__DECONST(char *, r)); 885123475Swpaul clear_words(); 886123475Swpaul return; 887123475Swpaul} 888123475Swpaul 889123475Swpaulvoid 890123475Swpaulpush_word (const char *w) 891123475Swpaul{ 892288924Samdmi3 893288924Samdmi3 if (idx == W_MAX) { 894288924Samdmi3 fprintf(stderr, "too many words; try bumping W_MAX in inf.h\n"); 895288924Samdmi3 exit(1); 896288924Samdmi3 } 897288924Samdmi3 898123475Swpaul if (w && strlen(w)) 899123475Swpaul words[idx++] = w; 900123475Swpaul else 901123475Swpaul words[idx++] = NULL; 902123475Swpaul return; 903123475Swpaul} 904123475Swpaul 905123475Swpaulvoid 906123475Swpaulclear_words (void) 907123475Swpaul{ 908123475Swpaul int i; 909123475Swpaul 910123475Swpaul for (i = 0; i < idx; i++) { 911123475Swpaul if (words[i]) { 912123475Swpaul free(__DECONST(char *, words[i])); 913123475Swpaul } 914123475Swpaul } 915123475Swpaul idx = 0; 916123475Swpaul bzero(words, sizeof(words)); 917123475Swpaul return; 918123475Swpaul} 919