mirror of
https://github.com/JanDeDobbeleer/oh-my-posh.git
synced 2024-11-14 23:14:05 -08:00
fix(windows): do not follow app store symlinks
This commit is contained in:
parent
d64de61436
commit
ab39417dc2
|
@ -10,6 +10,7 @@ import (
|
||||||
httplib "net/http"
|
httplib "net/http"
|
||||||
"net/http/httputil"
|
"net/http/httputil"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -388,7 +389,7 @@ func (term *Terminal) CommandPath(command string) string {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
path, err := term.LookPath(command)
|
path, err := exec.LookPath(command)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
term.cmdCache.Set(command, path)
|
term.cmdCache.Set(command, path)
|
||||||
term.Debug(path)
|
term.Debug(path)
|
||||||
|
|
|
@ -4,7 +4,6 @@ package runtime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
@ -148,10 +147,6 @@ func (term *Terminal) ConvertToLinuxPath(path string) string {
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) LookPath(command string) (string, error) {
|
|
||||||
return exec.LookPath(command)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (term *Terminal) DirIsWritable(path string) bool {
|
func (term *Terminal) DirIsWritable(path string) bool {
|
||||||
defer term.Trace(time.Now(), path)
|
defer term.Trace(time.Now(), path)
|
||||||
return unix.Access(path, unix.W_OK) == nil
|
return unix.Access(path, unix.W_OK) == nil
|
||||||
|
|
|
@ -4,8 +4,6 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
@ -251,17 +249,3 @@ func (term *Terminal) Connection(connectionType ConnectionType) (*Connection, er
|
||||||
term.Error(fmt.Errorf("Network type '%s' not found", connectionType))
|
term.Error(fmt.Errorf("Network type '%s' not found", connectionType))
|
||||||
return nil, &NotImplemented{}
|
return nil, &NotImplemented{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (term *Terminal) LookPath(command string) (string, error) {
|
|
||||||
winAppPath := filepath.Join(term.Getenv("LOCALAPPDATA"), `\Microsoft\WindowsApps\`, command)
|
|
||||||
if !strings.HasSuffix(winAppPath, ".exe") {
|
|
||||||
winAppPath += ".exe"
|
|
||||||
}
|
|
||||||
|
|
||||||
path, err := exec.LookPath(command)
|
|
||||||
if err == nil && path != winAppPath {
|
|
||||||
return path, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return readWinAppLink(winAppPath)
|
|
||||||
}
|
|
||||||
|
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
"unicode/utf16"
|
|
||||||
"unsafe"
|
"unsafe"
|
||||||
|
|
||||||
"github.com/jandedobbeleer/oh-my-posh/src/regex"
|
"github.com/jandedobbeleer/oh-my-posh/src/regex"
|
||||||
|
@ -116,46 +115,6 @@ func queryWindowTitles(processName, windowTitleRegex string) (string, error) {
|
||||||
return title, nil
|
return title, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type REPARSE_DATA_BUFFER struct { //nolint: revive
|
|
||||||
ReparseTag uint32
|
|
||||||
ReparseDataLength uint16
|
|
||||||
Reserved uint16
|
|
||||||
DUMMYUNIONNAME byte
|
|
||||||
}
|
|
||||||
|
|
||||||
type GenericDataBuffer struct {
|
|
||||||
DataBuffer [1]uint8
|
|
||||||
}
|
|
||||||
|
|
||||||
type AppExecLinkReparseBuffer struct {
|
|
||||||
Version uint32
|
|
||||||
StringList [1]uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
func (rb *AppExecLinkReparseBuffer) Path() (string, error) {
|
|
||||||
UTF16ToStringPosition := func(s []uint16) (string, int) {
|
|
||||||
for i, v := range s {
|
|
||||||
if v == 0 {
|
|
||||||
s = s[0:i]
|
|
||||||
return string(utf16.Decode(s)), i
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "", 0
|
|
||||||
}
|
|
||||||
stringList := (*[0xffff]uint16)(unsafe.Pointer(&rb.StringList[0]))[0:]
|
|
||||||
var link string
|
|
||||||
var position int
|
|
||||||
for i := 0; i <= 2; i++ {
|
|
||||||
link, position = UTF16ToStringPosition(stringList)
|
|
||||||
position++
|
|
||||||
if position >= len(stringList) {
|
|
||||||
return "", errors.New("invalid AppExecLinkReparseBuffer")
|
|
||||||
}
|
|
||||||
stringList = stringList[position:]
|
|
||||||
}
|
|
||||||
return link, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
advapi = syscall.NewLazyDLL("advapi32.dll")
|
advapi = syscall.NewLazyDLL("advapi32.dll")
|
||||||
procGetAce = advapi.NewProc("GetAce")
|
procGetAce = advapi.NewProc("GetAce")
|
||||||
|
@ -350,49 +309,3 @@ func (env *Terminal) Memory() (*Memory, error) {
|
||||||
PhysicalPercentUsed: float64(memStat.MemoryLoad),
|
PhysicalPercentUsed: float64(memStat.MemoryLoad),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// openSymlink calls CreateFile Windows API with FILE_FLAG_OPEN_REPARSE_POINT
|
|
||||||
// parameter, so that Windows does not follow symlink, if path is a symlink.
|
|
||||||
// openSymlink returns opened file handle.
|
|
||||||
func openSymlink(path string) (syscall.Handle, error) {
|
|
||||||
p, err := syscall.UTF16PtrFromString(path)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
attrs := uint32(syscall.FILE_FLAG_BACKUP_SEMANTICS)
|
|
||||||
// Use FILE_FLAG_OPEN_REPARSE_POINT, otherwise CreateFile will follow symlink.
|
|
||||||
// See https://docs.microsoft.com/en-us/windows/desktop/FileIO/symbolic-link-effects-on-file-systems-functions#createfile-and-createfiletransacted
|
|
||||||
attrs |= syscall.FILE_FLAG_OPEN_REPARSE_POINT
|
|
||||||
h, err := syscall.CreateFile(p, 0, 0, nil, syscall.OPEN_EXISTING, attrs, 0)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return h, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func readWinAppLink(path string) (string, error) {
|
|
||||||
h, err := openSymlink(path)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
defer syscall.CloseHandle(h) //nolint: errcheck
|
|
||||||
|
|
||||||
rdbbuf := make([]byte, syscall.MAXIMUM_REPARSE_DATA_BUFFER_SIZE)
|
|
||||||
var bytesReturned uint32
|
|
||||||
err = syscall.DeviceIoControl(h, syscall.FSCTL_GET_REPARSE_POINT, nil, 0, &rdbbuf[0], uint32(len(rdbbuf)), &bytesReturned, nil)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
rdb := (*REPARSE_DATA_BUFFER)(unsafe.Pointer(&rdbbuf[0]))
|
|
||||||
rb := (*GenericDataBuffer)(unsafe.Pointer(&rdb.DUMMYUNIONNAME))
|
|
||||||
appExecLink := (*AppExecLinkReparseBuffer)(unsafe.Pointer(&rb.DataBuffer))
|
|
||||||
if appExecLink.Version != 3 {
|
|
||||||
return "", errors.New("unknown AppExecLink version")
|
|
||||||
}
|
|
||||||
|
|
||||||
return appExecLink.Path()
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in a new issue