Skip to content

Commit

Permalink
windows: use proper system directory path in fallback loader
Browse files Browse the repository at this point in the history
The %WINDIR% variable is an odd choice and not even entirely reliable.
Since Windows 2000, there has been a specific function for determining
this information, so let's use it. It's also a useful function in its
own right for folks who want to launch system tools in a somewhat safe
way, like netsh.exe.

Updates golang/go#14959
Updates golang/go#30642

Change-Id: Ic24baf37d14f2daced0c1db2771b5a673d2c8852
Reviewed-on: https://go-review.googlesource.com/c/sys/+/165759
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
  • Loading branch information
zx2c4 authored and alexbrainman committed Mar 10, 2019
1 parent 980fc43 commit 10058d7
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 4 deletions.
8 changes: 4 additions & 4 deletions windows/dll_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,11 +359,11 @@ func loadLibraryEx(name string, system bool) (*DLL, error) {
// trying to load "foo.dll" out of the system
// folder, but LoadLibraryEx doesn't support
// that yet on their system, so emulate it.
windir, _ := Getenv("WINDIR") // old var; apparently works on XP
if windir == "" {
return nil, errString("%WINDIR% not defined")
systemdir, err := GetSystemDirectory()
if err != nil {
return nil, err
}
loadDLL = windir + "\\System32\\" + name
loadDLL = systemdir + "\\" + name
}
}
h, err := LoadLibraryEx(loadDLL, 0, flags)
Expand Down
18 changes: 18 additions & 0 deletions windows/security_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,7 @@ type Tokengroups struct {
//sys OpenProcessToken(h Handle, access uint32, token *Token) (err error) = advapi32.OpenProcessToken
//sys GetTokenInformation(t Token, infoClass uint32, info *byte, infoLen uint32, returnedLen *uint32) (err error) = advapi32.GetTokenInformation
//sys GetUserProfileDirectory(t Token, dir *uint16, dirLen *uint32) (err error) = userenv.GetUserProfileDirectoryW
//sys getSystemDirectory(dir *uint16, dirLen uint32) (len uint32, err error) = kernel32.GetSystemDirectoryW

// An access token contains the security information for a logon session.
// The system creates an access token when a user logs on, and every
Expand Down Expand Up @@ -468,6 +469,23 @@ func (t Token) GetUserProfileDirectory() (string, error) {
}
}

// GetSystemDirectory retrieves path to current location of the system
// directory, which is typically, though not always, C:\Windows\System32.
func GetSystemDirectory() (string, error) {
n := uint32(MAX_PATH)
for {
b := make([]uint16, n)
l, e := getSystemDirectory(&b[0], n)
if e != nil {
return "", e
}
if l <= n {
return UTF16ToString(b[:l]), nil
}
n = l
}
}

// IsMember reports whether the access token t is a member of the provided SID.
func (t Token) IsMember(sid *SID) (bool, error) {
var b int32
Expand Down
11 changes: 11 additions & 0 deletions windows/syscall_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package windows_test

import (
"strings"
"syscall"
"testing"

Expand Down Expand Up @@ -51,3 +52,13 @@ func TestGetProcAddressByOrdinal(t *testing.T) {
t.Error("shlwapi.dll:IsOS(OS_NT) returned 0, expected non-zero value")
}
}

func TestGetSystemDirectory(t *testing.T) {
d, err := windows.GetSystemDirectory()
if err != nil {
t.Fatalf("Failed to get system directory: %s", err)
}
if !strings.HasSuffix(strings.ToLower(d), "\\system32") {
t.Fatalf("System directory does not end in system32: %s", d)
}
}
14 changes: 14 additions & 0 deletions windows/zsyscall_windows.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 10058d7

Please sign in to comment.