windows: allow looking up well-known folder paths

This adds the recommended API for determining well-known folder paths,
such as where to place application configuration data. The MSDN
documentation mentions an optimization for the "current user" by passing
NULL as the token, so we provide both variants.

Updates golang/go#32248

Change-Id: I4a2d5d833543e6a0ba8f318944dd6493a0ec31d3
Reviewed-on: https://go-review.googlesource.com/c/sys/+/181637
Reviewed-by: Jason Donenfeld <Jason@zx2c4.com>
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Jason Donenfeld <Jason@zx2c4.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
This commit is contained in:
Jason A. Donenfeld
2019-06-13 12:46:09 +00:00
committed by Jason Donenfeld
parent ab3f67ed27
commit 5ed2794edf
8 changed files with 252 additions and 2 deletions
+20
View File
@@ -174,6 +174,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys CreateProcess(appName *uint16, commandLine *uint16, procSecurity *SecurityAttributes, threadSecurity *SecurityAttributes, inheritHandles bool, creationFlags uint32, env *uint16, currentDir *uint16, startupInfo *StartupInfo, outProcInfo *ProcessInformation) (err error) = CreateProcessW
//sys OpenProcess(da uint32, inheritHandle bool, pid uint32) (handle Handle, err error)
//sys ShellExecute(hwnd Handle, verb *uint16, file *uint16, args *uint16, cwd *uint16, showCmd int32) (err error) = shell32.ShellExecuteW
//sys shGetKnownFolderPath(id *KNOWNFOLDERID, flags uint32, token Token, path **uint16) (ret error) = shell32.SHGetKnownFolderPath
//sys TerminateProcess(handle Handle, exitcode uint32) (err error)
//sys GetExitCodeProcess(handle Handle, exitcode *uint32) (err error)
//sys GetStartupInfo(startupInfo *StartupInfo) (err error) = GetStartupInfoW
@@ -293,6 +294,7 @@ func NewCallbackCDecl(fn interface{}) uintptr {
//sys clsidFromString(lpsz *uint16, pclsid *GUID) (ret error) = ole32.CLSIDFromString
//sys stringFromGUID2(rguid *GUID, lpsz *uint16, cchMax int32) (chars int32) = ole32.StringFromGUID2
//sys coCreateGuid(pguid *GUID) (ret error) = ole32.CoCreateGuid
//sys coTaskMemFree(address unsafe.Pointer) = ole32.CoTaskMemFree
// syscall interface implementation for other packages
@@ -1284,3 +1286,21 @@ func (guid GUID) String() string {
}
return string(utf16.Decode(str[:chars-1]))
}
// KnownFolderPath returns a well-known folder path for the current user, specified by one of
// the FOLDERID_ constants, and chosen and optionally created based on a KF_ flag.
func KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, error) {
return Token(0).KnownFolderPath(folderID, flags)
}
// KnownFolderPath returns a well-known folder path for the user token, specified by one of
// the FOLDERID_ constants, and chosen and optionally created based on a KF_ flag.
func (t Token) KnownFolderPath(folderID *KNOWNFOLDERID, flags uint32) (string, error) {
var p *uint16
err := shGetKnownFolderPath(folderID, flags, t, &p)
if err != nil {
return "", err
}
defer coTaskMemFree(unsafe.Pointer(p))
return UTF16ToString((*[(1 << 30) - 1]uint16)(unsafe.Pointer(p))[:]), nil
}