@@ -6,48 +6,21 @@ import (
66 "bytes"
77 "encoding/base64"
88 "encoding/binary"
9- "errors"
109 "fmt"
1110 "os"
1211 "path/filepath"
13- "strings"
1412 "syscall"
1513 "unicode/utf16"
16- "unsafe"
1714
1815 "github.com/Microsoft/go-winio"
1916 "github.com/containers/podman/v6/pkg/machine/define"
17+ winutil "github.com/containers/podman/v6/pkg/machine/windows"
2018 "go.podman.io/storage/pkg/fileutils"
2119 "go.podman.io/storage/pkg/homedir"
2220 "golang.org/x/sys/windows"
2321 "golang.org/x/sys/windows/registry"
2422)
2523
26- type SHELLEXECUTEINFO struct {
27- cbSize uint32
28- fMask uint32
29- hwnd syscall.Handle
30- lpVerb uintptr
31- lpFile uintptr
32- lpParameters uintptr
33- lpDirectory uintptr
34- nShow int
35- hInstApp syscall.Handle
36- lpIDList uintptr
37- lpClass uintptr
38- hkeyClass syscall.Handle
39- dwHotKey uint32
40- hIconOrMonitor syscall.Handle
41- hProcess syscall.Handle
42- }
43-
44- // Cleaner to refer to the official OS constant names, and consistent with syscall
45- // Ref: https://learn.microsoft.com/en-us/windows/win32/api/shellapi/ns-shellapi-shellexecuteinfow#members
46- const (
47- SEE_MASK_NOCLOSEPROCESS = 0x40
48- SE_ERR_ACCESSDENIED = 0x05
49- )
50-
5124const (
5225 // ref: https://learn.microsoft.com/en-us/windows/win32/secauthz/privilege-constants#constants
5326 rebootPrivilege = "SeShutdownPrivilege"
@@ -78,76 +51,6 @@ func winVersionAtLeast(major uint, minor uint, build uint) bool {
7851 return true
7952}
8053
81- func relaunchElevatedWait () error {
82- e , _ := os .Executable ()
83- d , _ := os .Getwd ()
84- exe , _ := syscall .UTF16PtrFromString (e )
85- cwd , _ := syscall .UTF16PtrFromString (d )
86- arg , _ := syscall .UTF16PtrFromString (buildCommandArgs (true ))
87- verb , _ := syscall .UTF16PtrFromString ("runas" )
88-
89- shell32 := syscall .NewLazyDLL ("shell32.dll" )
90-
91- info := & SHELLEXECUTEINFO {
92- fMask : SEE_MASK_NOCLOSEPROCESS ,
93- hwnd : 0 ,
94- lpVerb : uintptr (unsafe .Pointer (verb )),
95- lpFile : uintptr (unsafe .Pointer (exe )),
96- lpParameters : uintptr (unsafe .Pointer (arg )),
97- lpDirectory : uintptr (unsafe .Pointer (cwd )),
98- nShow : syscall .SW_SHOWNORMAL ,
99- }
100- info .cbSize = uint32 (unsafe .Sizeof (* info ))
101- procShellExecuteEx := shell32 .NewProc ("ShellExecuteExW" )
102- if ret , _ , _ := procShellExecuteEx .Call (uintptr (unsafe .Pointer (info ))); ret == 0 { // 0 = False
103- err := syscall .GetLastError ()
104- if info .hInstApp == SE_ERR_ACCESSDENIED {
105- return wrapMaybe (err , "request to elevate privileges was denied" )
106- }
107- return wrapMaybef (err , "could not launch process, ShellEX Error = %d" , info .hInstApp )
108- }
109-
110- handle := info .hProcess
111- defer func () {
112- _ = syscall .CloseHandle (handle )
113- }()
114-
115- w , err := syscall .WaitForSingleObject (handle , syscall .INFINITE )
116- switch w {
117- case syscall .WAIT_OBJECT_0 :
118- break
119- case syscall .WAIT_FAILED :
120- return fmt .Errorf ("could not wait for process, failed: %w" , err )
121- default :
122- return fmt .Errorf ("could not wait for process, unknown error. event: %X, err: %v" , w , err )
123- }
124- var code uint32
125- if err := syscall .GetExitCodeProcess (handle , & code ); err != nil {
126- return err
127- }
128- if code != 0 {
129- return & ExitCodeError {uint (code )}
130- }
131-
132- return nil
133- }
134-
135- func wrapMaybe (err error , message string ) error {
136- if err != nil {
137- return fmt .Errorf ("%v: %w" , message , err )
138- }
139-
140- return errors .New (message )
141- }
142-
143- func wrapMaybef (err error , format string , args ... any ) error {
144- if err != nil {
145- return fmt .Errorf (format + ": %w" , append (args , err )... )
146- }
147-
148- return fmt .Errorf (format , args ... )
149- }
150-
15154func reboot () error {
15255 const (
15356 wtLocation = `Microsoft\WindowsApps\wt.exe`
@@ -157,7 +60,7 @@ func reboot() error {
15760 )
15861
15962 exe , _ := os .Executable ()
160- relaunch := fmt .Sprintf ("& %s %s" , syscall .EscapeArg (exe ), buildCommandArgs (false ))
63+ relaunch := fmt .Sprintf ("& %s %s" , syscall .EscapeArg (exe ), winutil . BuildCommandArgs (false ))
16164 encoded := base64 .StdEncoding .EncodeToString (encodeUTF16Bytes (relaunch ))
16265
16366 dataDir , err := homedir .GetDataHome ()
@@ -190,7 +93,7 @@ func reboot() error {
19093 "Alternatively, you can cancel and reboot manually\n \n " +
19194 "After rebooting, please wait a minute or two for podman machine to relaunch and continue installing."
19295
193- if MessageBox (message , "Podman Machine" , false ) != 1 {
96+ if winutil . MessageBox (message , "Podman Machine" , false ) != 1 {
19497 fmt .Println ("Reboot is required to continue installation, please reboot at your convenience" )
19598 os .Exit (ErrorSuccessRebootRequired )
19699 return nil
@@ -231,32 +134,3 @@ func encodeUTF16Bytes(s string) []byte {
231134 }
232135 return buf .Bytes ()
233136}
234-
235- func MessageBox (caption , title string , fail bool ) int {
236- var format uint32
237- if fail {
238- format = windows .MB_ICONERROR
239- } else {
240- format = windows .MB_OKCANCEL | windows .MB_ICONINFORMATION
241- }
242-
243- captionPtr , _ := syscall .UTF16PtrFromString (caption )
244- titlePtr , _ := syscall .UTF16PtrFromString (title )
245-
246- ret , _ := windows .MessageBox (0 , captionPtr , titlePtr , format )
247-
248- return int (ret )
249- }
250-
251- func buildCommandArgs (elevate bool ) string {
252- var args []string
253- for _ , arg := range os .Args [1 :] {
254- if arg != "--reexec" {
255- args = append (args , syscall .EscapeArg (arg ))
256- if elevate && arg == "init" {
257- args = append (args , "--reexec" )
258- }
259- }
260- }
261- return strings .Join (args , " " )
262- }
0 commit comments