syscall_windows_test.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  1. // Copyright 2012 The Go Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package windows_test
  5. import (
  6. "fmt"
  7. "io/ioutil"
  8. "os"
  9. "path/filepath"
  10. "runtime"
  11. "syscall"
  12. "testing"
  13. "golang.org/x/sys/windows"
  14. )
  15. func TestWin32finddata(t *testing.T) {
  16. dir, err := ioutil.TempDir("", "go-build")
  17. if err != nil {
  18. t.Fatalf("failed to create temp directory: %v", err)
  19. }
  20. defer os.RemoveAll(dir)
  21. path := filepath.Join(dir, "long_name.and_extension")
  22. f, err := os.Create(path)
  23. if err != nil {
  24. t.Fatalf("failed to create %v: %v", path, err)
  25. }
  26. f.Close()
  27. type X struct {
  28. fd windows.Win32finddata
  29. got byte
  30. pad [10]byte // to protect ourselves
  31. }
  32. var want byte = 2 // it is unlikely to have this character in the filename
  33. x := X{got: want}
  34. pathp, _ := windows.UTF16PtrFromString(path)
  35. h, err := windows.FindFirstFile(pathp, &(x.fd))
  36. if err != nil {
  37. t.Fatalf("FindFirstFile failed: %v", err)
  38. }
  39. err = windows.FindClose(h)
  40. if err != nil {
  41. t.Fatalf("FindClose failed: %v", err)
  42. }
  43. if x.got != want {
  44. t.Fatalf("memory corruption: want=%d got=%d", want, x.got)
  45. }
  46. }
  47. func TestFormatMessage(t *testing.T) {
  48. dll := windows.MustLoadDLL("netevent.dll")
  49. const TITLE_SC_MESSAGE_BOX uint32 = 0xC0001B75
  50. const flags uint32 = syscall.FORMAT_MESSAGE_FROM_HMODULE | syscall.FORMAT_MESSAGE_ARGUMENT_ARRAY | syscall.FORMAT_MESSAGE_IGNORE_INSERTS
  51. buf := make([]uint16, 300)
  52. _, err := windows.FormatMessage(flags, uintptr(dll.Handle), TITLE_SC_MESSAGE_BOX, 0, buf, nil)
  53. if err != nil {
  54. t.Fatalf("FormatMessage for handle=%x and errno=%x failed: %v", dll.Handle, TITLE_SC_MESSAGE_BOX, err)
  55. }
  56. }
  57. func abort(funcname string, err error) {
  58. panic(funcname + " failed: " + err.Error())
  59. }
  60. func ExampleLoadLibrary() {
  61. h, err := windows.LoadLibrary("kernel32.dll")
  62. if err != nil {
  63. abort("LoadLibrary", err)
  64. }
  65. defer windows.FreeLibrary(h)
  66. proc, err := windows.GetProcAddress(h, "GetVersion")
  67. if err != nil {
  68. abort("GetProcAddress", err)
  69. }
  70. r, _, _ := syscall.Syscall(uintptr(proc), 0, 0, 0, 0)
  71. major := byte(r)
  72. minor := uint8(r >> 8)
  73. build := uint16(r >> 16)
  74. print("windows version ", major, ".", minor, " (Build ", build, ")\n")
  75. }
  76. func TestTOKEN_ALL_ACCESS(t *testing.T) {
  77. if windows.TOKEN_ALL_ACCESS != 0xF01FF {
  78. t.Errorf("TOKEN_ALL_ACCESS = %x, want 0xF01FF", windows.TOKEN_ALL_ACCESS)
  79. }
  80. }
  81. func TestCreateWellKnownSid(t *testing.T) {
  82. sid, err := windows.CreateWellKnownSid(windows.WinBuiltinAdministratorsSid)
  83. if err != nil {
  84. t.Fatalf("Unable to create well known sid for administrators: %v", err)
  85. }
  86. sidStr, err := sid.String()
  87. if err != nil {
  88. t.Fatalf("Unable to convert sid into string: %v", err)
  89. }
  90. if sidStr != "S-1-5-32-544" {
  91. t.Fatalf("Expecting administrators to be S-1-5-32-544, but found %s instead", sidStr)
  92. }
  93. }
  94. func TestPseudoTokens(t *testing.T) {
  95. version, err := windows.GetVersion()
  96. if err != nil {
  97. t.Fatal(err)
  98. }
  99. if ((version&0xffff)>>8)|((version&0xff)<<8) < 0x0602 {
  100. return
  101. }
  102. realProcessToken, err := windows.OpenCurrentProcessToken()
  103. if err != nil {
  104. t.Fatal(err)
  105. }
  106. defer realProcessToken.Close()
  107. realProcessUser, err := realProcessToken.GetTokenUser()
  108. if err != nil {
  109. t.Fatal(err)
  110. }
  111. pseudoProcessToken := windows.GetCurrentProcessToken()
  112. pseudoProcessUser, err := pseudoProcessToken.GetTokenUser()
  113. if err != nil {
  114. t.Fatal(err)
  115. }
  116. if !windows.EqualSid(realProcessUser.User.Sid, pseudoProcessUser.User.Sid) {
  117. t.Fatal("The real process token does not have the same as the pseudo process token")
  118. }
  119. runtime.LockOSThread()
  120. defer runtime.UnlockOSThread()
  121. err = windows.RevertToSelf()
  122. if err != nil {
  123. t.Fatal(err)
  124. }
  125. pseudoThreadToken := windows.GetCurrentThreadToken()
  126. _, err = pseudoThreadToken.GetTokenUser()
  127. if err != windows.ERROR_NO_TOKEN {
  128. t.Fatal("Expected an empty thread token")
  129. }
  130. pseudoThreadEffectiveToken := windows.GetCurrentThreadEffectiveToken()
  131. pseudoThreadEffectiveUser, err := pseudoThreadEffectiveToken.GetTokenUser()
  132. if err != nil {
  133. t.Fatal(nil)
  134. }
  135. if !windows.EqualSid(realProcessUser.User.Sid, pseudoThreadEffectiveUser.User.Sid) {
  136. t.Fatal("The real process token does not have the same as the pseudo thread effective token, even though we aren't impersonating")
  137. }
  138. err = windows.ImpersonateSelf(windows.SecurityImpersonation)
  139. if err != nil {
  140. t.Fatal(err)
  141. }
  142. defer windows.RevertToSelf()
  143. pseudoThreadUser, err := pseudoThreadToken.GetTokenUser()
  144. if err != nil {
  145. t.Fatal(err)
  146. }
  147. if !windows.EqualSid(realProcessUser.User.Sid, pseudoThreadUser.User.Sid) {
  148. t.Fatal("The real process token does not have the same as the pseudo thread token after impersonating self")
  149. }
  150. }
  151. func TestGUID(t *testing.T) {
  152. guid, err := windows.GenerateGUID()
  153. if err != nil {
  154. t.Fatal(err)
  155. }
  156. if guid.Data1 == 0 && guid.Data2 == 0 && guid.Data3 == 0 && guid.Data4 == [8]byte{} {
  157. t.Fatal("Got an all zero GUID, which is overwhelmingly unlikely")
  158. }
  159. want := fmt.Sprintf("{%08X-%04X-%04X-%04X-%012X}", guid.Data1, guid.Data2, guid.Data3, guid.Data4[:2], guid.Data4[2:])
  160. got := guid.String()
  161. if got != want {
  162. t.Fatalf("String = %q; want %q", got, want)
  163. }
  164. guid2, err := windows.GUIDFromString(got)
  165. if err != nil {
  166. t.Fatal(err)
  167. }
  168. if guid2 != guid {
  169. t.Fatalf("Did not parse string back to original GUID = %q; want %q", guid2, guid)
  170. }
  171. _, err = windows.GUIDFromString("not-a-real-guid")
  172. if err != syscall.Errno(windows.CO_E_CLASSSTRING) {
  173. t.Fatalf("Bad GUID string error = %v; want CO_E_CLASSSTRING", err)
  174. }
  175. }
  176. func TestKnownFolderPath(t *testing.T) {
  177. token, err := windows.OpenCurrentProcessToken()
  178. if err != nil {
  179. t.Fatal(err)
  180. }
  181. defer token.Close()
  182. profileDir, err := token.GetUserProfileDirectory()
  183. if err != nil {
  184. t.Fatal(err)
  185. }
  186. want := filepath.Join(profileDir, "Desktop")
  187. got, err := windows.KnownFolderPath(windows.FOLDERID_Desktop, windows.KF_FLAG_DEFAULT)
  188. if err != nil {
  189. t.Fatal(err)
  190. }
  191. if want != got {
  192. t.Fatalf("Path = %q; want %q", got, want)
  193. }
  194. }