diff --git a/code/client/tunnel/vnc/link.go b/code/client/tunnel/vnc/link.go index d636650..a9ab69e 100644 --- a/code/client/tunnel/vnc/link.go +++ b/code/client/tunnel/vnc/link.go @@ -141,6 +141,7 @@ func (link *Link) localRead() { link.sendDiff(img) } link.img = img + size = img.Rect link.idx++ } } diff --git a/code/client/tunnel/vnc/worker/capture_windows.go b/code/client/tunnel/vnc/worker/capture_windows.go index b8ca4f6..998ac52 100644 --- a/code/client/tunnel/vnc/worker/capture_windows.go +++ b/code/client/tunnel/vnc/worker/capture_windows.go @@ -41,8 +41,13 @@ func (worker *Worker) capture() error { return errors.New("attach desktop: " + err.Error()) } defer detach() + cancel, hdc, err := worker.getHandle() + if err != nil { + return errors.New("get handle: " + err.Error()) + } + defer cancel() info := worker.info - err = worker.updateInfo() + err = worker.updateInfo(hdc) if err != nil { return errors.New("update info: " + err.Error()) } @@ -54,13 +59,13 @@ func (worker *Worker) capture() error { return errors.New("update buffer: " + err.Error()) } } - logging.Info("width=%d, height=%d, bits=%d", info.width, info.height, info.bits) - memDC, _, err := syscall.Syscall(define.FuncCreateCompatibleDC, 1, worker.hdc, 0, 0) + // logging.Info("width=%d, height=%d, bits=%d", info.width, info.height, info.bits) + memDC, _, err := syscall.Syscall(define.FuncCreateCompatibleDC, 1, hdc, 0, 0) if memDC == 0 { return errors.New("create dc: " + err.Error()) } defer syscall.Syscall(define.FuncDeleteDC, 1, memDC, 0, 0) - bitmap, _, err := syscall.Syscall(define.FuncCreateCompatibleBitmap, 3, worker.hdc, + bitmap, _, err := syscall.Syscall(define.FuncCreateCompatibleBitmap, 3, hdc, uintptr(worker.info.width), uintptr(worker.info.height)) if bitmap == 0 { return errors.New("create bitmap: " + err.Error()) @@ -72,11 +77,11 @@ func (worker *Worker) capture() error { } defer syscall.Syscall(define.FuncSelectObject, 2, memDC, oldDC, 0) ok, _, err := syscall.Syscall9(define.FuncBitBlt, 9, memDC, 0, 0, - uintptr(worker.info.width), uintptr(worker.info.height), worker.hdc, 0, 0, define.SRCCOPY) + uintptr(worker.info.width), uintptr(worker.info.height), hdc, 0, 0, define.SRCCOPY) if ok == 0 { return errors.New("bitblt: " + err.Error()) } - defer worker.copyImageData(bitmap) + defer worker.copyImageData(hdc, bitmap) if !worker.showCursor { return nil } @@ -119,7 +124,7 @@ type BITMAPINFOHEADER struct { BiClrImportant uint32 } -func (worker *Worker) copyImageData(bitmap uintptr) { +func (worker *Worker) copyImageData(hdc, bitmap uintptr) { var hdr BITMAPINFOHEADER hdr.BiSize = uint32(unsafe.Sizeof(hdr)) hdr.BiPlanes = 1 @@ -128,7 +133,7 @@ func (worker *Worker) copyImageData(bitmap uintptr) { hdr.BiHeight = int32(-worker.info.height) hdr.BiCompression = define.BI_RGB hdr.BiSizeImage = 0 - lines, _, err := syscall.Syscall9(define.FuncGetDIBits, 7, worker.hdc, bitmap, 0, uintptr(worker.info.height), + lines, _, err := syscall.Syscall9(define.FuncGetDIBits, 7, hdc, bitmap, 0, uintptr(worker.info.height), worker.buffer, uintptr(unsafe.Pointer(&hdr)), define.DIB_RGB_COLORS, 0, 0) if lines == 0 { logging.Error("get bits: %v", err) diff --git a/code/client/tunnel/vnc/worker/event.go b/code/client/tunnel/vnc/worker/event.go index 14ed9fc..a66840a 100644 --- a/code/client/tunnel/vnc/worker/event.go +++ b/code/client/tunnel/vnc/worker/event.go @@ -1,3 +1,4 @@ +//go:build !vnc // +build !vnc package worker diff --git a/code/client/tunnel/vnc/worker/event_auto.go b/code/client/tunnel/vnc/worker/event_auto.go index 8fceefa..f8c780d 100644 --- a/code/client/tunnel/vnc/worker/event_auto.go +++ b/code/client/tunnel/vnc/worker/event_auto.go @@ -1,3 +1,4 @@ +//go:build vnc // +build vnc package worker diff --git a/code/client/tunnel/vnc/worker/worker_windows.go b/code/client/tunnel/vnc/worker/worker_windows.go index 39d4aa5..8f86cf7 100644 --- a/code/client/tunnel/vnc/worker/worker_windows.go +++ b/code/client/tunnel/vnc/worker/worker_windows.go @@ -11,8 +11,6 @@ import ( ) type workerOsBased struct { - hwnd uintptr - hdc uintptr buffer uintptr } @@ -21,15 +19,19 @@ func attachDesktop() (func(), error) { locked := true oldDesktop, _, err := syscall.Syscall(define.FuncGetThreadDesktop, 1, uintptr(windows.GetCurrentThreadId()), 0, 0) if oldDesktop == 0 { + runtime.UnlockOSThread() return nil, fmt.Errorf("get thread desktop: %v", err) } desktop, _, err := syscall.Syscall(define.FuncOpenInputDesktop, 3, 0, 0, windows.GENERIC_ALL) if desktop == 0 { + runtime.UnlockOSThread() return nil, fmt.Errorf("open input desktop: %v", err) } ok, _, err := syscall.Syscall(define.FuncSetThreadDesktop, 1, desktop, 0, 0) if ok == 0 { - logging.Error("set thread desktop: %v", err) + syscall.Syscall(define.FuncCloseDesktop, 1, desktop, 0, 0) + runtime.UnlockOSThread() + return nil, fmt.Errorf("set thread desktop: %v", err) } return func() { syscall.Syscall(define.FuncSetThreadDesktop, 1, oldDesktop, 0, 0) @@ -47,11 +49,12 @@ func (worker *Worker) init() error { return err } defer detach() - err = worker.getHandle() + cancel, hdc, err := worker.getHandle() if err != nil { return err } - err = worker.updateInfo() + defer cancel() + err = worker.updateInfo(hdc) if err != nil { return err } @@ -59,33 +62,30 @@ func (worker *Worker) init() error { return worker.updateBuffer() } -func (worker *workerOsBased) getHandle() error { +func (worker *workerOsBased) getHandle() (func(), uintptr, error) { hwnd, _, err := syscall.Syscall(define.FuncGetDesktopWindow, 0, 0, 0, 0) if hwnd == 0 { - return fmt.Errorf("get desktop window: %v", err) + return nil, 0, fmt.Errorf("get desktop window: %v", err) } hdc, _, err := syscall.Syscall(define.FuncGetDC, 1, hwnd, 0, 0) if hdc == 0 { - return fmt.Errorf("get dc: %v", err) + return nil, 0, fmt.Errorf("get dc: %v", err) } - if worker.hdc != 0 { - syscall.Syscall(define.FuncReleaseDC, 2, worker.hwnd, worker.hdc, 0) - } - worker.hwnd = hwnd - worker.hdc = hdc - return nil + return func() { + syscall.Syscall(define.FuncReleaseDC, 2, hwnd, hdc, 0) + }, hdc, nil } -func (worker *Worker) updateInfo() error { - bits, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, worker.hdc, define.BITSPIXEL, 0) +func (worker *Worker) updateInfo(hdc uintptr) error { + bits, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, hdc, define.BITSPIXEL, 0) if bits == 0 { return fmt.Errorf("get device caps(bits): %v", err) } - width, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, worker.hdc, define.HORZRES, 0) + width, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, hdc, define.HORZRES, 0) if width == 0 { return fmt.Errorf("get device caps(width): %v", err) } - height, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, worker.hdc, define.VERTRES, 0) + height, _, err := syscall.Syscall(define.FuncGetDeviceCaps, 2, hdc, define.VERTRES, 0) if height == 0 { return fmt.Errorf("get device caps(height): %v", err) }