Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash issue on some special Windows machines. #89

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 44 additions & 8 deletions file_windows.go
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package zenity

import (
"context"
"fmt"
"path/filepath"
"runtime"
"sync"
"syscall"
"unicode/utf16"
"unsafe"
Expand Down Expand Up @@ -36,6 +39,12 @@ func selectFile(opts options) (string, error) {
args.MaxFile = uint32(len(res))
args.InitialDir, args.DefExt = initDirNameExt(opts.filename, res[:])

uninit, err := coInitialize()
if err != nil {
return "", err
}
defer uninit()

defer setup(args.Owner)()
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
if err != nil {
Expand Down Expand Up @@ -79,6 +88,12 @@ func selectFileMultiple(opts options) ([]string, error) {
args.MaxFile = uint32(len(res))
args.InitialDir, args.DefExt = initDirNameExt(opts.filename, res[:])

uninit, err := coInitialize()
if err != nil {
return nil, err
}
defer uninit()

defer setup(args.Owner)()
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
if err != nil {
Expand Down Expand Up @@ -153,6 +168,12 @@ func selectFileSave(opts options) (string, error) {
args.MaxFile = uint32(len(res))
args.InitialDir, args.DefExt = initDirNameExt(opts.filename, res[:])

uninit, err := coInitialize()
if err != nil {
return "", err
}
defer uninit()

defer setup(args.Owner)()
unhook, err := hookDialog(opts.ctx, opts.windowIcon, nil, nil)
if err != nil {
Expand All @@ -171,17 +192,15 @@ func selectFileSave(opts options) (string, error) {
}

func pickFolders(opts options, multi bool) (string, []string, error) {
uninit, err := coInitialize()
if err != nil {
return "", nil, err
}
defer uninit()

owner, _ := opts.attach.(win.HWND)
defer setup(owner)()

err := win.CoInitializeEx(0, win.COINIT_APARTMENTTHREADED|win.COINIT_DISABLE_OLE1DDE)
if err != win.RPC_E_CHANGED_MODE {
if err != nil {
return "", nil, err
}
defer win.CoUninitialize()
}

var dialog *win.IFileOpenDialog
err = win.CoCreateInstance(
win.CLSID_FileOpenDialog, nil, win.CLSCTX_ALL,
Expand Down Expand Up @@ -320,6 +339,23 @@ func browseForFolderCallback(wnd win.HWND, msg uint32, lparam, data uintptr) uin
return 0
}

var initializedMap sync.Map

func coInitialize() (context.CancelFunc, error) {
runtime.LockOSThread()
tid := win.GetCurrentThreadId()
if _, inited := initializedMap.Load(tid); inited {
return runtime.UnlockOSThread, nil
}
err := win.CoInitializeEx(0, win.COINIT_APARTMENTTHREADED|win.COINIT_DISABLE_OLE1DDE)
if err == nil || err == win.S_FALSE || err == win.RPC_E_CHANGED_MODE {
initializedMap.Store(tid, true)
return runtime.UnlockOSThread, nil
}
runtime.UnlockOSThread()
return nil, err
}

func initDirNameExt(filename string, name []uint16) (dir *uint16, ext *uint16) {
d, n, _ := splitDirAndName(filename)
e := filepath.Ext(n)
Expand Down
1 change: 1 addition & 0 deletions internal/win/ole32.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ const (

E_CANCELED = windows.ERROR_CANCELLED | windows.FACILITY_WIN32<<16 | 0x80000000
RPC_E_CHANGED_MODE = syscall.Errno(windows.RPC_E_CHANGED_MODE)
S_FALSE = syscall.Errno(windows.S_FALSE)
)

func CoInitializeEx(reserved uintptr, coInit uint32) error {
Expand Down
Loading