github.com/timsutton/packer@v1.3.2/common/terminal_windows.go (about) 1 // +build windows 2 3 package common 4 5 import ( 6 "syscall" 7 "unsafe" 8 ) 9 10 // windows constants and structures pulled from msdn 11 const ( 12 _STD_INPUT_HANDLE = -10 13 _STD_OUTPUT_HANDLE = -11 14 _STD_ERROR_HANDLE = -12 15 ) 16 17 type ( 18 _SHORT int16 19 _WORD uint16 20 21 _SMALL_RECT struct { 22 Left, Top, Right, Bottom _SHORT 23 } 24 _COORD struct { 25 X, Y _SHORT 26 } 27 _CONSOLE_SCREEN_BUFFER_INFO struct { 28 dwSize, dwCursorPosition _COORD 29 wAttributes _WORD 30 srWindow _SMALL_RECT 31 dwMaximumWindowSize _COORD 32 } 33 ) 34 35 // Low-level functions that call into Windows API for getting console info 36 var kernel32 = syscall.NewLazyDLL("kernel32.dll") 37 var kernel32_GetStdHandleProc = kernel32.NewProc("GetStdHandle") 38 var kernel32_GetConsoleScreenBufferInfoProc = kernel32.NewProc("GetConsoleScreenBufferInfo") 39 40 func kernel32_GetStdHandle(nStdHandle int32) (syscall.Handle, error) { 41 res, _, err := kernel32_GetStdHandleProc.Call(uintptr(nStdHandle)) 42 if res == uintptr(syscall.InvalidHandle) { 43 return syscall.InvalidHandle, error(err) 44 } 45 return syscall.Handle(res), nil 46 } 47 48 func kernel32_GetConsoleScreenBufferInfo(hConsoleOutput syscall.Handle, info *_CONSOLE_SCREEN_BUFFER_INFO) error { 49 ok, _, err := kernel32_GetConsoleScreenBufferInfoProc.Call(uintptr(hConsoleOutput), uintptr(unsafe.Pointer(info))) 50 if int(ok) == 0 { 51 return error(err) 52 } 53 return nil 54 } 55 56 // windows api to get the console screen buffer info 57 func getConsoleScreenBufferInfo(csbi *_CONSOLE_SCREEN_BUFFER_INFO) (err error) { 58 var ( 59 bi _CONSOLE_SCREEN_BUFFER_INFO 60 fd syscall.Handle 61 ) 62 63 // Re-open CONOUT$ as in some instances, stdout may be closed and guaranteed an stdout 64 if fd, err = syscall.Open("CONOUT$", syscall.O_RDWR, 0); err != nil { 65 return err 66 } 67 defer syscall.Close(fd) 68 69 // grab the dimensions for the console 70 if err = kernel32_GetConsoleScreenBufferInfo(fd, &bi); err != nil { 71 return err 72 } 73 74 *csbi = bi 75 return nil 76 } 77 78 func platformGetTerminalDimensions() (width, height int, err error) { 79 var csbi _CONSOLE_SCREEN_BUFFER_INFO 80 81 if err = getConsoleScreenBufferInfo(&csbi); err != nil { 82 return 0, 0, err 83 } 84 85 return int(csbi.dwSize.X), int(csbi.dwSize.Y), nil 86 }