Skip to content

Commit f52afb0

Browse files
committed
ZC v1314 : Shared mem for HPD, handling S4 in KMD and hardening of DVInstaller
1 parent 5c9b87d commit f52afb0

File tree

17 files changed

+668
-202
lines changed

17 files changed

+668
-202
lines changed

DVInstaller.ps1

Lines changed: 142 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,29 +6,68 @@
66
#--------------------------------------------------------------------------*/
77

88
#check if file present
9-
$global:maxcount = 30
9+
$global:maxcount = 10
1010
function is_present($filepath)
1111
{
1212
$isavailable = Test-Path $filepath
1313
return $isavailable
1414
}
1515

16+
function log_file()
17+
{
18+
$originalLogFile = "DvServer_log.txt"
19+
$incrementalLogFile = $originalLogFile
20+
$counter = 1
21+
22+
while (Test-Path $incrementalLogFile) {
23+
$incrementalLogFile = "{0}-{1}.txt" -f $originalLogFile.Replace('.txt',''), $counter
24+
$counter++
25+
}
26+
27+
return $incrementalLogFile
28+
29+
}
30+
1631
#check if all the required binaries are present or not
1732
function check_executables()
1833
{
19-
if ((is_present("DVServer\dvserver.cat") -eq $true) -and
20-
(is_present("DVServer\DVServer.dll") -eq $true) -and
21-
(is_present("DVServer\DVServer.inf") -eq $true) -and
22-
(is_present("DVServer\dvserverkmd.cat") -eq $true) -and
23-
(is_present("DVServer\DVServerKMD.inf") -eq $true) -and
24-
(is_present("DVServer\DVServerKMD.sys") -eq $true) -and
25-
(is_present("DVEnabler.dll") -eq $true) -and
26-
(is_present("GraphicsDriver\Graphics\iigd_dch.inf") -eq $true)){
27-
Write-Host "Setup files present"
28-
return "SUCCESS"
34+
$files = "DVServer\dvserver.cat", "DVServer\DVServer.dll", "DVServer\DVServer.inf", "DVServer\dvserverkmd.cat", "DVServer\DVServerKMD.inf", "DVServer\DVServerKMD.sys", "DVEnabler.dll"
35+
36+
# ArrayList to store the names of missing files
37+
$missingFiles = New-Object System.Collections.ArrayList
38+
39+
foreach ($file in $files) {
40+
if (-not (is_present $file)) {
41+
[void]$missingFiles.Add($file)
42+
}
2943
}
30-
Write-Host "Setup files don't exist.. Exiting.."
31-
return "FAIL"
44+
45+
# Output the result
46+
if ($missingFiles.Count -eq 0) {
47+
Write-Host "Setup files present"
48+
}
49+
else {
50+
Write-Host "The following files needed for installation are missing:"
51+
Write-Host ($missingFiles -join "`n")
52+
return "FAIL"
53+
}
54+
}
55+
56+
function dvserver_cleanup()
57+
{
58+
if(pnputil.exe /enum-drivers | findstr /i dvserverkmd.inf) {
59+
$driverPackage = Get-WmiObject -Class Win32_PnPSignedDriver | Where-Object { $_.DeviceName -eq "DVServerKMD Device" }
60+
if ($driverPackage) {
61+
$publishedName = $driverPackage.InfName
62+
pnputil.exe /delete-driver "$publishedName" /force /uninstall
63+
}
64+
}
65+
66+
Write-Host "Driver Installation failed.. "
67+
Write-Host "Please Reboot the system and Run the Installation Script Again."
68+
Stop-Transcript
69+
70+
Exit
3271
}
3372

3473
function start_dvenabler()
@@ -45,17 +84,18 @@ function start_dvenabler()
4584
$count = 0
4685

4786
rundll32.exe DVEnabler.dll,dvenabler_init
87+
Write-Host "Starting DVEnabler... Please wait..."
4888
# Before Rebooting the system, we need to make sure that DVEnabler.dll has been kick started
49-
# So adding a loop with a counter of maxcount = 30, To check if DVEnabler has started
50-
# If DVEnabler doesnt get started before 30 iteration, we will exit the script.
89+
# So adding a loop with a counter of maxcount = 10, To check if DVEnabler has started
90+
# If DVEnabler doesn’t get started before 10 iteration, we will exit the script.
5191
while($count -lt $maxcount){
5292
$dve = tasklist /m | findstr "DVEnabler.dll"
5393
if ($dve) {
5494
Write-Host "DVEnabler started as service ."
5595
break
5696
} else {
57-
Write-Host "Starting DVEnabler... Please wait..."
5897
$count ++
98+
Write-Host -NoNewline " $($count)/$maxcount Done `r"; sleep 1
5999
continue
60100
}
61101
}
@@ -69,63 +109,134 @@ function start_dvenabler()
69109
#Copying DVEnabler.DLL to system32 is required as part of the installation
70110
cp DVEnabler.dll C:\Windows\System32
71111

72-
#regiter a task to start the dvenabler.dll as a service during every user logon
112+
#Resgister the DVEnabler task during workstation lock and unlock
113+
Register_ScheduledTask
114+
115+
return "SUCCESS"
116+
}
117+
118+
function Register_ScheduledTask()
119+
{
120+
$TASK_SESSION_UNLOCK = 8 #TASK_SESSION_STATE_CHANGE_TYPE.TASK_SESSION_UNLOCK (taskschd.h)
121+
$TASK_SESSION_LOCK = 7 #TASK_SESSION_STATE_CHANGE_TYPE.TASK_SESSION_LOCK (taskschd.h)
122+
123+
$stateChangeTrigger = Get-CimClass `
124+
-Namespace ROOT\Microsoft\Windows\TaskScheduler `
125+
-ClassName MSFT_TaskSessionStateChangeTrigger
126+
127+
$onUnlockTrigger = New-CimInstance ` -CimClass $stateChangeTrigger `
128+
-Property @{ StateChange = $TASK_SESSION_UNLOCK } ` -ClientOnly
129+
130+
$onLockTrigger = New-CimInstance ` -CimClass $stateChangeTrigger `
131+
-Property @{ StateChange = $TASK_SESSION_LOCK } ` -ClientOnly
132+
73133
unregister-scheduledtask -TaskName "DVEnabler" -confirm:$false -ErrorAction SilentlyContinue
134+
unregister-scheduledtask -TaskName "StopDVEnabler" -confirm:$false -ErrorAction SilentlyContinue
135+
136+
#Register a task to start the dvenabler.dll as a service during every user logon or user unlock
74137
$ac = New-ScheduledTaskAction -Execute "rundll32.exe" -Argument "C:\Windows\System32\DVEnabler.dll,dvenabler_init"
75138
$tr = New-ScheduledTaskTrigger -AtLogOn
76-
$pr = New-ScheduledTaskPrincipal -Groupid "INTERACTIVE"
77-
Register-ScheduledTask -TaskName "DVEnabler" -Trigger $tr -TaskPath "\Microsoft\Windows\DVEnabler" -Action $ac -Principal $pr
139+
$pr = New-ScheduledTaskPrincipal -Groupid "INTERACTIVE" -RunLevel Highest
140+
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -ExecutionTimeLimit 0 -MultipleInstances Queue
141+
Register-ScheduledTask -TaskName "DVEnabler" -Trigger @($tr, $onUnlockTrigger) -TaskPath "\Microsoft\Windows\DVEnabler" -Action $ac -Principal $pr -Settings $settings
142+
143+
#Register a task to Stop the dvenabler.dll during every user lock
144+
$ac = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-ExecutionPolicy Bypass -NoProfile -WindowStyle Hidden -Command `"Stop-ScheduledTask -TaskName '\Microsoft\Windows\DVEnabler\DvEnabler'`""
145+
$pr = New-ScheduledTaskPrincipal -Groupid "INTERACTIVE" -RunLevel Highest
146+
$settings = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -ExecutionTimeLimit 0 -MultipleInstances Queue
147+
Register-ScheduledTask -TaskName "StopDVEnabler" -Trigger $onLockTrigger -TaskPath "\Microsoft\Windows\DVEnabler" -Action $ac -Principal $pr -Settings $settings
78148

79149
return "SUCCESS"
150+
80151
}
81152

82153
##Main##
154+
$logfile = log_file
155+
Start-Transcript -Path $logfile -Append
156+
83157
$ret = check_executables
84158
if ($ret -eq "FAIL") {
159+
Stop-Transcript
85160
Exit
86161
}
87162
else {
163+
# Do a refresh before starting the installation.
164+
pnputil /scan-devices
165+
88166
if ((is_present("DVServer.cer") -eq $true) -and
89167
(is_present("DVServerKMD.cer") -eq $true)){
90168
Write-Host "Start DVServer Certificate installation..."
91169
certutil -addstore root DVServer.cer
92170
certutil -addstore root DVServerKMD.cer
93171
}
94-
95-
Write-Host "Start Windows GFX Driver installation..."
96-
pnputil.exe /add-driver .\GraphicsDriver\Graphics\iigd_dch.inf /install
97172

98173
Write-Host "Start Zerocopy Driver installation..."
99174
pnputil.exe /add-driver .\DVServer\DVServerKMD.inf /install
100175
$count = 0
101176
# Before starting DVEnabler.dll we should make sure that DVServer UMD has started or not
102-
# So adding a loop with a counter of maxcount = 30, To check if DVServer UMD has started
103-
# if DVserver UMD doesnt get started before 30 iteration, we will exit the script
177+
# So adding a loop with a counter of maxcount = 10, To check if DVServer UMD has started
178+
# if DVserver UMD doesn’t get started before 10 iteration, we will exit the script
179+
Write-Host "DVServer loading...Please wait..."
104180
while($count -lt $maxcount){
105181
$dvs= tasklist /m | findstr "dvserver.dll"
106182
if ($dvs) {
107183
Write-Host "DVServer loaded successfully..."
108184
break
109185
} else {
110-
Write-Host "DVServer loading...Please wait..."
111186
$count ++
187+
Write-Host -NoNewline " $($count)/$maxcount Done `r"; sleep 1
112188
continue
113189
}
114190
}
191+
192+
# Reset the count
193+
$count = 0
194+
115195
if (!$dvs) {
116-
Write-Host "Failed to load DVServer UMD... Exiting"
117-
Exit
196+
Write-Host "Trying to install DVServer UMD..."
197+
pnputil.exe /add-driver .\DVServer\DVServer.inf /install
198+
while($count -lt $maxcount){
199+
$dvs= tasklist /m | findstr "dvserver.dll"
200+
if ($dvs) {
201+
Write-Host "DVServer loaded successfully..."
202+
break
203+
} else {
204+
$count ++
205+
Write-Host -NoNewline " $($count)/$maxcount Done `r"; sleep 1
206+
continue
207+
}
208+
}
209+
210+
}
211+
212+
if (!$dvs) {
213+
Write-Host "Failed to load DVServer UMD..."
214+
dvserver_cleanup
118215
}
119216

120-
#call start_dvnabler to run the dvenabler.sll as a service
217+
#call start_dvenabler to run the dvenabler.dll as a service
121218
$dve = start_dvenabler
122219
if ($dve -eq "SUCCESS") {
123-
Write-Host "Dvnabler succusfully started...."
220+
Write-Host "Dvenabler successfully started...."
124221
Write-Host "Rebooting Windows VM..."
222+
Stop-Transcript
125223
Restart-Computer
126224
} else {
127-
Write-Host "Fail to start Dvnabler.... Exiting!"
128-
Exit
225+
Write-Host "Failed to start DVEnabler...."
226+
227+
#Before cleanup, make IDD as primary monitor , so that the user can see the PowerShell window
228+
229+
# Get the second display device name
230+
$secondDisplay = (Get-WmiObject -Namespace "root\CIMV2" -Class Win32_VideoController | Select-Object -Skip 1 -First 1).Name
231+
232+
# Set the second display as the primary display using DisplaySwitch.exe
233+
DisplaySwitch.exe /internal
234+
DisplaySwitch.exe /external:$secondDisplay
235+
236+
# Restart the Explorer process to apply the changes
237+
Stop-Process -Name "explorer" -Force
238+
239+
dvserver_cleanup
129240
}
130241

131242
}

DVServerKMD/Device.cpp

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ NTSTATUS DVServerKMDEvtD0Exit(
335335
NTSTATUS status = STATUS_SUCCESS;
336336
PDEVICE_CONTEXT pDeviceContext;
337337
VioGpuAdapterLite* pVioGpuAdapterLite;
338-
338+
TRACING();
339339
UNREFERENCED_PARAMETER(PreviousState);
340340

341341
pDeviceContext = DeviceGetContext(Device);
@@ -383,7 +383,7 @@ BOOLEAN DVServerKMDEvtInterruptISR(
383383
{
384384
PDEVICE_CONTEXT pDeviceContext;
385385
VioGpuAdapterLite* pVioGpuAdapterLite;
386-
386+
TRACING();
387387
pDeviceContext = DeviceGetContext(WdfInterruptGetDevice(Interrupt));
388388

389389
//
@@ -424,7 +424,7 @@ void DVServerKMDEvtInterruptDPC(
424424
{
425425
PDEVICE_CONTEXT pDeviceContext;
426426
VioGpuAdapterLite* pVioGpuAdapterLite;
427-
427+
TRACING();
428428
UNREFERENCED_PARAMETER(AssociatedObject);
429429

430430
pDeviceContext = DeviceGetContext(WdfInterruptGetDevice(Interrupt));
@@ -440,6 +440,45 @@ void DVServerKMDEvtInterruptDPC(
440440
pVioGpuAdapterLite->DpcRoutine();
441441
}
442442

443+
NTSTATUS
444+
DVServerKMDEvtDeviceD0ExitPreInterruptsDisabled(
445+
IN WDFDEVICE Device,
446+
IN WDF_POWER_DEVICE_STATE TargetState
447+
)
448+
/*++
449+
450+
Routine Description:
451+
452+
EvtDeviceD0ExitPreInterruptsDisabled is called by the framework before the
453+
driver disables the device's hardware interrupts.
454+
455+
Arguments:
456+
457+
Device - Handle to a framework device object.
458+
459+
TargetState - A WDF_POWER_DEVICE_STATE-typed enumerator that identifies the
460+
device power state that the device is about to enter.
461+
462+
Return Value:
463+
464+
NTSTATUS - Failures will be logged, but not acted on.
465+
466+
--*/
467+
{
468+
UNREFERENCED_PARAMETER(TargetState);
469+
TRACING();
470+
PAGED_CODE();
471+
472+
PDEVICE_CONTEXT pDeviceContext;
473+
pDeviceContext = DeviceGetContext(Device);
474+
VioGpuAdapterLite* pVioGpuAdapterLite;
475+
pVioGpuAdapterLite = (VioGpuAdapterLite*)pDeviceContext->pvDeviceExtension;
476+
477+
pVioGpuAdapterLite->DestroyFrameBufferCursorObjExt();
478+
479+
return STATUS_SUCCESS;
480+
}
481+
443482
NTSTATUS DVServerKMDEvtInterruptEnable(
444483
IN WDFINTERRUPT Interrupt,
445484
IN WDFDEVICE AssociatedDevice
@@ -466,6 +505,7 @@ Return Value:
466505
467506
--*/
468507
{
508+
TRACING();
469509
UNREFERENCED_PARAMETER(Interrupt);
470510
UNREFERENCED_PARAMETER(AssociatedDevice);
471511

@@ -498,9 +538,16 @@ Return Value:
498538
499539
--*/
500540
{
501-
UNREFERENCED_PARAMETER(Interrupt);
541+
TRACING();
502542
UNREFERENCED_PARAMETER(AssociatedDevice);
503543

544+
PDEVICE_CONTEXT pDeviceContext;
545+
pDeviceContext = DeviceGetContext(WdfInterruptGetDevice(Interrupt));
546+
VioGpuAdapterLite* pVioGpuAdapterLite;
547+
pVioGpuAdapterLite = (VioGpuAdapterLite*)pDeviceContext->pvDeviceExtension;
548+
549+
pVioGpuAdapterLite->DisableInterruptExt();
550+
504551
return STATUS_SUCCESS;
505552
}
506553

DVServerKMD/Device.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ EVT_WDF_DEVICE_D0_ENTRY DVServerKMDEvtD0Entry;
5454
EVT_WDF_DEVICE_D0_EXIT DVServerKMDEvtD0Exit;
5555
EVT_WDF_INTERRUPT_ISR DVServerKMDEvtInterruptISR;
5656
EVT_WDF_INTERRUPT_DPC DVServerKMDEvtInterruptDPC;
57+
EVT_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED DVServerKMDEvtDeviceD0ExitPreInterruptsDisabled;
5758
EVT_WDF_INTERRUPT_ENABLE DVServerKMDEvtInterruptEnable;
5859
EVT_WDF_INTERRUPT_DISABLE DVServerKMDEvtInterruptDisable;
5960
EXTERN_C_END

DVServerKMD/Driver.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ Return Value:
127127
128128
--*/
129129
{
130+
TRACING();
130131
WPP_CLEANUP(WdfDriverWdmGetDriverObject(driver));
131132

132133
return;
@@ -187,6 +188,8 @@ Return Value:
187188
pnpPowerCallbacks.EvtDeviceD0Entry = DVServerKMDEvtD0Entry;
188189
pnpPowerCallbacks.EvtDeviceD0Exit = DVServerKMDEvtD0Exit;
189190

191+
pnpPowerCallbacks.EvtDeviceD0ExitPreInterruptsDisabled = DVServerKMDEvtDeviceD0ExitPreInterruptsDisabled;
192+
190193
//
191194
// Register the PnP Callbacks..
192195
//

0 commit comments

Comments
 (0)