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$"); 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 *); 63126706Swpaulstatic void dump_deviceids_pci (void); 64126706Swpaulstatic void dump_deviceids_pcmcia (void); 65186507Sweongyostatic void 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 86126706Swpaul dump_deviceids_pci(); 87126706Swpaul dump_deviceids_pcmcia(); 88186507Sweongyo dump_deviceids_usb(); 89126706Swpaul fprintf(outfp, "#ifdef NDIS_REGVALS\n"); 90123475Swpaul dump_regvals(); 91126706Swpaul fprintf(outfp, "#endif /* NDIS_REGVALS */\n"); 92123475Swpaul 93123475Swpaul return (0); 94123475Swpaul} 95123475Swpaul 96123475Swpaulvoid 97123475Swpaulsection_add (const char *s) 98123475Swpaul{ 99123475Swpaul struct section *sec; 100123475Swpaul 101123475Swpaul sec = malloc(sizeof(struct section)); 102123475Swpaul bzero(sec, sizeof(struct section)); 103123475Swpaul sec->name = s; 104123475Swpaul TAILQ_INSERT_TAIL(&sh, sec, link); 105123475Swpaul 106123475Swpaul return; 107123475Swpaul} 108123475Swpaul 109123475Swpaulstatic struct assign * 110123475Swpaulfind_assign (const char *s, const char *k) 111123475Swpaul{ 112123475Swpaul struct assign *assign; 113123475Swpaul char newkey[256]; 114123475Swpaul 115123475Swpaul /* Deal with string section lookups. */ 116123475Swpaul 117123475Swpaul if (k != NULL && k[0] == '%') { 118123475Swpaul bzero(newkey, sizeof(newkey)); 119123475Swpaul strncpy(newkey, k + 1, strlen(k) - 2); 120123475Swpaul k = newkey; 121123475Swpaul } 122123475Swpaul 123123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 124123475Swpaul if (strcasecmp(assign->section->name, s) == 0) { 125123475Swpaul if (k == NULL) 126123475Swpaul return(assign); 127123475Swpaul else 128123475Swpaul if (strcasecmp(assign->key, k) == 0) 129123475Swpaul return(assign); 130123475Swpaul } 131123475Swpaul } 132123475Swpaul return(NULL); 133123475Swpaul} 134123475Swpaul 135146243Swpaulstatic struct assign * 136146243Swpaulfind_next_assign (struct assign *a) 137146243Swpaul{ 138146243Swpaul struct assign *assign; 139146243Swpaul 140146243Swpaul TAILQ_FOREACH(assign, &ah, link) { 141146243Swpaul if (assign == a) 142146243Swpaul break; 143146243Swpaul } 144146243Swpaul 145146243Swpaul assign = assign->link.tqe_next; 146146243Swpaul 147146243Swpaul if (assign == NULL || assign->section != a->section) 148146243Swpaul return(NULL); 149146243Swpaul 150146243Swpaul return (assign); 151146243Swpaul} 152146243Swpaul 153123475Swpaulstatic const char * 154123475Swpaulstringcvt(const char *s) 155123475Swpaul{ 156123475Swpaul struct assign *manf; 157123475Swpaul 158123475Swpaul manf = find_assign("strings", s); 159123475Swpaul if (manf == NULL) 160123475Swpaul return(s); 161123475Swpaul return(manf->vals[0]); 162123475Swpaul} 163123475Swpaul 164123475Swpaulstruct section * 165123475Swpaulfind_section (const char *s) 166123475Swpaul{ 167123475Swpaul struct section *section; 168123475Swpaul 169123475Swpaul TAILQ_FOREACH(section, &sh, link) { 170123475Swpaul if (strcasecmp(section->name, s) == 0) 171123475Swpaul return(section); 172123475Swpaul } 173123475Swpaul return(NULL); 174123475Swpaul} 175123475Swpaul 176123475Swpaulstatic void 177126706Swpauldump_pcmcia_id(const char *s) 178126706Swpaul{ 179126706Swpaul char *manstr, *devstr; 180126706Swpaul char *p0, *p; 181126706Swpaul 182126706Swpaul p0 = __DECONST(char *, s); 183126706Swpaul 184126706Swpaul p = strchr(p0, '\\'); 185126706Swpaul if (p == NULL) 186126706Swpaul return; 187126706Swpaul p0 = p + 1; 188126706Swpaul 189126706Swpaul p = strchr(p0, '-'); 190126706Swpaul if (p == NULL) 191126706Swpaul return; 192126706Swpaul *p = '\0'; 193126706Swpaul 194126706Swpaul manstr = p0; 195126706Swpaul 196126706Swpaul /* Convert any underscores to spaces. */ 197126706Swpaul 198126706Swpaul while (*p0 != '\0') { 199126706Swpaul if (*p0 == '_') 200126706Swpaul *p0 = ' '; 201126706Swpaul p0++; 202126706Swpaul } 203126706Swpaul 204126706Swpaul p0 = p + 1; 205126706Swpaul p = strchr(p0, '-'); 206126706Swpaul if (p == NULL) 207126706Swpaul return; 208126706Swpaul *p = '\0'; 209126706Swpaul 210126706Swpaul devstr = p0; 211126706Swpaul 212126706Swpaul /* Convert any underscores to spaces. */ 213126706Swpaul 214126706Swpaul while (*p0 != '\0') { 215126706Swpaul if (*p0 == '_') 216126706Swpaul *p0 = ' '; 217126706Swpaul p0++; 218126706Swpaul } 219126706Swpaul 220126706Swpaul fprintf(ofp, "\t\\\n\t{ \"%s\", \"%s\", ", manstr, devstr); 221126706Swpaul return; 222126706Swpaul} 223126706Swpaul 224126706Swpaulstatic void 225123475Swpauldump_pci_id(const char *s) 226123475Swpaul{ 227123475Swpaul char *p; 228123620Swpaul char vidstr[7], didstr[7], subsysstr[14]; 229123475Swpaul 230123475Swpaul p = strcasestr(s, "VEN_"); 231123475Swpaul if (p == NULL) 232123475Swpaul return; 233123475Swpaul p += 4; 234123475Swpaul strcpy(vidstr, "0x"); 235123475Swpaul strncat(vidstr, p, 4); 236123475Swpaul p = strcasestr(s, "DEV_"); 237123475Swpaul if (p == NULL) 238123475Swpaul return; 239123475Swpaul p += 4; 240123475Swpaul strcpy(didstr, "0x"); 241123475Swpaul strncat(didstr, p, 4); 242123475Swpaul if (p == NULL) 243123475Swpaul return; 244123620Swpaul p = strcasestr(s, "SUBSYS_"); 245123620Swpaul if (p == NULL) 246123620Swpaul strcpy(subsysstr, "0x00000000"); 247123620Swpaul else { 248123620Swpaul p += 7; 249123620Swpaul strcpy(subsysstr, "0x"); 250123620Swpaul strncat(subsysstr, p, 8); 251123620Swpaul } 252123475Swpaul 253123620Swpaul fprintf(ofp, "\t\\\n\t{ %s, %s, %s, ", vidstr, didstr, subsysstr); 254123475Swpaul return; 255123475Swpaul} 256123475Swpaul 257123475Swpaulstatic void 258186507Sweongyodump_usb_id(const char *s) 259186507Sweongyo{ 260186507Sweongyo char *p; 261186507Sweongyo char vidstr[7], pidstr[7]; 262186507Sweongyo 263186507Sweongyo p = strcasestr(s, "VID_"); 264186507Sweongyo if (p == NULL) 265186507Sweongyo return; 266186507Sweongyo p += 4; 267186507Sweongyo strcpy(vidstr, "0x"); 268186507Sweongyo strncat(vidstr, p, 4); 269186507Sweongyo p = strcasestr(s, "PID_"); 270186507Sweongyo if (p == NULL) 271186507Sweongyo return; 272186507Sweongyo p += 4; 273186507Sweongyo strcpy(pidstr, "0x"); 274186507Sweongyo strncat(pidstr, p, 4); 275186507Sweongyo if (p == NULL) 276186507Sweongyo return; 277186507Sweongyo 278186507Sweongyo fprintf(ofp, "\t\\\n\t{ %s, %s, ", vidstr, pidstr); 279186507Sweongyo} 280186507Sweongyo 281186507Sweongyostatic void 282126706Swpauldump_deviceids_pci() 283123475Swpaul{ 284123475Swpaul struct assign *manf, *dev; 285123475Swpaul struct section *sec; 286123475Swpaul struct assign *assign; 287123483Swpaul char xpsec[256]; 288179855Sweongyo int first = 1, found = 0; 289123475Swpaul 290123475Swpaul /* Find manufacturer name */ 291123475Swpaul manf = find_assign("Manufacturer", NULL); 292123475Swpaul 293146243Swpaulnextmanf: 294146243Swpaul 295123475Swpaul /* Find manufacturer section */ 296123483Swpaul if (manf->vals[1] != NULL && 297123511Swpaul (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 298124094Swpaul strcasecmp(manf->vals[1], "NTx86") == 0 || 299141963Swpaul strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 300141963Swpaul strcasecmp(manf->vals[1], "NTamd64") == 0)) { 301123483Swpaul /* Handle Windows XP INF files. */ 302123483Swpaul snprintf(xpsec, sizeof(xpsec), "%s.%s", 303123483Swpaul manf->vals[0], manf->vals[1]); 304123483Swpaul sec = find_section(xpsec); 305123483Swpaul } else 306123483Swpaul sec = find_section(manf->vals[0]); 307123475Swpaul 308126706Swpaul /* See if there are any PCI device definitions. */ 309123475Swpaul 310126706Swpaul TAILQ_FOREACH(assign, &ah, link) { 311126706Swpaul if (assign->section == sec) { 312126706Swpaul dev = find_assign("strings", assign->key); 313126706Swpaul if (strcasestr(assign->vals[1], "PCI") != NULL) { 314126706Swpaul found++; 315126706Swpaul break; 316126706Swpaul } 317126706Swpaul } 318126706Swpaul } 319126706Swpaul 320126706Swpaul if (found == 0) 321146243Swpaul goto done; 322126706Swpaul 323126706Swpaul found = 0; 324126706Swpaul 325179855Sweongyo if (first == 1) { 326179855Sweongyo /* Emit start of PCI device table */ 327179855Sweongyo fprintf (ofp, "#define NDIS_PCI_DEV_TABLE"); 328179855Sweongyo first = 0; 329179855Sweongyo } 330179855Sweongyo 331125073Swpaulretry: 332125073Swpaul 333123475Swpaul /* 334123475Swpaul * Now run through all the device names listed 335123475Swpaul * in the manufacturer section and dump out the 336123475Swpaul * device descriptions and vendor/device IDs. 337123475Swpaul */ 338123475Swpaul 339123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 340123475Swpaul if (assign->section == sec) { 341123475Swpaul dev = find_assign("strings", assign->key); 342123475Swpaul /* Emit device IDs. */ 343123475Swpaul if (strcasestr(assign->vals[1], "PCI") != NULL) 344123475Swpaul dump_pci_id(assign->vals[1]); 345126706Swpaul else 346124886Swpaul continue; 347126706Swpaul /* Emit device description */ 348126706Swpaul fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); 349126706Swpaul found++; 350126706Swpaul } 351126706Swpaul } 352126706Swpaul 353126706Swpaul /* Someone tried to fool us. Shame on them. */ 354126706Swpaul if (!found) { 355126706Swpaul found++; 356126706Swpaul sec = find_section(manf->vals[0]); 357126706Swpaul goto retry; 358126706Swpaul } 359126706Swpaul 360146243Swpaul /* Handle Manufacturer sections with multiple entries. */ 361146243Swpaul manf = find_next_assign(manf); 362146243Swpaul 363146243Swpaul if (manf != NULL) 364146243Swpaul goto nextmanf; 365146243Swpaul 366146243Swpauldone: 367126706Swpaul /* Emit end of table */ 368126706Swpaul 369126706Swpaul fprintf(ofp, "\n\n"); 370126706Swpaul 371146243Swpaul return; 372126706Swpaul} 373126706Swpaul 374126706Swpaulstatic void 375126706Swpauldump_deviceids_pcmcia() 376126706Swpaul{ 377126706Swpaul struct assign *manf, *dev; 378126706Swpaul struct section *sec; 379126706Swpaul struct assign *assign; 380126706Swpaul char xpsec[256]; 381179855Sweongyo int first = 1, found = 0; 382126706Swpaul 383126706Swpaul /* Find manufacturer name */ 384126706Swpaul manf = find_assign("Manufacturer", NULL); 385126706Swpaul 386146243Swpaulnextmanf: 387146243Swpaul 388126706Swpaul /* Find manufacturer section */ 389126706Swpaul if (manf->vals[1] != NULL && 390126706Swpaul (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 391126706Swpaul strcasecmp(manf->vals[1], "NTx86") == 0 || 392141963Swpaul strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 393141963Swpaul strcasecmp(manf->vals[1], "NTamd64") == 0)) { 394126706Swpaul /* Handle Windows XP INF files. */ 395126706Swpaul snprintf(xpsec, sizeof(xpsec), "%s.%s", 396126706Swpaul manf->vals[0], manf->vals[1]); 397126706Swpaul sec = find_section(xpsec); 398126706Swpaul } else 399126706Swpaul sec = find_section(manf->vals[0]); 400126706Swpaul 401126706Swpaul /* See if there are any PCMCIA device definitions. */ 402126706Swpaul 403126706Swpaul TAILQ_FOREACH(assign, &ah, link) { 404126706Swpaul if (assign->section == sec) { 405126706Swpaul dev = find_assign("strings", assign->key); 406126706Swpaul if (strcasestr(assign->vals[1], "PCMCIA") != NULL) { 407126706Swpaul found++; 408126706Swpaul break; 409126706Swpaul } 410126706Swpaul } 411126706Swpaul } 412126706Swpaul 413126706Swpaul if (found == 0) 414146243Swpaul goto done; 415126706Swpaul 416126706Swpaul found = 0; 417126706Swpaul 418179855Sweongyo if (first == 1) { 419179855Sweongyo /* Emit start of PCMCIA device table */ 420179855Sweongyo fprintf (ofp, "#define NDIS_PCMCIA_DEV_TABLE"); 421179855Sweongyo first = 0; 422179855Sweongyo } 423126706Swpaul 424126706Swpaulretry: 425126706Swpaul 426126706Swpaul /* 427126706Swpaul * Now run through all the device names listed 428126706Swpaul * in the manufacturer section and dump out the 429126706Swpaul * device descriptions and vendor/device IDs. 430126706Swpaul */ 431126706Swpaul 432126706Swpaul TAILQ_FOREACH(assign, &ah, link) { 433126706Swpaul if (assign->section == sec) { 434126706Swpaul dev = find_assign("strings", assign->key); 435126706Swpaul /* Emit device IDs. */ 436126706Swpaul if (strcasestr(assign->vals[1], "PCMCIA") != NULL) 437123475Swpaul dump_pcmcia_id(assign->vals[1]); 438126706Swpaul else 439126706Swpaul continue; 440123475Swpaul /* Emit device description */ 441123480Swpaul fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); 442125073Swpaul found++; 443123475Swpaul } 444123475Swpaul } 445123475Swpaul 446125073Swpaul /* Someone tried to fool us. Shame on them. */ 447125073Swpaul if (!found) { 448125073Swpaul found++; 449125073Swpaul sec = find_section(manf->vals[0]); 450125073Swpaul goto retry; 451125073Swpaul } 452125073Swpaul 453146243Swpaul /* Handle Manufacturer sections with multiple entries. */ 454146243Swpaul manf = find_next_assign(manf); 455146243Swpaul 456146243Swpaul if (manf != NULL) 457146243Swpaul goto nextmanf; 458146243Swpaul 459146243Swpauldone: 460123475Swpaul /* Emit end of table */ 461123475Swpaul 462123480Swpaul fprintf(ofp, "\n\n"); 463123480Swpaul 464146243Swpaul return; 465123475Swpaul} 466123475Swpaul 467123475Swpaulstatic void 468186507Sweongyodump_deviceids_usb() 469186507Sweongyo{ 470186507Sweongyo struct assign *manf, *dev; 471186507Sweongyo struct section *sec; 472186507Sweongyo struct assign *assign; 473186507Sweongyo char xpsec[256]; 474186507Sweongyo int first = 1, found = 0; 475186507Sweongyo 476186507Sweongyo /* Find manufacturer name */ 477186507Sweongyo manf = find_assign("Manufacturer", NULL); 478186507Sweongyo 479186507Sweongyonextmanf: 480186507Sweongyo 481186507Sweongyo /* Find manufacturer section */ 482186507Sweongyo if (manf->vals[1] != NULL && 483186507Sweongyo (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 484186507Sweongyo strcasecmp(manf->vals[1], "NTx86") == 0 || 485186507Sweongyo strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 486186507Sweongyo strcasecmp(manf->vals[1], "NTamd64") == 0)) { 487186507Sweongyo /* Handle Windows XP INF files. */ 488186507Sweongyo snprintf(xpsec, sizeof(xpsec), "%s.%s", 489186507Sweongyo manf->vals[0], manf->vals[1]); 490186507Sweongyo sec = find_section(xpsec); 491186507Sweongyo } else 492186507Sweongyo sec = find_section(manf->vals[0]); 493186507Sweongyo 494186507Sweongyo /* See if there are any USB device definitions. */ 495186507Sweongyo 496186507Sweongyo TAILQ_FOREACH(assign, &ah, link) { 497186507Sweongyo if (assign->section == sec) { 498186507Sweongyo dev = find_assign("strings", assign->key); 499186507Sweongyo if (strcasestr(assign->vals[1], "USB") != NULL) { 500186507Sweongyo found++; 501186507Sweongyo break; 502186507Sweongyo } 503186507Sweongyo } 504186507Sweongyo } 505186507Sweongyo 506186507Sweongyo if (found == 0) 507186507Sweongyo goto done; 508186507Sweongyo 509186507Sweongyo found = 0; 510186507Sweongyo 511186507Sweongyo if (first == 1) { 512186507Sweongyo /* Emit start of USB device table */ 513186507Sweongyo fprintf (ofp, "#define NDIS_USB_DEV_TABLE"); 514186507Sweongyo first = 0; 515186507Sweongyo } 516186507Sweongyo 517186507Sweongyoretry: 518186507Sweongyo 519186507Sweongyo /* 520186507Sweongyo * Now run through all the device names listed 521186507Sweongyo * in the manufacturer section and dump out the 522186507Sweongyo * device descriptions and vendor/device IDs. 523186507Sweongyo */ 524186507Sweongyo 525186507Sweongyo TAILQ_FOREACH(assign, &ah, link) { 526186507Sweongyo if (assign->section == sec) { 527186507Sweongyo dev = find_assign("strings", assign->key); 528186507Sweongyo /* Emit device IDs. */ 529186507Sweongyo if (strcasestr(assign->vals[1], "USB") != NULL) 530186507Sweongyo dump_usb_id(assign->vals[1]); 531186507Sweongyo else 532186507Sweongyo continue; 533186507Sweongyo /* Emit device description */ 534186507Sweongyo fprintf (ofp, "\t\\\n\t\"%s\" },", dev->vals[0]); 535186507Sweongyo found++; 536186507Sweongyo } 537186507Sweongyo } 538186507Sweongyo 539186507Sweongyo /* Someone tried to fool us. Shame on them. */ 540186507Sweongyo if (!found) { 541186507Sweongyo found++; 542186507Sweongyo sec = find_section(manf->vals[0]); 543186507Sweongyo goto retry; 544186507Sweongyo } 545186507Sweongyo 546186507Sweongyo /* Handle Manufacturer sections with multiple entries. */ 547186507Sweongyo manf = find_next_assign(manf); 548186507Sweongyo 549186507Sweongyo if (manf != NULL) 550186507Sweongyo goto nextmanf; 551186507Sweongyo 552186507Sweongyodone: 553186507Sweongyo /* Emit end of table */ 554186507Sweongyo 555186507Sweongyo fprintf(ofp, "\n\n"); 556186507Sweongyo 557186507Sweongyo return; 558186507Sweongyo} 559186507Sweongyo 560186507Sweongyostatic void 561123620Swpauldump_addreg(const char *s, int devidx) 562123475Swpaul{ 563123475Swpaul struct section *sec; 564123475Swpaul struct reg *reg; 565123475Swpaul 566123475Swpaul /* Find the addreg section */ 567123475Swpaul sec = find_section(s); 568123475Swpaul 569123475Swpaul /* Dump all the keys defined in it. */ 570123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 571123475Swpaul /* 572123475Swpaul * Keys with an empty subkey are very easy to parse, 573123475Swpaul * so just deal with them here. If a parameter key 574123475Swpaul * of the same name also exists, prefer that one and 575123475Swpaul * skip this one. 576123475Swpaul */ 577123475Swpaul if (reg->section == sec) { 578123475Swpaul if (reg->subkey == NULL) { 579123475Swpaul fprintf(ofp, "\n\t{ \"%s\",", reg->key); 580123475Swpaul fprintf(ofp,"\n\t\"%s \",", reg->key); 581123620Swpaul fprintf(ofp, "\n\t{ \"%s\" }, %d },", 582123475Swpaul reg->value == NULL ? "" : 583123620Swpaul stringcvt(reg->value), devidx); 584124452Swpaul } else if (strncasecmp(reg->subkey, 585124452Swpaul "Ndi\\params", strlen("Ndi\\params")-1) == 0 && 586124886Swpaul (reg->key != NULL && strcasecmp(reg->key, 587124886Swpaul "ParamDesc") == 0)) 588123620Swpaul dump_paramreg(sec, reg, devidx); 589123475Swpaul } 590123475Swpaul } 591123475Swpaul 592123475Swpaul return; 593123475Swpaul} 594123475Swpaul 595123475Swpaulstatic void 596123475Swpauldump_enumreg(const struct section *s, const struct reg *r) 597123475Swpaul{ 598123475Swpaul struct reg *reg; 599123475Swpaul char enumkey[256]; 600123475Swpaul 601123475Swpaul sprintf(enumkey, "%s\\enum", r->subkey); 602123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 603123475Swpaul if (reg->section != s) 604123475Swpaul continue; 605123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, enumkey)) 606123475Swpaul continue; 607123483Swpaul fprintf(ofp, " [%s=%s]", reg->key, 608123483Swpaul stringcvt(reg->value)); 609123475Swpaul } 610123475Swpaul return; 611123475Swpaul} 612123475Swpaul 613123475Swpaulstatic void 614123475Swpauldump_editreg(const struct section *s, const struct reg *r) 615123475Swpaul{ 616123475Swpaul struct reg *reg; 617123475Swpaul 618123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 619123475Swpaul if (reg->section != s) 620123475Swpaul continue; 621123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 622123475Swpaul continue; 623124886Swpaul if (reg->key == NULL) 624124886Swpaul continue; 625123475Swpaul if (strcasecmp(reg->key, "LimitText") == 0) 626123475Swpaul fprintf(ofp, " [maxchars=%s]", reg->value); 627123475Swpaul if (strcasecmp(reg->key, "Optional") == 0 && 628123475Swpaul strcmp(reg->value, "1") == 0) 629123475Swpaul fprintf(ofp, " [optional]"); 630123475Swpaul } 631123475Swpaul return; 632123475Swpaul} 633123475Swpaul 634123475Swpaul/* Use this for int too */ 635123475Swpaulstatic void 636123475Swpauldump_dwordreg(const struct section *s, const struct reg *r) 637123475Swpaul{ 638123475Swpaul struct reg *reg; 639123475Swpaul 640123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 641123475Swpaul if (reg->section != s) 642123475Swpaul continue; 643123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 644123475Swpaul continue; 645124886Swpaul if (reg->key == NULL) 646124886Swpaul continue; 647123475Swpaul if (strcasecmp(reg->key, "min") == 0) 648123475Swpaul fprintf(ofp, " [min=%s]", reg->value); 649123475Swpaul if (strcasecmp(reg->key, "max") == 0) 650123475Swpaul fprintf(ofp, " [max=%s]", reg->value); 651123475Swpaul } 652123475Swpaul return; 653123475Swpaul} 654123475Swpaul 655123475Swpaulstatic void 656123620Swpauldump_defaultinfo(const struct section *s, const struct reg *r, int devidx) 657123475Swpaul{ 658123475Swpaul struct reg *reg; 659123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 660123475Swpaul if (reg->section != s) 661123475Swpaul continue; 662123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 663123475Swpaul continue; 664124886Swpaul if (reg->key == NULL || strcasecmp(reg->key, "Default")) 665123475Swpaul continue; 666123620Swpaul fprintf(ofp, "\n\t{ \"%s\" }, %d },", reg->value == NULL ? "" : 667123977Swpaul stringcvt(reg->value), devidx); 668178214Sthompsa return; 669123475Swpaul } 670178214Sthompsa /* Default registry entry missing */ 671178214Sthompsa fprintf(ofp, "\n\t{ \"\" }, %d },", devidx); 672123475Swpaul return; 673123475Swpaul} 674123475Swpaul 675123475Swpaulstatic void 676123475Swpauldump_paramdesc(const struct section *s, const struct reg *r) 677123475Swpaul{ 678123475Swpaul struct reg *reg; 679123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 680123475Swpaul if (reg->section != s) 681123475Swpaul continue; 682123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 683123475Swpaul continue; 684124886Swpaul if (reg->key == NULL || strcasecmp(reg->key, "ParamDesc")) 685123475Swpaul continue; 686123475Swpaul fprintf(ofp, "\n\t\"%s", stringcvt(r->value)); 687123475Swpaul break; 688123475Swpaul } 689123475Swpaul return; 690123475Swpaul} 691123475Swpaul 692123475Swpaulstatic void 693123475Swpauldump_typeinfo(const struct section *s, const struct reg *r) 694123475Swpaul{ 695123475Swpaul struct reg *reg; 696123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 697123475Swpaul if (reg->section != s) 698123475Swpaul continue; 699123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 700123475Swpaul continue; 701124886Swpaul if (reg->key == NULL) 702124886Swpaul continue; 703123475Swpaul if (strcasecmp(reg->key, "type")) 704123475Swpaul continue; 705123475Swpaul if (strcasecmp(reg->value, "dword") == 0 || 706123475Swpaul strcasecmp(reg->value, "int") == 0) 707123475Swpaul dump_dwordreg(s, r); 708123475Swpaul if (strcasecmp(reg->value, "enum") == 0) 709123475Swpaul dump_enumreg(s, r); 710123475Swpaul if (strcasecmp(reg->value, "edit") == 0) 711123475Swpaul dump_editreg(s, r); 712123475Swpaul } 713123475Swpaul return; 714123475Swpaul} 715123475Swpaul 716123475Swpaulstatic void 717123620Swpauldump_paramreg(const struct section *s, const struct reg *r, int devidx) 718123475Swpaul{ 719123475Swpaul const char *keyname; 720123475Swpaul 721123475Swpaul keyname = r->subkey + strlen("Ndi\\params\\"); 722123475Swpaul fprintf(ofp, "\n\t{ \"%s\",", keyname); 723123475Swpaul dump_paramdesc(s, r); 724123475Swpaul dump_typeinfo(s, r); 725123475Swpaul fprintf(ofp, "\","); 726123620Swpaul dump_defaultinfo(s, r, devidx); 727123475Swpaul 728123475Swpaul return; 729123475Swpaul} 730123475Swpaul 731141981Swpaulstatic void 732123475Swpauldump_regvals(void) 733123475Swpaul{ 734123620Swpaul struct assign *manf, *dev; 735123475Swpaul struct section *sec; 736123475Swpaul struct assign *assign; 737123475Swpaul char sname[256]; 738125073Swpaul int found = 0, i, is_winxp = 0, is_winnt = 0, devidx = 0; 739123475Swpaul 740124085Swpaul /* Find signature to check for special case of WinNT. */ 741124085Swpaul assign = find_assign("version", "signature"); 742124085Swpaul if (strcasecmp(assign->vals[0], "$windows nt$") == 0) 743124085Swpaul is_winnt++; 744124085Swpaul 745146243Swpaul /* Emit start of block */ 746146243Swpaul fprintf (ofp, "ndis_cfg ndis_regvals[] = {"); 747146243Swpaul 748123475Swpaul /* Find manufacturer name */ 749123475Swpaul manf = find_assign("Manufacturer", NULL); 750123475Swpaul 751146243Swpaulnextmanf: 752146243Swpaul 753123475Swpaul /* Find manufacturer section */ 754123483Swpaul if (manf->vals[1] != NULL && 755123511Swpaul (strcasecmp(manf->vals[1], "NT.5.1") == 0 || 756124094Swpaul strcasecmp(manf->vals[1], "NTx86") == 0 || 757141963Swpaul strcasecmp(manf->vals[1], "NTx86.5.1") == 0 || 758141963Swpaul strcasecmp(manf->vals[1], "NTamd64") == 0)) { 759123483Swpaul is_winxp++; 760123483Swpaul /* Handle Windows XP INF files. */ 761123483Swpaul snprintf(sname, sizeof(sname), "%s.%s", 762123483Swpaul manf->vals[0], manf->vals[1]); 763123483Swpaul sec = find_section(sname); 764123483Swpaul } else 765123483Swpaul sec = find_section(manf->vals[0]); 766123475Swpaul 767125073Swpaulretry: 768125073Swpaul 769123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 770123475Swpaul if (assign->section == sec) { 771125073Swpaul found++; 772123483Swpaul /* 773123483Swpaul * Find all the AddReg sections. 774123483Swpaul * Look for section names with .NT, unless 775123483Swpaul * this is a WinXP .INF file. 776123483Swpaul */ 777141963Swpaul 778123511Swpaul if (is_winxp) { 779123511Swpaul sprintf(sname, "%s.NTx86", assign->vals[0]); 780123511Swpaul dev = find_assign(sname, "AddReg"); 781141963Swpaul if (dev == NULL) { 782141963Swpaul sprintf(sname, "%s.NT", 783141963Swpaul assign->vals[0]); 784141963Swpaul dev = find_assign(sname, "AddReg"); 785141963Swpaul } 786123511Swpaul if (dev == NULL) 787123511Swpaul dev = find_assign(assign->vals[0], 788123511Swpaul "AddReg"); 789123511Swpaul } else { 790123483Swpaul sprintf(sname, "%s.NT", assign->vals[0]); 791123483Swpaul dev = find_assign(sname, "AddReg"); 792124085Swpaul if (dev == NULL && is_winnt) 793124085Swpaul dev = find_assign(assign->vals[0], 794124085Swpaul "AddReg"); 795123483Swpaul } 796123483Swpaul /* Section not found. */ 797123483Swpaul if (dev == NULL) 798123483Swpaul continue; 799123475Swpaul for (i = 0; i < W_MAX; i++) { 800123475Swpaul if (dev->vals[i] != NULL) 801123620Swpaul dump_addreg(dev->vals[i], devidx); 802123475Swpaul } 803123620Swpaul devidx++; 804123475Swpaul } 805123475Swpaul } 806123475Swpaul 807125073Swpaul if (!found) { 808125073Swpaul sec = find_section(manf->vals[0]); 809125073Swpaul is_winxp = 0; 810125073Swpaul found++; 811125073Swpaul goto retry; 812125073Swpaul } 813125073Swpaul 814146243Swpaul manf = find_next_assign(manf); 815146243Swpaul 816146243Swpaul if (manf != NULL) 817146243Swpaul goto nextmanf; 818146243Swpaul 819123620Swpaul fprintf(ofp, "\n\t{ NULL, NULL, { 0 }, 0 }\n};\n\n"); 820123475Swpaul 821123475Swpaul return; 822123475Swpaul} 823123475Swpaul 824123475Swpaulvoid 825123475Swpaulassign_add (const char *a) 826123475Swpaul{ 827123475Swpaul struct assign *assign; 828123475Swpaul int i; 829123475Swpaul 830123475Swpaul assign = malloc(sizeof(struct assign)); 831123475Swpaul bzero(assign, sizeof(struct assign)); 832123475Swpaul assign->section = TAILQ_LAST(&sh, section_head); 833123475Swpaul assign->key = sstrdup(a); 834123475Swpaul for (i = 0; i < idx; i++) 835123475Swpaul assign->vals[(idx - 1) - i] = sstrdup(words[i]); 836123475Swpaul TAILQ_INSERT_TAIL(&ah, assign, link); 837123475Swpaul 838123475Swpaul clear_words(); 839123475Swpaul return; 840123475Swpaul} 841123475Swpaul 842123475Swpaulvoid 843123475Swpauldefine_add (const char *d __unused) 844123475Swpaul{ 845123475Swpaul#ifdef notdef 846123475Swpaul fprintf(stderr, "define \"%s\"\n", d); 847123475Swpaul#endif 848123475Swpaul return; 849123475Swpaul} 850123475Swpaul 851123475Swpaulstatic char * 852123475Swpaulsstrdup(const char *str) 853123475Swpaul{ 854123475Swpaul if (str != NULL && strlen(str)) 855123475Swpaul return (strdup(str)); 856123475Swpaul return (NULL); 857123475Swpaul} 858123475Swpaul 859123475Swpaulstatic int 860123475Swpaulsatoi (const char *nptr) 861123475Swpaul{ 862123475Swpaul if (nptr != NULL && strlen(nptr)) 863123475Swpaul return (atoi(nptr)); 864123475Swpaul return (0); 865123475Swpaul} 866123475Swpaul 867123475Swpaulvoid 868123475Swpaulregkey_add (const char *r) 869123475Swpaul{ 870123475Swpaul struct reg *reg; 871123475Swpaul 872123475Swpaul reg = malloc(sizeof(struct reg)); 873123475Swpaul bzero(reg, sizeof(struct reg)); 874123475Swpaul reg->section = TAILQ_LAST(&sh, section_head); 875123475Swpaul reg->root = sstrdup(r); 876123475Swpaul reg->subkey = sstrdup(words[3]); 877123475Swpaul reg->key = sstrdup(words[2]); 878123475Swpaul reg->flags = satoi(words[1]); 879123475Swpaul reg->value = sstrdup(words[0]); 880123475Swpaul TAILQ_INSERT_TAIL(&rh, reg, link); 881123475Swpaul 882123475Swpaul free(__DECONST(char *, r)); 883123475Swpaul clear_words(); 884123475Swpaul return; 885123475Swpaul} 886123475Swpaul 887123475Swpaulvoid 888123475Swpaulpush_word (const char *w) 889123475Swpaul{ 890123475Swpaul if (w && strlen(w)) 891123475Swpaul words[idx++] = w; 892123475Swpaul else 893123475Swpaul words[idx++] = NULL; 894123475Swpaul return; 895123475Swpaul} 896123475Swpaul 897123475Swpaulvoid 898123475Swpaulclear_words (void) 899123475Swpaul{ 900123475Swpaul int i; 901123475Swpaul 902123475Swpaul for (i = 0; i < idx; i++) { 903123475Swpaul if (words[i]) { 904123475Swpaul free(__DECONST(char *, words[i])); 905123475Swpaul } 906123475Swpaul } 907123475Swpaul idx = 0; 908123475Swpaul bzero(words, sizeof(words)); 909123475Swpaul return; 910123475Swpaul} 911