Skip to content

Commit

Permalink
kernel.GetSystemPreferredUILanguages
Browse files Browse the repository at this point in the history
  • Loading branch information
CarsonSlovoka committed Jan 26, 2024
1 parent 5b307f6 commit 1988a30
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 11 deletions.
53 changes: 42 additions & 11 deletions v2/w32/kernel32_func.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,17 +28,18 @@ const (
PNFreeConsole ProcName = "FreeConsole"
PNFreeLibrary ProcName = "FreeLibrary"

PNGetConsoleWindow ProcName = "GetConsoleWindow"
PNGetCurrentProcess ProcName = "GetCurrentProcess"
PNGetCurrentThread ProcName = "GetCurrentThread"
PNGetCurrentThreadId ProcName = "GetCurrentThreadId"
PNGetExitCodeProcess ProcName = "GetExitCodeProcess"
PNGetLastError ProcName = "GetLastError"
PNGetModuleFileName ProcName = "GetModuleFileNameW"
PNGetModuleHandle ProcName = "GetModuleHandleW"
PNGetNativeSystemInfo ProcName = "GetNativeSystemInfo"
PNGetThreadDescription ProcName = "GetThreadDescription"
PNGetUserDefaultLCID ProcName = "GetUserDefaultLCID"
PNGetConsoleWindow ProcName = "GetConsoleWindow"
PNGetCurrentProcess ProcName = "GetCurrentProcess"
PNGetCurrentThread ProcName = "GetCurrentThread"
PNGetCurrentThreadId ProcName = "GetCurrentThreadId"
PNGetExitCodeProcess ProcName = "GetExitCodeProcess"
PNGetLastError ProcName = "GetLastError"
PNGetModuleFileName ProcName = "GetModuleFileNameW"
PNGetModuleHandle ProcName = "GetModuleHandleW"
PNGetNativeSystemInfo ProcName = "GetNativeSystemInfo"
PNGetSystemPreferredUILanguages ProcName = "GetSystemPreferredUILanguages"
PNGetThreadDescription ProcName = "GetThreadDescription"
PNGetUserDefaultLCID ProcName = "GetUserDefaultLCID"

PNGlobalAlloc ProcName = "GlobalAlloc"
PNGlobalFree ProcName = "GlobalFree"
Expand Down Expand Up @@ -115,6 +116,7 @@ func NewKernel32DLL(procList ...ProcName) *Kernel32DLL {
PNGetModuleFileName,
PNGetModuleHandle,
PNGetNativeSystemInfo,
PNGetSystemPreferredUILanguages,
PNGetThreadDescription,
PNGetUserDefaultLCID,

Expand Down Expand Up @@ -424,6 +426,35 @@ func (dll *Kernel32DLL) GetNativeSystemInfo() *SYSTEM_INFO {
return info
}

// GetSystemPreferredUILanguages https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getsystempreferreduilanguages
// Returns TRUE if successful or FALSE otherwise.
func (dll *Kernel32DLL) GetSystemPreferredUILanguages(flags, bufferSize uint32 /* 輸出結果的緩存區大小,如果太小就會發生錯誤 */) ([]string, error) {
proc := dll.mustProc(PNGetSystemPreferredUILanguages)
pwszLanguagesBuffer := make([]uint16, bufferSize)
var numLang uint32 // out
r1, _, err := syscall.SyscallN(proc.Addr(),
uintptr(flags),
uintptr(unsafe.Pointer(&numLang)),
uintptr(unsafe.Pointer(&pwszLanguagesBuffer[0])),
uintptr(unsafe.Pointer(&bufferSize)),
)
if r1 == 0 {
return nil, err // 可能的錯誤 ERROR_INSUFFICIENT_BUFFER (122)
}
var languages []string
var langStart int
for i, c := range pwszLanguagesBuffer { // 這個裡面放了很多語言,例如: [lang1, 0, lang2, 0,...lang3, 0]
if c == 0 { // 每一個語言結束之後都會接一個0,因此再次讀到0,我們就知道這是一個完整的語言
if i == langStart {
break // 表示已經沒有任何資料了
}
languages = append(languages, syscall.UTF16ToString(pwszLanguagesBuffer[langStart:i])) // 將目前的語言推入
langStart = i + 1 // 尋找下一個語言
}
}
return languages, nil
}

// GetThreadDescription https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getthreaddescription
// Returns hResult>=0 if successful
// SUCCEEDED(hResult)
Expand Down
11 changes: 11 additions & 0 deletions v2/w32/kernel32_func_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,17 @@ func ExampleKernel32DLL_GetNativeSystemInfo() {
// Output:
}

func ExampleKernel32DLL_GetSystemPreferredUILanguages() {
s1, err := kernelDll.GetSystemPreferredUILanguages(w32.MUI_LANGUAGE_ID, 64) // []string{"0404", "0409"}
s2, err := kernelDll.GetSystemPreferredUILanguages(w32.MUI_LANGUAGE_NAME, 64) // []string{"zh-TW", "en-US"}
s3, err := kernelDll.GetSystemPreferredUILanguages(w32.MUI_MACHINE_LANGUAGE_SETTINGS, 64) // 通常是: []string{"zh-TW", "en-US"}
if _, err = kernelDll.GetSystemPreferredUILanguages(w32.MUI_LANGUAGE_NAME, 1); err != nil { // 故意給比較小的緩存空間,所以會發生錯誤
// log.Printf("%s", err) // The data area passed to a system call is too small. [ERROR_INSUFFICIENT_BUFFER (122)]
}
log.Println(s1, s2, s3)
// Output:
}

func ExampleKernel32DLL_CreateFile() {
kernel32dll := w32.NewKernel32DLL(
w32.PNCreateFile,
Expand Down
8 changes: 8 additions & 0 deletions v2/w32/winnls_h.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package w32

// https://github.com/tpn/winsdk-10/blob/9b69fd26ac0c7d0b83d378dba01080e93349c2ed/Include/10.0.10240.0/um/WinNls.h#L898-L899
const (
MUI_LANGUAGE_ID = 0x4 // Use traditional language ID convention
MUI_LANGUAGE_NAME = 0x8 // Use ISO language (culture) name convention
MUI_MACHINE_LANGUAGE_SETTINGS = 0x400 // 取決於系統設定
)

0 comments on commit 1988a30

Please sign in to comment.