359 lines
11 KiB
Batchfile
359 lines
11 KiB
Batchfile
|
@echo off
|
||
|
REM ------------------------------------------------------------------
|
||
|
REM
|
||
|
REM drivercab.cmd
|
||
|
REM generates driver.cab for each sku
|
||
|
REM
|
||
|
REM Copyright (c) Microsoft Corporation. All rights reserved.
|
||
|
REM
|
||
|
REM ------------------------------------------------------------------
|
||
|
if defined _CPCMAGIC goto CPCBegin
|
||
|
perl -x "%~f0" %*
|
||
|
goto :EOF
|
||
|
#!perl
|
||
|
use strict;
|
||
|
use lib $ENV{RAZZLETOOLPATH} . "\\PostBuildScripts";
|
||
|
use lib $ENV{RAZZLETOOLPATH};
|
||
|
use PbuildEnv;
|
||
|
use ParseArgs;
|
||
|
|
||
|
sub Usage { print<<USAGE; exit(1) }
|
||
|
drivercab [-l <language>]
|
||
|
|
||
|
Generates driver.cab for each sku using *drivers.txt files generated by
|
||
|
cddata from drvindex.inf.
|
||
|
USAGE
|
||
|
|
||
|
parseargs('?' => \&Usage);
|
||
|
|
||
|
|
||
|
# *** NEXT FEW LINES ARE TEMPLATE ***
|
||
|
$ENV{"_CPCMAGIC"}++;exit(system($0)>>8);
|
||
|
__END__
|
||
|
:CPCBegin
|
||
|
set _CPCMAGIC=
|
||
|
setlocal ENABLEDELAYEDEXPANSION ENABLEEXTENSIONS
|
||
|
REM *** BEGIN YOUR CMD SCRIPT BELOW ***
|
||
|
|
||
|
REM
|
||
|
REM drivercab.cmd
|
||
|
REM
|
||
|
|
||
|
REM this script will generate a driver.cab for each sku appropriate to this
|
||
|
REM language. the files to be used are contained in drvindex.inf for each
|
||
|
REM sku, which is read by cddata.cmd, and passed through txt files here.
|
||
|
|
||
|
REM details:
|
||
|
REM we are passed .txt lists for each sku, and then a file called
|
||
|
REM commondrivers.txt for all common files. if the commondrivers.txt file
|
||
|
REM exists, we can assume that we are not in incremental mode, as the idea
|
||
|
REM of a common cab doesn't really make sense in an incremental environment.
|
||
|
REM
|
||
|
REM if commondrivers.txt does not exist, we will use cabinc.exe to add
|
||
|
REM the changed files in each SKU to the appropriate driver.cab
|
||
|
REM
|
||
|
REM if perdrivers.txt does not exist, then there are no changes for per or
|
||
|
REM alternately the per cab is equivalent to the common cab if not in
|
||
|
REM incremental mode.
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM setup
|
||
|
REM
|
||
|
REM get all appropriate products
|
||
|
call logmsg.cmd "Calculating which products to act on ..."
|
||
|
set Products=
|
||
|
for %%a in (pro per bla sbs srv ads dtc) do (
|
||
|
perl %RazzleToolPath%\cksku.pm -t:%%a -l:%lang% -a:%_BuildArch%
|
||
|
if !ErrorLevel! == 0 (
|
||
|
if not defined Products (
|
||
|
set Products=%%a
|
||
|
) else (
|
||
|
set Products=!Products! %%a
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
call logmsg.cmd "Checking for incremental mode ..."
|
||
|
set IncMode=TRUE
|
||
|
if exist %TMP%\commondrivers.txt set IncMode=
|
||
|
|
||
|
|
||
|
REM set up the temp cab locations
|
||
|
set TmpCabLocation=%_NTPOSTBLD%\cabs\driver\cabs
|
||
|
if not exist %TmpCabLocation% md %TmpCabLocation%
|
||
|
|
||
|
REM
|
||
|
REM test for incremental mode
|
||
|
REM
|
||
|
if defined IncMode goto :PerformIncrementalCabbing
|
||
|
goto :PerformFullCabbing
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM PerformIncrementalCabbing
|
||
|
REM
|
||
|
REM here we just want to go through our product list, and use cabinc.exe
|
||
|
REM to replace the old entries in driver.cab with the new ones.
|
||
|
REM
|
||
|
:PerformIncrementalCabbing
|
||
|
call logmsg.cmd "Performing incremental cabbing ..."
|
||
|
|
||
|
|
||
|
REM loop over products and cabinc the files in
|
||
|
for %%a in (%Products%) do (
|
||
|
REM the call to :SetMyInfDirName just sets the MyInfDirName env var to
|
||
|
REM whatever the inf subdir for that product is, like for ads it is entinf
|
||
|
set MyInfDirName=
|
||
|
call :SetMyInfDirName %%a
|
||
|
if not defined MyInfDirName (
|
||
|
call errmsg.cmd "Invalid sku %%a found ..."
|
||
|
)
|
||
|
set MyDriverCab=%_NTPOSTBLD%\!MyInfDirName!\driver.cab
|
||
|
if not exist !MyDriverCab! (
|
||
|
call errmsg.cmd "Can't perform incremental updates without full cabs ..."
|
||
|
goto :End
|
||
|
)
|
||
|
set MyFileList=%TMP%\%%adrivers.txt
|
||
|
if not exist !MyFileList! (
|
||
|
call logmsg.cmd "No files to change for %%a sku ..."
|
||
|
) else (
|
||
|
call logmsg.cmd "Replacing files for %%a sku ..."
|
||
|
set IncCommand=
|
||
|
set NewFiles=
|
||
|
for /f %%b in (!MyFileList!) do (
|
||
|
set NewFile=%_NTPOSTBLD%\%%b
|
||
|
for %%c in (!NewFile!) do set NewFileName=%%~nxc
|
||
|
extract.exe -d !MyDriverCab! !NewFileName! | findstr /ic:"No matching files"
|
||
|
if !ErrorLevel! NEQ 0 (
|
||
|
REM this file was already in the cab, replace it
|
||
|
set IncCommand=!IncCommand! !NewFile!
|
||
|
) else (
|
||
|
REM this file is new to the cab, add it
|
||
|
set NewFiles=!NewFiles! mergefile !NewFile!
|
||
|
)
|
||
|
)
|
||
|
if defined IncCommand (
|
||
|
call ExecuteCmd.cmd "cabinc.exe -t %NUMBER_OF_PROCESSORS% -q 40 -p 80 !MyDriverCab! !IncCommand!"
|
||
|
if !ErrorLevel! NEQ 0 (
|
||
|
call errmsg.cmd "Replace failed for %%a sku, file was !NewFile!,"
|
||
|
call errmsg.cmd "cab file was !MyDriverCab! ..."
|
||
|
) else (
|
||
|
call logmsg.cmd "!NewFileName! replaced in !MyDriverCab! ..."
|
||
|
)
|
||
|
)
|
||
|
if defined NewFiles (
|
||
|
call ExecuteCmd.cmd "cabbench.exe load !MyDriverCab! !NewFiles! save !MyDriverCab!.new"
|
||
|
if !ErrorLevel! NEQ 0 (
|
||
|
call errmsg.cmd "Add failed for %%a sku, file was !NewFile!,"
|
||
|
call errmsg.cmd "cab file was !MyDriverCab! ..."
|
||
|
) else (
|
||
|
call ExecuteCmd.cmd "del !MyDriverCab!"
|
||
|
call ExecuteCmd.cmd "ren !MyDriverCab!.new driver.cab"
|
||
|
call logmsg.cmd "!NewFileName! added to !MyDriverCab! ..."
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
call logmsg.cmd "Finished."
|
||
|
|
||
|
goto :End
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM PerformFullCabbing
|
||
|
REM
|
||
|
REM here we want to break the common list into NUM_PROCS sublists, then
|
||
|
REM multithread generation of those sub cabs. after that, we mash them all
|
||
|
REM back together, and then multithread generation of the sku specific cabs.
|
||
|
REM finally, we mash the sku specific cabs onto the common cab for each sku,
|
||
|
REM and put those in the fooinf\driver.cab position.
|
||
|
REM
|
||
|
:PerformFullCabbing
|
||
|
call logmsg.cmd "Performing full cabbing ..."
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM first, do the common cab. we want to break the list down into NUM_PROCS
|
||
|
REM lists, so we can thread them nicely
|
||
|
REM
|
||
|
call logmsg.cmd "Finding common drivers list ..."
|
||
|
set CommonList=%TMP%\commondrivers.txt
|
||
|
if not exist %CommonList% (
|
||
|
call errmsg.cmd "Could not find %CommonList% to generate driver.cab ..."
|
||
|
goto :End
|
||
|
)
|
||
|
set BackupName=%TMP%\backuplist.txt
|
||
|
if exist %BackupName% del /f /q %BackupName%
|
||
|
move %CommonList% %BackupName%
|
||
|
if exist %CommonList%.* del /f /q %CommonList%.*
|
||
|
move %BackupName% %CommonList%
|
||
|
set /a NumLists=%NUMBER_OF_PROCESSORS%
|
||
|
call logmsg.cmd "Splitting common drivers list into %NumLists% parts ..."
|
||
|
perl %RazzleToolPath%\PostBuildScripts\splitlist.pl -n %NumLists% -f %CommonList% -l %lang%
|
||
|
REM splitlist.pl creates commondrivers.txt.1, commondrivers.txt.2, etc
|
||
|
set /a NumThreads=0
|
||
|
for /l %%a in (1,1,%NumLists%) do (
|
||
|
if exist %CommonList%.%%a set /a NumThreads=%%a
|
||
|
)
|
||
|
REM now NumThreads is the list count
|
||
|
call logmsg.cmd "Created %NumThreads% sub lists ..."
|
||
|
REM set the common cab name and location
|
||
|
set CommonCab=%TmpCabLocation%\common.cab
|
||
|
if exist %CommonCab% del /f %CommonCab%
|
||
|
if exist %CommonCab% (
|
||
|
call errmsg.cmd "Failed to delete old common cab ..."
|
||
|
goto :End
|
||
|
)
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM now, we want to kick off our child processes and wait for them to finish.
|
||
|
REM the wrapper script will generate the DDF from the list we pass it on the
|
||
|
REM command line, in this case something like %TMP%\commondrivers.txt.1
|
||
|
REM
|
||
|
|
||
|
set EventList=
|
||
|
for /l %%a in (1,1,%NumThreads%) do (
|
||
|
call logmsg.cmd "Starting %CommonCab%.%%a cab ..."
|
||
|
set EventName=commoncab%%a
|
||
|
start "PB_CommonCab.%%a" /min cmd /c CabWrapper.cmd %CommonList%.%%a %CommonCab%.%%a !EventName!"
|
||
|
set EventList=!EventList! !EventName!
|
||
|
)
|
||
|
if not defined EventList (
|
||
|
REM hmmm?
|
||
|
call errmsg.cmd "No events to wait on for common cabs ..."
|
||
|
) else (
|
||
|
call logmsg.cmd "Waiting for common cabs ..."
|
||
|
perl %RazzleToolPath%\PostBuildScripts\cmdevt.pl -iwv !EventList!
|
||
|
)
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM check if there were errors in the generation
|
||
|
REM
|
||
|
call logmsg.cmd "Checking for errors in sub cab generation ..."
|
||
|
findstr /ic:"ERROR:" %LOGFILE% >nul 2>nul
|
||
|
if %ErrorLevel% == 0 (
|
||
|
REM we found some errors
|
||
|
call errmsg.cmd "There were errors generating the sub cabs for driver.cab"
|
||
|
call errmsg.cmd "Please investigate or run postbuild -full"
|
||
|
goto :End
|
||
|
)
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM the common cab now needs to be merged together. we will use cabbench.exe
|
||
|
REM to do this
|
||
|
REM
|
||
|
call logmsg.cmd "Merging common cab pieces back together ..."
|
||
|
if %NumThreads% == 1 (
|
||
|
REM only one cab, just rename it
|
||
|
call logmsg.cmd "Only one common cab, renaming ..."
|
||
|
move %TmpCabLocation%\common.cab.1 %CommonCab%
|
||
|
) else (
|
||
|
REM multiple cabs, merge them
|
||
|
set MergeCommand=load %TmpCabLocation%\common.cab.1
|
||
|
for /l %%a in (2,1,%NumThreads%) do (
|
||
|
set MergeCommand=!MergeCommand! load %TmpCabLocation%\common.cab.%%a merge
|
||
|
)
|
||
|
set MergeCommand=!MergeCommand! save %CommonCab%
|
||
|
call logmsg.cmd "Issuing merge ..."
|
||
|
call ExecuteCmd.cmd "cabbench.exe !MergeCommand!"
|
||
|
if !ErrorLevel! NEQ 0 (
|
||
|
call errmsg.cmd "Merge of common cab failed ..."
|
||
|
goto :End
|
||
|
)
|
||
|
)
|
||
|
if not exist %CommonCab% (
|
||
|
call errmsg.cmd "Common cab does not exist at %CommonCab% after merge ..."
|
||
|
goto :End
|
||
|
)
|
||
|
call logmsg.cmd "Merge successful, continuing ..."
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM now, we get to create the sub cabs for each sku. just kick off as many
|
||
|
REM threads as we need to do this, and give the short lists to the wrapper.
|
||
|
REM the wrapper will handle creating the DDFs from the lists we pass it.
|
||
|
REM
|
||
|
call logmsg.cmd "Creating sku specific cabs ..."
|
||
|
set EventList=
|
||
|
for %%a in (%Products%) do (
|
||
|
if not exist %TMP%\%%adrivers.txt (
|
||
|
call logmsg.cmd "No drivers to cab for %%a sku ..."
|
||
|
) else (
|
||
|
call logmsg.cmd "Starting generation for %%a specific drivers ..."
|
||
|
set EventName=%%adrivercab
|
||
|
REM syntax for CabWrapper.cmd is:
|
||
|
REM list of files
|
||
|
REM cab name to create
|
||
|
REM event name to signal
|
||
|
start "PB_%%adrivercab" /min cmd /c CabWrapper.cmd %TMP%\%%adrivers.txt %TmpCabLocation%\%%adriver.cab !EventName!
|
||
|
set EventList=!EventList! !EventName!
|
||
|
)
|
||
|
)
|
||
|
if not defined EventList (
|
||
|
REM no events to wait for? okay ... whatever ...
|
||
|
call logmsg.cmd "No sku specific cabs to wait for, continuing ..."
|
||
|
) else (
|
||
|
call logmsg.cmd "Waiting for sku specific cabs to generate ..."
|
||
|
perl %RazzleToolPath%\PostBuildScripts\cmdevt.pl -iwv %EventList%
|
||
|
)
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM now we have the common cab and the sku specific cabs, let's merge them
|
||
|
REM into full sku particular driver.cab files
|
||
|
REM
|
||
|
for %%a in (%Products%) do (
|
||
|
set MySkuCab=%_NTPOSTBLD%\%%ainf\driver.cab
|
||
|
if /i "%%a" == "pro" set MySkuCab=%_NTPOSTBLD%\driver.cab
|
||
|
if /i "%%a" == "ads" set MySkuCab=%_NTPOSTBLD%\entinf\driver.cab
|
||
|
if not exist %TmpCabLocation%\%%adriver.cab (
|
||
|
call logmsg.cmd "No %%a specific cab, copying common cab in place ..."
|
||
|
copy %CommonCab% !MySkuCab!
|
||
|
) else (
|
||
|
call logmsg.cmd "Merging %%a specific and common cabs ..."
|
||
|
set MergeCommand=load %TmpCabLocation%\%%adriver.cab
|
||
|
set MergeCommand=!MergeCommand! load %CommonCab%
|
||
|
set MergeCommand=!MergeCommand! merge save !MySkuCab!
|
||
|
call ExecuteCmd.cmd "cabbench.exe !MergeCommand!"
|
||
|
if !ErrorLevel! NEQ 0 (
|
||
|
call errmsg.cmd "Merge of %%a driver.cab failed ..."
|
||
|
) else (
|
||
|
call logmsg.cmd "Merge of %%a driver.cab successful ..."
|
||
|
)
|
||
|
)
|
||
|
)
|
||
|
|
||
|
|
||
|
REM
|
||
|
REM and we're done
|
||
|
REM
|
||
|
call logmsg.cmd "Finished."
|
||
|
|
||
|
|
||
|
goto :End
|
||
|
|
||
|
|
||
|
|
||
|
:SetMyInfDirName
|
||
|
set SkuName=%1
|
||
|
set MyInfDirName=
|
||
|
if /i "%SkuName%" == "pro" set MyInfDirName=.
|
||
|
if /i "%SkuName%" == "per" set MyInfDirName=perinf
|
||
|
if /i "%SkuName%" == "bla" set MyInfDirName=blainf
|
||
|
if /i "%SkuName%" == "sbs" set MyInfDirName=sbsinf
|
||
|
if /i "%SkuName%" == "srv" set MyInfDirName=srvinf
|
||
|
if /i "%SkuName%" == "ads" set MyInfDirName=entinf
|
||
|
if /i "%SkuName%" == "dtc" set MyInfDirName=dtcinf
|
||
|
goto :End
|
||
|
|
||
|
|
||
|
|
||
|
:end
|
||
|
if "%errors%" == "" set errors=0
|
||
|
seterror.exe "%errors%"& goto :EOF
|