First post, by myne
I was playing around with an old 9x box and drivers are a pain.
The library here is great, but I wish there was an online driver library to AUTOMATICALLY find drivers.
Or at least some sort of pack that can be looked up from a fresh machine.
I didn't do that.
I did what I think might be the first bit required:
Getting the drivers from a working install into a workable structure including versioning (I used the driver date in YYYYMMDD) that maybe, just maybe, someone will figure out a way to make a more automated driver library.
The script does not intentionally modify any existing files or the registry.
There is no reason it should. Weird bugs happen though.
The coding style... uh... it works. COMMAND.COM is more limited than CMD 🙁
Frankly, it's pretty horrible what had to be done. command.com doesn't have: IF with ELSE, (proper code blocks), FOR in a very useful format, WHILE, and a bunch of other things.
Ever made a while loop with if and goto?
How about if/else with gotos?
It's not pretty. I'm honestly a bit surprised that I got it to work at all.
Dependencies:
reg.exe in the win98 resource kit: https://archive.org/details/mswin98rskt
gawk.exe available here: https://gnuwin32.sourceforge.net/packages/gawk.htm
MSVCP60.dll available here: https://www.dll-files.com/msvcp60.dll.html (I used V 6.0.8168.0 but others might work)
xset.exe available here: https://xset.tripod.com/
How it works:
Reads the registry and finds PCI devices in HKLM\enum\pci
Follows that trail to find details and the INF file that installed them
Attempts to find the INF in (windows directory)\inf and inf\other
Reads the INF looking for the names of the files required
Scans the windows directory for the listed files
Copies the inf and required files to (this folder)\Drivers with subdirectories for driver class, and the driver folder includes its date version
Updates a 'master list' (VenDevList.txt of ALL vendor and device ids listed in each INF with the path to the driver (I figure this would be the index file if anyone ever put it into an online database)
How to use:
Download attached script with dependencies OR
Copy the code below into notepad.
Save as a .bat (I used drvbak.bat)
Get the 3 dependencies into the same folder
Run it from... Well, I've only tested it on the C drive of a 98 box, so I'm going to say put it in a folder in the C drive somewhere. It might run from d: etc, but I don't know.
If you get out of environment errors, configure the dos window with more memory
I used initial environment 4096, EMS 8192, XMS 8192, DPMI 2048
In theory it will run from dos mode.
I'm curious:
1) if anyone cares
2) if anyone likes it
3) how awful you all think my code is. Some could be revised already, I know, but if it ain't broke...
4) how badly it's going to completely fuck up on someone else's machine
rem Crazy batch script to attempt to backup win9x driversrem Version 2/11/23rem DD/MM/YY for you crazy yanks@echo offrem check for dependenciesset depend=yesecho.if not exist reg.exe echo You must have reg.exe in the same folder as this scriptif not exist reg.exe echo It is in the win98 resource kit: https://archive.org/details/mswin98rsktif not exist reg.exe set depend=noif not exist gawk.exe echo You must have gawk.exe in the same folder as this scriptif not exist gawk.exe echo It is available here: https://gnuwin32.sourceforge.net/packages/gawk.htmif not exist gawk.exe set depend=noif not exist MSVCP60.dll echo You must have MSVCP60.dll in same folder as this script to run gawkif not exist MSVCP60.dll echo V 6.0.8168.0 available here: https://www.dll-files.com/msvcp60.dll.htmlif not exist MSVCP60.dll set depend=noif not exist xset.exe echo You must have xset.exe in same folder as this script to run gawkif not exist xset.exe echo Available here: https://xset.tripod.com/if not exist xset.exe set depend=noecho.rem exit if reg and gawk aren't availableif %depend%==no goto eofxset a=clsrem running the script with /s will skip the intro/disclaimerif [%1]==[/s] goto clearvarsecho.echo.Echo This script is intended to backup EXISTING PCI drivers on Windows 9x/MEEcho It is unlikely to work on other versions due to registry differences.echo.Echo === How it works ===Echo 1) Reads the registry and finds PCI devices in HKLM\enum\pciEcho 2) Follows that trail to find details and the INF file that installed themEcho 3) Attempts to find the INF in (windows directory)\inf and inf\otherEcho 4) Reads the INF looking for the names of the files requiredecho 5) Scans the windows directory for the listed filesecho 6) Copies the inf and required files to (this folder)\Driversecho.echo Note: Running with /s skips this messageecho.echo The script does not intentionally modify any existing files or the registry.echo There is no reason it should. Weird bugs happen though.echo The coding style... uh... it works. COMMAND.COM is more limited than CMD :(echo Continue at your own risk...echo.echo.Xset /prompt "Press X to exit, or anything else to continue: " contynif %contyn%==x goto eofif %contyn%==X goto eofrem clear all the variables:clearvars
set contyn=set write=set countd=set vtemp=set vtemp2=set vtemp3=set vtemp4=set lineno=set exists=set isinf=set drvdatetemp=set startline=set pcitemp2=set depend=set classtemp=set classlist=set pcilist=set inftemp=set inflist=set pcilist=set drvlist=set inflist=set drvdatelist=set ddesclist=set pcitemp=set drvtemp=set inftemp=set classtemp=set pcivar=set drvversion=set drvname=set infname=set pname=set curdir=set ddesctemp=set authortemp=set fpath=set xset_msg=if exist filelist.txt del filelist.txtif exist err.txt del err.txtif exist flist2.txt del flist2.txtif %end%==end goto endrem set some stuffxset startline=4xset lineno=%startline%xset countD=1echo VEN-DEV;Class;driver author;device name;driverdate;infname > driverlist.csvclsEcho Looking in the registry for PCI devicesecho.echo Manufacturer Device Description Driver Dateecho ------------ ------------------ -----------:loop1startrem *****************************************************************rem loop through the pci subkeys in the registry until "end of file"rem this is basically a while loop done with goto because... dos :/rem Looking in the registry for PCI devicesreg query HKLM\enum\pci | xset /line %lineno% pcitemprem if EOF exit loopif [%xset_msg%]==[END-OF-FILE] goto loop1endrem trim bracketsxset /left -1 pcitemp=%pcitemp%xset /right -1 pcitemp=%pcitemp%rem trim back to vendor/device, replace ampersand into variable pci(#)xset /left 17 pcitemp2=%PCItemp%rem xset /left 17 vtemp=%pcitemp%rem xset /left 8 vtemp2=%vtemp%rem xset /right 8 vtemp3=%vtemp%rem xset pcivar=%vtemp2%-%vtemp3%xset pcivar=%pcitemp2%;rem add to variable pcilistxset /append pcilist=%pcitemp2%;rem find the class in registryreg query hklm\enum\pci\%pcitemp% /s | find /i "Class " | xset /mid 17 50 classtempxset /append pcivar=%classtemp%;xset /append classlist=%classtemp%;rem find the driver location in registryreg query hklm\enum\pci\%pcitemp% /s | find /i "Driver" | xset /right -17 drvtemprem find the driver author in registryreg query hklm\system\currentcontrolset\services\class\%drvtemp% /s | find /i "providername" | xset /mid 24 50 authortempxset /append pcivar=%authortemp%;rem Finding name of driver based on above locationreg query hklm\system\currentcontrolset\services\class\%drvtemp% /s | find /i "driverdesc" | xset /mid 22 50 ddesctemprem add inf to variable ddesclistxset /append ddesclist=%ddesctemp%;rem add inf to variable pci(#)xset /append pcivar=%ddesctemp%;rem find driver datereg query hklm\system\currentcontrolset\services\class\%drvtemp% /s | find /i "driverdate" | xset /mid 22 10 drvdatetemprem rearrange date from MMDDYYYY to YYYYMMDD and add to var drvdatetemp (assuming it's consistently US formatted MM-DD-YYYY)rem fix leading blank if single digit monthxset /left 10 drvdatetemp=%drvdatetemp%rem check if it is a single digit monthxset /mid 2 1 vtemp2=%drvdatetemp%rem fix single digit monthif [%vtemp2%]==[-] xset drvdatetemp=0%drvdatetemp%rem finally set the damn monthxset /left 2 vtemp2=%drvdatetemp%rem get dayrem but first fix the single digitsxset /mid 4 2 vtemp3=%drvdatetemp%xset vtemp3=%vtemp3%xset /length vtemp4=%vtemp3%if [%vtemp4%]==[1] xset vtemp3=0%vtemp3%rem get Yearxset /right 4 vtemp=%drvdatetemp%rem rearrange into YYYYMMDDxset drvdatetemp=%vtemp%%vtemp2%%vtemp3%xset /append drvdatelist=%drvdatetemp%;rem add to var pci(#)xset /append pcivar=%drvdatetemp%;rem find name of infreg query hklm\system\currentcontrolset\services\class\%drvtemp% /s | find /i "infpath" | xset /mid 19 50 inftemprem add inf to variable inflist and 2xset /append inflist=%inftemp%;rem add inf to variable pci(#)xset /append pcivar=%inftemp%rem see if the inf is in the inf dirset exists=0if exist %windir%\inf\%inftemp% set exists=1if exist %windir%\inf\%inftemp% echo %windir%\inf\%inftemp% >> filelist.txtif not [%Exists%]==[1] if exist %windir%\inf\other\%inftemp% set exists=2if exist %windir%\inf\other\%inftemp% echo %windir%\inf\other\%inftemp% >> filelist.txtif [%exists%]==[0] echo $%inftemp% NotFound >> filelist.txtrem if not exist %windir%\inf\%inftemp% echo $%inftemp% NotFound >> filelist.txtrem if exist %windir%\inf\%inftemp%rem the syntax of this can best be described as "are you on drugs?" but here goes...rem if exists (set above) is 1 then it's in the inf dir, gawk (search) the file, ignoring case for "[*copyfiles]" and 'flag' the lines between that and the next "[" for output to filelist.txtif [%exists%]==[1] gawk.exe "BEGIN{IGNORECASE = 1} /\[.*copyfiles/ {flag=1;next} /\[/ {flag=0} flag" %windir%\inf\%inftemp%>> filelist.txtrem same as above but it's in the "other" subfolderif [%exists%]==[2] gawk.exe "BEGIN{IGNORECASE = 1} /\[.*copyfiles/ {flag=1;next} /\[/ {flag=0} flag" %windir%\inf\other\%inftemp%>> filelist.txtecho %errorlevel% %inftemp% >> err.txtecho %PCIvar% >> driverlist.csvxset /left 22 vtemp=%authortemp%xset /left 45 vtemp2=%ddesctemp%echo %vtemp% %vtemp2% %drvdatetemp%rem increment countersxset /math lineno = %lineno% + 1xset /math CountD = %CountD% + 1goto loop1start:loop1endrem don't forget old dos has 8char labels! damnit.rem gotta drop the count by 1 because the eof check comes after the incrementxset /math CountD = %CountD% - 1echo.Echo Found %CountD% PCI driversecho.rem *****************************************************************rem echo loopxset lineno=1if exist flist2.txt del flist2.txtecho Searching for the driver filesrem this loop is to get all the files referenced in the inf files:loop2startrem again, basically a "while not end of file"type filelist.txt | xset /line %lineno% vtemprem if EOF exit loopif [%xset_msg%]==[END-OF-FILE] goto loop2endrem check first char isn't error ($)rem hack to work around dos' weird handling of semicolons while setting vtemp2 to the 1st char of vtemp. note the "%vtemp%#" in case it's blank in which case it will be #echo %vtemp%# | gawk "{gsub(\";\",\"#\"); print}" | xset /left 1 vtemp2rem if it is $, echo to err.txtif [%vtemp2%]==[$] echo %vtemp% >> err.txtrem try and trim the bullshit from the drivername - it looks like it's usually commas. Might need editing if more are foundxset /separator "," /word 1 vtemp3=%vtemp%rem figure out if it was a comment in the original inf (; replaced by #) or an error set above ($) and write it to a file if notxset write=yesif [%vtemp2%]==[$] xset write=noif [%vtemp2%]==[#] xset write=norem if [%vtemp2%]==[ ] xset write=norem if [%vtemp2%]==[] xset write=norem pauseif %write%==yes echo %vtemp3% >> flist2.txtrem increment countersxset /math lineno = %lineno% + 1goto loop2start:loop2endrem now to find and copy the drivers into foldersxset lineno=1echo Finding and copying driver files. This could take a minute or so...cd | xset curdir:loop3startrem echo onset isinf=nrem again, basically a "while not end of file"type flist2.txt | xset /line %lineno% vtemprem if EOF exit loopif [%xset_msg%]==[END-OF-FILE] goto loop3endrem check if infxset /separator "." /UPPER /word 2 vtemp2=%vtemp%rem this should be if var=inf, but the only way to do code blocks is like thisif not %vtemp2%==INF goto skipinfrem ok so this is a bit retarded but to get the second last word (filename without extension) we have to reverse it, get the 2nd word and rereverse itxset /reverse vtemp3=%vtemp%xset /separator "\." /word 2 vtemp3=%vtemp3%xset /reverse vtemp3=%vtemp3%rem same to get the full inf filename backxset /reverse infname=%vtemp%xset /separator "\" /word 1 infname=%infname%xset /reverse infname=%infname%rem now we have the name of the driver, gotta look up the date from drvdatelist by first matching the # from inflistxset countd=1rem basically this is an if/else done the worst way possible. First part "if" inf, "else" is file with weird overlapping gotos ugh.:loop31startecho %inflist% | xset /separator ";" /word %countd% drvnameif [%xset_msg%]==[END-OF-FILE] goto end31loopif %drvname%==%infname% echo %drvdatelist% |xset /separator ";" /word %countd% drvversionecho %classlist% | xset /separator ";" /word %countd% classtempif %drvname%==%infname% goto end31loopxset /math CountD = %CountD% + 1goto :loop31startrem so its going to loop until the version is found or it runs out of 'words' in the variable... hopefully...:end31looprem make dirsif not exist %curdir%\drivers\nul md %curdir%\driversif not exist %curdir%\drivers\%classtemp%\nul md %curdir%\drivers\%classtemp%if not exist %curdir%\drivers\%classtemp%\%vtemp3%-%drvversion%\nul md %curdir%\drivers\%classtemp%\%vtemp3%-%drvversion%copy %vtemp% %curdir%\drivers\%classtemp%\%vtemp3%-%drvversion%rem update driverlistrem add all the vendor and device IDs to vendevlist.txt so in theory sometime later we might be able to implement a driver find utilitygawk.exe -F. "BEGIN{IGNORECASE = 1; } /^%%PCI\\/ { print $1\",.\\drivers\\%classtemp%\\%vtemp3%-%drvversion%\\%infname%.inf\" }" %vtemp% >> VenDevList.txtgoto skipdrvrem Told you there were weird overlapping gotos:skipinfrem find the driver filescd %windir%dir /s /b %vtemp% | %curdir%\xset fpathcd %curdir%copy %fpath% %curdir%\drivers\%classtemp%\%vtemp3%-%drvversion%:skipdrvxset /math lineno = %lineno% + 1goto loop3start:loop3endrem clear all the variables and temp filesset end=endgoto clearvars:endset end=dir /s /b .\drivers |moreecho.echo In theory that should show your drivers which you can now backup for later.echo.:eof
I built:
Convert old ASUS ASC boardviews to KICAD PCB!
Re: A comprehensive guide to install and play MechWarrior 2 on new versions on Windows.
Dos+Windows 3.11+tcp+vbe_svga auto-install iso template
Script to backup Win9x\ME drivers from a working install
Re: The thing no one asked for: KICAD 440bx reference schematic
