Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for bkalldrv.pl

(view source code of bkalldrv.pl as plain text)

  1. #! perl
  2.  
  3. if ( @ARGV[0] ) {
  4. 	die( "\nBkAllDrv.pl,  Version 2.21 for Windows 2000 / XP\n",
  5. 	     "Backup all device drivers installed on your PC\n\n",
  6. 	     "Usage:  BKALLDRV.PL  [ /A ]\n\n",
  7. 	     "Where:  /A  forces ALL drivers to be backed up, including inactive ones\n\n",
  8. 	     "Notes:  [1] This script requires Microsoft's DEVCON utility, available at:\n",
  9. 	     "            http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q311272\n",
  10. 	     "        [2] A directory \"Drivers\\<hostname>\" will be created in the current\n",
  11. 	     "            directory; drivers will be backed up in subdirectories.\n",
  12. 	     "        [3] In the \"Drivers\\<hostname>\" directory, a log file \"bkalldrv.log\"\n",
  13. 	     "            will be created, which can aid in restoring backed up drivers.\n",
  14. 	     "        [4] If duplicate device names exist, they will be backed up in the\n",
  15. 	     "            same directory.\n",
  16. 	     "        [5] Existing files will be overwritten unless they are read-only.\n",
  17. 	     "        [6] This script will abort on directory or log file creation errors,\n",
  18. 	     "            but not on file copy errors.\n\n",
  19. 	     "Written by Rob van der Woude\nhttp://www.robvanderwoude.com\n" ) unless uc( @ARGV[0] ) eq "/A";
  20. }
  21.  
  22. # Check command line argument
  23. if ( @ARGV[0] ) {
  24. 	$find = "FindAll"
  25. } else {
  26. 	$find = "Find"
  27. }
  28.  
  29. # Reset counters
  30. $devcount  = 0;
  31. $dircount  = 0;
  32. $errcount  = 0;
  33. $filecount = 0;
  34.  
  35. # External modules
  36. use File::Copy;
  37. use Sys::Hostname;
  38.  
  39. # Get host name
  40. $host = hostname();
  41.  
  42. # Create backup target directory for this particular host
  43. mkdir "Drivers";
  44. mkdir "Drivers\\$host";
  45. if ( $! ) {
  46. 	die "Error $! while creating directory Drivers\\$host: $^E\n" unless ( $! eq "File exists" )
  47. }
  48.  
  49. # Display message
  50. print "\nGathering driver information, please wait...\n\n";
  51.  
  52. # Variable used to check if DEVCON.EXE is available
  53. $missing = 1;
  54.  
  55. # Create empty log files
  56. open( LOG,   "> ./Drivers/$host/bkalldrv.log" ) or die( "Error creating log file.\n" );
  57. open( ERROR, "> ./Drivers/$host/bkalldrv.err" ) or die( "Error creating error log file.\n" );
  58.  
  59. # List all hardware IDs using DEVCON.EXE, then use
  60. # DEVCON.EXE again to list the associated driver files
  61. foreach ( `devcon.exe $find * 2>nul \| find.exe \"\\\"` ) {
  62. 	if ( $_ =~ m/^([^:\s]+)\s*:\s*([^\s][^\n]+)$/ ) {
  63. 		# On match assume DEVCON.EXE is available
  64. 		$missing = 0;
  65. 		$hwid    = $1;
  66. 		$name    = $2;
  67. 		# $dirname is "escaped" $name
  68. 		$dirname = $2;
  69. 		$dirname =~ s/\//_/g;
  70. 		$dirname =~ s/,/ /g;
  71. 		$dirname =~ s/:/ /g;
  72. 		$dirname =~ s/;/ /g;
  73. 		$dirname =~ s/  / /g;
  74. 		$dirname =~ s/&/_and_/g;
  75. 		$dirname =~ s/\(/[/g;
  76. 		$dirname =~ s/\)/]/g;
  77. 		$dirname =~ s/^\s*([^\s].*[^\s])\s*$/$1/;
  78. 		if ( $name ) {
  79. 			# Find and copy driver files for this particular hardware
  80. 			# ID, and keep count of the total number of files copied
  81. 			foreach ( `devcon.exe DriverFiles \"\@$hwid\"` ) {
  82. 				SELECT: {
  83. 					if ( $_ =~ m/^        ([A-Z]:\\[^\n]+)$/i ) {
  84. 						if ( copy( $1, "Drivers\\$host\\$class\\$dirname" ) ) {
  85. 							$filecount = $filecount + 1;
  86. 						} else {
  87. 							$msg = "Error copying $1 to Drivers\\$host\\$class\\$dirname: $!\n    $^E\n";
  88. 							print $msg;
  89. 							print ERROR "[".( $errcount + 1 )."] $msg";
  90. 							$errcount = $errcount + 1;
  91. 						}
  92. 						last SELECT;
  93. 					}
  94. 					if ( $_ =~ m/^    Driver installed from ([A-Z]:\\[^\[]+) \[[^\]]+\]\. (No|[0-9]+) file\(?s?\)? used by driver.?$/i ) {
  95. 						if ( copy( $1, "Drivers\\$host\\$class\\$dirname" ) ) {
  96. 							$filecount = $filecount + 1;
  97. 						} else {
  98. 							$msg = "Error copying $1 to Drivers\\$host\\$class\\$dirname: $!\n    $^E\n";
  99. 							print $msg;
  100. 							print ERROR "[".( $errcount + 1 )."] $msg";
  101. 							$errcount = $errcount + 1;
  102. 						}
  103. 						if ( $1 =~ m/.*\\([^\\]+)$/ ) {
  104. 							$inf = "\\$1";
  105. 						} else {
  106. 							$inf = "";
  107. 						}
  108. 						# Log hardware ID and associated INF file
  109. 						print LOG ( $devcount + 1 )."\t$hwid\t$class\\$dirname"."$inf\n";
  110. 						last SELECT;
  111. 					}
  112. 					if ( $_ =~ m/^([^\s][^\\]+)\\.+/i ) {
  113. 						$class = $1;
  114. 						mkdir "Drivers\\$host\\$class";
  115. 						if ( $! ) {
  116. 							$descr = $!;
  117. 							$msg   = "Error creating directory Drivers\\$host\\$class: $!\n    $^E\n";
  118. 							if  ( $descr ne "File exists" and $descr ne "Bad file descriptor" ) {
  119. 								print ERROR "[".( $errcount + 1 )."] $msg";
  120. 								close( ERROR );
  121. 								die $msg;
  122. 							}
  123. 						}
  124. 						last SELECT;
  125. 					}
  126. 					if ( $_ =~ m/^    Name: ([^\$]+)$/i ) {
  127. 						print "Backing up driver files for $1";
  128. 						mkdir "Drivers\\$host\\$class\\$dirname";
  129. 						if ( $! ) {
  130. 							$descr = $!;
  131. 							$msg   = "Error creating directory Drivers\\$host\\$class\\$dirname: $!\n    $^E\n";
  132. 							if  ( $descr ne "File exists" and $descr ne "Bad file descriptor" ) {
  133. 								print ERROR "[".( $errcount + 1 )."] $msg";
  134. 								close( ERROR );
  135. 								die $msg;
  136. 							}
  137. 						}
  138. 						$dircount = $dircount + 1;
  139. 						last SELECT;
  140. 					}
  141. 					if ( $_ =~ m/^(No|[0-9]+) matching device\(?s?\)? found.?$/i ) {
  142. 						if ( uc( $1 ) ne "NO" ) {
  143. 							$devcount = $devcount + 1;
  144. 						}
  145. 					}
  146. 				}
  147. 			}
  148. 		}
  149. 	}
  150. }
  151.  
  152. # Close log files
  153. close( LOG );
  154. close( ERROR );
  155.  
  156. # Display error message if DEVCON.EXE isn't available
  157. if ( $missing ) {
  158. 	print( "DEVCON.EXE not found! Please download it at:\n",
  159. 	       "http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q311272\n" )
  160. }
  161.  
  162. # Display summary
  163. print "\nBacked up $filecount driver files for $devcount devices\n";
  164. if ( $errcount ) {
  165. 	print( "\n$errcount errors were encountered while copying; please check the\n",
  166. 	       "error log \"Drivers\\$host\\bkalldrv.err\" for missed files.\n" );
  167. } else {
  168. 	unlink ERROR;
  169. }
  170.  

page last uploaded: 2017-04-06, 13:33