-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathinstall-inf.pl
105 lines (83 loc) · 2.15 KB
/
install-inf.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
use strict;
use Win32::API;
#...............................................................................
my $infFileName = @ARGV [0] || die ("usage: install-inf.pl <inf-file>\n");
open (my $f, '<', $infFileName) || die ("cannot open $infFileName: $!\n");
my $hwId;
while (my $s = <$f>)
{
if ($s =~ m/[\s]*;/)
{
next;
}
if ($s =~ m/([^\s]*VID_[0-9a-f]{4}&PID_[0-9a-f]{4}[^\s]*)/i)
{
$hwId = $1;
last;
}
}
if (!$hwId)
{
die ("HWID not found in: $infFileName\n");
}
print ("installing $infFileName for HWID $hwId...\n");
my $UpdateDriverForPlugAndPlayDevicesA = Win32::API->new (
"newdev.dll",
"BOOL
UpdateDriverForPlugAndPlayDevicesA (
HWND hwndParent,
LPCSTR HardwareId,
LPCSTR FullInfPath,
DWORD InstallFlags,
PBOOL bRebootRequired
)"
) || die ("cannot find newdev.dll:UpdateDriverForPlugAndPlayDevicesA: $!\n");
my $NULL = 0;
my $INSTALLFLAG_FORCE = 1;
my $result = $UpdateDriverForPlugAndPlayDevicesA->Call (
$NULL,
$hwId,
$infFileName,
$INSTALLFLAG_FORCE,
$NULL
);
if (!$result)
{
my $error = Win32::GetLastError ();
my $message = getWinErrorMessage ($error);
die (sprintf ("error (%d 0x%08x): %s\n", $error, $error, $message));
}
print ("done.\n");
#...............................................................................
sub getWinErrorMessage
{
my ($error) = @_;
my $s = Win32::FormatMessage ($error);
if ($s)
{
return $s;
}
# try again with HRESULT_FROM_SETUPAPI
# special handling for setupapi errors is needed --
# FormatMessage fails unless setupapi errors are converted to HRESULT
my $FACILITY_WIN32 = 7;
my $FACILITY_SETUPAPI = 15;
my $APPLICATION_ERROR_MASK = 0x20000000;
my $ERROR_SEVERITY_ERROR = 0xC0000000;
my $mask = $APPLICATION_ERROR_MASK | $ERROR_SEVERITY_ERROR;
if (($error & $mask) == $mask)
{
$error = ($error & 0x0000ffff) | ($FACILITY_SETUPAPI << 16) | 0x80000000;
}
elsif (!($error & 0x80000000))
{
$error = ($error & 0x0000ffff) | ($FACILITY_WIN32 << 16) | 0x80000000;
}
my $s = Win32::FormatMessage ($error);
if ($s)
{
return $s;
}
return "<undefined-error>";
}
#...............................................................................