diff --git a/.gitignore b/.gitignore index 3973f33..627ca78 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -aminal \ No newline at end of file +aminal +aminal.exe +*.syso +.idea \ No newline at end of file diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..db588bc --- /dev/null +++ b/.travis.yml @@ -0,0 +1,37 @@ +language: go +os: +- linux +- osx +go: +- 1.10.x +- 1.11.x +- master +matrix: + allow_failures: + - go: master + fast_finish: true +go_import_path: github.com/liamg/aminal +before_install: +- if [[ $TRAVIS_OS_NAME == 'linux' ]]; then sudo apt-get install -y xorg-dev libgl1-mesa-dev + gcc-multilib gcc-mingw-w64-x86-64 && go get github.com/mitchellh/gox; fi +script: +- make test +- if [[ $TRAVIS_OS_NAME == 'osx' ]]; then make build-darwin-native-travis; fi +- if [[ $TRAVIS_OS_NAME == 'linux' ]]; then make build-linux-travis; fi +- if [[ $TRAVIS_OS_NAME == 'linux' ]]; then make windows-cross-compile-travis; fi +env: + global: + - secure: YOUR_SECURE_TOKEN +deploy: + provider: releases + skip_cleanup: true + api_key: + secure: YOUR_SECURE_TOKEN + file: + - bin/darwin/aminal-darwin-amd64 + - bin/linux/aminal-linux-amd64 + - bin/windows/aminal-windows-amd64.exe + on: + repo: liamg/aminal + tags: true + condition: "$TRAVIS_GO_VERSION =~ ^1\\.11" diff --git a/Makefile b/Makefile index ab6de91..9749f29 100644 --- a/Makefile +++ b/Makefile @@ -33,3 +33,25 @@ build-darwin: .PHONY: package-debian package-debian: build-linux ./scripts/package-debian.sh "${CIRCLE_TAG}" bin/linux/${BINARY}-linux-amd64 + +.PHONY: build-linux-travis +build-linux-travis: + mkdir -p bin/linux + GOOS=linux GOARCH=amd64 CGO_ENABLED=1 go build -o bin/linux/${BINARY}-linux-amd64 -ldflags "-X github.com/liamg/aminal/version.Version=${TRAVIS_TAG}" + +.PHONY: windows-cross-compile-travis +windows-cross-compile-travis: + mkdir -p bin/windows + x86_64-w64-mingw32-windres -o aminal.syso aminal.rc + GOOS=windows GOARCH=amd64 CGO_ENABLED=1 CXX=x86_64-w64-mingw32-g++ CC=x86_64-w64-mingw32-gcc go build -o bin/windows/${BINARY}-windows-amd64.exe -ldflags "-X github.com/liamg/aminal/version.Version=${TRAVIS_TAG}" + +.PHONY: build-windows +build-windows: + windres -o aminal.syso aminal.rc + go build -o ${BINARY}-windows-amd64.exe + +.PHONY: build-darwin-native-travis +build-darwin-native-travis: + mkdir -p bin/darwin + GOOS=darwin GOARCH=amd64 CGO_ENABLED=1 go build -o bin/darwin/${BINARY}-darwin-amd64 -ldflags "-X github.com/liamg/aminal/version.Version=${TRAVIS_TAG}" + diff --git a/README.md b/README.md index 52cadab..b5f4ef7 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Ensure you have your latest graphics card drivers installed before use. - Scrollback buffer - Clipboard access - Clickable URLs -- Multi platform support (Windows coming soon...) +- Multi platform support (Windows, Linux, OSX) - Sixel support - Hints/overlays - Built-in patched fonts for powerline @@ -41,11 +41,11 @@ brew install aminal ### Windows -A Windows version of Aminal is expected in the next 1-2 months. +Dev environment setup instructions are available [there](windows.md). ### Prebuilt Binaries -Prebuilt binaries are available for Linux and OSX on the [releases](https://github.com/liamg/aminal/releases) page. +Prebuilt binaries are available for Linux, OSX and Windows on the [releases](https://github.com/liamg/aminal/releases) page. Download the binary and `sudo cp aminal-* /usr/local/bin/aminal && chmod +x /usr/local/bin/aminal`. @@ -97,6 +97,8 @@ Aminal looks for a config file in the following places, and stops when it finds * `$HOME/.config/aminal/config.toml` * `$HOME/.aminal.toml` +Note that on Windows Aminal uses `%USERPROFILE%` environment variable instead of `$HOME` + It will write a config file to whichever of those directories exists (preferring the top of the list) the first time it runs, if one doesn't already exist. You can ignore the config and use defaults by specifying `--ignore-config` as a CLI flag. @@ -108,6 +110,7 @@ debug = false # Enable debug logging to stdout. Defaults to false. slomo = false # Enable slow motion output mode, useful for debugging shells/terminal GUI apps etc. Defaults to false. shell = "/bin/bash" # The shell to run for the terminal session. Defaults to the users shell. search_url = "https://www.google.com/search?q=$QUERY" # The search engine to use for the "search selected text" action. Defaults to google. Set this to your own search url using $QUERY as the keywords to replace when searching. +max_lines = 1000 # Maximum number of lines in the terminal buffer. [colours] cursor = "#e8dfd6" diff --git a/aminal.exe.manifest b/aminal.exe.manifest new file mode 100644 index 0000000..3f8f3aa --- /dev/null +++ b/aminal.exe.manifest @@ -0,0 +1,21 @@ + + + + + + + + + \ No newline at end of file diff --git a/aminal.ico b/aminal.ico new file mode 100644 index 0000000..e211020 Binary files /dev/null and b/aminal.ico differ diff --git a/aminal.rc b/aminal.rc new file mode 100644 index 0000000..4d8f697 --- /dev/null +++ b/aminal.rc @@ -0,0 +1,3 @@ +100 ICON "aminal.ico" +100 24 "aminal.exe.manifest" +GLFW_ICON ICON "aminal.ico" diff --git a/buffer/buffer.go b/buffer/buffer.go index e31f364..11266d3 100644 --- a/buffer/buffer.go +++ b/buffer/buffer.go @@ -28,6 +28,7 @@ type Buffer struct { selectionExpanded bool // whether the selection to word expansion has already run on this point selectionClickTime time.Time defaultCell Cell + maxLines uint64 } type Position struct { @@ -36,7 +37,7 @@ type Position struct { } // NewBuffer creates a new terminal buffer -func NewBuffer(viewCols uint16, viewLines uint16, attr CellAttributes) *Buffer { +func NewBuffer(viewCols uint16, viewLines uint16, attr CellAttributes, maxLines uint64) *Buffer { b := &Buffer{ cursorX: 0, cursorY: 0, @@ -44,6 +45,7 @@ func NewBuffer(viewCols uint16, viewLines uint16, attr CellAttributes) *Buffer { cursorAttr: attr, autoWrap: true, defaultCell: Cell{attr: attr}, + maxLines: maxLines, } b.SetVerticalMargins(0, uint(viewLines-1)) b.ResizeView(viewCols, viewLines) @@ -479,8 +481,16 @@ func (buffer *Buffer) insertLine() { if !buffer.InScrollableRegion() { pos := buffer.RawLine() - out := make([]Line, len(buffer.lines)+1) - copy(out[:pos], buffer.lines[:pos]) + maxLines := buffer.getMaxLines() + newLineCount := uint64(len(buffer.lines) + 1) + if newLineCount > maxLines { + newLineCount = maxLines + } + + out := make([]Line, newLineCount) + copy( + out[ : pos - ( uint64(len(buffer.lines)) + 1 - newLineCount )], + buffer.lines[ uint64(len(buffer.lines)) + 1 - newLineCount : pos] ) out[pos] = newLine() copy(out[pos+1:], buffer.lines[pos:]) buffer.lines = out @@ -575,6 +585,10 @@ func (buffer *Buffer) Index() { if buffer.cursorY >= buffer.ViewHeight()-1 { buffer.lines = append(buffer.lines, newLine()) + maxLines := buffer.getMaxLines() + if uint64(len(buffer.lines)) > maxLines { + buffer.lines = buffer.lines[ uint64(len(buffer.lines)) - maxLines : ] + } } else { buffer.cursorY++ } @@ -1025,3 +1039,12 @@ func (buffer *Buffer) ResizeView(width uint16, height uint16) { buffer.SetVerticalMargins(0, uint(buffer.viewHeight-1)) } + +func (buffer *Buffer) getMaxLines() uint64 { + result := buffer.maxLines + if result < uint64(buffer.viewHeight) { + result = uint64(buffer.viewHeight) + } + + return result +} diff --git a/buffer/buffer_test.go b/buffer/buffer_test.go index 400cf0c..523635c 100644 --- a/buffer/buffer_test.go +++ b/buffer/buffer_test.go @@ -10,7 +10,7 @@ import ( ) func TestTabbing(t *testing.T) { - b := NewBuffer(30, 3, CellAttributes{}) + b := NewBuffer(30, 3, CellAttributes{}, 1000) b.Write([]rune("hello")...) b.Tab() b.Write([]rune("x")...) @@ -39,7 +39,7 @@ hell xxx good } func TestOffsets(t *testing.T) { - b := NewBuffer(10, 3, CellAttributes{}) + b := NewBuffer(10, 3, CellAttributes{}, 1000) b.Write([]rune("hello")...) b.CarriageReturn() b.NewLine() @@ -60,7 +60,7 @@ func TestOffsets(t *testing.T) { } func TestBufferCreation(t *testing.T) { - b := NewBuffer(10, 20, CellAttributes{}) + b := NewBuffer(10, 20, CellAttributes{}, 1000) assert.Equal(t, uint16(10), b.Width()) assert.Equal(t, uint16(20), b.ViewHeight()) assert.Equal(t, uint16(0), b.CursorColumn()) @@ -70,7 +70,7 @@ func TestBufferCreation(t *testing.T) { func TestBufferWriteIncrementsCursorCorrectly(t *testing.T) { - b := NewBuffer(5, 4, CellAttributes{}) + b := NewBuffer(5, 4, CellAttributes{}, 1000) /*01234 |----- @@ -117,7 +117,7 @@ func TestBufferWriteIncrementsCursorCorrectly(t *testing.T) { } func TestWritingNewLineAsFirstRuneOnWrappedLine(t *testing.T) { - b := NewBuffer(3, 20, CellAttributes{}) + b := NewBuffer(3, 20, CellAttributes{}, 1000) b.Write('a', 'b', 'c') assert.Equal(t, uint16(3), b.cursorX) assert.Equal(t, uint16(0), b.cursorY) @@ -140,7 +140,7 @@ func TestWritingNewLineAsFirstRuneOnWrappedLine(t *testing.T) { } func TestWritingNewLineAsSecondRuneOnWrappedLine(t *testing.T) { - b := NewBuffer(3, 20, CellAttributes{}) + b := NewBuffer(3, 20, CellAttributes{}, 1000) /* |abc |d @@ -168,7 +168,7 @@ func TestWritingNewLineAsSecondRuneOnWrappedLine(t *testing.T) { func TestSetPosition(t *testing.T) { - b := NewBuffer(120, 80, CellAttributes{}) + b := NewBuffer(120, 80, CellAttributes{}, 1000) assert.Equal(t, 0, int(b.CursorColumn())) assert.Equal(t, 0, int(b.CursorLine())) b.SetPosition(60, 10) @@ -184,7 +184,7 @@ func TestSetPosition(t *testing.T) { } func TestMovePosition(t *testing.T) { - b := NewBuffer(120, 80, CellAttributes{}) + b := NewBuffer(120, 80, CellAttributes{}, 1000) assert.Equal(t, 0, int(b.CursorColumn())) assert.Equal(t, 0, int(b.CursorLine())) b.MovePosition(-1, -1) @@ -206,7 +206,7 @@ func TestMovePosition(t *testing.T) { func TestVisibleLines(t *testing.T) { - b := NewBuffer(80, 10, CellAttributes{}) + b := NewBuffer(80, 10, CellAttributes{}, 1000) b.Write([]rune("hello 1")...) b.CarriageReturn() b.NewLine() @@ -256,7 +256,7 @@ func TestVisibleLines(t *testing.T) { } func TestClearWithoutFullView(t *testing.T) { - b := NewBuffer(80, 10, CellAttributes{}) + b := NewBuffer(80, 10, CellAttributes{}, 1000) b.Write([]rune("hello 1")...) b.CarriageReturn() b.NewLine() @@ -272,7 +272,7 @@ func TestClearWithoutFullView(t *testing.T) { } func TestClearWithFullView(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello 1")...) b.CarriageReturn() b.NewLine() @@ -303,7 +303,7 @@ func TestClearWithFullView(t *testing.T) { } func TestCarriageReturn(t *testing.T) { - b := NewBuffer(80, 20, CellAttributes{}) + b := NewBuffer(80, 20, CellAttributes{}, 1000) b.Write([]rune("hello!")...) b.CarriageReturn() b.Write([]rune("secret")...) @@ -312,7 +312,7 @@ func TestCarriageReturn(t *testing.T) { } func TestCarriageReturnOnFullLine(t *testing.T) { - b := NewBuffer(20, 20, CellAttributes{}) + b := NewBuffer(20, 20, CellAttributes{}, 1000) b.Write([]rune("abcdeabcdeabcdeabcde")...) b.CarriageReturn() b.Write([]rune("xxxxxxxxxxxxxxxxxxxx")...) @@ -321,7 +321,7 @@ func TestCarriageReturnOnFullLine(t *testing.T) { } func TestCarriageReturnOnFullLastLine(t *testing.T) { - b := NewBuffer(20, 2, CellAttributes{}) + b := NewBuffer(20, 2, CellAttributes{}, 1000) b.NewLine() b.Write([]rune("abcdeabcdeabcdeabcde")...) b.CarriageReturn() @@ -332,7 +332,7 @@ func TestCarriageReturnOnFullLastLine(t *testing.T) { } func TestCarriageReturnOnWrappedLine(t *testing.T) { - b := NewBuffer(80, 6, CellAttributes{}) + b := NewBuffer(80, 6, CellAttributes{}, 1000) b.Write([]rune("hello!")...) b.CarriageReturn() b.Write([]rune("secret")...) @@ -342,7 +342,7 @@ func TestCarriageReturnOnWrappedLine(t *testing.T) { } func TestCarriageReturnOnLineThatDoesntExist(t *testing.T) { - b := NewBuffer(6, 10, CellAttributes{}) + b := NewBuffer(6, 10, CellAttributes{}, 1000) b.cursorY = 3 b.CarriageReturn() assert.Equal(t, uint16(0), b.cursorX) @@ -350,7 +350,7 @@ func TestCarriageReturnOnLineThatDoesntExist(t *testing.T) { } func TestGetCell(t *testing.T) { - b := NewBuffer(80, 20, CellAttributes{}) + b := NewBuffer(80, 20, CellAttributes{}, 1000) b.Write([]rune("Hello")...) b.CarriageReturn() b.NewLine() @@ -366,7 +366,7 @@ func TestGetCell(t *testing.T) { } func TestGetCellWithHistory(t *testing.T) { - b := NewBuffer(80, 2, CellAttributes{}) + b := NewBuffer(80, 2, CellAttributes{}, 1000) b.Write([]rune("Hello")...) b.CarriageReturn() @@ -384,7 +384,7 @@ func TestGetCellWithHistory(t *testing.T) { } func TestGetCellWithBadCursor(t *testing.T) { - b := NewBuffer(80, 2, CellAttributes{}) + b := NewBuffer(80, 2, CellAttributes{}, 1000) b.Write([]rune("Hello\r\nthere\r\nsomething...")...) require.Nil(t, b.GetCell(8, 3)) require.Nil(t, b.GetCell(90, 0)) @@ -392,12 +392,12 @@ func TestGetCellWithBadCursor(t *testing.T) { } func TestCursorAttr(t *testing.T) { - b := NewBuffer(80, 2, CellAttributes{}) + b := NewBuffer(80, 2, CellAttributes{}, 1000) assert.Equal(t, &b.cursorAttr, b.CursorAttr()) } func TestCursorPositionQuerying(t *testing.T) { - b := NewBuffer(80, 20, CellAttributes{}) + b := NewBuffer(80, 20, CellAttributes{}, 1000) b.cursorX = 17 b.cursorY = 9 assert.Equal(t, b.cursorX, b.CursorColumn()) @@ -405,7 +405,7 @@ func TestCursorPositionQuerying(t *testing.T) { } func TestRawPositionQuerying(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("a")...) b.CarriageReturn() b.NewLine() @@ -442,7 +442,7 @@ func TestRawPositionQuerying(t *testing.T) { // CSI 2 K func TestEraseLine(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello, this is a test")...) b.CarriageReturn() b.NewLine() @@ -454,7 +454,7 @@ func TestEraseLine(t *testing.T) { // CSI 1 K func TestEraseLineToCursor(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello, this is a test")...) b.CarriageReturn() b.NewLine() @@ -468,7 +468,7 @@ func TestEraseLineToCursor(t *testing.T) { // CSI 0 K func TestEraseLineAfterCursor(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello, this is a test")...) b.CarriageReturn() b.NewLine() @@ -479,7 +479,7 @@ func TestEraseLineAfterCursor(t *testing.T) { assert.Equal(t, "dele", b.lines[1].String()) } func TestEraseDisplay(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello")...) b.CarriageReturn() b.NewLine() @@ -495,7 +495,7 @@ func TestEraseDisplay(t *testing.T) { } } func TestEraseDisplayToCursor(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello")...) b.CarriageReturn() b.NewLine() @@ -513,7 +513,7 @@ func TestEraseDisplayToCursor(t *testing.T) { } func TestEraseDisplayFromCursor(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello")...) b.CarriageReturn() b.NewLine() @@ -529,7 +529,7 @@ func TestEraseDisplayFromCursor(t *testing.T) { assert.Equal(t, "", lines[2].String()) } func TestBackspace(t *testing.T) { - b := NewBuffer(80, 5, CellAttributes{}) + b := NewBuffer(80, 5, CellAttributes{}, 1000) b.Write([]rune("hello")...) b.Backspace() b.Backspace() @@ -539,7 +539,7 @@ func TestBackspace(t *testing.T) { } func TestHorizontalResizeView(t *testing.T) { - b := NewBuffer(80, 10, CellAttributes{}) + b := NewBuffer(80, 10, CellAttributes{}, 1000) // 60 characters b.Write([]rune(`hellohellohellohellohellohellohellohellohellohellohellohello`)...) @@ -621,3 +621,17 @@ hellohellohellohellohellohellohellohellohellohellohellohello goodbyegoo dbye */ + +func TestBufferMaxLines(t *testing.T) { + b := NewBuffer(80, 2, CellAttributes{}, 2) + + b.Write([]rune("hello")...) + b.NewLine() + b.Write([]rune("funny")...) + b.NewLine() + b.Write([]rune("world")...) + + assert.Equal(t, 2, len(b.lines)) + assert.Equal(t, "funny", b.lines[0].String()) + assert.Equal(t, "world", b.lines[1].String()) +} \ No newline at end of file diff --git a/config.go b/config.go index f74a935..356660a 100644 --- a/config.go +++ b/config.go @@ -5,8 +5,8 @@ import ( "fmt" "io/ioutil" "os" - "strings" - + "os/user" + "path/filepath" "github.com/liamg/aminal/config" "github.com/liamg/aminal/version" ) @@ -44,7 +44,13 @@ func getConfig() *config.Config { func loadConfigFile() *config.Config { - home := os.Getenv("HOME") + usr, err := user.Current() + if err != nil { + fmt.Printf("Failed to get current user information: %s\n", err) + return &config.DefaultConfig + } + + home := usr.HomeDir if home == "" { return &config.DefaultConfig } @@ -53,11 +59,11 @@ func loadConfigFile() *config.Config { xdgHome := os.Getenv("XDG_CONFIG_HOME") if xdgHome != "" { - places = append(places, fmt.Sprintf("%s/aminal/config.toml", xdgHome)) + places = append(places, filepath.Join(xdgHome, "aminal/config.toml")) } - places = append(places, fmt.Sprintf("%s/.config/aminal/config.toml", home)) - places = append(places, fmt.Sprintf("%s/.aminal.toml", home)) + places = append(places, filepath.Join(home, ".config/aminal/config.toml")) + places = append(places, filepath.Join(home, ".aminal.toml")) for _, place := range places { if b, err := ioutil.ReadFile(place); err == nil { @@ -69,20 +75,18 @@ func loadConfigFile() *config.Config { } } - parts := strings.Split(places[0], string(os.PathSeparator)) - path := strings.Join(parts[0:len(parts)-1], string(os.PathSeparator)) - - err := os.MkdirAll(path, 0744) - if err != nil { - panic(err) - } - if b, err := config.DefaultConfig.Encode(); err != nil { fmt.Printf("Failed to encode config file: %s\n", err) } else { - if err := ioutil.WriteFile(fmt.Sprintf("%s/config.toml", path), b, 0644); err != nil { - fmt.Printf("Failed to encode config file: %s\n", err) + err = os.MkdirAll(filepath.Dir(places[0]), 0744) + if err != nil { + fmt.Printf("Failed to create config file directory: %s\n", err) + } else { + if err = ioutil.WriteFile(places[0], b, 0644); err != nil { + fmt.Printf("Failed to encode config file: %s\n", err) + } } } + return &config.DefaultConfig } diff --git a/config/config.go b/config/config.go index 28024be..bae52f5 100644 --- a/config/config.go +++ b/config/config.go @@ -13,6 +13,7 @@ type Config struct { Shell string `toml:"shell"` KeyMapping KeyMappingConfig `toml:"keys"` SearchURL string `toml:"search_url"` + MaxLines uint64 `toml:"max_lines"` } type KeyMappingConfig map[string]string diff --git a/config/defaults.go b/config/defaults.go index 9ff3544..2e84ff0 100644 --- a/config/defaults.go +++ b/config/defaults.go @@ -28,6 +28,7 @@ var DefaultConfig = Config{ }, KeyMapping: KeyMappingConfig(map[string]string{}), SearchURL: "https://www.google.com/search?q=$QUERY", + MaxLines: 1000, } func init() { diff --git a/gui/fonts.go b/gui/fonts.go index a060fd3..2c7166b 100644 --- a/gui/fonts.go +++ b/gui/fonts.go @@ -15,7 +15,7 @@ func (gui *GUI) getPackedFont(name string) (*glfont.Font, error) { return nil, fmt.Errorf("packaged font '%s' could not be read: %s", name, err) } - font, err := glfont.LoadFont(bytes.NewReader(fontBytes), gui.fontScale/gui.scale(), gui.width, gui.height) + font, err := glfont.LoadFont(bytes.NewReader(fontBytes), gui.fontScale*gui.dpiScale/gui.scale(), gui.Width(), gui.Height()) if err != nil { return nil, fmt.Errorf("font '%s' failed to load: %v", name, err) } diff --git a/gui/gui.go b/gui/gui.go index 6d33a8d..482e134 100644 --- a/gui/gui.go +++ b/gui/gui.go @@ -25,6 +25,7 @@ type GUI struct { terminal *terminal.Terminal width int //window width in pixels height int //window height in pixels + dpiScale float32 fontMap *FontMap fontScale float32 renderer *OpenGLRenderer @@ -37,6 +38,85 @@ type GUI struct { resizeLock *sync.Mutex } +func Min(x, y int) int { + if x < y { + return x + } + return y +} + +func Max(x, y int) int { + if x > y { + return x + } + return y +} + +func (g *GUI) GetMonitor() *glfw.Monitor { + + if g.window == nil { + panic("to determine current monitor the window must be set") + } + monitors := glfw.GetMonitors() + + if len(monitors) == 1 { + return glfw.GetPrimaryMonitor() + } + + x, y := g.window.GetPos() + w, h := g.window.GetSize() + var currentMonitor *glfw.Monitor + bestMatch := 0 + + for _, monitor := range monitors { + mode := monitor.GetVideoMode() + mx, my := monitor.GetPos() + overlap := Max(0, Min(x + w, mx + mode.Width) - Max(x, mx)) * + Max(0, Min(y + h, my + mode.Height) - Max(y, my)) + if bestMatch < overlap { + bestMatch = overlap + currentMonitor = monitor + } + } + + if currentMonitor == nil { + panic("was not able to resolve current monitor") + } + + return currentMonitor +} + +// RecalculateDpiScale calculates dpi scale in comparison with "standard" monitor's dpi values +func (g *GUI) RecalculateDpiScale() { + const standardDpi = 96 + const mmPerInch = 25.4 + m := g.GetMonitor() + widthMM, _ := m.GetPhysicalSize() + + if widthMM == 0 { + g.dpiScale = 1.0 + } else { + monitorDpi := float32(m.GetVideoMode().Width) / (float32(widthMM) / mmPerInch) + g.dpiScale = monitorDpi / standardDpi + } +} + +func (g *GUI) Width() int { + return int(float32(g.width) * g.dpiScale) +} + +func (g *GUI) SetWidth(width int) { + g.width = int(float32(width) / g.dpiScale) +} + +func (g *GUI) Height() int { + return int(float32(g.height) * g.dpiScale) +} + +func (g *GUI) SetHeight(height int) { + g.height = int(float32(height) / g.dpiScale) +} + func New(config *config.Config, terminal *terminal.Terminal, logger *zap.SugaredLogger) (*GUI, error) { shortcuts, err := config.KeyMapping.GenerateActionMap() @@ -49,6 +129,7 @@ func New(config *config.Config, terminal *terminal.Terminal, logger *zap.Sugared logger: logger, width: 800, height: 600, + dpiScale: 1, terminal: terminal, fontScale: 14.0, terminalAlpha: 1, @@ -73,14 +154,14 @@ func (gui *GUI) resize(w *glfw.Window, width int, height int) { gui.logger.Debugf("Initiating GUI resize to %dx%d", width, height) - gui.width = width - gui.height = height + gui.SetWidth(width) + gui.SetHeight(height) gui.logger.Debugf("Updating font resolutions...") gui.loadFonts() gui.logger.Debugf("Setting renderer area...") - gui.renderer.SetArea(0, 0, width, height) + gui.renderer.SetArea(0, 0, gui.Width(), gui.Height()) gui.logger.Debugf("Calculating size in cols/rows...") cols, rows := gui.renderer.GetTermSize() @@ -91,7 +172,7 @@ func (gui *GUI) resize(w *glfw.Window, width int, height int) { } gui.logger.Debugf("Setting viewport size...") - gl.Viewport(0, 0, int32(gui.width), int32(gui.height)) + gl.Viewport(0, 0, int32(gui.Width()), int32(gui.Height())) gui.terminal.SetCharSize(gui.renderer.cellWidth, gui.renderer.cellHeight) @@ -120,6 +201,8 @@ func (gui *GUI) Render() error { gui.logger.Debugf("Creating window...") var err error gui.window, err = gui.createWindow() + gui.RecalculateDpiScale() + gui.window.SetSize(gui.Width(), gui.Height()) if err != nil { return fmt.Errorf("Failed to create window: %s", err) } @@ -141,7 +224,7 @@ func (gui *GUI) Render() error { titleChan := make(chan bool, 1) - gui.renderer = NewOpenGLRenderer(gui.config, gui.fontMap, 0, 0, gui.width, gui.height, gui.colourAttr, program) + gui.renderer = NewOpenGLRenderer(gui.config, gui.fontMap, 0, 0, gui.Width(), gui.Height(), gui.colourAttr, program) gui.window.SetFramebufferSizeCallback(gui.resize) gui.window.SetKeyCallback(gui.key) @@ -158,8 +241,10 @@ func (gui *GUI) Render() error { } }) - w, h := gui.window.GetFramebufferSize() - gui.resize(gui.window, w, h) + { + w, h := gui.window.GetFramebufferSize() + gui.resize(gui.window, w, h) + } gui.logger.Debugf("Starting pty read handling...") @@ -401,7 +486,7 @@ func (gui *GUI) createWindow() (*glfw.Window, error) { return nil, fmt.Errorf("failed to create window, please update your graphics drivers and try again") } - window.SetSizeLimits(300, 150, 10000, 10000) + window.SetSizeLimits(int(300 * gui.dpiScale), int(150 * gui.dpiScale), 10000, 10000) window.MakeContextCurrent() window.Show() window.Focus() @@ -414,7 +499,7 @@ func (gui *GUI) createWindowWithOpenGLVersion(major int, minor int) (*glfw.Windo glfw.WindowHint(glfw.ContextVersionMajor, major) glfw.WindowHint(glfw.ContextVersionMinor, minor) - window, err := glfw.CreateWindow(gui.width, gui.height, "Terminal", nil, nil) + window, err := glfw.CreateWindow(gui.Width(), gui.Height(), "Terminal", nil, nil) if err != nil { e := err.Error() if i := strings.Index(e, ", got version "); i > -1 { @@ -425,7 +510,6 @@ func (gui *GUI) createWindowWithOpenGLVersion(major int, minor int) (*glfw.Windo if min, miErr := strconv.Atoi(v[1]); miErr == nil { return gui.createWindowWithOpenGLVersion(maj, min) } - } } } diff --git a/gui/renderer.go b/gui/renderer.go index c998a0d..5b08b20 100644 --- a/gui/renderer.go +++ b/gui/renderer.go @@ -36,7 +36,7 @@ type rectangle struct { cv uint32 colourAttr uint32 colour [3]float32 - points []float32 + points [18]float32 prog uint32 } @@ -49,10 +49,33 @@ func (r *OpenGLRenderer) CellHeight() float32 { } func (r *OpenGLRenderer) Clean() { + for _, rect := range r.rectangles { + rect.Free() + } + r.rectangles = map[[2]uint]*rectangle{} } -func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) *rectangle { +func (r *OpenGLRenderer) initRectangle(rect *rectangle, x float32, y float32, colourAttr uint32) { + + if rect == nil { + panic("rect pointer is nil") + } + + if rect.vao != 0 { + gl.DeleteVertexArrays(1, &rect.vao) + rect.vao = 0 + } + + if rect.vbo != 0 { + gl.DeleteBuffers(1, &rect.vbo) + rect.vbo = 0 + } + + if rect.cv != 0 { + gl.DeleteBuffers(1, &rect.cv) + rect.cv = 0 + } halfAreaWidth := float32(r.areaWidth / 2) halfAreaHeight := float32(r.areaHeight / 2) @@ -62,8 +85,7 @@ func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) * w := r.cellWidth / halfAreaWidth h := (r.cellHeight) / halfAreaHeight - rect := &rectangle{ - points: []float32{ + rect.points = [18]float32{ x, y, 0, x, y + h, 0, x + w, y + h, 0, @@ -71,17 +93,15 @@ func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) * x + w, y, 0, x, y, 0, x + w, y + h, 0, - }, - colourAttr: colourAttr, - prog: r.program, - } + } - gl.UseProgram(rect.prog) + rect.colourAttr = colourAttr + rect.prog = r.program // SHAPE gl.GenBuffers(1, &rect.vbo) gl.BindBuffer(gl.ARRAY_BUFFER, rect.vbo) - gl.BufferData(gl.ARRAY_BUFFER, 4*len(rect.points), gl.Ptr(rect.points), gl.STATIC_DRAW) + gl.BufferData(gl.ARRAY_BUFFER, 4*len(rect.points), gl.Ptr(&rect.points[0]), gl.STATIC_DRAW) gl.GenVertexArrays(1, &rect.vao) gl.BindVertexArray(rect.vao) @@ -94,6 +114,13 @@ func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) * gl.GenBuffers(1, &rect.cv) rect.setColour([3]float32{0, 1, 0}) +} + +func (r *OpenGLRenderer) newRectangle(x float32, y float32, colourAttr uint32) *rectangle { + + rect := &rectangle{} + + r.initRectangle(rect, x, y, colourAttr) return rect } @@ -132,6 +159,10 @@ func (rect *rectangle) Free() { gl.DeleteVertexArrays(1, &rect.vao) gl.DeleteBuffers(1, &rect.vbo) gl.DeleteBuffers(1, &rect.cv) + + rect.vao = 0 + rect.vbo = 0 + rect.cv = 0 } func NewOpenGLRenderer(config *config.Config, fontMap *FontMap, areaX int, areaY int, areaWidth int, areaHeight int, colourAttr uint32, program uint32) *OpenGLRenderer { @@ -167,21 +198,25 @@ func (r *OpenGLRenderer) SetArea(areaX int, areaY int, areaWidth int, areaHeight //= f.LineHeight() // includes vertical padding r.termCols = uint(math.Floor(float64(float32(r.areaWidth) / r.cellWidth))) r.termRows = uint(math.Floor(float64(float32(r.areaHeight) / r.cellHeight))) - r.rectangles = map[[2]uint]*rectangle{} + + r.Clean() } func (r *OpenGLRenderer) getRectangle(col uint, row uint) *rectangle { - - rect, ok := r.rectangles[[2]uint{col, row}] - if ok { - rect.Free() - } - x := float32(float32(col) * r.cellWidth) - y := float32(float32(row)*r.cellHeight) + r.cellHeight + y := float32(float32(row) * r.cellHeight) + r.cellHeight - r.rectangles[[2]uint{col, row}] = r.newRectangle(x, y, r.colourAttr) - return r.rectangles[[2]uint{col, row}] + coords := [2]uint{col, row} + + rect, ok := r.rectangles[coords] + if ok { + r.initRectangle(rect, x, y, r.colourAttr) + return rect + } else { + rect = r.newRectangle(x, y, r.colourAttr) + r.rectangles[coords] = rect + return rect + } } func (r *OpenGLRenderer) DrawCursor(col uint, row uint, colour config.Colour) { diff --git a/main.go b/main.go index 4d793e8..0f73a10 100644 --- a/main.go +++ b/main.go @@ -3,12 +3,10 @@ package main import ( "fmt" "os" - "os/exec" "runtime" - "syscall" - "github.com/kr/pty" "github.com/liamg/aminal/gui" + "github.com/liamg/aminal/platform" "github.com/liamg/aminal/terminal" "github.com/riywo/loginshell" ) @@ -26,7 +24,8 @@ func main() { defer logger.Sync() logger.Infof("Allocating pty...") - pty, tty, err := pty.Open() + + pty, err := platform.NewPty(80, 25) if err != nil { logger.Fatalf("Failed to allocate pty: %s", err) } @@ -43,12 +42,8 @@ func main() { os.Setenv("TERM", "xterm-256color") // controversial! easier than installing terminfo everywhere, but obviously going to be slightly different to xterm functionality, so we'll see... os.Setenv("COLORTERM", "truecolor") - shell := exec.Command(shellStr) - shell.Stdout = tty - shell.Stdin = tty - shell.Stderr = tty - shell.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true} - if err := shell.Start(); err != nil { + guestProcess, err := pty.CreateGuestProcess(shellStr) + if err != nil { pty.Close() logger.Fatalf("Failed to start your shell: %s", err) } @@ -60,8 +55,15 @@ func main() { if err != nil { logger.Fatalf("Cannot start: %s", err) } + + go func() { + if err := guestProcess.Wait(); err != nil { + logger.Fatalf("Failed to wait for guest process: %s", err) + } + g.Close() + }() + if err := g.Render(); err != nil { logger.Fatalf("Render error: %s", err) } - } diff --git a/platform/cmdProc.go b/platform/cmdProc.go new file mode 100644 index 0000000..aa4e50a --- /dev/null +++ b/platform/cmdProc.go @@ -0,0 +1,28 @@ +package platform + +import ( + "os/exec" +) + +type cmdProc struct { + cmd *exec.Cmd +} + +func newCmdProc(c *exec.Cmd) *cmdProc { + return &cmdProc{ + cmd: c, + } +} + +func (p *cmdProc) Wait() error { + return p.cmd.Wait() +} + +func (p *cmdProc) Close() error { + if p == nil || p.cmd == nil || p.cmd.Process == nil { + return nil + } + ret := p.cmd.Process.Kill() + p.cmd = nil + return ret +} diff --git a/platform/interfaces.go b/platform/interfaces.go new file mode 100644 index 0000000..a88967c --- /dev/null +++ b/platform/interfaces.go @@ -0,0 +1,22 @@ +package platform + +import ( + "io" +) + +// Process represents a child process by pid or HPROCESS in a platform-independent way +type Process interface { + io.Closer + + Wait() error + // TODO: make useful stuff here +} + +// Pty represents a pseudo-terminal either by pty/tty file pair or by HCON +type Pty interface { + io.ReadWriteCloser + + Resize(x int, y int) error + CreateGuestProcess(imagePath string) (Process, error) + GetPlatformDependentSettings() PlatformDependentSettings +} diff --git a/platform/settings.go b/platform/settings.go new file mode 100644 index 0000000..bbbeae3 --- /dev/null +++ b/platform/settings.go @@ -0,0 +1,6 @@ +package platform + +// PlatformDependentSettings Settings specific to the platform +type PlatformDependentSettings struct { + OSCTerminators map[rune]struct{} +} diff --git a/platform/unixpty.go b/platform/unixpty.go new file mode 100644 index 0000000..2f043f9 --- /dev/null +++ b/platform/unixpty.go @@ -0,0 +1,101 @@ +//+build !windows + +package platform + +import ( + "errors" + "os" + "os/exec" + "syscall" + "unsafe" + + "github.com/kr/pty" +) + +type unixPty struct { + pty *os.File + tty *os.File + platformDependentSettings PlatformDependentSettings +} + +type winsize struct { + Height uint16 + Width uint16 + x uint16 //ignored, but necessary for ioctl calls + y uint16 //ignored, but necessary for ioctl calls +} + +func (p *unixPty) Read(b []byte) (int, error) { + if p == nil || p.pty == nil { + return 0, errors.New("Attempted to read from a deallocated pty") + } + return p.pty.Read(b) +} + +func (p *unixPty) Write(b []byte) (int, error) { + if p == nil || p.pty == nil { + return 0, errors.New("Attempted to write to a deallocated pty") + } + return p.pty.Write(b) +} + +func (p *unixPty) Close() error { + if p == nil || p.pty == nil { + return nil + } + ret := p.pty.Close() + p.pty = nil + p.tty = nil + return ret +} + +func (p *unixPty) Resize(x, y int) error { + size := winsize{ + Height: uint16(y), + Width: uint16(x), + x: 0, + y: 0, + } + _, _, errno := syscall.Syscall(syscall.SYS_IOCTL, uintptr(p.pty.Fd()), + uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(&size))) + + if errno != 0 { + return errors.New(errno.Error()) + } + + return nil +} + +func (p *unixPty) CreateGuestProcess(imagePath string) (Process, error) { + if p == nil || p.tty == nil { + return nil, errors.New("Attempted to create a process on a deallocated pty") + } + shell := newCmdProc(exec.Command(imagePath)) + shell.cmd.Stdout = p.tty + shell.cmd.Stdin = p.tty + shell.cmd.Stderr = p.tty + shell.cmd.SysProcAttr = &syscall.SysProcAttr{Setctty: true, Setsid: true} + if err := shell.cmd.Start(); err != nil { + return nil, err + } + + return shell, nil +} + +func (pty *unixPty) GetPlatformDependentSettings() PlatformDependentSettings { + return pty.platformDependentSettings +} + +func NewPty(x, y int) (Pty, error) { + innerPty, innerTty, err := pty.Open() + if err != nil { + return nil, err + } + return &unixPty{ + pty: innerPty, + tty: innerTty, + platformDependentSettings: PlatformDependentSettings{ + OSCTerminators: map[rune]struct{}{0x07: {}, 0x5c: {}}, + }, + }, nil +} diff --git a/platform/vendor/github.com/MaxRis/w32/AUTHORS b/platform/vendor/github.com/MaxRis/w32/AUTHORS new file mode 100644 index 0000000..93ec5db --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/AUTHORS @@ -0,0 +1,19 @@ +# This is the official list of 'w32' authors for copyright purposes. + +# Names should be added to this file as +# Name or Organization +# The email address is not required for organizations. + +# Please keep the list sorted. + +# Contributors +# ============ + +Allen Dang +Benny Siegert +Bruno Bigras +Daniel Joos +Gerald Rosenberg +Liam Bowen +Michael Henke +Paul Maddox \ No newline at end of file diff --git a/platform/vendor/github.com/MaxRis/w32/LICENSE b/platform/vendor/github.com/MaxRis/w32/LICENSE new file mode 100644 index 0000000..9f36608 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2010-2012 The w32 Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The names of the authors may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/platform/vendor/github.com/MaxRis/w32/README.md b/platform/vendor/github.com/MaxRis/w32/README.md new file mode 100644 index 0000000..ed196e7 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/README.md @@ -0,0 +1,33 @@ +About w32 +========== + +w32 is a wrapper of windows apis for the Go Programming Language. + +It wraps win32 apis to "Go style" to make them easier to use. + +Setup +===== + +1. Make sure you have a working Go installation and build environment, + see this go-nuts post for details: + http://groups.google.com/group/golang-nuts/msg/5c87630a84f4fd0c + + Updated versions of the Windows Go build are available here: + http://code.google.com/p/gomingw/downloads/list + +2. Create a "gopath" directory if you do not have one yet and set the + GOPATH variable accordingly. For example: + mkdir -p go-externals/src + export GOPATH=${PWD}/go-externals + +3. go get github.com/AllenDang/w32 + +4. go install github.com/AllenDang/w32... + +Contribute +========== + +Contributions in form of design, code, documentation, bug reporting or other +ways you see fit are very welcome. + +Thank You! diff --git a/platform/vendor/github.com/MaxRis/w32/advapi32.go b/platform/vendor/github.com/MaxRis/w32/advapi32.go new file mode 100644 index 0000000..10e1416 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/advapi32.go @@ -0,0 +1,389 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "errors" + "fmt" + "syscall" + "unsafe" +) + +var ( + modadvapi32 = syscall.NewLazyDLL("advapi32.dll") + + // procRegSetKeyValue = modadvapi32.NewProc("RegSetKeyValueW") + procCloseEventLog = modadvapi32.NewProc("CloseEventLog") + procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") + procControlService = modadvapi32.NewProc("ControlService") + procControlTrace = modadvapi32.NewProc("ControlTraceW") + procInitializeSecurityDescriptor = modadvapi32.NewProc("InitializeSecurityDescriptor") + procOpenEventLog = modadvapi32.NewProc("OpenEventLogW") + procOpenSCManager = modadvapi32.NewProc("OpenSCManagerW") + procOpenService = modadvapi32.NewProc("OpenServiceW") + procReadEventLog = modadvapi32.NewProc("ReadEventLogW") + procRegCloseKey = modadvapi32.NewProc("RegCloseKey") + procRegCreateKeyEx = modadvapi32.NewProc("RegCreateKeyExW") + procRegEnumKeyEx = modadvapi32.NewProc("RegEnumKeyExW") + procRegGetValue = modadvapi32.NewProc("RegGetValueW") + procRegOpenKeyEx = modadvapi32.NewProc("RegOpenKeyExW") + procRegSetValueEx = modadvapi32.NewProc("RegSetValueExW") + procSetSecurityDescriptorDacl = modadvapi32.NewProc("SetSecurityDescriptorDacl") + procStartService = modadvapi32.NewProc("StartServiceW") + procStartTrace = modadvapi32.NewProc("StartTraceW") +) + +var ( + SystemTraceControlGuid = GUID{ + 0x9e814aad, + 0x3204, + 0x11d2, + [8]byte{0x9a, 0x82, 0x00, 0x60, 0x08, 0xa8, 0x69, 0x39}, + } +) + +func RegCreateKey(hKey HKEY, subKey string) HKEY { + var result HKEY + ret, _, _ := procRegCreateKeyEx.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(0), + uintptr(0), + uintptr(0), + uintptr(KEY_ALL_ACCESS), + uintptr(0), + uintptr(unsafe.Pointer(&result)), + uintptr(0)) + _ = ret + return result +} + +func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY { + var result HKEY + ret, _, _ := procRegOpenKeyEx.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(0), + uintptr(samDesired), + uintptr(unsafe.Pointer(&result))) + + if ret != ERROR_SUCCESS { + panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired)) + } + return result +} + +func RegCloseKey(hKey HKEY) error { + var err error + ret, _, _ := procRegCloseKey.Call( + uintptr(hKey)) + + if ret != ERROR_SUCCESS { + err = errors.New("RegCloseKey failed") + } + return err +} + +func RegGetRaw(hKey HKEY, subKey string, value string) []byte { + var bufLen uint32 + var valptr unsafe.Pointer + if len(value) > 0 { + valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value)) + } + procRegGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(valptr), + uintptr(RRF_RT_ANY), + 0, + 0, + uintptr(unsafe.Pointer(&bufLen))) + + if bufLen == 0 { + return nil + } + + buf := make([]byte, bufLen) + ret, _, _ := procRegGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(valptr), + uintptr(RRF_RT_ANY), + 0, + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&bufLen))) + + if ret != ERROR_SUCCESS { + return nil + } + + return buf +} + +func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) { + var lptr, vptr unsafe.Pointer + if len(subKey) > 0 { + lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) + } + if len(value) > 0 { + vptr = unsafe.Pointer(&value[0]) + } + ret, _, _ := procRegSetValueEx.Call( + uintptr(hKey), + uintptr(lptr), + uintptr(0), + uintptr(REG_BINARY), + uintptr(vptr), + uintptr(len(value))) + + return int(ret) +} + +func RegGetString(hKey HKEY, subKey string, value string) string { + var bufLen uint32 + procRegGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), + uintptr(RRF_RT_REG_SZ), + 0, + 0, + uintptr(unsafe.Pointer(&bufLen))) + + if bufLen == 0 { + return "" + } + + buf := make([]uint16, bufLen) + ret, _, _ := procRegGetValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), + uintptr(RRF_RT_REG_SZ), + 0, + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&bufLen))) + + if ret != ERROR_SUCCESS { + return "" + } + + return syscall.UTF16ToString(buf) +} + +/* +func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType uint32, data uintptr, cbData uint16) (errno int) { + ret, _, _ := procRegSetKeyValue.Call( + uintptr(hKey), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))), + uintptr(dwType), + data, + uintptr(cbData)) + + return int(ret) +} +*/ + +func RegEnumKeyEx(hKey HKEY, index uint32) string { + var bufLen uint32 = 255 + buf := make([]uint16, bufLen) + procRegEnumKeyEx.Call( + uintptr(hKey), + uintptr(index), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(&bufLen)), + 0, + 0, + 0, + 0) + return syscall.UTF16ToString(buf) +} + +func OpenEventLog(servername string, sourcename string) HANDLE { + ret, _, _ := procOpenEventLog.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename)))) + + return HANDLE(ret) +} + +func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool { + ret, _, _ := procReadEventLog.Call( + uintptr(eventlog), + uintptr(readflags), + uintptr(recordoffset), + uintptr(unsafe.Pointer(&buffer[0])), + uintptr(numberofbytestoread), + uintptr(unsafe.Pointer(bytesread)), + uintptr(unsafe.Pointer(minnumberofbytesneeded))) + + return ret != 0 +} + +func CloseEventLog(eventlog HANDLE) bool { + ret, _, _ := procCloseEventLog.Call( + uintptr(eventlog)) + + return ret != 0 +} + +func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) { + var p1, p2 uintptr + if len(lpMachineName) > 0 { + p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName))) + } + if len(lpDatabaseName) > 0 { + p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName))) + } + ret, _, _ := procOpenSCManager.Call( + p1, + p2, + uintptr(dwDesiredAccess)) + + if ret == 0 { + return 0, syscall.GetLastError() + } + + return HANDLE(ret), nil +} + +func CloseServiceHandle(hSCObject HANDLE) error { + ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject)) + if ret == 0 { + return syscall.GetLastError() + } + return nil +} + +func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) { + ret, _, _ := procOpenService.Call( + uintptr(hSCManager), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))), + uintptr(dwDesiredAccess)) + + if ret == 0 { + return 0, syscall.GetLastError() + } + + return HANDLE(ret), nil +} + +func StartService(hService HANDLE, lpServiceArgVectors []string) error { + l := len(lpServiceArgVectors) + var ret uintptr + if l == 0 { + ret, _, _ = procStartService.Call( + uintptr(hService), + 0, + 0) + } else { + lpArgs := make([]uintptr, l) + for i := 0; i < l; i++ { + lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i]))) + } + + ret, _, _ = procStartService.Call( + uintptr(hService), + uintptr(l), + uintptr(unsafe.Pointer(&lpArgs[0]))) + } + + if ret == 0 { + return syscall.GetLastError() + } + + return nil +} + +func ControlService(hService HANDLE, dwControl uint32, lpServiceStatus *SERVICE_STATUS) bool { + if lpServiceStatus == nil { + panic("ControlService:lpServiceStatus cannot be nil") + } + + ret, _, _ := procControlService.Call( + uintptr(hService), + uintptr(dwControl), + uintptr(unsafe.Pointer(lpServiceStatus))) + + return ret != 0 +} + +func ControlTrace(hTrace TRACEHANDLE, lpSessionName string, props *EVENT_TRACE_PROPERTIES, dwControl uint32) (success bool, e error) { + + ret, _, _ := procControlTrace.Call( + uintptr(unsafe.Pointer(hTrace)), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpSessionName))), + uintptr(unsafe.Pointer(props)), + uintptr(dwControl)) + + if ret == ERROR_SUCCESS { + return true, nil + } + e = errors.New(fmt.Sprintf("error: 0x%x", ret)) + return +} + +func StartTrace(lpSessionName string, props *EVENT_TRACE_PROPERTIES) (hTrace TRACEHANDLE, e error) { + + ret, _, _ := procStartTrace.Call( + uintptr(unsafe.Pointer(&hTrace)), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpSessionName))), + uintptr(unsafe.Pointer(props))) + + if ret == ERROR_SUCCESS { + return + } + e = errors.New(fmt.Sprintf("error: 0x%x", ret)) + return +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa378863(v=vs.85).aspx +func InitializeSecurityDescriptor(rev uint16) (pSecurityDescriptor *SECURITY_DESCRIPTOR, e error) { + + pSecurityDescriptor = &SECURITY_DESCRIPTOR{} + + ret, _, _ := procInitializeSecurityDescriptor.Call( + uintptr(unsafe.Pointer(pSecurityDescriptor)), + uintptr(rev), + ) + + if ret != 0 { + return + } + e = syscall.GetLastError() + return +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa379583(v=vs.85).aspx +func SetSecurityDescriptorDacl(pSecurityDescriptor *SECURITY_DESCRIPTOR, pDacl *ACL) (e error) { + + if pSecurityDescriptor == nil { + return errors.New("null descriptor") + } + + var ret uintptr + if pDacl == nil { + ret, _, _ = procSetSecurityDescriptorDacl.Call( + uintptr(unsafe.Pointer(pSecurityDescriptor)), + uintptr(1), // DaclPresent + uintptr(0), // pDacl + uintptr(0), // DaclDefaulted + ) + } else { + ret, _, _ = procSetSecurityDescriptorDacl.Call( + uintptr(unsafe.Pointer(pSecurityDescriptor)), + uintptr(1), // DaclPresent + uintptr(unsafe.Pointer(pDacl)), + uintptr(0), //DaclDefaulted + ) + } + + if ret != 0 { + return + } + e = syscall.GetLastError() + return +} diff --git a/platform/vendor/github.com/MaxRis/w32/advapi32_constants.go b/platform/vendor/github.com/MaxRis/w32/advapi32_constants.go new file mode 100644 index 0000000..fa3c767 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/advapi32_constants.go @@ -0,0 +1,300 @@ +package w32 + +// Registry predefined keys +const ( + HKEY_CLASSES_ROOT HKEY = 0x80000000 + HKEY_CURRENT_USER HKEY = 0x80000001 + HKEY_LOCAL_MACHINE HKEY = 0x80000002 + HKEY_USERS HKEY = 0x80000003 + HKEY_PERFORMANCE_DATA HKEY = 0x80000004 + HKEY_CURRENT_CONFIG HKEY = 0x80000005 + HKEY_DYN_DATA HKEY = 0x80000006 +) + +// Registry Key Security and Access Rights +const ( + KEY_ALL_ACCESS = 0xF003F + KEY_CREATE_SUB_KEY = 0x0004 + KEY_ENUMERATE_SUB_KEYS = 0x0008 + KEY_NOTIFY = 0x0010 + KEY_QUERY_VALUE = 0x0001 + KEY_SET_VALUE = 0x0002 + KEY_READ = 0x20019 + KEY_WRITE = 0x20006 +) + +const ( + NFR_ANSI = 1 + NFR_UNICODE = 2 + NF_QUERY = 3 + NF_REQUERY = 4 +) + +// Registry value types +const ( + RRF_RT_REG_NONE = 0x00000001 + RRF_RT_REG_SZ = 0x00000002 + RRF_RT_REG_EXPAND_SZ = 0x00000004 + RRF_RT_REG_BINARY = 0x00000008 + RRF_RT_REG_DWORD = 0x00000010 + RRF_RT_REG_MULTI_SZ = 0x00000020 + RRF_RT_REG_QWORD = 0x00000040 + RRF_RT_DWORD = (RRF_RT_REG_BINARY | RRF_RT_REG_DWORD) + RRF_RT_QWORD = (RRF_RT_REG_BINARY | RRF_RT_REG_QWORD) + RRF_RT_ANY = 0x0000ffff + RRF_NOEXPAND = 0x10000000 + RRF_ZEROONFAILURE = 0x20000000 + REG_PROCESS_APPKEY = 0x00000001 + REG_MUI_STRING_TRUNCATE = 0x00000001 +) + +// Service Control Manager object specific access types +const ( + SC_MANAGER_CONNECT = 0x0001 + SC_MANAGER_CREATE_SERVICE = 0x0002 + SC_MANAGER_ENUMERATE_SERVICE = 0x0004 + SC_MANAGER_LOCK = 0x0008 + SC_MANAGER_QUERY_LOCK_STATUS = 0x0010 + SC_MANAGER_MODIFY_BOOT_CONFIG = 0x0020 + SC_MANAGER_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE | SC_MANAGER_ENUMERATE_SERVICE | SC_MANAGER_LOCK | SC_MANAGER_QUERY_LOCK_STATUS | SC_MANAGER_MODIFY_BOOT_CONFIG +) + +// Service Types (Bit Mask) +const ( + SERVICE_KERNEL_DRIVER = 0x00000001 + SERVICE_FILE_SYSTEM_DRIVER = 0x00000002 + SERVICE_ADAPTER = 0x00000004 + SERVICE_RECOGNIZER_DRIVER = 0x00000008 + SERVICE_DRIVER = SERVICE_KERNEL_DRIVER | SERVICE_FILE_SYSTEM_DRIVER | SERVICE_RECOGNIZER_DRIVER + SERVICE_WIN32_OWN_PROCESS = 0x00000010 + SERVICE_WIN32_SHARE_PROCESS = 0x00000020 + SERVICE_WIN32 = SERVICE_WIN32_OWN_PROCESS | SERVICE_WIN32_SHARE_PROCESS + SERVICE_INTERACTIVE_PROCESS = 0x00000100 + SERVICE_TYPE_ALL = SERVICE_WIN32 | SERVICE_ADAPTER | SERVICE_DRIVER | SERVICE_INTERACTIVE_PROCESS +) + +// Service State -- for CurrentState +const ( + SERVICE_STOPPED = 0x00000001 + SERVICE_START_PENDING = 0x00000002 + SERVICE_STOP_PENDING = 0x00000003 + SERVICE_RUNNING = 0x00000004 + SERVICE_CONTINUE_PENDING = 0x00000005 + SERVICE_PAUSE_PENDING = 0x00000006 + SERVICE_PAUSED = 0x00000007 +) + +// Controls Accepted (Bit Mask) +const ( + SERVICE_ACCEPT_STOP = 0x00000001 + SERVICE_ACCEPT_PAUSE_CONTINUE = 0x00000002 + SERVICE_ACCEPT_SHUTDOWN = 0x00000004 + SERVICE_ACCEPT_PARAMCHANGE = 0x00000008 + SERVICE_ACCEPT_NETBINDCHANGE = 0x00000010 + SERVICE_ACCEPT_HARDWAREPROFILECHANGE = 0x00000020 + SERVICE_ACCEPT_POWEREVENT = 0x00000040 + SERVICE_ACCEPT_SESSIONCHANGE = 0x00000080 + SERVICE_ACCEPT_PRESHUTDOWN = 0x00000100 + SERVICE_ACCEPT_TIMECHANGE = 0x00000200 + SERVICE_ACCEPT_TRIGGEREVENT = 0x00000400 +) + +// Service object specific access type +const ( + SERVICE_QUERY_CONFIG = 0x0001 + SERVICE_CHANGE_CONFIG = 0x0002 + SERVICE_QUERY_STATUS = 0x0004 + SERVICE_ENUMERATE_DEPENDENTS = 0x0008 + SERVICE_START = 0x0010 + SERVICE_STOP = 0x0020 + SERVICE_PAUSE_CONTINUE = 0x0040 + SERVICE_INTERROGATE = 0x0080 + SERVICE_USER_DEFINED_CONTROL = 0x0100 + + SERVICE_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | + SERVICE_QUERY_CONFIG | + SERVICE_CHANGE_CONFIG | + SERVICE_QUERY_STATUS | + SERVICE_ENUMERATE_DEPENDENTS | + SERVICE_START | + SERVICE_STOP | + SERVICE_PAUSE_CONTINUE | + SERVICE_INTERROGATE | + SERVICE_USER_DEFINED_CONTROL +) + +const ( + KERNEL_LOGGER_NAME = "NT Kernel Logger" +) + +// WNODE flags, for ETW (Event Tracing for Windows) / WMI +const ( + WNODE_FLAG_ALL_DATA = 0x00000001 + WNODE_FLAG_SINGLE_INSTANCE = 0x00000002 + WNODE_FLAG_SINGLE_ITEM = 0x00000004 + WNODE_FLAG_EVENT_ITEM = 0x00000008 + WNODE_FLAG_FIXED_INSTANCE_SIZE = 0x00000010 + WNODE_FLAG_TOO_SMALL = 0x00000020 + WNODE_FLAG_INSTANCES_SAME = 0x00000040 + WNODE_FLAG_STATIC_INSTANCE_NAMES = 0x00000080 + WNODE_FLAG_INTERNAL = 0x00000100 + WNODE_FLAG_USE_TIMESTAMP = 0x00000200 + WNODE_FLAG_PERSIST_EVENT = 0x00000400 + WNODE_FLAG_EVENT_REFERENCE = 0x00002000 + WNODE_FLAG_ANSI_INSTANCENAMES = 0x00004000 + WNODE_FLAG_METHOD_ITEM = 0x00008000 + WNODE_FLAG_PDO_INSTANCE_NAMES = 0x00010000 + WNODE_FLAG_TRACED_GUID = 0x00020000 + WNODE_FLAG_LOG_WNODE = 0x00040000 + WNODE_FLAG_USE_GUID_PTR = 0x00080000 + WNODE_FLAG_USE_MOF_PTR = 0x00100000 + WNODE_FLAG_NO_HEADER = 0x00200000 + WNODE_FLAG_SEVERITY_MASK = 0xff000000 +) + +// ETW flags and types etc +const ( + EVENT_TRACE_TYPE_INFO = 0x00 + EVENT_TRACE_TYPE_START = 0x01 + EVENT_TRACE_TYPE_END = 0x02 + EVENT_TRACE_TYPE_STOP = 0x02 + EVENT_TRACE_TYPE_DC_START = 0x03 + EVENT_TRACE_TYPE_DC_END = 0x04 + EVENT_TRACE_TYPE_EXTENSION = 0x05 + EVENT_TRACE_TYPE_REPLY = 0x06 + EVENT_TRACE_TYPE_DEQUEUE = 0x07 + EVENT_TRACE_TYPE_RESUME = 0x07 + EVENT_TRACE_TYPE_CHECKPOINT = 0x08 + EVENT_TRACE_TYPE_SUSPEND = 0x08 + EVENT_TRACE_TYPE_WINEVT_SEND = 0x09 + EVENT_TRACE_TYPE_WINEVT_RECEIVE = 0XF0 + TRACE_LEVEL_NONE = 0 + TRACE_LEVEL_CRITICAL = 1 + TRACE_LEVEL_FATAL = 1 + TRACE_LEVEL_ERROR = 2 + TRACE_LEVEL_WARNING = 3 + TRACE_LEVEL_INFORMATION = 4 + TRACE_LEVEL_VERBOSE = 5 + TRACE_LEVEL_RESERVED6 = 6 + TRACE_LEVEL_RESERVED7 = 7 + TRACE_LEVEL_RESERVED8 = 8 + TRACE_LEVEL_RESERVED9 = 9 + EVENT_TRACE_TYPE_LOAD = 0x0A + EVENT_TRACE_TYPE_IO_READ = 0x0A + EVENT_TRACE_TYPE_IO_WRITE = 0x0B + EVENT_TRACE_TYPE_IO_READ_INIT = 0x0C + EVENT_TRACE_TYPE_IO_WRITE_INIT = 0x0D + EVENT_TRACE_TYPE_IO_FLUSH = 0x0E + EVENT_TRACE_TYPE_IO_FLUSH_INIT = 0x0F + EVENT_TRACE_TYPE_MM_TF = 0x0A + EVENT_TRACE_TYPE_MM_DZF = 0x0B + EVENT_TRACE_TYPE_MM_COW = 0x0C + EVENT_TRACE_TYPE_MM_GPF = 0x0D + EVENT_TRACE_TYPE_MM_HPF = 0x0E + EVENT_TRACE_TYPE_MM_AV = 0x0F + EVENT_TRACE_TYPE_SEND = 0x0A + EVENT_TRACE_TYPE_RECEIVE = 0x0B + EVENT_TRACE_TYPE_CONNECT = 0x0C + EVENT_TRACE_TYPE_DISCONNECT = 0x0D + EVENT_TRACE_TYPE_RETRANSMIT = 0x0E + EVENT_TRACE_TYPE_ACCEPT = 0x0F + EVENT_TRACE_TYPE_RECONNECT = 0x10 + EVENT_TRACE_TYPE_CONNFAIL = 0x11 + EVENT_TRACE_TYPE_COPY_TCP = 0x12 + EVENT_TRACE_TYPE_COPY_ARP = 0x13 + EVENT_TRACE_TYPE_ACKFULL = 0x14 + EVENT_TRACE_TYPE_ACKPART = 0x15 + EVENT_TRACE_TYPE_ACKDUP = 0x16 + EVENT_TRACE_TYPE_GUIDMAP = 0x0A + EVENT_TRACE_TYPE_CONFIG = 0x0B + EVENT_TRACE_TYPE_SIDINFO = 0x0C + EVENT_TRACE_TYPE_SECURITY = 0x0D + EVENT_TRACE_TYPE_REGCREATE = 0x0A + EVENT_TRACE_TYPE_REGOPEN = 0x0B + EVENT_TRACE_TYPE_REGDELETE = 0x0C + EVENT_TRACE_TYPE_REGQUERY = 0x0D + EVENT_TRACE_TYPE_REGSETVALUE = 0x0E + EVENT_TRACE_TYPE_REGDELETEVALUE = 0x0F + EVENT_TRACE_TYPE_REGQUERYVALUE = 0x10 + EVENT_TRACE_TYPE_REGENUMERATEKEY = 0x11 + EVENT_TRACE_TYPE_REGENUMERATEVALUEKEY = 0x12 + EVENT_TRACE_TYPE_REGQUERYMULTIPLEVALUE = 0x13 + EVENT_TRACE_TYPE_REGSETINFORMATION = 0x14 + EVENT_TRACE_TYPE_REGFLUSH = 0x15 + EVENT_TRACE_TYPE_REGKCBCREATE = 0x16 + EVENT_TRACE_TYPE_REGKCBDELETE = 0x17 + EVENT_TRACE_TYPE_REGKCBRUNDOWNBEGIN = 0x18 + EVENT_TRACE_TYPE_REGKCBRUNDOWNEND = 0x19 + EVENT_TRACE_TYPE_REGVIRTUALIZE = 0x1A + EVENT_TRACE_TYPE_REGCLOSE = 0x1B + EVENT_TRACE_TYPE_REGSETSECURITY = 0x1C + EVENT_TRACE_TYPE_REGQUERYSECURITY = 0x1D + EVENT_TRACE_TYPE_REGCOMMIT = 0x1E + EVENT_TRACE_TYPE_REGPREPARE = 0x1F + EVENT_TRACE_TYPE_REGROLLBACK = 0x20 + EVENT_TRACE_TYPE_REGMOUNTHIVE = 0x21 + EVENT_TRACE_TYPE_CONFIG_CPU = 0x0A + EVENT_TRACE_TYPE_CONFIG_PHYSICALDISK = 0x0B + EVENT_TRACE_TYPE_CONFIG_LOGICALDISK = 0x0C + EVENT_TRACE_TYPE_CONFIG_NIC = 0x0D + EVENT_TRACE_TYPE_CONFIG_VIDEO = 0x0E + EVENT_TRACE_TYPE_CONFIG_SERVICES = 0x0F + EVENT_TRACE_TYPE_CONFIG_POWER = 0x10 + EVENT_TRACE_TYPE_CONFIG_NETINFO = 0x11 + EVENT_TRACE_TYPE_CONFIG_IRQ = 0x15 + EVENT_TRACE_TYPE_CONFIG_PNP = 0x16 + EVENT_TRACE_TYPE_CONFIG_IDECHANNEL = 0x17 + EVENT_TRACE_TYPE_CONFIG_PLATFORM = 0x19 + EVENT_TRACE_FLAG_PROCESS = 0x00000001 + EVENT_TRACE_FLAG_THREAD = 0x00000002 + EVENT_TRACE_FLAG_IMAGE_LOAD = 0x00000004 + EVENT_TRACE_FLAG_DISK_IO = 0x00000100 + EVENT_TRACE_FLAG_DISK_FILE_IO = 0x00000200 + EVENT_TRACE_FLAG_MEMORY_PAGE_FAULTS = 0x00001000 + EVENT_TRACE_FLAG_MEMORY_HARD_FAULTS = 0x00002000 + EVENT_TRACE_FLAG_NETWORK_TCPIP = 0x00010000 + EVENT_TRACE_FLAG_REGISTRY = 0x00020000 + EVENT_TRACE_FLAG_DBGPRINT = 0x00040000 + EVENT_TRACE_FLAG_PROCESS_COUNTERS = 0x00000008 + EVENT_TRACE_FLAG_CSWITCH = 0x00000010 + EVENT_TRACE_FLAG_DPC = 0x00000020 + EVENT_TRACE_FLAG_INTERRUPT = 0x00000040 + EVENT_TRACE_FLAG_SYSTEMCALL = 0x00000080 + EVENT_TRACE_FLAG_DISK_IO_INIT = 0x00000400 + EVENT_TRACE_FLAG_ALPC = 0x00100000 + EVENT_TRACE_FLAG_SPLIT_IO = 0x00200000 + EVENT_TRACE_FLAG_DRIVER = 0x00800000 + EVENT_TRACE_FLAG_PROFILE = 0x01000000 + EVENT_TRACE_FLAG_FILE_IO = 0x02000000 + EVENT_TRACE_FLAG_FILE_IO_INIT = 0x04000000 + EVENT_TRACE_FLAG_DISPATCHER = 0x00000800 + EVENT_TRACE_FLAG_VIRTUAL_ALLOC = 0x00004000 + EVENT_TRACE_FLAG_EXTENSION = 0x80000000 + EVENT_TRACE_FLAG_FORWARD_WMI = 0x40000000 + EVENT_TRACE_FLAG_ENABLE_RESERVE = 0x20000000 + EVENT_TRACE_FILE_MODE_NONE = 0x00000000 + EVENT_TRACE_FILE_MODE_SEQUENTIAL = 0x00000001 + EVENT_TRACE_FILE_MODE_CIRCULAR = 0x00000002 + EVENT_TRACE_FILE_MODE_APPEND = 0x00000004 + EVENT_TRACE_REAL_TIME_MODE = 0x00000100 + EVENT_TRACE_DELAY_OPEN_FILE_MODE = 0x00000200 + EVENT_TRACE_BUFFERING_MODE = 0x00000400 + EVENT_TRACE_PRIVATE_LOGGER_MODE = 0x00000800 + EVENT_TRACE_ADD_HEADER_MODE = 0x00001000 + EVENT_TRACE_USE_GLOBAL_SEQUENCE = 0x00004000 + EVENT_TRACE_USE_LOCAL_SEQUENCE = 0x00008000 + EVENT_TRACE_RELOG_MODE = 0x00010000 + EVENT_TRACE_USE_PAGED_MEMORY = 0x01000000 + EVENT_TRACE_FILE_MODE_NEWFILE = 0x00000008 + EVENT_TRACE_FILE_MODE_PREALLOCATE = 0x00000020 + EVENT_TRACE_NONSTOPPABLE_MODE = 0x00000040 + EVENT_TRACE_SECURE_MODE = 0x00000080 + EVENT_TRACE_USE_KBYTES_FOR_SIZE = 0x00002000 + EVENT_TRACE_PRIVATE_IN_PROC = 0x00020000 + EVENT_TRACE_MODE_RESERVED = 0x00100000 + EVENT_TRACE_NO_PER_PROCESSOR_BUFFERING = 0x10000000 + EVENT_TRACE_CONTROL_QUERY = 0 + EVENT_TRACE_CONTROL_STOP = 1 + EVENT_TRACE_CONTROL_UPDATE = 2 + EVENT_TRACE_CONTROL_FLUSH = 3 +) diff --git a/platform/vendor/github.com/MaxRis/w32/advapi32_test.go b/platform/vendor/github.com/MaxRis/w32/advapi32_test.go new file mode 100644 index 0000000..72a9198 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/advapi32_test.go @@ -0,0 +1,41 @@ +package w32 + +import ( + "testing" +) + +func TestInitializeSecurityDescriptor(t *testing.T) { + sd, err := InitializeSecurityDescriptor(1) + if err != nil { + t.Errorf("Failed: %v", err) + } + t.Logf("SD:\n%#v\n", *sd) +} + +func TestSetSecurityDescriptorDacl(t *testing.T) { + + sd, err := InitializeSecurityDescriptor(1) + if err != nil { + t.Errorf("Failed to initialize: %v", err) + } + err = SetSecurityDescriptorDacl(sd, nil) + if err != nil { + t.Errorf("Failed to set NULL DACL: %v", err) + } + t.Logf("[OK] Set NULL DACL") + + empty := &ACL{ + AclRevision: 4, + Sbz1: 0, + AclSize: 4, + AceCount: 0, + Sbz2: 0, + } + err = SetSecurityDescriptorDacl(sd, empty) + if err != nil { + t.Errorf("Failed to set empty DACL: %v", err) + } + t.Logf("[OK] Set empty DACL") + t.Logf("SD:\n%#v\n", *sd) + +} diff --git a/platform/vendor/github.com/MaxRis/w32/advapi32_typedef.go b/platform/vendor/github.com/MaxRis/w32/advapi32_typedef.go new file mode 100644 index 0000000..3a4308c --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/advapi32_typedef.go @@ -0,0 +1,122 @@ +package w32 + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa374931(v=vs.85).aspx +type ACL struct { + AclRevision byte + Sbz1 byte + AclSize uint16 + AceCount uint16 + Sbz2 uint16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa379561(v=vs.85).aspx + +type SECURITY_DESCRIPTOR_CONTROL uint16 + +type SECURITY_DESCRIPTOR struct { + Revision byte + Sbz1 byte + Control SECURITY_DESCRIPTOR_CONTROL + Owner uintptr + Group uintptr + Sacl *ACL + Dacl *ACL +} + +type SID_IDENTIFIER_AUTHORITY struct { + Value [6]byte +} + +// typedef struct _SID // 4 elements, 0xC bytes (sizeof) +// { +// /*0x000*/ UINT8 Revision; +// /*0x001*/ UINT8 SubAuthorityCount; +// /*0x002*/ struct _SID_IDENTIFIER_AUTHORITY IdentifierAuthority; // 1 elements, 0x6 bytes (sizeof) +// /*0x008*/ ULONG32 SubAuthority[1]; +// }SID, *PSID; +type SID struct { + Revision byte + SubAuthorityCount byte + IdentifierAuthority SID_IDENTIFIER_AUTHORITY + SubAuthority uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363646.aspx +type EVENTLOGRECORD struct { + Length uint32 + Reserved uint32 + RecordNumber uint32 + TimeGenerated uint32 + TimeWritten uint32 + EventID uint32 + EventType uint16 + NumStrings uint16 + EventCategory uint16 + ReservedFlags uint16 + ClosingRecordNumber uint32 + StringOffset uint32 + UserSidLength uint32 + UserSidOffset uint32 + DataLength uint32 + DataOffset uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms685996.aspx +type SERVICE_STATUS struct { + DwServiceType uint32 + DwCurrentState uint32 + DwControlsAccepted uint32 + DwWin32ExitCode uint32 + DwServiceSpecificExitCode uint32 + DwCheckPoint uint32 + DwWaitHint uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa364160(v=vs.85).aspx +type WNODE_HEADER struct { + BufferSize uint32 + ProviderId uint32 + HistoricalContext uint64 + KernelHandle HANDLE + Guid GUID + ClientContext uint32 + Flags uint32 +} + +// These partially compensate for the anonymous unions we removed, but there +// are no setters. +func (w WNODE_HEADER) TimeStamp() uint64 { + // TODO: Cast to the stupid LARGE_INTEGER struct which is, itself, nasty + // and union-y + return uint64(w.KernelHandle) +} + +func (w WNODE_HEADER) Version() uint32 { + return uint32(w.HistoricalContext >> 32) +} + +func (w WNODE_HEADER) Linkage() uint32 { + return uint32(w.HistoricalContext) +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa363784(v=vs.85).aspx +type EVENT_TRACE_PROPERTIES struct { + Wnode WNODE_HEADER + BufferSize uint32 + MinimumBuffers uint32 + MaximumBuffers uint32 + MaximumFileSize uint32 + LogFileMode uint32 + FlushTimer uint32 + EnableFlags uint32 + AgeLimit int32 + NumberOfBuffers uint32 + FreeBuffers uint32 + EventsLost uint32 + BuffersWritten uint32 + LogBuffersLost uint32 + RealTimeBuffersLost uint32 + LoggerThreadId HANDLE + LogFileNameOffset uint32 + LoggerNameOffset uint32 +} diff --git a/platform/vendor/github.com/MaxRis/w32/alpc.go b/platform/vendor/github.com/MaxRis/w32/alpc.go new file mode 100644 index 0000000..408d47e --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/alpc.go @@ -0,0 +1,304 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "fmt" + // "github.com/davecgh/go-spew/spew" + "syscall" + "unsafe" +) + +var ( + modntdll = syscall.NewLazyDLL("ntdll.dll") + + procAlpcGetMessageAttribute = modntdll.NewProc("AlpcGetMessageAttribute") + procNtAlpcAcceptConnectPort = modntdll.NewProc("NtAlpcAcceptConnectPort") + procNtAlpcCancelMessage = modntdll.NewProc("NtAlpcCancelMessage") + procNtAlpcConnectPort = modntdll.NewProc("NtAlpcConnectPort") + procNtAlpcCreatePort = modntdll.NewProc("NtAlpcCreatePort") + procNtAlpcDisconnectPort = modntdll.NewProc("NtAlpcDisconnectPort") + procNtAlpcSendWaitReceivePort = modntdll.NewProc("NtAlpcSendWaitReceivePort") + procRtlCreateUnicodeStringFromAsciiz = modntdll.NewProc("RtlCreateUnicodeStringFromAsciiz") +) + +//func RtlCreateUnicodeStringFromAsciiz(s string) (us UNICODE_STRING, e error) { +// +// cs := C.CString(s) +// defer C.free(unsafe.Pointer(cs)) +// +// ret, _, lastErr := procRtlCreateUnicodeStringFromAsciiz.Call( +// uintptr(unsafe.Pointer(&us)), +// uintptr(unsafe.Pointer(cs)), +// ) +// +// if ret != 1 { // ret is a BOOL ( I think ) +// e = lastErr +// } +// +// return +//} + +//func newUnicodeString(s string) (us UNICODE_STRING, e error) { +// // TODO probably not the most efficient way to do this, but I couldn't +// // work out how to manually initialize the UNICODE_STRING struct in a way +// // that the ALPC subsystem liked. +// us, e = RtlCreateUnicodeStringFromAsciiz(s) +// return +//} + +// (this is a macro) +// VOID InitializeObjectAttributes( +// [out] POBJECT_ATTRIBUTES InitializedAttributes, +// [in] PUNICODE_STRING ObjectName, +// [in] ULONG Attributes, +// [in] HANDLE RootDirectory, +// [in, optional] PSECURITY_DESCRIPTOR SecurityDescriptor +// ) +//func InitializeObjectAttributes( +// name string, +// attributes uint32, +// rootDir HANDLE, +// pSecurityDescriptor *SECURITY_DESCRIPTOR, +//) (oa OBJECT_ATTRIBUTES, e error) { +// +// oa = OBJECT_ATTRIBUTES{ +// RootDirectory: rootDir, +// Attributes: attributes, +// SecurityDescriptor: pSecurityDescriptor, +// } +// oa.Length = uint32(unsafe.Sizeof(oa)) +// +// if len(name) > 0 { +// us, err := newUnicodeString(name) +// if err != nil { +// e = err +// return +// } +// oa.ObjectName = &us +// } +// +// return +//} + +// NTSTATUS +// NtAlpcCreatePort( +// __out PHANDLE PortHandle, +// __in POBJECT_ATTRIBUTES ObjectAttributes, +// __in_opt PALPC_PORT_ATTRIBUTES PortAttributes +// ); +func NtAlpcCreatePort(pObjectAttributes *OBJECT_ATTRIBUTES, pPortAttributes *ALPC_PORT_ATTRIBUTES) (hPort HANDLE, e error) { + + ret, _, _ := procNtAlpcCreatePort.Call( + uintptr(unsafe.Pointer(&hPort)), + uintptr(unsafe.Pointer(pObjectAttributes)), + uintptr(unsafe.Pointer(pPortAttributes)), + ) + + if ret != ERROR_SUCCESS { + return hPort, fmt.Errorf("0x%x", ret) + } + + return +} + +// NTSTATUS +// NtAlpcConnectPort( +// __out PHANDLE PortHandle, +// __in PUNICODE_STRING PortName, +// __in POBJECT_ATTRIBUTES ObjectAttributes, +// __in_opt PALPC_PORT_ATTRIBUTES PortAttributes, +// __in ULONG Flags, +// __in_opt PSID RequiredServerSid, +// __inout PPORT_MESSAGE ConnectionMessage, +// __inout_opt PULONG BufferLength, +// __inout_opt PALPC_MESSAGE_ATTRIBUTES OutMessageAttributes, +// __inout_opt PALPC_MESSAGE_ATTRIBUTES InMessageAttributes, +// __in_opt PLARGE_INTEGER Timeout +// ); +//func NtAlpcConnectPort( +// destPort string, +// pClientObjAttrs *OBJECT_ATTRIBUTES, +// pClientAlpcPortAttrs *ALPC_PORT_ATTRIBUTES, +// flags uint32, +// pRequiredServerSid *SID, +// pConnMsg *AlpcShortMessage, +// pBufLen *uint32, +// pOutMsgAttrs *ALPC_MESSAGE_ATTRIBUTES, +// pInMsgAttrs *ALPC_MESSAGE_ATTRIBUTES, +// timeout *int64, +//) (hPort HANDLE, e error) { +// +// destPortU, e := newUnicodeString(destPort) +// if e != nil { +// return +// } +// +// ret, _, _ := procNtAlpcConnectPort.Call( +// uintptr(unsafe.Pointer(&hPort)), +// uintptr(unsafe.Pointer(&destPortU)), +// uintptr(unsafe.Pointer(pClientObjAttrs)), +// uintptr(unsafe.Pointer(pClientAlpcPortAttrs)), +// uintptr(flags), +// uintptr(unsafe.Pointer(pRequiredServerSid)), +// uintptr(unsafe.Pointer(pConnMsg)), +// uintptr(unsafe.Pointer(pBufLen)), +// uintptr(unsafe.Pointer(pOutMsgAttrs)), +// uintptr(unsafe.Pointer(pInMsgAttrs)), +// uintptr(unsafe.Pointer(timeout)), +// ) +// +// if ret != ERROR_SUCCESS { +// e = fmt.Errorf("0x%x", ret) +// } +// return +//} + +// NTSTATUS +// NtAlpcAcceptConnectPort( +// __out PHANDLE PortHandle, +// __in HANDLE ConnectionPortHandle, +// __in ULONG Flags, +// __in POBJECT_ATTRIBUTES ObjectAttributes, +// __in PALPC_PORT_ATTRIBUTES PortAttributes, +// __in_opt PVOID PortContext, +// __in PPORT_MESSAGE ConnectionRequest, +// __inout_opt PALPC_MESSAGE_ATTRIBUTES ConnectionMessageAttributes, +// __in BOOLEAN AcceptConnection +// ); +func NtAlpcAcceptConnectPort( + hSrvConnPort HANDLE, + flags uint32, + pObjAttr *OBJECT_ATTRIBUTES, + pPortAttr *ALPC_PORT_ATTRIBUTES, + pContext *AlpcPortContext, + pConnReq *AlpcShortMessage, + pConnMsgAttrs *ALPC_MESSAGE_ATTRIBUTES, + accept uintptr, +) (hPort HANDLE, e error) { + + ret, _, _ := procNtAlpcAcceptConnectPort.Call( + uintptr(unsafe.Pointer(&hPort)), + uintptr(hSrvConnPort), + uintptr(flags), + uintptr(unsafe.Pointer(pObjAttr)), + uintptr(unsafe.Pointer(pPortAttr)), + uintptr(unsafe.Pointer(pContext)), + uintptr(unsafe.Pointer(pConnReq)), + uintptr(unsafe.Pointer(pConnMsgAttrs)), + accept, + ) + + if ret != ERROR_SUCCESS { + e = fmt.Errorf("0x%x", ret) + } + return +} + +// NTSTATUS +// NtAlpcSendWaitReceivePort( +// __in HANDLE PortHandle, +// __in ULONG Flags, +// __in_opt PPORT_MESSAGE SendMessage, +// __in_opt PALPC_MESSAGE_ATTRIBUTES SendMessageAttributes, +// __inout_opt PPORT_MESSAGE ReceiveMessage, +// __inout_opt PULONG BufferLength, +// __inout_opt PALPC_MESSAGE_ATTRIBUTES ReceiveMessageAttributes, +// __in_opt PLARGE_INTEGER Timeout +// ); +func NtAlpcSendWaitReceivePort( + hPort HANDLE, + flags uint32, + sendMsg *AlpcShortMessage, // Should actually point to PORT_MESSAGE + payload + sendMsgAttrs *ALPC_MESSAGE_ATTRIBUTES, + recvMsg *AlpcShortMessage, + recvBufLen *uint32, + recvMsgAttrs *ALPC_MESSAGE_ATTRIBUTES, + timeout *int64, // use native int64 +) (e error) { + + ret, _, _ := procNtAlpcSendWaitReceivePort.Call( + uintptr(hPort), + uintptr(flags), + uintptr(unsafe.Pointer(sendMsg)), + uintptr(unsafe.Pointer(sendMsgAttrs)), + uintptr(unsafe.Pointer(recvMsg)), + uintptr(unsafe.Pointer(recvBufLen)), + uintptr(unsafe.Pointer(recvMsgAttrs)), + uintptr(unsafe.Pointer(timeout)), + ) + + if ret != ERROR_SUCCESS { + e = fmt.Errorf("0x%x", ret) + } + return +} + +// NTSYSAPI +// PVOID +// NTAPI +// AlpcGetMessageAttribute( +// __in PALPC_MESSAGE_ATTRIBUTES Buffer, +// __in ULONG AttributeFlag +// ); + +// This basically returns a pointer to the correct struct for whichever +// message attribute you asked for. In Go terms, it returns unsafe.Pointer +// which you should then cast. Example: + +// ptr := AlpcGetMessageAttribute(&recvMsgAttrs, ALPC_MESSAGE_CONTEXT_ATTRIBUTE) +// if ptr != nil { +// context := (*ALPC_CONTEXT_ATTR)(ptr) +// } +func AlpcGetMessageAttribute(buf *ALPC_MESSAGE_ATTRIBUTES, attr uint32) unsafe.Pointer { + + ret, _, _ := procAlpcGetMessageAttribute.Call( + uintptr(unsafe.Pointer(buf)), + uintptr(attr), + ) + return unsafe.Pointer(ret) +} + +// NTSYSCALLAPI +// NTSTATUS +// NTAPI +// NtAlpcCancelMessage( +// __in HANDLE PortHandle, +// __in ULONG Flags, +// __in PALPC_CONTEXT_ATTR MessageContext +// ); +func NtAlpcCancelMessage(hPort HANDLE, flags uint32, pMsgContext *ALPC_CONTEXT_ATTR) (e error) { + + ret, _, _ := procNtAlpcCancelMessage.Call( + uintptr(hPort), + uintptr(flags), + uintptr(unsafe.Pointer(pMsgContext)), + ) + + if ret != ERROR_SUCCESS { + e = fmt.Errorf("0x%x", ret) + } + return +} + +// NTSYSCALLAPI +// NTSTATUS +// NTAPI +// NtAlpcDisconnectPort( +// __in HANDLE PortHandle, +// __in ULONG Flags +// ); +func NtAlpcDisconnectPort(hPort HANDLE, flags uint32) (e error) { + + ret, _, _ := procNtAlpcDisconnectPort.Call( + uintptr(hPort), + uintptr(flags), + ) + + if ret != ERROR_SUCCESS { + e = fmt.Errorf("0x%x", ret) + } + return +} diff --git a/platform/vendor/github.com/MaxRis/w32/alpc_constants.go b/platform/vendor/github.com/MaxRis/w32/alpc_constants.go new file mode 100644 index 0000000..82d9d2e --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/alpc_constants.go @@ -0,0 +1,64 @@ +package w32 + +const ( + ALPC_PORFLG_ALLOW_LPC_REQUESTS = 0x20000 + ALPC_PORFLG_SYSTEM_PROCESS = 0x100000 + ALPC_PORFLG_WAITABLE_PORT = 0x40000 +) + +const ( + ALPC_MSGFLG_REPLY_MESSAGE = 0x1 + ALPC_MSGFLG_LPC_MODE = 0x2 // ? + ALPC_MSGFLG_RELEASE_MESSAGE = 0x10000 // dbg + ALPC_MSGFLG_SYNC_REQUEST = 0x20000 // dbg + ALPC_MSGFLG_WAIT_USER_MODE = 0x100000 + ALPC_MSGFLG_WAIT_ALERTABLE = 0x200000 + ALPC_MSGFLG_WOW64_CALL = 0x80000000 // dbg +) +const ( + ALPC_MESSAGE_SECURITY_ATTRIBUTE = 0x80000000 + ALPC_MESSAGE_VIEW_ATTRIBUTE = 0x40000000 + ALPC_MESSAGE_CONTEXT_ATTRIBUTE = 0x20000000 + ALPC_MESSAGE_HANDLE_ATTRIBUTE = 0x10000000 +) + +const ( + OBJ_INHERIT = 0x00000002 + OBJ_PERMANENT = 0x00000010 + OBJ_EXCLUSIVE = 0x00000020 + OBJ_CASE_INSENSITIVE = 0x00000040 + OBJ_OPENIF = 0x00000080 + OBJ_OPENLINK = 0x00000100 + OBJ_KERNEL_HANDLE = 0x00000200 +) + +const ( + LPC_REQUEST = 1 + LPC_REPLY = 2 + LPC_DATAGRAM = 3 + LPC_LOST_REPLY = 4 + LPC_PORT_CLOSED = 5 + LPC_CLIENT_DIED = 6 + LPC_EXCEPTION = 7 + LPC_DEBUG_EVENT = 8 + LPC_ERROR_EVENT = 9 + LPC_CONNECTION_REQUEST = 10 + LPC_CONTINUATION_REQUIRED = 0x2000 +) + +const ( + SecurityAnonymous uint32 = 1 + SecurityIdentification uint32 = 2 + SecurityImpersonation uint32 = 3 + SecurityDelegation uint32 = 4 +) + +const ( + SECURITY_DYNAMIC_TRACKING byte = 1 + SECURITY_STATIC_TRACKING byte = 0 +) + +const ( + ALPC_SYNC_OBJECT_TYPE uint32 = 2 + ALPC_THREAD_OBJECT_TYPE uint32 = 4 +) diff --git a/platform/vendor/github.com/MaxRis/w32/alpc_test.go b/platform/vendor/github.com/MaxRis/w32/alpc_test.go new file mode 100644 index 0000000..6d1c7d4 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/alpc_test.go @@ -0,0 +1,137 @@ +package w32 + +import ( + "testing" +) + +var testPortName = "\\TestAlpcPort" + +var basicPortAttr = ALPC_PORT_ATTRIBUTES{ + MaxMessageLength: uint64(SHORT_MESSAGE_MAX_SIZE), + SecurityQos: SECURITY_QUALITY_OF_SERVICE{ + Length: SECURITY_QOS_SIZE, + ContextTrackingMode: SECURITY_DYNAMIC_TRACKING, + EffectiveOnly: 1, + ImpersonationLevel: SecurityAnonymous, + }, + Flags: ALPC_PORFLG_ALLOW_LPC_REQUESTS, + DupObjectTypes: ALPC_SYNC_OBJECT_TYPE, +} + +func ObjectAttributes(name string) (oa OBJECT_ATTRIBUTES, e error) { + + sd, e := InitializeSecurityDescriptor(1) + if e != nil { + return + } + + e = SetSecurityDescriptorDacl(sd, nil) + if e != nil { + return + } + + oa, e = InitializeObjectAttributes(name, 0, 0, sd) + return +} + +func Send( + hPort HANDLE, + msg *AlpcShortMessage, + flags uint32, + pMsgAttrs *ALPC_MESSAGE_ATTRIBUTES, + timeout *int64, +) (e error) { + + e = NtAlpcSendWaitReceivePort(hPort, flags, msg, pMsgAttrs, nil, nil, nil, timeout) + return + +} + +func Recv( + hPort HANDLE, + pMsg *AlpcShortMessage, + pMsgAttrs *ALPC_MESSAGE_ATTRIBUTES, + timeout *int64, +) (bufLen uint32, e error) { + + bufLen = uint32(pMsg.TotalLength) + e = NtAlpcSendWaitReceivePort(hPort, 0, nil, nil, pMsg, &bufLen, pMsgAttrs, timeout) + return + +} + +// Convenience method to create an ALPC port with a NULL DACL. Requires an +// absolute port name ( where / is the root of the kernel object directory ) +func CreatePort(name string) (hPort HANDLE, e error) { + + oa, e := ObjectAttributes(name) + if e != nil { + return + } + + hPort, e = NtAlpcCreatePort(&oa, &basicPortAttr) + + return +} + +func ConnectPort(serverName, clientName string, pConnMsg *AlpcShortMessage) (hPort HANDLE, e error) { + + oa, e := InitializeObjectAttributes(clientName, 0, 0, nil) + if e != nil { + return + } + + hPort, e = NtAlpcConnectPort( + serverName, + &oa, + &basicPortAttr, + ALPC_PORFLG_ALLOW_LPC_REQUESTS, + nil, + pConnMsg, + nil, + nil, + nil, + nil, + ) + + return +} + +func Accept( + hSrv HANDLE, + context *AlpcPortContext, + pConnReq *AlpcShortMessage, + accept bool, +) (hPort HANDLE, e error) { + + oa, _ := InitializeObjectAttributes("", 0, 0, nil) + + var accepted uintptr + if accept { + accepted++ + } + + hPort, e = NtAlpcAcceptConnectPort( + hSrv, + 0, + &oa, + &basicPortAttr, + context, + pConnReq, + nil, + accepted, + ) + + return +} + +func TestNtAlpcCreatePort(t *testing.T) { + + hPort, err := CreatePort(testPortName) + + if err != nil { + t.Errorf("failed to create ALPC port %v: %v", testPortName, err) + } else { + t.Logf("[OK] Created ALPC port %v with handle 0x%x", testPortName, hPort) + } +} diff --git a/platform/vendor/github.com/MaxRis/w32/alpc_typedef.go b/platform/vendor/github.com/MaxRis/w32/alpc_typedef.go new file mode 100644 index 0000000..52b35c9 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/alpc_typedef.go @@ -0,0 +1,181 @@ +package w32 + +import ( + "errors" +) + +// nt!_ALPC_MESSAGE_ATTRIBUTES +// +0x000 AllocatedAttributes : Uint4B +// +0x004 ValidAttributes : Uint4B +type ALPC_MESSAGE_ATTRIBUTES struct { + AllocatedAttributes uint32 + ValidAttributes uint32 +} + +type ALPC_CONTEXT_ATTR struct { + PortContext *AlpcPortContext + MessageContext uintptr + Sequence uint32 + MessageId uint32 + CallbackId uint32 +} + +type ALPC_HANDLE_ATTR struct { + Flags uint32 + Handle HANDLE + ObjectType uint32 + DesiredAccess uint32 +} + +// nt!_CLIENT_ID +// +0x000 UniqueProcess : Ptr64 Void +// +0x008 UniqueThread : Ptr64 Void +type CLIENT_ID struct { + UniqueProcess uintptr + UniqueThread uintptr +} + +// nt!_UNICODE_STRING +// +0x000 Length : Uint2B +// +0x002 MaximumLength : Uint2B +// +0x008 Buffer : Ptr64 Uint2B +type UNICODE_STRING struct { + Length uint16 + MaximumLength uint16 + _ [4]byte // align to 0x08 + Buffer *uint16 +} + +// nt!_OBJECT_ATTRIBUTES +// +0x000 Length : Uint4B +// +0x008 RootDirectory : Ptr64 Void +// +0x010 ObjectName : Ptr64 _UNICODE_STRING +// +0x018 Attributes : Uint4B +// +0x020 SecurityDescriptor : Ptr64 Void +// +0x028 SecurityQualityOfService : Ptr64 Void +type OBJECT_ATTRIBUTES struct { + Length uint32 + _ [4]byte // align to 0x08 + RootDirectory HANDLE + ObjectName *UNICODE_STRING + Attributes uint32 + _ [4]byte // align to 0x20 + SecurityDescriptor *SECURITY_DESCRIPTOR + SecurityQualityOfService *SECURITY_QUALITY_OF_SERVICE +} + +// cf: http://j00ru.vexillium.org/?p=502 for legacy RPC +// nt!_PORT_MESSAGE +// +0x000 u1 : +// +0x004 u2 : +// +0x008 ClientId : _CLIENT_ID +// +0x008 DoNotUseThisField : Float +// +0x018 MessageId : Uint4B +// +0x020 ClientViewSize : Uint8B +// +0x020 CallbackId : Uint4B +type PORT_MESSAGE struct { + DataLength uint16 // These are the two unnamed unions + TotalLength uint16 // without Length and ZeroInit + Type uint16 + DataInfoOffset uint16 + ClientId CLIENT_ID + MessageId uint32 + _ [4]byte // align up to 0x20 + ClientViewSize uint64 +} + +func (pm PORT_MESSAGE) CallbackId() uint32 { + return uint32(pm.ClientViewSize >> 32) +} + +func (pm PORT_MESSAGE) DoNotUseThisField() float64 { + panic("WE TOLD YOU NOT TO USE THIS FIELD") +} + +const PORT_MESSAGE_SIZE = 0x28 + +// http://www.nirsoft.net/kernel_struct/vista/SECURITY_QUALITY_OF_SERVICE.html +type SECURITY_QUALITY_OF_SERVICE struct { + Length uint32 + ImpersonationLevel uint32 + ContextTrackingMode byte + EffectiveOnly byte + _ [2]byte // align to 12 bytes +} + +const SECURITY_QOS_SIZE = 12 + +// nt!_ALPC_PORT_ATTRIBUTES +// +0x000 Flags : Uint4B +// +0x004 SecurityQos : _SECURITY_QUALITY_OF_SERVICE +// +0x010 MaxMessageLength : Uint8B +// +0x018 MemoryBandwidth : Uint8B +// +0x020 MaxPoolUsage : Uint8B +// +0x028 MaxSectionSize : Uint8B +// +0x030 MaxViewSize : Uint8B +// +0x038 MaxTotalSectionSize : Uint8B +// +0x040 DupObjectTypes : Uint4B +// +0x044 Reserved : Uint4B +type ALPC_PORT_ATTRIBUTES struct { + Flags uint32 + SecurityQos SECURITY_QUALITY_OF_SERVICE + MaxMessageLength uint64 // must be filled out + MemoryBandwidth uint64 + MaxPoolUsage uint64 + MaxSectionSize uint64 + MaxViewSize uint64 + MaxTotalSectionSize uint64 + DupObjectTypes uint32 + Reserved uint32 +} + +const SHORT_MESSAGE_MAX_SIZE uint16 = 65535 // MAX_USHORT +const SHORT_MESSAGE_MAX_PAYLOAD uint16 = SHORT_MESSAGE_MAX_SIZE - PORT_MESSAGE_SIZE + +// LPC uses the first 4 bytes of the payload as an LPC Command, but this is +// NOT represented here, to allow the use of raw ALPC. For legacy LPC, callers +// must include the command as part of their payload. +type AlpcShortMessage struct { + PORT_MESSAGE + Data [SHORT_MESSAGE_MAX_PAYLOAD]byte +} + +func NewAlpcShortMessage() AlpcShortMessage { + sm := AlpcShortMessage{} + sm.TotalLength = SHORT_MESSAGE_MAX_SIZE + return sm +} + +func (sm *AlpcShortMessage) SetData(d []byte) (e error) { + + copy(sm.Data[:], d) + if len(d) > int(SHORT_MESSAGE_MAX_PAYLOAD) { + e = errors.New("data too big - truncated") + sm.DataLength = SHORT_MESSAGE_MAX_PAYLOAD + sm.TotalLength = SHORT_MESSAGE_MAX_SIZE + return + } + sm.TotalLength = uint16(PORT_MESSAGE_SIZE + len(d)) + sm.DataLength = uint16(len(d)) + return + +} + +// TODO - is this still useful? +func (sm *AlpcShortMessage) GetData() []byte { + if int(sm.DataLength) > int(SHORT_MESSAGE_MAX_PAYLOAD) { + return sm.Data[:] // truncate + } + return sm.Data[:sm.DataLength] +} + +func (sm *AlpcShortMessage) Reset() { + // zero the PORT_MESSAGE header + sm.PORT_MESSAGE = PORT_MESSAGE{} + sm.TotalLength = SHORT_MESSAGE_MAX_SIZE + sm.DataLength = 0 +} + +type AlpcPortContext struct { + Handle HANDLE +} diff --git a/platform/vendor/github.com/MaxRis/w32/comctl32.go b/platform/vendor/github.com/MaxRis/w32/comctl32.go new file mode 100644 index 0000000..4f4e6b5 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/comctl32.go @@ -0,0 +1,109 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modcomctl32 = syscall.NewLazyDLL("comctl32.dll") + + procInitCommonControlsEx = modcomctl32.NewProc("InitCommonControlsEx") + procImageList_Create = modcomctl32.NewProc("ImageList_Create") + procImageList_Destroy = modcomctl32.NewProc("ImageList_Destroy") + procImageList_GetImageCount = modcomctl32.NewProc("ImageList_GetImageCount") + procImageList_SetImageCount = modcomctl32.NewProc("ImageList_SetImageCount") + procImageList_Add = modcomctl32.NewProc("ImageList_Add") + procImageList_ReplaceIcon = modcomctl32.NewProc("ImageList_ReplaceIcon") + procImageList_Remove = modcomctl32.NewProc("ImageList_Remove") + procTrackMouseEvent = modcomctl32.NewProc("_TrackMouseEvent") +) + +func InitCommonControlsEx(lpInitCtrls *INITCOMMONCONTROLSEX) bool { + ret, _, _ := procInitCommonControlsEx.Call( + uintptr(unsafe.Pointer(lpInitCtrls))) + + return ret != 0 +} + +func ImageList_Create(cx, cy int, flags uint, cInitial, cGrow int) HIMAGELIST { + ret, _, _ := procImageList_Create.Call( + uintptr(cx), + uintptr(cy), + uintptr(flags), + uintptr(cInitial), + uintptr(cGrow)) + + if ret == 0 { + panic("Create image list failed") + } + + return HIMAGELIST(ret) +} + +func ImageList_Destroy(himl HIMAGELIST) bool { + ret, _, _ := procImageList_Destroy.Call( + uintptr(himl)) + + return ret != 0 +} + +func ImageList_GetImageCount(himl HIMAGELIST) int { + ret, _, _ := procImageList_GetImageCount.Call( + uintptr(himl)) + + return int(ret) +} + +func ImageList_SetImageCount(himl HIMAGELIST, uNewCount uint) bool { + ret, _, _ := procImageList_SetImageCount.Call( + uintptr(himl), + uintptr(uNewCount)) + + return ret != 0 +} + +func ImageList_Add(himl HIMAGELIST, hbmImage, hbmMask HBITMAP) int { + ret, _, _ := procImageList_Add.Call( + uintptr(himl), + uintptr(hbmImage), + uintptr(hbmMask)) + + return int(ret) +} + +func ImageList_ReplaceIcon(himl HIMAGELIST, i int, hicon HICON) int { + ret, _, _ := procImageList_ReplaceIcon.Call( + uintptr(himl), + uintptr(i), + uintptr(hicon)) + + return int(ret) +} + +func ImageList_AddIcon(himl HIMAGELIST, hicon HICON) int { + return ImageList_ReplaceIcon(himl, -1, hicon) +} + +func ImageList_Remove(himl HIMAGELIST, i int) bool { + ret, _, _ := procImageList_Remove.Call( + uintptr(himl), + uintptr(i)) + + return ret != 0 +} + +func ImageList_RemoveAll(himl HIMAGELIST) bool { + return ImageList_Remove(himl, -1) +} + +func TrackMouseEvent(tme *TRACKMOUSEEVENT) bool { + ret, _, _ := procTrackMouseEvent.Call( + uintptr(unsafe.Pointer(tme))) + + return ret != 0 +} diff --git a/platform/vendor/github.com/MaxRis/w32/comdlg32.go b/platform/vendor/github.com/MaxRis/w32/comdlg32.go new file mode 100644 index 0000000..37bc985 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/comdlg32.go @@ -0,0 +1,38 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modcomdlg32 = syscall.NewLazyDLL("comdlg32.dll") + + procGetSaveFileName = modcomdlg32.NewProc("GetSaveFileNameW") + procGetOpenFileName = modcomdlg32.NewProc("GetOpenFileNameW") + procCommDlgExtendedError = modcomdlg32.NewProc("CommDlgExtendedError") +) + +func GetOpenFileName(ofn *OPENFILENAME) bool { + ret, _, _ := procGetOpenFileName.Call( + uintptr(unsafe.Pointer(ofn))) + + return ret != 0 +} + +func GetSaveFileName(ofn *OPENFILENAME) bool { + ret, _, _ := procGetSaveFileName.Call( + uintptr(unsafe.Pointer(ofn))) + + return ret != 0 +} + +func CommDlgExtendedError() uint { + ret, _, _ := procCommDlgExtendedError.Call() + + return uint(ret) +} diff --git a/platform/vendor/github.com/MaxRis/w32/constants.go b/platform/vendor/github.com/MaxRis/w32/constants.go new file mode 100644 index 0000000..1775ca8 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/constants.go @@ -0,0 +1,2628 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +const ( + FALSE = 0 + TRUE = 1 +) + +const ( + NO_ERROR = 0 + ERROR_SUCCESS = 0 + ERROR_FILE_NOT_FOUND = 2 + ERROR_PATH_NOT_FOUND = 3 + ERROR_ACCESS_DENIED = 5 + ERROR_INVALID_HANDLE = 6 + ERROR_BAD_FORMAT = 11 + ERROR_INVALID_NAME = 123 + ERROR_MORE_DATA = 234 + ERROR_NO_MORE_ITEMS = 259 + ERROR_INVALID_SERVICE_CONTROL = 1052 + ERROR_SERVICE_REQUEST_TIMEOUT = 1053 + ERROR_SERVICE_NO_THREAD = 1054 + ERROR_SERVICE_DATABASE_LOCKED = 1055 + ERROR_SERVICE_ALREADY_RUNNING = 1056 + ERROR_SERVICE_DISABLED = 1058 + ERROR_SERVICE_DOES_NOT_EXIST = 1060 + ERROR_SERVICE_CANNOT_ACCEPT_CTRL = 1061 + ERROR_SERVICE_NOT_ACTIVE = 1062 + ERROR_DATABASE_DOES_NOT_EXIST = 1065 + ERROR_SERVICE_DEPENDENCY_FAIL = 1068 + ERROR_SERVICE_LOGON_FAILED = 1069 + ERROR_SERVICE_MARKED_FOR_DELETE = 1072 + ERROR_SERVICE_DEPENDENCY_DELETED = 1075 +) + +const ( + SE_ERR_FNF = 2 + SE_ERR_PNF = 3 + SE_ERR_ACCESSDENIED = 5 + SE_ERR_OOM = 8 + SE_ERR_DLLNOTFOUND = 32 + SE_ERR_SHARE = 26 + SE_ERR_ASSOCINCOMPLETE = 27 + SE_ERR_DDETIMEOUT = 28 + SE_ERR_DDEFAIL = 29 + SE_ERR_DDEBUSY = 30 + SE_ERR_NOASSOC = 31 +) + +const ( + CW_USEDEFAULT = ^0x7fffffff +) + +// ShowWindow constants +const ( + SW_HIDE = 0 + SW_NORMAL = 1 + SW_SHOWNORMAL = 1 + SW_SHOWMINIMIZED = 2 + SW_MAXIMIZE = 3 + SW_SHOWMAXIMIZED = 3 + SW_SHOWNOACTIVATE = 4 + SW_SHOW = 5 + SW_MINIMIZE = 6 + SW_SHOWMINNOACTIVE = 7 + SW_SHOWNA = 8 + SW_RESTORE = 9 + SW_SHOWDEFAULT = 10 + SW_FORCEMINIMIZE = 11 +) + +// Window class styles +const ( + CS_VREDRAW = 0x00000001 + CS_HREDRAW = 0x00000002 + CS_KEYCVTWINDOW = 0x00000004 + CS_DBLCLKS = 0x00000008 + CS_OWNDC = 0x00000020 + CS_CLASSDC = 0x00000040 + CS_PARENTDC = 0x00000080 + CS_NOKEYCVT = 0x00000100 + CS_NOCLOSE = 0x00000200 + CS_SAVEBITS = 0x00000800 + CS_BYTEALIGNCLIENT = 0x00001000 + CS_BYTEALIGNWINDOW = 0x00002000 + CS_GLOBALCLASS = 0x00004000 + CS_IME = 0x00010000 + CS_DROPSHADOW = 0x00020000 +) + +// Predefined cursor constants +const ( + IDC_ARROW = 32512 + IDC_IBEAM = 32513 + IDC_WAIT = 32514 + IDC_CROSS = 32515 + IDC_UPARROW = 32516 + IDC_SIZENWSE = 32642 + IDC_SIZENESW = 32643 + IDC_SIZEWE = 32644 + IDC_SIZENS = 32645 + IDC_SIZEALL = 32646 + IDC_NO = 32648 + IDC_HAND = 32649 + IDC_APPSTARTING = 32650 + IDC_HELP = 32651 + IDC_ICON = 32641 + IDC_SIZE = 32640 +) + +// Predefined icon constants +const ( + IDI_APPLICATION = 32512 + IDI_HAND = 32513 + IDI_QUESTION = 32514 + IDI_EXCLAMATION = 32515 + IDI_ASTERISK = 32516 + IDI_WINLOGO = 32517 + IDI_WARNING = IDI_EXCLAMATION + IDI_ERROR = IDI_HAND + IDI_INFORMATION = IDI_ASTERISK +) + +// Button style constants +const ( + BS_3STATE = 5 + BS_AUTO3STATE = 6 + BS_AUTOCHECKBOX = 3 + BS_AUTORADIOBUTTON = 9 + BS_BITMAP = 128 + BS_BOTTOM = 0X800 + BS_CENTER = 0X300 + BS_CHECKBOX = 2 + BS_DEFPUSHBUTTON = 1 + BS_GROUPBOX = 7 + BS_ICON = 64 + BS_LEFT = 256 + BS_LEFTTEXT = 32 + BS_MULTILINE = 0X2000 + BS_NOTIFY = 0X4000 + BS_OWNERDRAW = 0XB + BS_PUSHBUTTON = 0 + BS_PUSHLIKE = 4096 + BS_RADIOBUTTON = 4 + BS_RIGHT = 512 + BS_RIGHTBUTTON = 32 + BS_TEXT = 0 + BS_TOP = 0X400 + BS_USERBUTTON = 8 + BS_VCENTER = 0XC00 + BS_FLAT = 0X8000 +) + +// Button state constants +const ( + BST_CHECKED = 1 + BST_INDETERMINATE = 2 + BST_UNCHECKED = 0 + BST_FOCUS = 8 + BST_PUSHED = 4 +) + +// Predefined brushes constants +const ( + COLOR_3DDKSHADOW = 21 + COLOR_3DFACE = 15 + COLOR_3DHILIGHT = 20 + COLOR_3DHIGHLIGHT = 20 + COLOR_3DLIGHT = 22 + COLOR_BTNHILIGHT = 20 + COLOR_3DSHADOW = 16 + COLOR_ACTIVEBORDER = 10 + COLOR_ACTIVECAPTION = 2 + COLOR_APPWORKSPACE = 12 + COLOR_BACKGROUND = 1 + COLOR_DESKTOP = 1 + COLOR_BTNFACE = 15 + COLOR_BTNHIGHLIGHT = 20 + COLOR_BTNSHADOW = 16 + COLOR_BTNTEXT = 18 + COLOR_CAPTIONTEXT = 9 + COLOR_GRAYTEXT = 17 + COLOR_HIGHLIGHT = 13 + COLOR_HIGHLIGHTTEXT = 14 + COLOR_INACTIVEBORDER = 11 + COLOR_INACTIVECAPTION = 3 + COLOR_INACTIVECAPTIONTEXT = 19 + COLOR_INFOBK = 24 + COLOR_INFOTEXT = 23 + COLOR_MENU = 4 + COLOR_MENUTEXT = 7 + COLOR_SCROLLBAR = 0 + COLOR_WINDOW = 5 + COLOR_WINDOWFRAME = 6 + COLOR_WINDOWTEXT = 8 + COLOR_HOTLIGHT = 26 + COLOR_GRADIENTACTIVECAPTION = 27 + COLOR_GRADIENTINACTIVECAPTION = 28 +) + +// Button message constants +const ( + BM_CLICK = 245 + BM_GETCHECK = 240 + BM_GETIMAGE = 246 + BM_GETSTATE = 242 + BM_SETCHECK = 241 + BM_SETIMAGE = 247 + BM_SETSTATE = 243 + BM_SETSTYLE = 244 +) + +// Button notifications +const ( + BN_CLICKED = 0 + BN_PAINT = 1 + BN_HILITE = 2 + BN_PUSHED = BN_HILITE + BN_UNHILITE = 3 + BN_UNPUSHED = BN_UNHILITE + BN_DISABLE = 4 + BN_DOUBLECLICKED = 5 + BN_DBLCLK = BN_DOUBLECLICKED + BN_SETFOCUS = 6 + BN_KILLFOCUS = 7 +) + +// GetWindowLong and GetWindowLongPtr constants +const ( + GWL_EXSTYLE = -20 + GWL_STYLE = -16 + GWL_WNDPROC = -4 + GWLP_WNDPROC = -4 + GWL_HINSTANCE = -6 + GWLP_HINSTANCE = -6 + GWL_HWNDPARENT = -8 + GWLP_HWNDPARENT = -8 + GWL_ID = -12 + GWLP_ID = -12 + GWL_USERDATA = -21 + GWLP_USERDATA = -21 +) + +// Window style constants +const ( + WS_OVERLAPPED = 0X00000000 + WS_POPUP = 0X80000000 + WS_CHILD = 0X40000000 + WS_MINIMIZE = 0X20000000 + WS_VISIBLE = 0X10000000 + WS_DISABLED = 0X08000000 + WS_CLIPSIBLINGS = 0X04000000 + WS_CLIPCHILDREN = 0X02000000 + WS_MAXIMIZE = 0X01000000 + WS_CAPTION = 0X00C00000 + WS_BORDER = 0X00800000 + WS_DLGFRAME = 0X00400000 + WS_VSCROLL = 0X00200000 + WS_HSCROLL = 0X00100000 + WS_SYSMENU = 0X00080000 + WS_THICKFRAME = 0X00040000 + WS_GROUP = 0X00020000 + WS_TABSTOP = 0X00010000 + WS_MINIMIZEBOX = 0X00020000 + WS_MAXIMIZEBOX = 0X00010000 + WS_TILED = 0X00000000 + WS_ICONIC = 0X20000000 + WS_SIZEBOX = 0X00040000 + WS_OVERLAPPEDWINDOW = 0X00000000 | 0X00C00000 | 0X00080000 | 0X00040000 | 0X00020000 | 0X00010000 + WS_POPUPWINDOW = 0X80000000 | 0X00800000 | 0X00080000 + WS_CHILDWINDOW = 0X40000000 +) + +// Extended window style constants +const ( + WS_EX_DLGMODALFRAME = 0X00000001 + WS_EX_NOPARENTNOTIFY = 0X00000004 + WS_EX_TOPMOST = 0X00000008 + WS_EX_ACCEPTFILES = 0X00000010 + WS_EX_TRANSPARENT = 0X00000020 + WS_EX_MDICHILD = 0X00000040 + WS_EX_TOOLWINDOW = 0X00000080 + WS_EX_WINDOWEDGE = 0X00000100 + WS_EX_CLIENTEDGE = 0X00000200 + WS_EX_CONTEXTHELP = 0X00000400 + WS_EX_RIGHT = 0X00001000 + WS_EX_LEFT = 0X00000000 + WS_EX_RTLREADING = 0X00002000 + WS_EX_LTRREADING = 0X00000000 + WS_EX_LEFTSCROLLBAR = 0X00004000 + WS_EX_RIGHTSCROLLBAR = 0X00000000 + WS_EX_CONTROLPARENT = 0X00010000 + WS_EX_STATICEDGE = 0X00020000 + WS_EX_APPWINDOW = 0X00040000 + WS_EX_OVERLAPPEDWINDOW = 0X00000100 | 0X00000200 + WS_EX_PALETTEWINDOW = 0X00000100 | 0X00000080 | 0X00000008 + WS_EX_LAYERED = 0X00080000 + WS_EX_NOINHERITLAYOUT = 0X00100000 + WS_EX_LAYOUTRTL = 0X00400000 + WS_EX_NOACTIVATE = 0X08000000 +) + +// Window message constants +const ( + WM_APP = 32768 + WM_ACTIVATE = 6 + WM_ACTIVATEAPP = 28 + WM_AFXFIRST = 864 + WM_AFXLAST = 895 + WM_ASKCBFORMATNAME = 780 + WM_CANCELJOURNAL = 75 + WM_CANCELMODE = 31 + WM_CAPTURECHANGED = 533 + WM_CHANGECBCHAIN = 781 + WM_CHAR = 258 + WM_CHARTOITEM = 47 + WM_CHILDACTIVATE = 34 + WM_CLEAR = 771 + WM_CLOSE = 16 + WM_COMMAND = 273 + WM_COMMNOTIFY = 68 /* OBSOLETE */ + WM_COMPACTING = 65 + WM_COMPAREITEM = 57 + WM_CONTEXTMENU = 123 + WM_COPY = 769 + WM_COPYDATA = 74 + WM_CREATE = 1 + WM_CTLCOLORBTN = 309 + WM_CTLCOLORDLG = 310 + WM_CTLCOLOREDIT = 307 + WM_CTLCOLORLISTBOX = 308 + WM_CTLCOLORMSGBOX = 306 + WM_CTLCOLORSCROLLBAR = 311 + WM_CTLCOLORSTATIC = 312 + WM_CUT = 768 + WM_DEADCHAR = 259 + WM_DELETEITEM = 45 + WM_DESTROY = 2 + WM_DESTROYCLIPBOARD = 775 + WM_DEVICECHANGE = 537 + WM_DEVMODECHANGE = 27 + WM_DISPLAYCHANGE = 126 + WM_DRAWCLIPBOARD = 776 + WM_DRAWITEM = 43 + WM_DROPFILES = 563 + WM_ENABLE = 10 + WM_ENDSESSION = 22 + WM_ENTERIDLE = 289 + WM_ENTERMENULOOP = 529 + WM_ENTERSIZEMOVE = 561 + WM_ERASEBKGND = 20 + WM_EXITMENULOOP = 530 + WM_EXITSIZEMOVE = 562 + WM_FONTCHANGE = 29 + WM_GETDLGCODE = 135 + WM_GETFONT = 49 + WM_GETHOTKEY = 51 + WM_GETICON = 127 + WM_GETMINMAXINFO = 36 + WM_GETTEXT = 13 + WM_GETTEXTLENGTH = 14 + WM_HANDHELDFIRST = 856 + WM_HANDHELDLAST = 863 + WM_HELP = 83 + WM_HOTKEY = 786 + WM_HSCROLL = 276 + WM_HSCROLLCLIPBOARD = 782 + WM_ICONERASEBKGND = 39 + WM_INITDIALOG = 272 + WM_INITMENU = 278 + WM_INITMENUPOPUP = 279 + WM_INPUT = 0X00FF + WM_INPUTLANGCHANGE = 81 + WM_INPUTLANGCHANGEREQUEST = 80 + WM_KEYDOWN = 256 + WM_KEYUP = 257 + WM_KILLFOCUS = 8 + WM_MDIACTIVATE = 546 + WM_MDICASCADE = 551 + WM_MDICREATE = 544 + WM_MDIDESTROY = 545 + WM_MDIGETACTIVE = 553 + WM_MDIICONARRANGE = 552 + WM_MDIMAXIMIZE = 549 + WM_MDINEXT = 548 + WM_MDIREFRESHMENU = 564 + WM_MDIRESTORE = 547 + WM_MDISETMENU = 560 + WM_MDITILE = 550 + WM_MEASUREITEM = 44 + WM_GETOBJECT = 0X003D + WM_CHANGEUISTATE = 0X0127 + WM_UPDATEUISTATE = 0X0128 + WM_QUERYUISTATE = 0X0129 + WM_UNINITMENUPOPUP = 0X0125 + WM_MENURBUTTONUP = 290 + WM_MENUCOMMAND = 0X0126 + WM_MENUGETOBJECT = 0X0124 + WM_MENUDRAG = 0X0123 + WM_APPCOMMAND = 0X0319 + WM_MENUCHAR = 288 + WM_MENUSELECT = 287 + WM_MOVE = 3 + WM_MOVING = 534 + WM_NCACTIVATE = 134 + WM_NCCALCSIZE = 131 + WM_NCCREATE = 129 + WM_NCDESTROY = 130 + WM_NCHITTEST = 132 + WM_NCLBUTTONDBLCLK = 163 + WM_NCLBUTTONDOWN = 161 + WM_NCLBUTTONUP = 162 + WM_NCMBUTTONDBLCLK = 169 + WM_NCMBUTTONDOWN = 167 + WM_NCMBUTTONUP = 168 + WM_NCXBUTTONDOWN = 171 + WM_NCXBUTTONUP = 172 + WM_NCXBUTTONDBLCLK = 173 + WM_NCMOUSEHOVER = 0X02A0 + WM_NCMOUSELEAVE = 0X02A2 + WM_NCMOUSEMOVE = 160 + WM_NCPAINT = 133 + WM_NCRBUTTONDBLCLK = 166 + WM_NCRBUTTONDOWN = 164 + WM_NCRBUTTONUP = 165 + WM_NEXTDLGCTL = 40 + WM_NEXTMENU = 531 + WM_NOTIFY = 78 + WM_NOTIFYFORMAT = 85 + WM_NULL = 0 + WM_PAINT = 15 + WM_PAINTCLIPBOARD = 777 + WM_PAINTICON = 38 + WM_PALETTECHANGED = 785 + WM_PALETTEISCHANGING = 784 + WM_PARENTNOTIFY = 528 + WM_PASTE = 770 + WM_PENWINFIRST = 896 + WM_PENWINLAST = 911 + WM_POWER = 72 + WM_POWERBROADCAST = 536 + WM_PRINT = 791 + WM_PRINTCLIENT = 792 + WM_QUERYDRAGICON = 55 + WM_QUERYENDSESSION = 17 + WM_QUERYNEWPALETTE = 783 + WM_QUERYOPEN = 19 + WM_QUEUESYNC = 35 + WM_QUIT = 18 + WM_RENDERALLFORMATS = 774 + WM_RENDERFORMAT = 773 + WM_SETCURSOR = 32 + WM_SETFOCUS = 7 + WM_SETFONT = 48 + WM_SETHOTKEY = 50 + WM_SETICON = 128 + WM_SETREDRAW = 11 + WM_SETTEXT = 12 + WM_SETTINGCHANGE = 26 + WM_SHOWWINDOW = 24 + WM_SIZE = 5 + WM_SIZECLIPBOARD = 779 + WM_SIZING = 532 + WM_SPOOLERSTATUS = 42 + WM_STYLECHANGED = 125 + WM_STYLECHANGING = 124 + WM_SYSCHAR = 262 + WM_SYSCOLORCHANGE = 21 + WM_SYSCOMMAND = 274 + WM_SYSDEADCHAR = 263 + WM_SYSKEYDOWN = 260 + WM_SYSKEYUP = 261 + WM_TCARD = 82 + WM_THEMECHANGED = 794 + WM_TIMECHANGE = 30 + WM_TIMER = 275 + WM_UNDO = 772 + WM_USER = 1024 + WM_USERCHANGED = 84 + WM_VKEYTOITEM = 46 + WM_VSCROLL = 277 + WM_VSCROLLCLIPBOARD = 778 + WM_WINDOWPOSCHANGED = 71 + WM_WINDOWPOSCHANGING = 70 + WM_WININICHANGE = 26 + WM_KEYFIRST = 256 + WM_KEYLAST = 264 + WM_SYNCPAINT = 136 + WM_MOUSEACTIVATE = 33 + WM_MOUSEMOVE = 512 + WM_LBUTTONDOWN = 513 + WM_LBUTTONUP = 514 + WM_LBUTTONDBLCLK = 515 + WM_RBUTTONDOWN = 516 + WM_RBUTTONUP = 517 + WM_RBUTTONDBLCLK = 518 + WM_MBUTTONDOWN = 519 + WM_MBUTTONUP = 520 + WM_MBUTTONDBLCLK = 521 + WM_MOUSEWHEEL = 522 + WM_XBUTTONDOWN = 523 + WM_XBUTTONUP = 524 + WM_XBUTTONDBLCLK = 525 + WM_MOUSEHWHEEL = 526 + WM_MOUSEFIRST = 512 + WM_MOUSELAST = 526 + WM_MOUSEHOVER = 0X2A1 + WM_MOUSELEAVE = 0X2A3 + WM_CLIPBOARDUPDATE = 0x031D +) + +// WM_ACTIVATE +const ( + WA_INACTIVE = 0 + WA_ACTIVE = 1 + WA_CLICKACTIVE = 2 +) + +const LF_FACESIZE = 32 + +// Font weight constants +const ( + FW_DONTCARE = 0 + FW_THIN = 100 + FW_EXTRALIGHT = 200 + FW_ULTRALIGHT = FW_EXTRALIGHT + FW_LIGHT = 300 + FW_NORMAL = 400 + FW_REGULAR = 400 + FW_MEDIUM = 500 + FW_SEMIBOLD = 600 + FW_DEMIBOLD = FW_SEMIBOLD + FW_BOLD = 700 + FW_EXTRABOLD = 800 + FW_ULTRABOLD = FW_EXTRABOLD + FW_HEAVY = 900 + FW_BLACK = FW_HEAVY +) + +// Charset constants +const ( + ANSI_CHARSET = 0 + DEFAULT_CHARSET = 1 + SYMBOL_CHARSET = 2 + SHIFTJIS_CHARSET = 128 + HANGEUL_CHARSET = 129 + HANGUL_CHARSET = 129 + GB2312_CHARSET = 134 + CHINESEBIG5_CHARSET = 136 + GREEK_CHARSET = 161 + TURKISH_CHARSET = 162 + HEBREW_CHARSET = 177 + ARABIC_CHARSET = 178 + BALTIC_CHARSET = 186 + RUSSIAN_CHARSET = 204 + THAI_CHARSET = 222 + EASTEUROPE_CHARSET = 238 + OEM_CHARSET = 255 + JOHAB_CHARSET = 130 + VIETNAMESE_CHARSET = 163 + MAC_CHARSET = 77 +) + +// Font output precision constants +const ( + OUT_DEFAULT_PRECIS = 0 + OUT_STRING_PRECIS = 1 + OUT_CHARACTER_PRECIS = 2 + OUT_STROKE_PRECIS = 3 + OUT_TT_PRECIS = 4 + OUT_DEVICE_PRECIS = 5 + OUT_RASTER_PRECIS = 6 + OUT_TT_ONLY_PRECIS = 7 + OUT_OUTLINE_PRECIS = 8 + OUT_PS_ONLY_PRECIS = 10 +) + +// Font clipping precision constants +const ( + CLIP_DEFAULT_PRECIS = 0 + CLIP_CHARACTER_PRECIS = 1 + CLIP_STROKE_PRECIS = 2 + CLIP_MASK = 15 + CLIP_LH_ANGLES = 16 + CLIP_TT_ALWAYS = 32 + CLIP_EMBEDDED = 128 +) + +// Font output quality constants +const ( + DEFAULT_QUALITY = 0 + DRAFT_QUALITY = 1 + PROOF_QUALITY = 2 + NONANTIALIASED_QUALITY = 3 + ANTIALIASED_QUALITY = 4 + CLEARTYPE_QUALITY = 5 +) + +// Font pitch constants +const ( + DEFAULT_PITCH = 0 + FIXED_PITCH = 1 + VARIABLE_PITCH = 2 +) + +// Font family constants +const ( + FF_DECORATIVE = 80 + FF_DONTCARE = 0 + FF_MODERN = 48 + FF_ROMAN = 16 + FF_SCRIPT = 64 + FF_SWISS = 32 +) + +// DeviceCapabilities capabilities +const ( + DC_FIELDS = 1 + DC_PAPERS = 2 + DC_PAPERSIZE = 3 + DC_MINEXTENT = 4 + DC_MAXEXTENT = 5 + DC_BINS = 6 + DC_DUPLEX = 7 + DC_SIZE = 8 + DC_EXTRA = 9 + DC_VERSION = 10 + DC_DRIVER = 11 + DC_BINNAMES = 12 + DC_ENUMRESOLUTIONS = 13 + DC_FILEDEPENDENCIES = 14 + DC_TRUETYPE = 15 + DC_PAPERNAMES = 16 + DC_ORIENTATION = 17 + DC_COPIES = 18 + DC_BINADJUST = 19 + DC_EMF_COMPLIANT = 20 + DC_DATATYPE_PRODUCED = 21 + DC_COLLATE = 22 + DC_MANUFACTURER = 23 + DC_MODEL = 24 + DC_PERSONALITY = 25 + DC_PRINTRATE = 26 + DC_PRINTRATEUNIT = 27 + DC_PRINTERMEM = 28 + DC_MEDIAREADY = 29 + DC_STAPLE = 30 + DC_PRINTRATEPPM = 31 + DC_COLORDEVICE = 32 + DC_NUP = 33 + DC_MEDIATYPENAMES = 34 + DC_MEDIATYPES = 35 +) + +// GetDeviceCaps index constants +const ( + DRIVERVERSION = 0 + TECHNOLOGY = 2 + HORZSIZE = 4 + VERTSIZE = 6 + HORZRES = 8 + VERTRES = 10 + LOGPIXELSX = 88 + LOGPIXELSY = 90 + BITSPIXEL = 12 + PLANES = 14 + NUMBRUSHES = 16 + NUMPENS = 18 + NUMFONTS = 22 + NUMCOLORS = 24 + NUMMARKERS = 20 + ASPECTX = 40 + ASPECTY = 42 + ASPECTXY = 44 + PDEVICESIZE = 26 + CLIPCAPS = 36 + SIZEPALETTE = 104 + NUMRESERVED = 106 + COLORRES = 108 + PHYSICALWIDTH = 110 + PHYSICALHEIGHT = 111 + PHYSICALOFFSETX = 112 + PHYSICALOFFSETY = 113 + SCALINGFACTORX = 114 + SCALINGFACTORY = 115 + VREFRESH = 116 + DESKTOPHORZRES = 118 + DESKTOPVERTRES = 117 + BLTALIGNMENT = 119 + SHADEBLENDCAPS = 120 + COLORMGMTCAPS = 121 + RASTERCAPS = 38 + CURVECAPS = 28 + LINECAPS = 30 + POLYGONALCAPS = 32 + TEXTCAPS = 34 +) + +// GetDeviceCaps TECHNOLOGY constants +const ( + DT_PLOTTER = 0 + DT_RASDISPLAY = 1 + DT_RASPRINTER = 2 + DT_RASCAMERA = 3 + DT_CHARSTREAM = 4 + DT_METAFILE = 5 + DT_DISPFILE = 6 +) + +// GetDeviceCaps SHADEBLENDCAPS constants +const ( + SB_NONE = 0x00 + SB_CONST_ALPHA = 0x01 + SB_PIXEL_ALPHA = 0x02 + SB_PREMULT_ALPHA = 0x04 + SB_GRAD_RECT = 0x10 + SB_GRAD_TRI = 0x20 +) + +// GetDeviceCaps COLORMGMTCAPS constants +const ( + CM_NONE = 0x00 + CM_DEVICE_ICM = 0x01 + CM_GAMMA_RAMP = 0x02 + CM_CMYK_COLOR = 0x04 +) + +// GetDeviceCaps RASTERCAPS constants +const ( + RC_BANDING = 2 + RC_BITBLT = 1 + RC_BITMAP64 = 8 + RC_DI_BITMAP = 128 + RC_DIBTODEV = 512 + RC_FLOODFILL = 4096 + RC_GDI20_OUTPUT = 16 + RC_PALETTE = 256 + RC_SCALING = 4 + RC_STRETCHBLT = 2048 + RC_STRETCHDIB = 8192 + RC_DEVBITS = 0x8000 + RC_OP_DX_OUTPUT = 0x4000 +) + +// GetDeviceCaps CURVECAPS constants +const ( + CC_NONE = 0 + CC_CIRCLES = 1 + CC_PIE = 2 + CC_CHORD = 4 + CC_ELLIPSES = 8 + CC_WIDE = 16 + CC_STYLED = 32 + CC_WIDESTYLED = 64 + CC_INTERIORS = 128 + CC_ROUNDRECT = 256 +) + +// GetDeviceCaps LINECAPS constants +const ( + LC_NONE = 0 + LC_POLYLINE = 2 + LC_MARKER = 4 + LC_POLYMARKER = 8 + LC_WIDE = 16 + LC_STYLED = 32 + LC_WIDESTYLED = 64 + LC_INTERIORS = 128 +) + +// GetDeviceCaps POLYGONALCAPS constants +const ( + PC_NONE = 0 + PC_POLYGON = 1 + PC_POLYPOLYGON = 256 + PC_PATHS = 512 + PC_RECTANGLE = 2 + PC_WINDPOLYGON = 4 + PC_SCANLINE = 8 + PC_TRAPEZOID = 4 + PC_WIDE = 16 + PC_STYLED = 32 + PC_WIDESTYLED = 64 + PC_INTERIORS = 128 +) + +// GetDeviceCaps TEXTCAPS constants +const ( + TC_OP_CHARACTER = 1 + TC_OP_STROKE = 2 + TC_CP_STROKE = 4 + TC_CR_90 = 8 + TC_CR_ANY = 16 + TC_SF_X_YINDEP = 32 + TC_SA_DOUBLE = 64 + TC_SA_INTEGER = 128 + TC_SA_CONTIN = 256 + TC_EA_DOUBLE = 512 + TC_IA_ABLE = 1024 + TC_UA_ABLE = 2048 + TC_SO_ABLE = 4096 + TC_RA_ABLE = 8192 + TC_VA_ABLE = 16384 + TC_RESERVED = 32768 + TC_SCROLLBLT = 65536 +) + +// Static control styles +const ( + SS_BITMAP = 14 + SS_BLACKFRAME = 7 + SS_BLACKRECT = 4 + SS_CENTER = 1 + SS_CENTERIMAGE = 512 + SS_EDITCONTROL = 0x2000 + SS_ENHMETAFILE = 15 + SS_ETCHEDFRAME = 18 + SS_ETCHEDHORZ = 16 + SS_ETCHEDVERT = 17 + SS_GRAYFRAME = 8 + SS_GRAYRECT = 5 + SS_ICON = 3 + SS_LEFT = 0 + SS_LEFTNOWORDWRAP = 0xc + SS_NOPREFIX = 128 + SS_NOTIFY = 256 + SS_OWNERDRAW = 0xd + SS_REALSIZECONTROL = 0x040 + SS_REALSIZEIMAGE = 0x800 + SS_RIGHT = 2 + SS_RIGHTJUST = 0x400 + SS_SIMPLE = 11 + SS_SUNKEN = 4096 + SS_WHITEFRAME = 9 + SS_WHITERECT = 6 + SS_USERITEM = 10 + SS_TYPEMASK = 0x0000001F + SS_ENDELLIPSIS = 0x00004000 + SS_PATHELLIPSIS = 0x00008000 + SS_WORDELLIPSIS = 0x0000C000 + SS_ELLIPSISMASK = 0x0000C000 +) + +// Edit styles +const ( + ES_LEFT = 0x0000 + ES_CENTER = 0x0001 + ES_RIGHT = 0x0002 + ES_MULTILINE = 0x0004 + ES_UPPERCASE = 0x0008 + ES_LOWERCASE = 0x0010 + ES_PASSWORD = 0x0020 + ES_AUTOVSCROLL = 0x0040 + ES_AUTOHSCROLL = 0x0080 + ES_NOHIDESEL = 0x0100 + ES_OEMCONVERT = 0x0400 + ES_READONLY = 0x0800 + ES_WANTRETURN = 0x1000 + ES_NUMBER = 0x2000 +) + +// Edit notifications +const ( + EN_SETFOCUS = 0x0100 + EN_KILLFOCUS = 0x0200 + EN_CHANGE = 0x0300 + EN_UPDATE = 0x0400 + EN_ERRSPACE = 0x0500 + EN_MAXTEXT = 0x0501 + EN_HSCROLL = 0x0601 + EN_VSCROLL = 0x0602 + EN_ALIGN_LTR_EC = 0x0700 + EN_ALIGN_RTL_EC = 0x0701 +) + +// Edit messages +const ( + EM_GETSEL = 0x00B0 + EM_SETSEL = 0x00B1 + EM_GETRECT = 0x00B2 + EM_SETRECT = 0x00B3 + EM_SETRECTNP = 0x00B4 + EM_SCROLL = 0x00B5 + EM_LINESCROLL = 0x00B6 + EM_SCROLLCARET = 0x00B7 + EM_GETMODIFY = 0x00B8 + EM_SETMODIFY = 0x00B9 + EM_GETLINECOUNT = 0x00BA + EM_LINEINDEX = 0x00BB + EM_SETHANDLE = 0x00BC + EM_GETHANDLE = 0x00BD + EM_GETTHUMB = 0x00BE + EM_LINELENGTH = 0x00C1 + EM_REPLACESEL = 0x00C2 + EM_GETLINE = 0x00C4 + EM_LIMITTEXT = 0x00C5 + EM_CANUNDO = 0x00C6 + EM_UNDO = 0x00C7 + EM_FMTLINES = 0x00C8 + EM_LINEFROMCHAR = 0x00C9 + EM_SETTABSTOPS = 0x00CB + EM_SETPASSWORDCHAR = 0x00CC + EM_EMPTYUNDOBUFFER = 0x00CD + EM_GETFIRSTVISIBLELINE = 0x00CE + EM_SETREADONLY = 0x00CF + EM_SETWORDBREAKPROC = 0x00D0 + EM_GETWORDBREAKPROC = 0x00D1 + EM_GETPASSWORDCHAR = 0x00D2 + EM_SETMARGINS = 0x00D3 + EM_GETMARGINS = 0x00D4 + EM_SETLIMITTEXT = EM_LIMITTEXT + EM_GETLIMITTEXT = 0x00D5 + EM_POSFROMCHAR = 0x00D6 + EM_CHARFROMPOS = 0x00D7 + EM_SETIMESTATUS = 0x00D8 + EM_GETIMESTATUS = 0x00D9 + EM_SETCUEBANNER = 0x1501 + EM_GETCUEBANNER = 0x1502 +) + +const ( + CCM_FIRST = 0x2000 + CCM_LAST = CCM_FIRST + 0x200 + CCM_SETBKCOLOR = 8193 + CCM_SETCOLORSCHEME = 8194 + CCM_GETCOLORSCHEME = 8195 + CCM_GETDROPTARGET = 8196 + CCM_SETUNICODEFORMAT = 8197 + CCM_GETUNICODEFORMAT = 8198 + CCM_SETVERSION = 0x2007 + CCM_GETVERSION = 0x2008 + CCM_SETNOTIFYWINDOW = 0x2009 + CCM_SETWINDOWTHEME = 0x200b + CCM_DPISCALE = 0x200c +) + +// Common controls styles +const ( + CCS_TOP = 1 + CCS_NOMOVEY = 2 + CCS_BOTTOM = 3 + CCS_NORESIZE = 4 + CCS_NOPARENTALIGN = 8 + CCS_ADJUSTABLE = 32 + CCS_NODIVIDER = 64 + CCS_VERT = 128 + CCS_LEFT = 129 + CCS_NOMOVEX = 130 + CCS_RIGHT = 131 +) + +// ProgressBar messages +const ( + PROGRESS_CLASS = "msctls_progress32" + PBM_SETPOS = WM_USER + 2 + PBM_DELTAPOS = WM_USER + 3 + PBM_SETSTEP = WM_USER + 4 + PBM_STEPIT = WM_USER + 5 + PBM_SETRANGE32 = 1030 + PBM_GETRANGE = 1031 + PBM_GETPOS = 1032 + PBM_SETBARCOLOR = 1033 + PBM_SETBKCOLOR = CCM_SETBKCOLOR + PBS_SMOOTH = 1 + PBS_VERTICAL = 4 +) + +// GetOpenFileName and GetSaveFileName extended flags +const ( + OFN_EX_NOPLACESBAR = 0x00000001 +) + +// GetOpenFileName and GetSaveFileName flags +const ( + OFN_ALLOWMULTISELECT = 0x00000200 + OFN_CREATEPROMPT = 0x00002000 + OFN_DONTADDTORECENT = 0x02000000 + OFN_ENABLEHOOK = 0x00000020 + OFN_ENABLEINCLUDENOTIFY = 0x00400000 + OFN_ENABLESIZING = 0x00800000 + OFN_ENABLETEMPLATE = 0x00000040 + OFN_ENABLETEMPLATEHANDLE = 0x00000080 + OFN_EXPLORER = 0x00080000 + OFN_EXTENSIONDIFFERENT = 0x00000400 + OFN_FILEMUSTEXIST = 0x00001000 + OFN_FORCESHOWHIDDEN = 0x10000000 + OFN_HIDEREADONLY = 0x00000004 + OFN_LONGNAMES = 0x00200000 + OFN_NOCHANGEDIR = 0x00000008 + OFN_NODEREFERENCELINKS = 0x00100000 + OFN_NOLONGNAMES = 0x00040000 + OFN_NONETWORKBUTTON = 0x00020000 + OFN_NOREADONLYRETURN = 0x00008000 + OFN_NOTESTFILECREATE = 0x00010000 + OFN_NOVALIDATE = 0x00000100 + OFN_OVERWRITEPROMPT = 0x00000002 + OFN_PATHMUSTEXIST = 0x00000800 + OFN_READONLY = 0x00000001 + OFN_SHAREAWARE = 0x00004000 + OFN_SHOWHELP = 0x00000010 +) + +//SHBrowseForFolder flags +const ( + BIF_RETURNONLYFSDIRS = 0x00000001 + BIF_DONTGOBELOWDOMAIN = 0x00000002 + BIF_STATUSTEXT = 0x00000004 + BIF_RETURNFSANCESTORS = 0x00000008 + BIF_EDITBOX = 0x00000010 + BIF_VALIDATE = 0x00000020 + BIF_NEWDIALOGSTYLE = 0x00000040 + BIF_BROWSEINCLUDEURLS = 0x00000080 + BIF_USENEWUI = BIF_EDITBOX | BIF_NEWDIALOGSTYLE + BIF_UAHINT = 0x00000100 + BIF_NONEWFOLDERBUTTON = 0x00000200 + BIF_NOTRANSLATETARGETS = 0x00000400 + BIF_BROWSEFORCOMPUTER = 0x00001000 + BIF_BROWSEFORPRINTER = 0x00002000 + BIF_BROWSEINCLUDEFILES = 0x00004000 + BIF_SHAREABLE = 0x00008000 + BIF_BROWSEFILEJUNCTIONS = 0x00010000 +) + +//MessageBox flags +const ( + MB_OK = 0x00000000 + MB_OKCANCEL = 0x00000001 + MB_ABORTRETRYIGNORE = 0x00000002 + MB_YESNOCANCEL = 0x00000003 + MB_YESNO = 0x00000004 + MB_RETRYCANCEL = 0x00000005 + MB_CANCELTRYCONTINUE = 0x00000006 + MB_ICONHAND = 0x00000010 + MB_ICONQUESTION = 0x00000020 + MB_ICONEXCLAMATION = 0x00000030 + MB_ICONASTERISK = 0x00000040 + MB_USERICON = 0x00000080 + MB_ICONWARNING = MB_ICONEXCLAMATION + MB_ICONERROR = MB_ICONHAND + MB_ICONINFORMATION = MB_ICONASTERISK + MB_ICONSTOP = MB_ICONHAND + MB_DEFBUTTON1 = 0x00000000 + MB_DEFBUTTON2 = 0x00000100 + MB_DEFBUTTON3 = 0x00000200 + MB_DEFBUTTON4 = 0x00000300 +) + +//COM +const ( + E_INVALIDARG = 0x80070057 + E_OUTOFMEMORY = 0x8007000E + E_UNEXPECTED = 0x8000FFFF +) + +const ( + S_OK = 0 + S_FALSE = 0x0001 + RPC_E_CHANGED_MODE = 0x80010106 +) + +// GetSystemMetrics constants +const ( + SM_CXSCREEN = 0 + SM_CYSCREEN = 1 + SM_CXVSCROLL = 2 + SM_CYHSCROLL = 3 + SM_CYCAPTION = 4 + SM_CXBORDER = 5 + SM_CYBORDER = 6 + SM_CXDLGFRAME = 7 + SM_CYDLGFRAME = 8 + SM_CYVTHUMB = 9 + SM_CXHTHUMB = 10 + SM_CXICON = 11 + SM_CYICON = 12 + SM_CXCURSOR = 13 + SM_CYCURSOR = 14 + SM_CYMENU = 15 + SM_CXFULLSCREEN = 16 + SM_CYFULLSCREEN = 17 + SM_CYKANJIWINDOW = 18 + SM_MOUSEPRESENT = 19 + SM_CYVSCROLL = 20 + SM_CXHSCROLL = 21 + SM_DEBUG = 22 + SM_SWAPBUTTON = 23 + SM_RESERVED1 = 24 + SM_RESERVED2 = 25 + SM_RESERVED3 = 26 + SM_RESERVED4 = 27 + SM_CXMIN = 28 + SM_CYMIN = 29 + SM_CXSIZE = 30 + SM_CYSIZE = 31 + SM_CXFRAME = 32 + SM_CYFRAME = 33 + SM_CXMINTRACK = 34 + SM_CYMINTRACK = 35 + SM_CXDOUBLECLK = 36 + SM_CYDOUBLECLK = 37 + SM_CXICONSPACING = 38 + SM_CYICONSPACING = 39 + SM_MENUDROPALIGNMENT = 40 + SM_PENWINDOWS = 41 + SM_DBCSENABLED = 42 + SM_CMOUSEBUTTONS = 43 + SM_CXFIXEDFRAME = SM_CXDLGFRAME + SM_CYFIXEDFRAME = SM_CYDLGFRAME + SM_CXSIZEFRAME = SM_CXFRAME + SM_CYSIZEFRAME = SM_CYFRAME + SM_SECURE = 44 + SM_CXEDGE = 45 + SM_CYEDGE = 46 + SM_CXMINSPACING = 47 + SM_CYMINSPACING = 48 + SM_CXSMICON = 49 + SM_CYSMICON = 50 + SM_CYSMCAPTION = 51 + SM_CXSMSIZE = 52 + SM_CYSMSIZE = 53 + SM_CXMENUSIZE = 54 + SM_CYMENUSIZE = 55 + SM_ARRANGE = 56 + SM_CXMINIMIZED = 57 + SM_CYMINIMIZED = 58 + SM_CXMAXTRACK = 59 + SM_CYMAXTRACK = 60 + SM_CXMAXIMIZED = 61 + SM_CYMAXIMIZED = 62 + SM_NETWORK = 63 + SM_CLEANBOOT = 67 + SM_CXDRAG = 68 + SM_CYDRAG = 69 + SM_SHOWSOUNDS = 70 + SM_CXMENUCHECK = 71 + SM_CYMENUCHECK = 72 + SM_SLOWMACHINE = 73 + SM_MIDEASTENABLED = 74 + SM_MOUSEWHEELPRESENT = 75 + SM_XVIRTUALSCREEN = 76 + SM_YVIRTUALSCREEN = 77 + SM_CXVIRTUALSCREEN = 78 + SM_CYVIRTUALSCREEN = 79 + SM_CMONITORS = 80 + SM_SAMEDISPLAYFORMAT = 81 + SM_IMMENABLED = 82 + SM_CXFOCUSBORDER = 83 + SM_CYFOCUSBORDER = 84 + SM_TABLETPC = 86 + SM_MEDIACENTER = 87 + SM_STARTER = 88 + SM_SERVERR2 = 89 + SM_CMETRICS = 91 + SM_REMOTESESSION = 0x1000 + SM_SHUTTINGDOWN = 0x2000 + SM_REMOTECONTROL = 0x2001 + SM_CARETBLINKINGENABLED = 0x2002 +) + +const ( + CLSCTX_INPROC_SERVER = 1 + CLSCTX_INPROC_HANDLER = 2 + CLSCTX_LOCAL_SERVER = 4 + CLSCTX_INPROC_SERVER16 = 8 + CLSCTX_REMOTE_SERVER = 16 + CLSCTX_ALL = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER | CLSCTX_LOCAL_SERVER + CLSCTX_INPROC = CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER + CLSCTX_SERVER = CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER | CLSCTX_REMOTE_SERVER +) + +const ( + COINIT_APARTMENTTHREADED = 0x2 + COINIT_MULTITHREADED = 0x0 + COINIT_DISABLE_OLE1DDE = 0x4 + COINIT_SPEED_OVER_MEMORY = 0x8 +) + +const ( + DISPATCH_METHOD = 1 + DISPATCH_PROPERTYGET = 2 + DISPATCH_PROPERTYPUT = 4 + DISPATCH_PROPERTYPUTREF = 8 +) + +const ( + CC_FASTCALL = iota + CC_CDECL + CC_MSCPASCAL + CC_PASCAL = CC_MSCPASCAL + CC_MACPASCAL + CC_STDCALL + CC_FPFASTCALL + CC_SYSCALL + CC_MPWCDECL + CC_MPWPASCAL + CC_MAX = CC_MPWPASCAL +) + +const ( + VT_EMPTY = 0x0 + VT_NULL = 0x1 + VT_I2 = 0x2 + VT_I4 = 0x3 + VT_R4 = 0x4 + VT_R8 = 0x5 + VT_CY = 0x6 + VT_DATE = 0x7 + VT_BSTR = 0x8 + VT_DISPATCH = 0x9 + VT_ERROR = 0xa + VT_BOOL = 0xb + VT_VARIANT = 0xc + VT_UNKNOWN = 0xd + VT_DECIMAL = 0xe + VT_I1 = 0x10 + VT_UI1 = 0x11 + VT_UI2 = 0x12 + VT_UI4 = 0x13 + VT_I8 = 0x14 + VT_UI8 = 0x15 + VT_INT = 0x16 + VT_UINT = 0x17 + VT_VOID = 0x18 + VT_HRESULT = 0x19 + VT_PTR = 0x1a + VT_SAFEARRAY = 0x1b + VT_CARRAY = 0x1c + VT_USERDEFINED = 0x1d + VT_LPSTR = 0x1e + VT_LPWSTR = 0x1f + VT_RECORD = 0x24 + VT_INT_PTR = 0x25 + VT_UINT_PTR = 0x26 + VT_FILETIME = 0x40 + VT_BLOB = 0x41 + VT_STREAM = 0x42 + VT_STORAGE = 0x43 + VT_STREAMED_OBJECT = 0x44 + VT_STORED_OBJECT = 0x45 + VT_BLOB_OBJECT = 0x46 + VT_CF = 0x47 + VT_CLSID = 0x48 + VT_BSTR_BLOB = 0xfff + VT_VECTOR = 0x1000 + VT_ARRAY = 0x2000 + VT_BYREF = 0x4000 + VT_RESERVED = 0x8000 + VT_ILLEGAL = 0xffff + VT_ILLEGALMASKED = 0xfff + VT_TYPEMASK = 0xfff +) + +const ( + DISPID_UNKNOWN = -1 + DISPID_VALUE = 0 + DISPID_PROPERTYPUT = -3 + DISPID_NEWENUM = -4 + DISPID_EVALUATE = -5 + DISPID_CONSTRUCTOR = -6 + DISPID_DESTRUCTOR = -7 + DISPID_COLLECT = -8 +) + +const ( + MONITOR_DEFAULTTONULL = 0x00000000 + MONITOR_DEFAULTTOPRIMARY = 0x00000001 + MONITOR_DEFAULTTONEAREST = 0x00000002 + + MONITORINFOF_PRIMARY = 0x00000001 +) + +const ( + CCHDEVICENAME = 32 + CCHFORMNAME = 32 +) + +const ( + IDOK = 1 + IDCANCEL = 2 + IDABORT = 3 + IDRETRY = 4 + IDIGNORE = 5 + IDYES = 6 + IDNO = 7 + IDCLOSE = 8 + IDHELP = 9 + IDTRYAGAIN = 10 + IDCONTINUE = 11 + IDTIMEOUT = 32000 +) + +// Generic WM_NOTIFY notification codes +const ( + NM_FIRST = 0 + NM_OUTOFMEMORY = NM_FIRST - 1 + NM_CLICK = NM_FIRST - 2 + NM_DBLCLK = NM_FIRST - 3 + NM_RETURN = NM_FIRST - 4 + NM_RCLICK = NM_FIRST - 5 + NM_RDBLCLK = NM_FIRST - 6 + NM_SETFOCUS = NM_FIRST - 7 + NM_KILLFOCUS = NM_FIRST - 8 + NM_CUSTOMDRAW = NM_FIRST - 12 + NM_HOVER = NM_FIRST - 13 + NM_NCHITTEST = NM_FIRST - 14 + NM_KEYDOWN = NM_FIRST - 15 + NM_RELEASEDCAPTURE = NM_FIRST - 16 + NM_SETCURSOR = NM_FIRST - 17 + NM_CHAR = NM_FIRST - 18 + NM_TOOLTIPSCREATED = NM_FIRST - 19 + NM_LAST = NM_FIRST - 99 +) + +// ListView messages +const ( + LVM_FIRST = 0x1000 + LVM_GETITEMCOUNT = LVM_FIRST + 4 + LVM_SETIMAGELIST = LVM_FIRST + 3 + LVM_GETIMAGELIST = LVM_FIRST + 2 + LVM_GETITEM = LVM_FIRST + 75 + LVM_SETITEM = LVM_FIRST + 76 + LVM_INSERTITEM = LVM_FIRST + 77 + LVM_DELETEITEM = LVM_FIRST + 8 + LVM_DELETEALLITEMS = LVM_FIRST + 9 + LVM_GETCALLBACKMASK = LVM_FIRST + 10 + LVM_SETCALLBACKMASK = LVM_FIRST + 11 + LVM_SETUNICODEFORMAT = CCM_SETUNICODEFORMAT + LVM_GETNEXTITEM = LVM_FIRST + 12 + LVM_FINDITEM = LVM_FIRST + 83 + LVM_GETITEMRECT = LVM_FIRST + 14 + LVM_GETSTRINGWIDTH = LVM_FIRST + 87 + LVM_HITTEST = LVM_FIRST + 18 + LVM_ENSUREVISIBLE = LVM_FIRST + 19 + LVM_SCROLL = LVM_FIRST + 20 + LVM_REDRAWITEMS = LVM_FIRST + 21 + LVM_ARRANGE = LVM_FIRST + 22 + LVM_EDITLABEL = LVM_FIRST + 118 + LVM_GETEDITCONTROL = LVM_FIRST + 24 + LVM_GETCOLUMN = LVM_FIRST + 95 + LVM_SETCOLUMN = LVM_FIRST + 96 + LVM_INSERTCOLUMN = LVM_FIRST + 97 + LVM_DELETECOLUMN = LVM_FIRST + 28 + LVM_GETCOLUMNWIDTH = LVM_FIRST + 29 + LVM_SETCOLUMNWIDTH = LVM_FIRST + 30 + LVM_GETHEADER = LVM_FIRST + 31 + LVM_CREATEDRAGIMAGE = LVM_FIRST + 33 + LVM_GETVIEWRECT = LVM_FIRST + 34 + LVM_GETTEXTCOLOR = LVM_FIRST + 35 + LVM_SETTEXTCOLOR = LVM_FIRST + 36 + LVM_GETTEXTBKCOLOR = LVM_FIRST + 37 + LVM_SETTEXTBKCOLOR = LVM_FIRST + 38 + LVM_GETTOPINDEX = LVM_FIRST + 39 + LVM_GETCOUNTPERPAGE = LVM_FIRST + 40 + LVM_GETORIGIN = LVM_FIRST + 41 + LVM_UPDATE = LVM_FIRST + 42 + LVM_SETITEMSTATE = LVM_FIRST + 43 + LVM_GETITEMSTATE = LVM_FIRST + 44 + LVM_GETITEMTEXT = LVM_FIRST + 115 + LVM_SETITEMTEXT = LVM_FIRST + 116 + LVM_SETITEMCOUNT = LVM_FIRST + 47 + LVM_SORTITEMS = LVM_FIRST + 48 + LVM_SETITEMPOSITION32 = LVM_FIRST + 49 + LVM_GETSELECTEDCOUNT = LVM_FIRST + 50 + LVM_GETITEMSPACING = LVM_FIRST + 51 + LVM_GETISEARCHSTRING = LVM_FIRST + 117 + LVM_SETICONSPACING = LVM_FIRST + 53 + LVM_SETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 54 + LVM_GETEXTENDEDLISTVIEWSTYLE = LVM_FIRST + 55 + LVM_GETSUBITEMRECT = LVM_FIRST + 56 + LVM_SUBITEMHITTEST = LVM_FIRST + 57 + LVM_SETCOLUMNORDERARRAY = LVM_FIRST + 58 + LVM_GETCOLUMNORDERARRAY = LVM_FIRST + 59 + LVM_SETHOTITEM = LVM_FIRST + 60 + LVM_GETHOTITEM = LVM_FIRST + 61 + LVM_SETHOTCURSOR = LVM_FIRST + 62 + LVM_GETHOTCURSOR = LVM_FIRST + 63 + LVM_APPROXIMATEVIEWRECT = LVM_FIRST + 64 + LVM_SETWORKAREAS = LVM_FIRST + 65 + LVM_GETWORKAREAS = LVM_FIRST + 70 + LVM_GETNUMBEROFWORKAREAS = LVM_FIRST + 73 + LVM_GETSELECTIONMARK = LVM_FIRST + 66 + LVM_SETSELECTIONMARK = LVM_FIRST + 67 + LVM_SETHOVERTIME = LVM_FIRST + 71 + LVM_GETHOVERTIME = LVM_FIRST + 72 + LVM_SETTOOLTIPS = LVM_FIRST + 74 + LVM_GETTOOLTIPS = LVM_FIRST + 78 + LVM_SORTITEMSEX = LVM_FIRST + 81 + LVM_SETBKIMAGE = LVM_FIRST + 138 + LVM_GETBKIMAGE = LVM_FIRST + 139 + LVM_SETSELECTEDCOLUMN = LVM_FIRST + 140 + LVM_SETVIEW = LVM_FIRST + 142 + LVM_GETVIEW = LVM_FIRST + 143 + LVM_INSERTGROUP = LVM_FIRST + 145 + LVM_SETGROUPINFO = LVM_FIRST + 147 + LVM_GETGROUPINFO = LVM_FIRST + 149 + LVM_REMOVEGROUP = LVM_FIRST + 150 + LVM_MOVEGROUP = LVM_FIRST + 151 + LVM_GETGROUPCOUNT = LVM_FIRST + 152 + LVM_GETGROUPINFOBYINDEX = LVM_FIRST + 153 + LVM_MOVEITEMTOGROUP = LVM_FIRST + 154 + LVM_GETGROUPRECT = LVM_FIRST + 98 + LVM_SETGROUPMETRICS = LVM_FIRST + 155 + LVM_GETGROUPMETRICS = LVM_FIRST + 156 + LVM_ENABLEGROUPVIEW = LVM_FIRST + 157 + LVM_SORTGROUPS = LVM_FIRST + 158 + LVM_INSERTGROUPSORTED = LVM_FIRST + 159 + LVM_REMOVEALLGROUPS = LVM_FIRST + 160 + LVM_HASGROUP = LVM_FIRST + 161 + LVM_GETGROUPSTATE = LVM_FIRST + 92 + LVM_GETFOCUSEDGROUP = LVM_FIRST + 93 + LVM_SETTILEVIEWINFO = LVM_FIRST + 162 + LVM_GETTILEVIEWINFO = LVM_FIRST + 163 + LVM_SETTILEINFO = LVM_FIRST + 164 + LVM_GETTILEINFO = LVM_FIRST + 165 + LVM_SETINSERTMARK = LVM_FIRST + 166 + LVM_GETINSERTMARK = LVM_FIRST + 167 + LVM_INSERTMARKHITTEST = LVM_FIRST + 168 + LVM_GETINSERTMARKRECT = LVM_FIRST + 169 + LVM_SETINSERTMARKCOLOR = LVM_FIRST + 170 + LVM_GETINSERTMARKCOLOR = LVM_FIRST + 171 + LVM_SETINFOTIP = LVM_FIRST + 173 + LVM_GETSELECTEDCOLUMN = LVM_FIRST + 174 + LVM_ISGROUPVIEWENABLED = LVM_FIRST + 175 + LVM_GETOUTLINECOLOR = LVM_FIRST + 176 + LVM_SETOUTLINECOLOR = LVM_FIRST + 177 + LVM_CANCELEDITLABEL = LVM_FIRST + 179 + LVM_MAPINDEXTOID = LVM_FIRST + 180 + LVM_MAPIDTOINDEX = LVM_FIRST + 181 + LVM_ISITEMVISIBLE = LVM_FIRST + 182 + LVM_GETNEXTITEMINDEX = LVM_FIRST + 211 +) + +// ListView notifications +const ( + LVN_FIRST = -100 + + LVN_ITEMCHANGING = LVN_FIRST - 0 + LVN_ITEMCHANGED = LVN_FIRST - 1 + LVN_INSERTITEM = LVN_FIRST - 2 + LVN_DELETEITEM = LVN_FIRST - 3 + LVN_DELETEALLITEMS = LVN_FIRST - 4 + LVN_BEGINLABELEDITA = LVN_FIRST - 5 + LVN_BEGINLABELEDITW = LVN_FIRST - 75 + LVN_ENDLABELEDITA = LVN_FIRST - 6 + LVN_ENDLABELEDITW = LVN_FIRST - 76 + LVN_COLUMNCLICK = LVN_FIRST - 8 + LVN_BEGINDRAG = LVN_FIRST - 9 + LVN_BEGINRDRAG = LVN_FIRST - 11 + LVN_ODCACHEHINT = LVN_FIRST - 13 + LVN_ODFINDITEMA = LVN_FIRST - 52 + LVN_ODFINDITEMW = LVN_FIRST - 79 + LVN_ITEMACTIVATE = LVN_FIRST - 14 + LVN_ODSTATECHANGED = LVN_FIRST - 15 + LVN_HOTTRACK = LVN_FIRST - 21 + LVN_GETDISPINFO = LVN_FIRST - 77 + LVN_SETDISPINFO = LVN_FIRST - 78 + LVN_KEYDOWN = LVN_FIRST - 55 + LVN_MARQUEEBEGIN = LVN_FIRST - 56 + LVN_GETINFOTIP = LVN_FIRST - 58 + LVN_INCREMENTALSEARCH = LVN_FIRST - 63 + LVN_BEGINSCROLL = LVN_FIRST - 80 + LVN_ENDSCROLL = LVN_FIRST - 81 +) + +// ListView LVNI constants +const ( + LVNI_ALL = 0 + LVNI_FOCUSED = 1 + LVNI_SELECTED = 2 + LVNI_CUT = 4 + LVNI_DROPHILITED = 8 + LVNI_ABOVE = 256 + LVNI_BELOW = 512 + LVNI_TOLEFT = 1024 + LVNI_TORIGHT = 2048 +) + +// ListView styles +const ( + LVS_ICON = 0x0000 + LVS_REPORT = 0x0001 + LVS_SMALLICON = 0x0002 + LVS_LIST = 0x0003 + LVS_TYPEMASK = 0x0003 + LVS_SINGLESEL = 0x0004 + LVS_SHOWSELALWAYS = 0x0008 + LVS_SORTASCENDING = 0x0010 + LVS_SORTDESCENDING = 0x0020 + LVS_SHAREIMAGELISTS = 0x0040 + LVS_NOLABELWRAP = 0x0080 + LVS_AUTOARRANGE = 0x0100 + LVS_EDITLABELS = 0x0200 + LVS_OWNERDATA = 0x1000 + LVS_NOSCROLL = 0x2000 + LVS_TYPESTYLEMASK = 0xfc00 + LVS_ALIGNTOP = 0x0000 + LVS_ALIGNLEFT = 0x0800 + LVS_ALIGNMASK = 0x0c00 + LVS_OWNERDRAWFIXED = 0x0400 + LVS_NOCOLUMNHEADER = 0x4000 + LVS_NOSORTHEADER = 0x8000 +) + +// ListView extended styles +const ( + LVS_EX_GRIDLINES = 0x00000001 + LVS_EX_SUBITEMIMAGES = 0x00000002 + LVS_EX_CHECKBOXES = 0x00000004 + LVS_EX_TRACKSELECT = 0x00000008 + LVS_EX_HEADERDRAGDROP = 0x00000010 + LVS_EX_FULLROWSELECT = 0x00000020 + LVS_EX_ONECLICKACTIVATE = 0x00000040 + LVS_EX_TWOCLICKACTIVATE = 0x00000080 + LVS_EX_FLATSB = 0x00000100 + LVS_EX_REGIONAL = 0x00000200 + LVS_EX_INFOTIP = 0x00000400 + LVS_EX_UNDERLINEHOT = 0x00000800 + LVS_EX_UNDERLINECOLD = 0x00001000 + LVS_EX_MULTIWORKAREAS = 0x00002000 + LVS_EX_LABELTIP = 0x00004000 + LVS_EX_BORDERSELECT = 0x00008000 + LVS_EX_DOUBLEBUFFER = 0x00010000 + LVS_EX_HIDELABELS = 0x00020000 + LVS_EX_SINGLEROW = 0x00040000 + LVS_EX_SNAPTOGRID = 0x00080000 + LVS_EX_SIMPLESELECT = 0x00100000 +) + +// ListView column flags +const ( + LVCF_FMT = 0x0001 + LVCF_WIDTH = 0x0002 + LVCF_TEXT = 0x0004 + LVCF_SUBITEM = 0x0008 + LVCF_IMAGE = 0x0010 + LVCF_ORDER = 0x0020 +) + +// ListView column format constants +const ( + LVCFMT_LEFT = 0x0000 + LVCFMT_RIGHT = 0x0001 + LVCFMT_CENTER = 0x0002 + LVCFMT_JUSTIFYMASK = 0x0003 + LVCFMT_IMAGE = 0x0800 + LVCFMT_BITMAP_ON_RIGHT = 0x1000 + LVCFMT_COL_HAS_IMAGES = 0x8000 +) + +// ListView item flags +const ( + LVIF_TEXT = 0x00000001 + LVIF_IMAGE = 0x00000002 + LVIF_PARAM = 0x00000004 + LVIF_STATE = 0x00000008 + LVIF_INDENT = 0x00000010 + LVIF_NORECOMPUTE = 0x00000800 + LVIF_GROUPID = 0x00000100 + LVIF_COLUMNS = 0x00000200 +) + +// ListView item states +const ( + LVIS_FOCUSED = 1 + LVIS_SELECTED = 2 + LVIS_CUT = 4 + LVIS_DROPHILITED = 8 + LVIS_OVERLAYMASK = 0xF00 + LVIS_STATEIMAGEMASK = 0xF000 +) + +// ListView hit test constants +const ( + LVHT_NOWHERE = 0x00000001 + LVHT_ONITEMICON = 0x00000002 + LVHT_ONITEMLABEL = 0x00000004 + LVHT_ONITEMSTATEICON = 0x00000008 + LVHT_ONITEM = LVHT_ONITEMICON | LVHT_ONITEMLABEL | LVHT_ONITEMSTATEICON + + LVHT_ABOVE = 0x00000008 + LVHT_BELOW = 0x00000010 + LVHT_TORIGHT = 0x00000020 + LVHT_TOLEFT = 0x00000040 +) + +// ListView image list types +const ( + LVSIL_NORMAL = 0 + LVSIL_SMALL = 1 + LVSIL_STATE = 2 + LVSIL_GROUPHEADER = 3 +) + +// InitCommonControlsEx flags +const ( + ICC_LISTVIEW_CLASSES = 1 + ICC_TREEVIEW_CLASSES = 2 + ICC_BAR_CLASSES = 4 + ICC_TAB_CLASSES = 8 + ICC_UPDOWN_CLASS = 16 + ICC_PROGRESS_CLASS = 32 + ICC_HOTKEY_CLASS = 64 + ICC_ANIMATE_CLASS = 128 + ICC_WIN95_CLASSES = 255 + ICC_DATE_CLASSES = 256 + ICC_USEREX_CLASSES = 512 + ICC_COOL_CLASSES = 1024 + ICC_INTERNET_CLASSES = 2048 + ICC_PAGESCROLLER_CLASS = 4096 + ICC_NATIVEFNTCTL_CLASS = 8192 + INFOTIPSIZE = 1024 + ICC_STANDARD_CLASSES = 0x00004000 + ICC_LINK_CLASS = 0x00008000 +) + +// Dialog Codes +const ( + DLGC_WANTARROWS = 0x0001 + DLGC_WANTTAB = 0x0002 + DLGC_WANTALLKEYS = 0x0004 + DLGC_WANTMESSAGE = 0x0004 + DLGC_HASSETSEL = 0x0008 + DLGC_DEFPUSHBUTTON = 0x0010 + DLGC_UNDEFPUSHBUTTON = 0x0020 + DLGC_RADIOBUTTON = 0x0040 + DLGC_WANTCHARS = 0x0080 + DLGC_STATIC = 0x0100 + DLGC_BUTTON = 0x2000 +) + +// Get/SetWindowWord/Long offsets for use with WC_DIALOG windows +const ( + DWL_MSGRESULT = 0 + DWL_DLGPROC = 4 + DWL_USER = 8 +) + +// PeekMessage wRemoveMsg value +const ( + PM_NOREMOVE = 0x000 + PM_REMOVE = 0x001 + PM_NOYIELD = 0x002 +) + +// ImageList flags +const ( + ILC_MASK = 0x00000001 + ILC_COLOR = 0x00000000 + ILC_COLORDDB = 0x000000FE + ILC_COLOR4 = 0x00000004 + ILC_COLOR8 = 0x00000008 + ILC_COLOR16 = 0x00000010 + ILC_COLOR24 = 0x00000018 + ILC_COLOR32 = 0x00000020 + ILC_PALETTE = 0x00000800 + ILC_MIRROR = 0x00002000 + ILC_PERITEMMIRROR = 0x00008000 + ILC_ORIGINALSIZE = 0x00010000 + ILC_HIGHQUALITYSCALE = 0x00020000 +) + +// Keystroke Message Flags +const ( + KF_EXTENDED = 0x0100 + KF_DLGMODE = 0x0800 + KF_MENUMODE = 0x1000 + KF_ALTDOWN = 0x2000 + KF_REPEAT = 0x4000 + KF_UP = 0x8000 +) + +// Virtual-Key Codes +const ( + VK_LBUTTON = 0x01 + VK_RBUTTON = 0x02 + VK_CANCEL = 0x03 + VK_MBUTTON = 0x04 + VK_XBUTTON1 = 0x05 + VK_XBUTTON2 = 0x06 + VK_BACK = 0x08 + VK_TAB = 0x09 + VK_CLEAR = 0x0C + VK_RETURN = 0x0D + VK_SHIFT = 0x10 + VK_CONTROL = 0x11 + VK_MENU = 0x12 + VK_PAUSE = 0x13 + VK_CAPITAL = 0x14 + VK_KANA = 0x15 + VK_HANGEUL = 0x15 + VK_HANGUL = 0x15 + VK_JUNJA = 0x17 + VK_FINAL = 0x18 + VK_HANJA = 0x19 + VK_KANJI = 0x19 + VK_ESCAPE = 0x1B + VK_CONVERT = 0x1C + VK_NONCONVERT = 0x1D + VK_ACCEPT = 0x1E + VK_MODECHANGE = 0x1F + VK_SPACE = 0x20 + VK_PRIOR = 0x21 + VK_NEXT = 0x22 + VK_END = 0x23 + VK_HOME = 0x24 + VK_LEFT = 0x25 + VK_UP = 0x26 + VK_RIGHT = 0x27 + VK_DOWN = 0x28 + VK_SELECT = 0x29 + VK_PRINT = 0x2A + VK_EXECUTE = 0x2B + VK_SNAPSHOT = 0x2C + VK_INSERT = 0x2D + VK_DELETE = 0x2E + VK_HELP = 0x2F + VK_LWIN = 0x5B + VK_RWIN = 0x5C + VK_APPS = 0x5D + VK_SLEEP = 0x5F + VK_NUMPAD0 = 0x60 + VK_NUMPAD1 = 0x61 + VK_NUMPAD2 = 0x62 + VK_NUMPAD3 = 0x63 + VK_NUMPAD4 = 0x64 + VK_NUMPAD5 = 0x65 + VK_NUMPAD6 = 0x66 + VK_NUMPAD7 = 0x67 + VK_NUMPAD8 = 0x68 + VK_NUMPAD9 = 0x69 + VK_MULTIPLY = 0x6A + VK_ADD = 0x6B + VK_SEPARATOR = 0x6C + VK_SUBTRACT = 0x6D + VK_DECIMAL = 0x6E + VK_DIVIDE = 0x6F + VK_F1 = 0x70 + VK_F2 = 0x71 + VK_F3 = 0x72 + VK_F4 = 0x73 + VK_F5 = 0x74 + VK_F6 = 0x75 + VK_F7 = 0x76 + VK_F8 = 0x77 + VK_F9 = 0x78 + VK_F10 = 0x79 + VK_F11 = 0x7A + VK_F12 = 0x7B + VK_F13 = 0x7C + VK_F14 = 0x7D + VK_F15 = 0x7E + VK_F16 = 0x7F + VK_F17 = 0x80 + VK_F18 = 0x81 + VK_F19 = 0x82 + VK_F20 = 0x83 + VK_F21 = 0x84 + VK_F22 = 0x85 + VK_F23 = 0x86 + VK_F24 = 0x87 + VK_NUMLOCK = 0x90 + VK_SCROLL = 0x91 + VK_OEM_NEC_EQUAL = 0x92 + VK_OEM_FJ_JISHO = 0x92 + VK_OEM_FJ_MASSHOU = 0x93 + VK_OEM_FJ_TOUROKU = 0x94 + VK_OEM_FJ_LOYA = 0x95 + VK_OEM_FJ_ROYA = 0x96 + VK_LSHIFT = 0xA0 + VK_RSHIFT = 0xA1 + VK_LCONTROL = 0xA2 + VK_RCONTROL = 0xA3 + VK_LMENU = 0xA4 + VK_RMENU = 0xA5 + VK_BROWSER_BACK = 0xA6 + VK_BROWSER_FORWARD = 0xA7 + VK_BROWSER_REFRESH = 0xA8 + VK_BROWSER_STOP = 0xA9 + VK_BROWSER_SEARCH = 0xAA + VK_BROWSER_FAVORITES = 0xAB + VK_BROWSER_HOME = 0xAC + VK_VOLUME_MUTE = 0xAD + VK_VOLUME_DOWN = 0xAE + VK_VOLUME_UP = 0xAF + VK_MEDIA_NEXT_TRACK = 0xB0 + VK_MEDIA_PREV_TRACK = 0xB1 + VK_MEDIA_STOP = 0xB2 + VK_MEDIA_PLAY_PAUSE = 0xB3 + VK_LAUNCH_MAIL = 0xB4 + VK_LAUNCH_MEDIA_SELECT = 0xB5 + VK_LAUNCH_APP1 = 0xB6 + VK_LAUNCH_APP2 = 0xB7 + VK_OEM_1 = 0xBA + VK_OEM_PLUS = 0xBB + VK_OEM_COMMA = 0xBC + VK_OEM_MINUS = 0xBD + VK_OEM_PERIOD = 0xBE + VK_OEM_2 = 0xBF + VK_OEM_3 = 0xC0 + VK_OEM_4 = 0xDB + VK_OEM_5 = 0xDC + VK_OEM_6 = 0xDD + VK_OEM_7 = 0xDE + VK_OEM_8 = 0xDF + VK_OEM_AX = 0xE1 + VK_OEM_102 = 0xE2 + VK_ICO_HELP = 0xE3 + VK_ICO_00 = 0xE4 + VK_PROCESSKEY = 0xE5 + VK_ICO_CLEAR = 0xE6 + VK_PACKET = 0xE7 + VK_OEM_RESET = 0xE9 + VK_OEM_JUMP = 0xEA + VK_OEM_PA1 = 0xEB + VK_OEM_PA2 = 0xEC + VK_OEM_PA3 = 0xED + VK_OEM_WSCTRL = 0xEE + VK_OEM_CUSEL = 0xEF + VK_OEM_ATTN = 0xF0 + VK_OEM_FINISH = 0xF1 + VK_OEM_COPY = 0xF2 + VK_OEM_AUTO = 0xF3 + VK_OEM_ENLW = 0xF4 + VK_OEM_BACKTAB = 0xF5 + VK_ATTN = 0xF6 + VK_CRSEL = 0xF7 + VK_EXSEL = 0xF8 + VK_EREOF = 0xF9 + VK_PLAY = 0xFA + VK_ZOOM = 0xFB + VK_NONAME = 0xFC + VK_PA1 = 0xFD + VK_OEM_CLEAR = 0xFE +) + +// Registry Value Types +const ( + REG_NONE = 0 + REG_SZ = 1 + REG_EXPAND_SZ = 2 + REG_BINARY = 3 + REG_DWORD = 4 + REG_DWORD_LITTLE_ENDIAN = 4 + REG_DWORD_BIG_ENDIAN = 5 + REG_LINK = 6 + REG_MULTI_SZ = 7 + REG_RESOURCE_LIST = 8 + REG_FULL_RESOURCE_DESCRIPTOR = 9 + REG_RESOURCE_REQUIREMENTS_LIST = 10 + REG_QWORD = 11 + REG_QWORD_LITTLE_ENDIAN = 11 +) + +// Tooltip styles +const ( + TTS_ALWAYSTIP = 0x01 + TTS_NOPREFIX = 0x02 + TTS_NOANIMATE = 0x10 + TTS_NOFADE = 0x20 + TTS_BALLOON = 0x40 + TTS_CLOSE = 0x80 + TTS_USEVISUALSTYLE = 0x100 +) + +// Tooltip messages +const ( + TTM_ACTIVATE = (WM_USER + 1) + TTM_SETDELAYTIME = (WM_USER + 3) + TTM_ADDTOOL = (WM_USER + 50) + TTM_DELTOOL = (WM_USER + 51) + TTM_NEWTOOLRECT = (WM_USER + 52) + TTM_RELAYEVENT = (WM_USER + 7) + TTM_GETTOOLINFO = (WM_USER + 53) + TTM_SETTOOLINFO = (WM_USER + 54) + TTM_HITTEST = (WM_USER + 55) + TTM_GETTEXT = (WM_USER + 56) + TTM_UPDATETIPTEXT = (WM_USER + 57) + TTM_GETTOOLCOUNT = (WM_USER + 13) + TTM_ENUMTOOLS = (WM_USER + 58) + TTM_GETCURRENTTOOL = (WM_USER + 59) + TTM_WINDOWFROMPOINT = (WM_USER + 16) + TTM_TRACKACTIVATE = (WM_USER + 17) + TTM_TRACKPOSITION = (WM_USER + 18) + TTM_SETTIPBKCOLOR = (WM_USER + 19) + TTM_SETTIPTEXTCOLOR = (WM_USER + 20) + TTM_GETDELAYTIME = (WM_USER + 21) + TTM_GETTIPBKCOLOR = (WM_USER + 22) + TTM_GETTIPTEXTCOLOR = (WM_USER + 23) + TTM_SETMAXTIPWIDTH = (WM_USER + 24) + TTM_GETMAXTIPWIDTH = (WM_USER + 25) + TTM_SETMARGIN = (WM_USER + 26) + TTM_GETMARGIN = (WM_USER + 27) + TTM_POP = (WM_USER + 28) + TTM_UPDATE = (WM_USER + 29) + TTM_GETBUBBLESIZE = (WM_USER + 30) + TTM_ADJUSTRECT = (WM_USER + 31) + TTM_SETTITLE = (WM_USER + 33) + TTM_POPUP = (WM_USER + 34) + TTM_GETTITLE = (WM_USER + 35) +) + +// Tooltip icons +const ( + TTI_NONE = 0 + TTI_INFO = 1 + TTI_WARNING = 2 + TTI_ERROR = 3 + TTI_INFO_LARGE = 4 + TTI_WARNING_LARGE = 5 + TTI_ERROR_LARGE = 6 +) + +// Tooltip notifications +const ( + TTN_FIRST = -520 + TTN_LAST = -549 + TTN_GETDISPINFO = (TTN_FIRST - 10) + TTN_SHOW = (TTN_FIRST - 1) + TTN_POP = (TTN_FIRST - 2) + TTN_LINKCLICK = (TTN_FIRST - 3) + TTN_NEEDTEXT = TTN_GETDISPINFO +) + +const ( + TTF_IDISHWND = 0x0001 + TTF_CENTERTIP = 0x0002 + TTF_RTLREADING = 0x0004 + TTF_SUBCLASS = 0x0010 + TTF_TRACK = 0x0020 + TTF_ABSOLUTE = 0x0080 + TTF_TRANSPARENT = 0x0100 + TTF_PARSELINKS = 0x1000 + TTF_DI_SETITEM = 0x8000 +) + +const ( + SWP_NOSIZE = 0x0001 + SWP_NOMOVE = 0x0002 + SWP_NOZORDER = 0x0004 + SWP_NOREDRAW = 0x0008 + SWP_NOACTIVATE = 0x0010 + SWP_FRAMECHANGED = 0x0020 + SWP_SHOWWINDOW = 0x0040 + SWP_HIDEWINDOW = 0x0080 + SWP_NOCOPYBITS = 0x0100 + SWP_NOOWNERZORDER = 0x0200 + SWP_NOSENDCHANGING = 0x0400 + SWP_DRAWFRAME = SWP_FRAMECHANGED + SWP_NOREPOSITION = SWP_NOOWNERZORDER + SWP_DEFERERASE = 0x2000 + SWP_ASYNCWINDOWPOS = 0x4000 +) + +// Predefined window handles +const ( + HWND_BROADCAST = HWND(0xFFFF) + HWND_BOTTOM = HWND(1) + HWND_NOTOPMOST = ^HWND(1) // -2 + HWND_TOP = HWND(0) + HWND_TOPMOST = ^HWND(0) // -1 + HWND_DESKTOP = HWND(0) + HWND_MESSAGE = ^HWND(2) // -3 +) + +// Pen types +const ( + PS_COSMETIC = 0x00000000 + PS_GEOMETRIC = 0x00010000 + PS_TYPE_MASK = 0x000F0000 +) + +// Pen styles +const ( + PS_SOLID = 0 + PS_DASH = 1 + PS_DOT = 2 + PS_DASHDOT = 3 + PS_DASHDOTDOT = 4 + PS_NULL = 5 + PS_INSIDEFRAME = 6 + PS_USERSTYLE = 7 + PS_ALTERNATE = 8 + PS_STYLE_MASK = 0x0000000F +) + +// Pen cap types +const ( + PS_ENDCAP_ROUND = 0x00000000 + PS_ENDCAP_SQUARE = 0x00000100 + PS_ENDCAP_FLAT = 0x00000200 + PS_ENDCAP_MASK = 0x00000F00 +) + +// Pen join types +const ( + PS_JOIN_ROUND = 0x00000000 + PS_JOIN_BEVEL = 0x00001000 + PS_JOIN_MITER = 0x00002000 + PS_JOIN_MASK = 0x0000F000 +) + +// Hatch styles +const ( + HS_HORIZONTAL = 0 + HS_VERTICAL = 1 + HS_FDIAGONAL = 2 + HS_BDIAGONAL = 3 + HS_CROSS = 4 + HS_DIAGCROSS = 5 +) + +// Stock Logical Objects +const ( + WHITE_BRUSH = 0 + LTGRAY_BRUSH = 1 + GRAY_BRUSH = 2 + DKGRAY_BRUSH = 3 + BLACK_BRUSH = 4 + NULL_BRUSH = 5 + HOLLOW_BRUSH = NULL_BRUSH + WHITE_PEN = 6 + BLACK_PEN = 7 + NULL_PEN = 8 + OEM_FIXED_FONT = 10 + ANSI_FIXED_FONT = 11 + ANSI_VAR_FONT = 12 + SYSTEM_FONT = 13 + DEVICE_DEFAULT_FONT = 14 + DEFAULT_PALETTE = 15 + SYSTEM_FIXED_FONT = 16 + DEFAULT_GUI_FONT = 17 + DC_BRUSH = 18 + DC_PEN = 19 +) + +// Brush styles +const ( + BS_SOLID = 0 + BS_NULL = 1 + BS_HOLLOW = BS_NULL + BS_HATCHED = 2 + BS_PATTERN = 3 + BS_INDEXED = 4 + BS_DIBPATTERN = 5 + BS_DIBPATTERNPT = 6 + BS_PATTERN8X8 = 7 + BS_DIBPATTERN8X8 = 8 + BS_MONOPATTERN = 9 +) + +// TRACKMOUSEEVENT flags +const ( + TME_HOVER = 0x00000001 + TME_LEAVE = 0x00000002 + TME_NONCLIENT = 0x00000010 + TME_QUERY = 0x40000000 + TME_CANCEL = 0x80000000 + + HOVER_DEFAULT = 0xFFFFFFFF +) + +// WM_NCHITTEST and MOUSEHOOKSTRUCT Mouse Position Codes +const ( + HTERROR = (-2) + HTTRANSPARENT = (-1) + HTNOWHERE = 0 + HTCLIENT = 1 + HTCAPTION = 2 + HTSYSMENU = 3 + HTGROWBOX = 4 + HTSIZE = HTGROWBOX + HTMENU = 5 + HTHSCROLL = 6 + HTVSCROLL = 7 + HTMINBUTTON = 8 + HTMAXBUTTON = 9 + HTLEFT = 10 + HTRIGHT = 11 + HTTOP = 12 + HTTOPLEFT = 13 + HTTOPRIGHT = 14 + HTBOTTOM = 15 + HTBOTTOMLEFT = 16 + HTBOTTOMRIGHT = 17 + HTBORDER = 18 + HTREDUCE = HTMINBUTTON + HTZOOM = HTMAXBUTTON + HTSIZEFIRST = HTLEFT + HTSIZELAST = HTBOTTOMRIGHT + HTOBJECT = 19 + HTCLOSE = 20 + HTHELP = 21 +) + +// DrawText[Ex] format flags +const ( + DT_TOP = 0x00000000 + DT_LEFT = 0x00000000 + DT_CENTER = 0x00000001 + DT_RIGHT = 0x00000002 + DT_VCENTER = 0x00000004 + DT_BOTTOM = 0x00000008 + DT_WORDBREAK = 0x00000010 + DT_SINGLELINE = 0x00000020 + DT_EXPANDTABS = 0x00000040 + DT_TABSTOP = 0x00000080 + DT_NOCLIP = 0x00000100 + DT_EXTERNALLEADING = 0x00000200 + DT_CALCRECT = 0x00000400 + DT_NOPREFIX = 0x00000800 + DT_INTERNAL = 0x00001000 + DT_EDITCONTROL = 0x00002000 + DT_PATH_ELLIPSIS = 0x00004000 + DT_END_ELLIPSIS = 0x00008000 + DT_MODIFYSTRING = 0x00010000 + DT_RTLREADING = 0x00020000 + DT_WORD_ELLIPSIS = 0x00040000 + DT_NOFULLWIDTHCHARBREAK = 0x00080000 + DT_HIDEPREFIX = 0x00100000 + DT_PREFIXONLY = 0x00200000 +) + +const CLR_INVALID = 0xFFFFFFFF + +// Background Modes +const ( + TRANSPARENT = 1 + OPAQUE = 2 + BKMODE_LAST = 2 +) + +// Global Memory Flags +const ( + GMEM_FIXED = 0x0000 + GMEM_MOVEABLE = 0x0002 + GMEM_NOCOMPACT = 0x0010 + GMEM_NODISCARD = 0x0020 + GMEM_ZEROINIT = 0x0040 + GMEM_MODIFY = 0x0080 + GMEM_DISCARDABLE = 0x0100 + GMEM_NOT_BANKED = 0x1000 + GMEM_SHARE = 0x2000 + GMEM_DDESHARE = 0x2000 + GMEM_NOTIFY = 0x4000 + GMEM_LOWER = GMEM_NOT_BANKED + GMEM_VALID_FLAGS = 0x7F72 + GMEM_INVALID_HANDLE = 0x8000 + GHND = (GMEM_MOVEABLE | GMEM_ZEROINIT) + GPTR = (GMEM_FIXED | GMEM_ZEROINIT) +) + +// Ternary raster operations +const ( + SRCCOPY = 0x00CC0020 + SRCPAINT = 0x00EE0086 + SRCAND = 0x008800C6 + SRCINVERT = 0x00660046 + SRCERASE = 0x00440328 + NOTSRCCOPY = 0x00330008 + NOTSRCERASE = 0x001100A6 + MERGECOPY = 0x00C000CA + MERGEPAINT = 0x00BB0226 + PATCOPY = 0x00F00021 + PATPAINT = 0x00FB0A09 + PATINVERT = 0x005A0049 + DSTINVERT = 0x00550009 + BLACKNESS = 0x00000042 + WHITENESS = 0x00FF0062 + NOMIRRORBITMAP = 0x80000000 + CAPTUREBLT = 0x40000000 +) + +// Clipboard formats +const ( + CF_TEXT = 1 + CF_BITMAP = 2 + CF_METAFILEPICT = 3 + CF_SYLK = 4 + CF_DIF = 5 + CF_TIFF = 6 + CF_OEMTEXT = 7 + CF_DIB = 8 + CF_PALETTE = 9 + CF_PENDATA = 10 + CF_RIFF = 11 + CF_WAVE = 12 + CF_UNICODETEXT = 13 + CF_ENHMETAFILE = 14 + CF_HDROP = 15 + CF_LOCALE = 16 + CF_DIBV5 = 17 + CF_MAX = 18 + CF_OWNERDISPLAY = 0x0080 + CF_DSPTEXT = 0x0081 + CF_DSPBITMAP = 0x0082 + CF_DSPMETAFILEPICT = 0x0083 + CF_DSPENHMETAFILE = 0x008E + CF_PRIVATEFIRST = 0x0200 + CF_PRIVATELAST = 0x02FF + CF_GDIOBJFIRST = 0x0300 + CF_GDIOBJLAST = 0x03FF +) + +// Bitmap compression formats +const ( + BI_RGB = 0 + BI_RLE8 = 1 + BI_RLE4 = 2 + BI_BITFIELDS = 3 + BI_JPEG = 4 + BI_PNG = 5 +) + +// SetDIBitsToDevice fuColorUse +const ( + DIB_PAL_COLORS = 1 + DIB_RGB_COLORS = 0 +) + +const ( + STANDARD_RIGHTS_REQUIRED = 0x000F +) + +// MapVirtualKey maptypes +const ( + MAPVK_VK_TO_CHAR = 2 + MAPVK_VK_TO_VSC = 0 + MAPVK_VSC_TO_VK = 1 + MAPVK_VSC_TO_VK_EX = 3 +) + +// ReadEventLog Flags +const ( + EVENTLOG_SEEK_READ = 0x0002 + EVENTLOG_SEQUENTIAL_READ = 0x0001 + EVENTLOG_FORWARDS_READ = 0x0004 + EVENTLOG_BACKWARDS_READ = 0x0008 +) + +// CreateToolhelp32Snapshot flags +const ( + TH32CS_SNAPHEAPLIST = 0x00000001 + TH32CS_SNAPPROCESS = 0x00000002 + TH32CS_SNAPTHREAD = 0x00000004 + TH32CS_SNAPMODULE = 0x00000008 + TH32CS_SNAPMODULE32 = 0x00000010 + TH32CS_INHERIT = 0x80000000 + TH32CS_SNAPALL = TH32CS_SNAPHEAPLIST | TH32CS_SNAPMODULE | TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD +) + +const ( + MAX_MODULE_NAME32 = 255 + MAX_PATH = 260 +) + +const ( + FOREGROUND_BLUE = 0x0001 + FOREGROUND_GREEN = 0x0002 + FOREGROUND_RED = 0x0004 + FOREGROUND_INTENSITY = 0x0008 + BACKGROUND_BLUE = 0x0010 + BACKGROUND_GREEN = 0x0020 + BACKGROUND_RED = 0x0040 + BACKGROUND_INTENSITY = 0x0080 + COMMON_LVB_LEADING_BYTE = 0x0100 + COMMON_LVB_TRAILING_BYTE = 0x0200 + COMMON_LVB_GRID_HORIZONTAL = 0x0400 + COMMON_LVB_GRID_LVERTICAL = 0x0800 + COMMON_LVB_GRID_RVERTICAL = 0x1000 + COMMON_LVB_REVERSE_VIDEO = 0x4000 + COMMON_LVB_UNDERSCORE = 0x8000 +) + +// Flags used by the DWM_BLURBEHIND structure to indicate +// which of its members contain valid information. +const ( + DWM_BB_ENABLE = 0x00000001 // A value for the fEnable member has been specified. + DWM_BB_BLURREGION = 0x00000002 // A value for the hRgnBlur member has been specified. + DWM_BB_TRANSITIONONMAXIMIZED = 0x00000004 // A value for the fTransitionOnMaximized member has been specified. +) + +// Flags used by the DwmEnableComposition function +// to change the state of Desktop Window Manager (DWM) composition. +const ( + DWM_EC_DISABLECOMPOSITION = 0 // Disable composition + DWM_EC_ENABLECOMPOSITION = 1 // Enable composition +) + +// enum-lite implementation for the following constant structure +type DWM_SHOWCONTACT int32 + +const ( + DWMSC_DOWN = 0x00000001 + DWMSC_UP = 0x00000002 + DWMSC_DRAG = 0x00000004 + DWMSC_HOLD = 0x00000008 + DWMSC_PENBARREL = 0x00000010 + DWMSC_NONE = 0x00000000 + DWMSC_ALL = 0xFFFFFFFF +) + +// enum-lite implementation for the following constant structure +type DWM_SOURCE_FRAME_SAMPLING int32 + +// TODO: need to verify this construction +// Flags used by the DwmSetPresentParameters function +// to specify the frame sampling type +const ( + DWM_SOURCE_FRAME_SAMPLING_POINT = iota + 1 + DWM_SOURCE_FRAME_SAMPLING_COVERAGE + DWM_SOURCE_FRAME_SAMPLING_LAST +) + +// Flags used by the DWM_THUMBNAIL_PROPERTIES structure to +// indicate which of its members contain valid information. +const ( + DWM_TNP_RECTDESTINATION = 0x00000001 // A value for the rcDestination member has been specified + DWM_TNP_RECTSOURCE = 0x00000002 // A value for the rcSource member has been specified + DWM_TNP_OPACITY = 0x00000004 // A value for the opacity member has been specified + DWM_TNP_VISIBLE = 0x00000008 // A value for the fVisible member has been specified + DWM_TNP_SOURCECLIENTAREAONLY = 0x00000010 // A value for the fSourceClientAreaOnly member has been specified +) + +// enum-lite implementation for the following constant structure +type DWMFLIP3DWINDOWPOLICY int32 + +// TODO: need to verify this construction +// Flags used by the DwmSetWindowAttribute function +// to specify the Flip3D window policy +const ( + DWMFLIP3D_DEFAULT = iota + 1 + DWMFLIP3D_EXCLUDEBELOW + DWMFLIP3D_EXCLUDEABOVE + DWMFLIP3D_LAST +) + +// enum-lite implementation for the following constant structure +type DWMNCRENDERINGPOLICY int32 + +// TODO: need to verify this construction +// Flags used by the DwmSetWindowAttribute function +// to specify the non-client area rendering policy +const ( + DWMNCRP_USEWINDOWSTYLE = iota + 1 + DWMNCRP_DISABLED + DWMNCRP_ENABLED + DWMNCRP_LAST +) + +// enum-lite implementation for the following constant structure +type DWMTRANSITION_OWNEDWINDOW_TARGET int32 + +const ( + DWMTRANSITION_OWNEDWINDOW_NULL = -1 + DWMTRANSITION_OWNEDWINDOW_REPOSITION = 0 +) + +// enum-lite implementation for the following constant structure +type DWMWINDOWATTRIBUTE int32 + +// TODO: need to verify this construction +// Flags used by the DwmGetWindowAttribute and DwmSetWindowAttribute functions +// to specify window attributes for non-client rendering +const ( + DWMWA_NCRENDERING_ENABLED = iota + 1 + DWMWA_NCRENDERING_POLICY + DWMWA_TRANSITIONS_FORCEDISABLED + DWMWA_ALLOW_NCPAINT + DWMWA_CAPTION_BUTTON_BOUNDS + DWMWA_NONCLIENT_RTL_LAYOUT + DWMWA_FORCE_ICONIC_REPRESENTATION + DWMWA_FLIP3D_POLICY + DWMWA_EXTENDED_FRAME_BOUNDS + DWMWA_HAS_ICONIC_BITMAP + DWMWA_DISALLOW_PEEK + DWMWA_EXCLUDED_FROM_PEEK + DWMWA_CLOAK + DWMWA_CLOAKED + DWMWA_FREEZE_REPRESENTATION + DWMWA_LAST +) + +// enum-lite implementation for the following constant structure +type GESTURE_TYPE int32 + +// TODO: use iota? +// Identifies the gesture type +const ( + GT_PEN_TAP = 0 + GT_PEN_DOUBLETAP = 1 + GT_PEN_RIGHTTAP = 2 + GT_PEN_PRESSANDHOLD = 3 + GT_PEN_PRESSANDHOLDABORT = 4 + GT_TOUCH_TAP = 5 + GT_TOUCH_DOUBLETAP = 6 + GT_TOUCH_RIGHTTAP = 7 + GT_TOUCH_PRESSANDHOLD = 8 + GT_TOUCH_PRESSANDHOLDABORT = 9 + GT_TOUCH_PRESSANDTAP = 10 +) + +// Icons +const ( + ICON_SMALL = 0 + ICON_BIG = 1 + ICON_SMALL2 = 2 +) + +const ( + SIZE_RESTORED = 0 + SIZE_MINIMIZED = 1 + SIZE_MAXIMIZED = 2 + SIZE_MAXSHOW = 3 + SIZE_MAXHIDE = 4 +) + +// XButton values +const ( + XBUTTON1 = 1 + XBUTTON2 = 2 +) + +// Devmode +const ( + DM_SPECVERSION = 0x0401 + + DM_ORIENTATION = 0x00000001 + DM_PAPERSIZE = 0x00000002 + DM_PAPERLENGTH = 0x00000004 + DM_PAPERWIDTH = 0x00000008 + DM_SCALE = 0x00000010 + DM_POSITION = 0x00000020 + DM_NUP = 0x00000040 + DM_DISPLAYORIENTATION = 0x00000080 + DM_COPIES = 0x00000100 + DM_DEFAULTSOURCE = 0x00000200 + DM_PRINTQUALITY = 0x00000400 + DM_COLOR = 0x00000800 + DM_DUPLEX = 0x00001000 + DM_YRESOLUTION = 0x00002000 + DM_TTOPTION = 0x00004000 + DM_COLLATE = 0x00008000 + DM_FORMNAME = 0x00010000 + DM_LOGPIXELS = 0x00020000 + DM_BITSPERPEL = 0x00040000 + DM_PELSWIDTH = 0x00080000 + DM_PELSHEIGHT = 0x00100000 + DM_DISPLAYFLAGS = 0x00200000 + DM_DISPLAYFREQUENCY = 0x00400000 + DM_ICMMETHOD = 0x00800000 + DM_ICMINTENT = 0x01000000 + DM_MEDIATYPE = 0x02000000 + DM_DITHERTYPE = 0x04000000 + DM_PANNINGWIDTH = 0x08000000 + DM_PANNINGHEIGHT = 0x10000000 + DM_DISPLAYFIXEDOUTPUT = 0x20000000 +) + +// ChangeDisplaySettings +const ( + CDS_UPDATEREGISTRY = 0x00000001 + CDS_TEST = 0x00000002 + CDS_FULLSCREEN = 0x00000004 + CDS_GLOBAL = 0x00000008 + CDS_SET_PRIMARY = 0x00000010 + CDS_VIDEOPARAMETERS = 0x00000020 + CDS_RESET = 0x40000000 + CDS_NORESET = 0x10000000 + + DISP_CHANGE_SUCCESSFUL = 0 + DISP_CHANGE_RESTART = 1 + DISP_CHANGE_FAILED = -1 + DISP_CHANGE_BADMODE = -2 + DISP_CHANGE_NOTUPDATED = -3 + DISP_CHANGE_BADFLAGS = -4 + DISP_CHANGE_BADPARAM = -5 + DISP_CHANGE_BADDUALVIEW = -6 +) + +const ( + ENUM_CURRENT_SETTINGS = 0xFFFFFFFF + ENUM_REGISTRY_SETTINGS = 0xFFFFFFFE +) + +// PIXELFORMATDESCRIPTOR +const ( + PFD_TYPE_RGBA = 0 + PFD_TYPE_COLORINDEX = 1 + + PFD_MAIN_PLANE = 0 + PFD_OVERLAY_PLANE = 1 + PFD_UNDERLAY_PLANE = -1 + + PFD_DOUBLEBUFFER = 0x00000001 + PFD_STEREO = 0x00000002 + PFD_DRAW_TO_WINDOW = 0x00000004 + PFD_DRAW_TO_BITMAP = 0x00000008 + PFD_SUPPORT_GDI = 0x00000010 + PFD_SUPPORT_OPENGL = 0x00000020 + PFD_GENERIC_FORMAT = 0x00000040 + PFD_NEED_PALETTE = 0x00000080 + PFD_NEED_SYSTEM_PALETTE = 0x00000100 + PFD_SWAP_EXCHANGE = 0x00000200 + PFD_SWAP_COPY = 0x00000400 + PFD_SWAP_LAYER_BUFFERS = 0x00000800 + PFD_GENERIC_ACCELERATED = 0x00001000 + PFD_SUPPORT_DIRECTDRAW = 0x00002000 + PFD_DIRECT3D_ACCELERATED = 0x00004000 + PFD_SUPPORT_COMPOSITION = 0x00008000 + + PFD_DEPTH_DONTCARE = 0x20000000 + PFD_DOUBLEBUFFER_DONTCARE = 0x40000000 + PFD_STEREO_DONTCARE = 0x80000000 +) + +const ( + INPUT_MOUSE = 0 + INPUT_KEYBOARD = 1 + INPUT_HARDWARE = 2 +) + +const ( + MOUSEEVENTF_ABSOLUTE = 0x8000 + MOUSEEVENTF_HWHEEL = 0x01000 + MOUSEEVENTF_MOVE = 0x0001 + MOUSEEVENTF_MOVE_NOCOALESCE = 0x2000 + MOUSEEVENTF_LEFTDOWN = 0x0002 + MOUSEEVENTF_LEFTUP = 0x0004 + MOUSEEVENTF_RIGHTDOWN = 0x0008 + MOUSEEVENTF_RIGHTUP = 0x0010 + MOUSEEVENTF_MIDDLEDOWN = 0x0020 + MOUSEEVENTF_MIDDLEUP = 0x0040 + MOUSEEVENTF_VIRTUALDESK = 0x4000 + MOUSEEVENTF_WHEEL = 0x0800 + MOUSEEVENTF_XDOWN = 0x0080 + MOUSEEVENTF_XUP = 0x0100 +) + +// Windows Hooks (WH_*) +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990(v=vs.85).aspx +const ( + WH_CALLWNDPROC = 4 + WH_CALLWNDPROCRET = 12 + WH_CBT = 5 + WH_DEBUG = 9 + WH_FOREGROUNDIDLE = 11 + WH_GETMESSAGE = 3 + WH_JOURNALPLAYBACK = 1 + WH_JOURNALRECORD = 0 + WH_KEYBOARD = 2 + WH_KEYBOARD_LL = 13 + WH_MOUSE = 7 + WH_MOUSE_LL = 14 + WH_MSGFILTER = -1 + WH_SHELL = 10 + WH_SYSMSGFILTER = 6 +) + +const ( + MEM_COMMIT = 0x00001000 + MEM_RESERVE = 0x00002000 + MEM_RESET = 0x00080000 + MEM_RESET_UNDO = 0x1000000 + + MEM_LARGE_PAGES = 0x20000000 + MEM_PHYSICAL = 0x00400000 + MEM_TOP_DOWN = 0x00100000 + + MEM_DECOMMIT = 0x4000 + MEM_RELEASE = 0x8000 +) + +const ( + PROCESS_CREATE_PROCESS = 0x0080 + PROCESS_CREATE_THREAD = 0x0002 + PROCESS_DUP_HANDLE = 0x0040 + PROCESS_QUERY_INFORMATION = 0x0400 + PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 + PROCESS_SET_INFORMATION = 0x0200 + PROCESS_SET_QUOTA = 0x0100 + PROCESS_SUSPEND_RESUME = 0x0800 + PROCESS_TERMINATE = 0x0001 + PROCESS_VM_OPERATION = 0x0008 + PROCESS_VM_READ = 0x0010 + PROCESS_VM_WRITE = 0x0020 + SYNCHRONIZE = 0x00100000 +) + +const ( + PAGE_EXECUTE = 0x10 + PAGE_EXECUTE_READ = 0x20 + PAGE_EXECUTE_READWRITE = 0x40 + PAGE_EXECUTE_WRITECOPY = 0x80 + PAGE_NOACCESS = 0x01 + PAGE_READWRITE = 0x04 + PAGE_WRITECOPY = 0x08 + PAGE_TARGETS_INVALID = 0x40000000 + PAGE_TARGETS_NO_UPDATE = 0x40000000 +) + +// SendMessageTimeout Flags +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms644952(v=vs.85).aspx +const ( + SMTO_ABORTIFHUNG = 0x0002 + SMTO_BLOCK = 0x0001 + SMTO_NORMAL = 0x0000 + SMTO_NOTIMEOUTIFNOTHUNG = 0x0008 + SMTO_ERRORONEXIT = 0x0020 +) + +// RedrawWindow Flags +const ( + RDW_ERASE = 4 + RDW_ALLCHILDREN = 0x80 + RDW_ERASENOW = 0x200 + RDW_FRAME = 0x400 + RDW_INTERNALPAINT = 2 + RDW_INVALIDATE = 1 + RDW_NOCHILDREN = 0x40 + RDW_NOERASE = 0x20 + RDW_NOFRAME = 0x800 + RDW_NOINTERNALPAINT = 0x10 + RDW_UPDATENOW = 0x100 + RDW_VALIDATE = 8 +) diff --git a/platform/vendor/github.com/MaxRis/w32/create_process.go b/platform/vendor/github.com/MaxRis/w32/create_process.go new file mode 100644 index 0000000..9caf9ff --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/create_process.go @@ -0,0 +1,152 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + kernel32 = syscall.NewLazyDLL("kernel32.dll") + + procCreateProcessW = kernel32.NewProc("CreateProcessW") + procTerminateProcess = kernel32.NewProc("TerminateProcess") + procGetExitCodeProcess = kernel32.NewProc("GetExitCodeProcess") + procWaitForSingleObject = kernel32.NewProc("WaitForSingleObject") +) + +// WINBASEAPI WINBOOL WINAPI +// CreateProcessW ( +// LPCWSTR lpApplicationName, +// LPWSTR lpCommandLine, +// LPSECURITY_ATTRIBUTES lpProcessAttributes, +// LPSECURITY_ATTRIBUTES lpThreadAttributes +// WINBOOL bInheritHandles +// DWORD dwCreationFlags +// LPVOID lpEnvironment +// LPCWSTR lpCurrentDirectory +// LPSTARTUPINFOW lpStartupInfo +// LPPROCESS_INFORMATION lpProcessInformation +//); +func CreateProcessW( + lpApplicationName, lpCommandLine string, + lpProcessAttributes, lpThreadAttributes *SECURITY_ATTRIBUTES, + bInheritHandles BOOL, + dwCreationFlags uint32, + lpEnvironment unsafe.Pointer, + lpCurrentDirectory string, + lpStartupInfo *STARTUPINFOW, + lpProcessInformation *PROCESS_INFORMATION, +) (e error) { + + var lpAN, lpCL, lpCD *uint16 + if len(lpApplicationName) > 0 { + lpAN, e = syscall.UTF16PtrFromString(lpApplicationName) + if e != nil { + return + } + } + if len(lpCommandLine) > 0 { + lpCL, e = syscall.UTF16PtrFromString(lpCommandLine) + if e != nil { + return + } + } + if len(lpCurrentDirectory) > 0 { + lpCD, e = syscall.UTF16PtrFromString(lpCurrentDirectory) + if e != nil { + return + } + } + + ret, _, lastErr := procCreateProcessW.Call( + uintptr(unsafe.Pointer(lpAN)), + uintptr(unsafe.Pointer(lpCL)), + uintptr(unsafe.Pointer(lpProcessAttributes)), + uintptr(unsafe.Pointer(lpProcessInformation)), + uintptr(bInheritHandles), + uintptr(dwCreationFlags), + uintptr(lpEnvironment), + uintptr(unsafe.Pointer(lpCD)), + uintptr(unsafe.Pointer(lpStartupInfo)), + uintptr(unsafe.Pointer(lpProcessInformation)), + ) + + if ret == 0 { + e = lastErr + } + + return +} + +func CreateProcessQuick(cmd string) (pi PROCESS_INFORMATION, e error) { + si := &STARTUPINFOW{} + e = CreateProcessW( + "", + cmd, + nil, + nil, + 0, + 0, + unsafe.Pointer(nil), + "", + si, + &pi, + ) + return +} + +func TerminateProcess(hProcess HANDLE, exitCode uint32) (e error) { + ret, _, lastErr := procTerminateProcess.Call( + uintptr(hProcess), + uintptr(exitCode), + ) + + if ret == 0 { + e = lastErr + } + + return +} + +func GetExitCodeProcess(hProcess HANDLE) (code uintptr, e error) { + ret, _, lastErr := procGetExitCodeProcess.Call( + uintptr(hProcess), + uintptr(unsafe.Pointer(&code)), + ) + + if ret == 0 { + e = lastErr + } + + return +} + +// DWORD WINAPI WaitForSingleObject( +// _In_ HANDLE hHandle, +// _In_ DWORD dwMilliseconds +// ); + +func WaitForSingleObject(hHandle HANDLE, msecs uint32) (ok bool, e error) { + + ret, _, lastErr := procWaitForSingleObject.Call( + uintptr(hHandle), + uintptr(msecs), + ) + + if ret == WAIT_OBJECT_0 { + ok = true + return + } + + // don't set e for timeouts, or it will be ERROR_SUCCESS which is + // confusing + if ret != WAIT_TIMEOUT { + e = lastErr + } + return + +} diff --git a/platform/vendor/github.com/MaxRis/w32/create_process_constants.go b/platform/vendor/github.com/MaxRis/w32/create_process_constants.go new file mode 100644 index 0000000..c37d7e5 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/create_process_constants.go @@ -0,0 +1,9 @@ +package w32 + +const ( + WAIT_ABANDONED = 0x00000080 + WAIT_OBJECT_0 = 0x00000000 + WAIT_TIMEOUT = 0x00000102 + WAIT_FAILED = 0xFFFFFFFF + INFINITE = 0xFFFFFFFF +) diff --git a/platform/vendor/github.com/MaxRis/w32/create_process_test.go b/platform/vendor/github.com/MaxRis/w32/create_process_test.go new file mode 100644 index 0000000..7e64b1d --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/create_process_test.go @@ -0,0 +1,47 @@ +package w32 + +import ( + "testing" +) + +var testProcess = "notepad.exe" +var wantCode = uint32(42) + +func TestCreateProcess(t *testing.T) { + + pi, err := CreateProcessQuick(testProcess) + if err != nil { + t.Errorf("[!!] Failed to create %s: %s", testProcess, err) + } else { + t.Logf("[OK] Created process %s with handle 0x%x, PID %d", testProcess, pi.Process, pi.ProcessId) + } + + err = TerminateProcess(pi.Process, wantCode) + if err != nil { + t.Errorf("[!!]Failed to terminate %s: %s", testProcess, err) + } else { + t.Logf("[OK] Called TerminateProcess on PID %d", pi.ProcessId) + } + + err = WaitForSingleObject(pi.Process, 1000) // 1000ms + if err != nil { + t.Errorf("[!!] failed in WaitForSingleObject: %s", err) + } else { + t.Logf("[OK] WaitForSingleObject returned...") + } + + // make sure we see the magic exit code we asked for + code, err := GetExitCodeProcess(pi.Process) + if err != nil { + t.Errorf("[!!] Failed to get exit code for PID %d: %s", pi.ProcessId, err) + } else { + t.Logf("[OK] PID %d Exited with code %d", pi.ProcessId, code) + } + if code != 42 { + t.Errorf("[!!] Unexpected exit code for PID %d - want %d, got %d", pi.ProcessId, wantCode, code) + } + + CloseHandle(pi.Process) + CloseHandle(pi.Thread) + +} diff --git a/platform/vendor/github.com/MaxRis/w32/create_process_typedef.go b/platform/vendor/github.com/MaxRis/w32/create_process_typedef.go new file mode 100644 index 0000000..df05972 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/create_process_typedef.go @@ -0,0 +1,68 @@ +package w32 + +// typedef struct _PROCESS_INFORMATION { +// HANDLE hProcess; +// HANDLE hThread; +// DWORD dwProcessId; +// DWORD dwThreadId; +// } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION; + +type PROCESS_INFORMATION struct { + Process HANDLE + Thread HANDLE + ProcessId uint32 + ThreadId uint32 +} + +// typedef struct _STARTUPINFOW { +// DWORD cb; +// LPWSTR lpReserved; +// LPWSTR lpDesktop; +// LPWSTR lpTitle; +// DWORD dwX; +// DWORD dwY; +// DWORD dwXSize; +// DWORD dwYSize; +// DWORD dwXCountChars; +// DWORD dwYCountChars; +// DWORD dwFillAttribute; +// DWORD dwFlags; +// WORD wShowWindow; +// WORD cbReserved2; +// LPBYTE lpReserved2; +// HANDLE hStdInput; +// HANDLE hStdOutput; +// HANDLE hStdError; +// } STARTUPINFOW, *LPSTARTUPINFOW; + +type STARTUPINFOW struct { + cb uint32 + _ *uint16 + Desktop *uint16 + Title *uint16 + X uint32 + Y uint32 + XSize uint32 + YSize uint32 + XCountChars uint32 + YCountChars uint32 + FillAttribute uint32 + Flags uint32 + ShowWindow uint16 + _ uint16 + _ *uint8 + StdInput HANDLE + StdOutput HANDLE + StdError HANDLE +} + +// combase!_SECURITY_ATTRIBUTES +// +0x000 nLength : Uint4B +// +0x008 lpSecurityDescriptor : Ptr64 Void +// +0x010 bInheritHandle : Int4B + +type SECURITY_ATTRIBUTES struct { + Length uint32 + SecurityDescriptor uintptr + InheritHandle BOOL +} diff --git a/platform/vendor/github.com/MaxRis/w32/dwmapi.go b/platform/vendor/github.com/MaxRis/w32/dwmapi.go new file mode 100644 index 0000000..eb656d1 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/dwmapi.go @@ -0,0 +1,254 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "fmt" + "syscall" + "unsafe" +) + +// DEFINED IN THE DWM API BUT NOT IMPLEMENTED BY MS: +// DwmAttachMilContent +// DwmDetachMilContent +// DwmEnableComposition +// DwmGetGraphicsStreamClient +// DwmGetGraphicsStreamTransformHint + +var ( + moddwmapi = syscall.NewLazyDLL("dwmapi.dll") + + procDwmDefWindowProc = moddwmapi.NewProc("DwmDefWindowProc") + procDwmEnableBlurBehindWindow = moddwmapi.NewProc("DwmEnableBlurBehindWindow") + procDwmEnableMMCSS = moddwmapi.NewProc("DwmEnableMMCSS") + procDwmExtendFrameIntoClientArea = moddwmapi.NewProc("DwmExtendFrameIntoClientArea") + procDwmFlush = moddwmapi.NewProc("DwmFlush") + procDwmGetColorizationColor = moddwmapi.NewProc("DwmGetColorizationColor") + procDwmGetCompositionTimingInfo = moddwmapi.NewProc("DwmGetCompositionTimingInfo") + procDwmGetTransportAttributes = moddwmapi.NewProc("DwmGetTransportAttributes") + procDwmGetWindowAttribute = moddwmapi.NewProc("DwmGetWindowAttribute") + procDwmInvalidateIconicBitmaps = moddwmapi.NewProc("DwmInvalidateIconicBitmaps") + procDwmIsCompositionEnabled = moddwmapi.NewProc("DwmIsCompositionEnabled") + procDwmModifyPreviousDxFrameDuration = moddwmapi.NewProc("DwmModifyPreviousDxFrameDuration") + procDwmQueryThumbnailSourceSize = moddwmapi.NewProc("DwmQueryThumbnailSourceSize") + procDwmRegisterThumbnail = moddwmapi.NewProc("DwmRegisterThumbnail") + procDwmRenderGesture = moddwmapi.NewProc("DwmRenderGesture") + procDwmSetDxFrameDuration = moddwmapi.NewProc("DwmSetDxFrameDuration") + procDwmSetIconicLivePreviewBitmap = moddwmapi.NewProc("DwmSetIconicLivePreviewBitmap") + procDwmSetIconicThumbnail = moddwmapi.NewProc("DwmSetIconicThumbnail") + procDwmSetPresentParameters = moddwmapi.NewProc("DwmSetPresentParameters") + procDwmSetWindowAttribute = moddwmapi.NewProc("DwmSetWindowAttribute") + procDwmShowContact = moddwmapi.NewProc("DwmShowContact") + procDwmTetherContact = moddwmapi.NewProc("DwmTetherContact") + procDwmTransitionOwnedWindow = moddwmapi.NewProc("DwmTransitionOwnedWindow") + procDwmUnregisterThumbnail = moddwmapi.NewProc("DwmUnregisterThumbnail") + procDwmUpdateThumbnailProperties = moddwmapi.NewProc("DwmUpdateThumbnailProperties") +) + +func DwmDefWindowProc(hWnd HWND, msg uint, wParam, lParam uintptr) (bool, uint) { + var result uint + ret, _, _ := procDwmDefWindowProc.Call( + uintptr(hWnd), + uintptr(msg), + wParam, + lParam, + uintptr(unsafe.Pointer(&result))) + return ret != 0, result +} + +func DwmEnableBlurBehindWindow(hWnd HWND, pBlurBehind *DWM_BLURBEHIND) HRESULT { + ret, _, _ := procDwmEnableBlurBehindWindow.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pBlurBehind))) + return HRESULT(ret) +} + +func DwmEnableMMCSS(fEnableMMCSS bool) HRESULT { + ret, _, _ := procDwmEnableMMCSS.Call( + uintptr(BoolToBOOL(fEnableMMCSS))) + return HRESULT(ret) +} + +func DwmExtendFrameIntoClientArea(hWnd HWND, pMarInset *MARGINS) HRESULT { + ret, _, _ := procDwmExtendFrameIntoClientArea.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pMarInset))) + return HRESULT(ret) +} + +func DwmFlush() HRESULT { + ret, _, _ := procDwmFlush.Call() + return HRESULT(ret) +} + +func DwmGetColorizationColor(pcrColorization *uint32, pfOpaqueBlend *BOOL) HRESULT { + ret, _, _ := procDwmGetColorizationColor.Call( + uintptr(unsafe.Pointer(pcrColorization)), + uintptr(unsafe.Pointer(pfOpaqueBlend))) + return HRESULT(ret) +} + +func DwmGetCompositionTimingInfo(hWnd HWND, pTimingInfo *DWM_TIMING_INFO) HRESULT { + ret, _, _ := procDwmGetCompositionTimingInfo.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pTimingInfo))) + return HRESULT(ret) +} + +func DwmGetTransportAttributes(pfIsRemoting *BOOL, pfIsConnected *BOOL, pDwGeneration *uint32) HRESULT { + ret, _, _ := procDwmGetTransportAttributes.Call( + uintptr(unsafe.Pointer(pfIsRemoting)), + uintptr(unsafe.Pointer(pfIsConnected)), + uintptr(unsafe.Pointer(pDwGeneration))) + return HRESULT(ret) +} + +// TODO: verify handling of variable arguments +func DwmGetWindowAttribute(hWnd HWND, dwAttribute uint32) (pAttribute interface{}, result HRESULT) { + var pvAttribute, pvAttrSize uintptr + switch dwAttribute { + case DWMWA_NCRENDERING_ENABLED: + v := new(BOOL) + pAttribute = v + pvAttribute = uintptr(unsafe.Pointer(v)) + pvAttrSize = unsafe.Sizeof(*v) + case DWMWA_CAPTION_BUTTON_BOUNDS, DWMWA_EXTENDED_FRAME_BOUNDS: + v := new(RECT) + pAttribute = v + pvAttribute = uintptr(unsafe.Pointer(v)) + pvAttrSize = unsafe.Sizeof(*v) + case DWMWA_CLOAKED: + panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not currently supported.", dwAttribute)) + default: + panic(fmt.Sprintf("DwmGetWindowAttribute(%d) is not valid.", dwAttribute)) + } + + ret, _, _ := procDwmGetWindowAttribute.Call( + uintptr(hWnd), + uintptr(dwAttribute), + pvAttribute, + pvAttrSize) + result = HRESULT(ret) + return +} + +func DwmInvalidateIconicBitmaps(hWnd HWND) HRESULT { + ret, _, _ := procDwmInvalidateIconicBitmaps.Call( + uintptr(hWnd)) + return HRESULT(ret) +} + +func DwmIsCompositionEnabled(pfEnabled *BOOL) HRESULT { + ret, _, _ := procDwmIsCompositionEnabled.Call( + uintptr(unsafe.Pointer(pfEnabled))) + return HRESULT(ret) +} + +func DwmModifyPreviousDxFrameDuration(hWnd HWND, cRefreshes int, fRelative bool) HRESULT { + ret, _, _ := procDwmModifyPreviousDxFrameDuration.Call( + uintptr(hWnd), + uintptr(cRefreshes), + uintptr(BoolToBOOL(fRelative))) + return HRESULT(ret) +} + +func DwmQueryThumbnailSourceSize(hThumbnail HTHUMBNAIL, pSize *SIZE) HRESULT { + ret, _, _ := procDwmQueryThumbnailSourceSize.Call( + uintptr(hThumbnail), + uintptr(unsafe.Pointer(pSize))) + return HRESULT(ret) +} + +func DwmRegisterThumbnail(hWndDestination HWND, hWndSource HWND, phThumbnailId *HTHUMBNAIL) HRESULT { + ret, _, _ := procDwmRegisterThumbnail.Call( + uintptr(hWndDestination), + uintptr(hWndSource), + uintptr(unsafe.Pointer(phThumbnailId))) + return HRESULT(ret) +} + +func DwmRenderGesture(gt GESTURE_TYPE, cContacts uint, pdwPointerID *uint32, pPoints *POINT) { + procDwmRenderGesture.Call( + uintptr(gt), + uintptr(cContacts), + uintptr(unsafe.Pointer(pdwPointerID)), + uintptr(unsafe.Pointer(pPoints))) + return +} + +func DwmSetDxFrameDuration(hWnd HWND, cRefreshes int) HRESULT { + ret, _, _ := procDwmSetDxFrameDuration.Call( + uintptr(hWnd), + uintptr(cRefreshes)) + return HRESULT(ret) +} + +func DwmSetIconicLivePreviewBitmap(hWnd HWND, hbmp HBITMAP, pptClient *POINT, dwSITFlags uint32) HRESULT { + ret, _, _ := procDwmSetIconicLivePreviewBitmap.Call( + uintptr(hWnd), + uintptr(hbmp), + uintptr(unsafe.Pointer(pptClient)), + uintptr(dwSITFlags)) + return HRESULT(ret) +} + +func DwmSetIconicThumbnail(hWnd HWND, hbmp HBITMAP, dwSITFlags uint32) HRESULT { + ret, _, _ := procDwmSetIconicThumbnail.Call( + uintptr(hWnd), + uintptr(hbmp), + uintptr(dwSITFlags)) + return HRESULT(ret) +} + +func DwmSetPresentParameters(hWnd HWND, pPresentParams *DWM_PRESENT_PARAMETERS) HRESULT { + ret, _, _ := procDwmSetPresentParameters.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(pPresentParams))) + return HRESULT(ret) +} + +func DwmSetWindowAttribute(hWnd HWND, dwAttribute uint32, pvAttribute LPCVOID, cbAttribute uint32) HRESULT { + ret, _, _ := procDwmSetWindowAttribute.Call( + uintptr(hWnd), + uintptr(dwAttribute), + uintptr(pvAttribute), + uintptr(cbAttribute)) + return HRESULT(ret) +} + +func DwmShowContact(dwPointerID uint32, eShowContact DWM_SHOWCONTACT) { + procDwmShowContact.Call( + uintptr(dwPointerID), + uintptr(eShowContact)) + return +} + +func DwmTetherContact(dwPointerID uint32, fEnable bool, ptTether POINT) { + procDwmTetherContact.Call( + uintptr(dwPointerID), + uintptr(BoolToBOOL(fEnable)), + uintptr(unsafe.Pointer(&ptTether))) + return +} + +func DwmTransitionOwnedWindow(hWnd HWND, target DWMTRANSITION_OWNEDWINDOW_TARGET) { + procDwmTransitionOwnedWindow.Call( + uintptr(hWnd), + uintptr(target)) + return +} + +func DwmUnregisterThumbnail(hThumbnailId HTHUMBNAIL) HRESULT { + ret, _, _ := procDwmUnregisterThumbnail.Call( + uintptr(hThumbnailId)) + return HRESULT(ret) +} + +func DwmUpdateThumbnailProperties(hThumbnailId HTHUMBNAIL, ptnProperties *DWM_THUMBNAIL_PROPERTIES) HRESULT { + ret, _, _ := procDwmUpdateThumbnailProperties.Call( + uintptr(hThumbnailId), + uintptr(unsafe.Pointer(ptnProperties))) + return HRESULT(ret) +} diff --git a/platform/vendor/github.com/MaxRis/w32/fork.go b/platform/vendor/github.com/MaxRis/w32/fork.go new file mode 100644 index 0000000..b5543b9 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/fork.go @@ -0,0 +1,174 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +// #include +//import ( +// "C" +//) + +// Based on C code found here https://gist.github.com/juntalis/4366916 +// Original code license: +/* + * fork.c + * Experimental fork() on Windows. Requires NT 6 subsystem or + * newer. + * + * Copyright (c) 2012 William Pitcock + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * This software is provided 'as is' and without any warranty, express or + * implied. In no event shall the authors be liable for any damages arising + * from the use of this software. + */ + +import ( + "fmt" + "syscall" + "unsafe" +) + +var ( + ntdll = syscall.NewLazyDLL("ntdll.dll") + + procRtlCloneUserProcess = ntdll.NewProc("RtlCloneUserProcess") + procAllocConsole = modkernel32.NewProc("AllocConsole") + procOpenProcess = modkernel32.NewProc("OpenProcess") + procOpenThread = modkernel32.NewProc("OpenThread") + procResumeThread = modkernel32.NewProc("ResumeThread") +) + +func OpenProcess(desiredAccess int, inheritHandle bool, processId uintptr) (h HANDLE, e error) { + inherit := uintptr(0) + if inheritHandle { + inherit = 1 + } + + ret, _, lastErr := procOpenProcess.Call( + uintptr(desiredAccess), + inherit, + uintptr(processId), + ) + + if ret == 0 { + e = lastErr + } + + h = HANDLE(ret) + return +} + +func OpenThread(desiredAccess int, inheritHandle bool, threadId uintptr) (h HANDLE, e error) { + inherit := uintptr(0) + if inheritHandle { + inherit = 1 + } + + ret, _, lastErr := procOpenThread.Call( + uintptr(desiredAccess), + inherit, + uintptr(threadId), + ) + + if ret == 0 { + e = lastErr + } + + h = HANDLE(ret) + return +} + +// DWORD WINAPI ResumeThread( +// _In_ HANDLE hThread +// ); +func ResumeThread(ht HANDLE) (e error) { + + ret, _, lastErr := procResumeThread.Call( + uintptr(ht), + ) + if ret == ^uintptr(0) { // -1 + e = lastErr + } + return +} + +// BOOL WINAPI AllocConsole(void); +func AllocConsole() (e error) { + ret, _, lastErr := procAllocConsole.Call() + if ret != ERROR_SUCCESS { + e = lastErr + } + return +} + +// NTSYSAPI +// NTSTATUS +// NTAPI RtlCloneUserProcess ( +// _In_ ULONG ProcessFlags, +// _In_opt_ PSECURITY_DESCRIPTOR ProcessSecurityDescriptor, +// _In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor, +// _In_opt_ HANDLE DebugPort, +// _Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation +// ) + +func RtlCloneUserProcess( + ProcessFlags uint32, + ProcessSecurityDescriptor, ThreadSecurityDescriptor *SECURITY_DESCRIPTOR, // in advapi32_typedef.go + DebugPort HANDLE, + ProcessInformation *RTL_USER_PROCESS_INFORMATION, +) (status uintptr) { + + status, _, _ = procRtlCloneUserProcess.Call( + uintptr(ProcessFlags), + uintptr(unsafe.Pointer(ProcessSecurityDescriptor)), + uintptr(unsafe.Pointer(ThreadSecurityDescriptor)), + uintptr(DebugPort), + uintptr(unsafe.Pointer(ProcessInformation)), + ) + + return +} + +// Fork creates a clone of the current process using the undocumented +// RtlCloneUserProcess call in ntdll, similar to unix fork(). The +// return value in the parent is the child PID. In the child it is 0. +func Fork() (pid uintptr, e error) { + + pi := &RTL_USER_PROCESS_INFORMATION{} + + ret := RtlCloneUserProcess( + RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED|RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, + nil, + nil, + HANDLE(0), + pi, + ) + + switch ret { + case RTL_CLONE_PARENT: + pid = pi.ClientId.UniqueProcess + ht, err := OpenThread(THREAD_ALL_ACCESS, false, pi.ClientId.UniqueThread) + if err != nil { + e = fmt.Errorf("OpenThread: %s", err) + } + err = ResumeThread(ht) + if err != nil { + e = fmt.Errorf("ResumeThread: %s", err) + } + CloseHandle(ht) + case RTL_CLONE_CHILD: + pid = 0 + err := AllocConsole() + if err != nil { + e = fmt.Errorf("AllocConsole: %s", err) + } + default: + e = fmt.Errorf("0x%x", ret) + } + return +} diff --git a/platform/vendor/github.com/MaxRis/w32/fork_constants.go b/platform/vendor/github.com/MaxRis/w32/fork_constants.go new file mode 100644 index 0000000..3e9b217 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/fork_constants.go @@ -0,0 +1,26 @@ +package w32 + +const ( + RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED = 0x00000001 + RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES = 0x00000002 + RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE = 0x00000004 + + RTL_CLONE_PARENT = 0 + RTL_CLONE_CHILD = 297 + + THREAD_TERMINATE = 0x0001 + THREAD_SUSPEND_RESUME = 0x0002 + THREAD_GET_CONTEXT = 0x0008 + THREAD_SET_CONTEXT = 0x0010 + THREAD_SET_INFORMATION = 0x0020 + THREAD_QUERY_INFORMATION = 0x0040 + THREAD_SET_THREAD_TOKEN = 0x0080 + THREAD_IMPERSONATE = 0x0100 + THREAD_DIRECT_IMPERSONATION = 0x0200 + THREAD_SET_LIMITED_INFORMATION = 0x0400 + THREAD_QUERY_LIMITED_INFORMATION = 0x0800 + THREAD_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff + + PROCESS_SET_SESSIONID = 0x0004 + PROCESS_ALL_ACCESS = STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0xffff +) diff --git a/platform/vendor/github.com/MaxRis/w32/fork_test.go b/platform/vendor/github.com/MaxRis/w32/fork_test.go new file mode 100644 index 0000000..47b52ba --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/fork_test.go @@ -0,0 +1,50 @@ +package w32 + +import ( + "fmt" + "io/ioutil" + "os" + "path" + "strconv" + "testing" + "time" +) + +var forkFn = path.Join(os.TempDir(), "forktest.pid") + +func TestFork(t *testing.T) { + + ppid := os.Getpid() + t.Logf("[OK] I am PID %d", ppid) + pid, err := Fork() + if err != nil { + t.Fatalf("[!!] Failed to fork. PID: %d: %s", pid, err) + } + + if pid == 0 { + // We can't log anything here because our stdout doesn't point + // to the same console as our parent. + // + // This process won't show up in Task Manager, and os.Getpid() won't + // work, I guess because we haven't told CSRSS we exist. + f, _ := os.Create(forkFn) + f.WriteString(fmt.Sprintf("%d", ppid)) + f.Close() + } else { + t.Logf("[OK] Forked child with PID %d", pid) + t.Logf("[OK] Sleeping, then trying to read checkfile.") + time.Sleep(2 * time.Second) + raw, err := ioutil.ReadFile(forkFn) + if err != nil { + t.Fatalf("[!!] Failed to read PID checkfile: %s", err) + } + if string(raw) == strconv.Itoa(ppid) { + t.Logf("[OK] Found PID checkfile - PID matches!") + } else { + t.Errorf("[!] Child reported PID %q vs %q!", string(raw), strconv.Itoa(ppid)) + } + os.Remove(forkFn) + + } + +} diff --git a/platform/vendor/github.com/MaxRis/w32/fork_typedef.go b/platform/vendor/github.com/MaxRis/w32/fork_typedef.go new file mode 100644 index 0000000..fcb9049 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/fork_typedef.go @@ -0,0 +1,89 @@ +package w32 + +// combase!_SECTION_IMAGE_INFORMATION +// +0x000 TransferAddress : Ptr64 Void +// +0x008 ZeroBits : Uint4B +// +0x010 MaximumStackSize : Uint8B +// +0x018 CommittedStackSize : Uint8B +// +0x020 SubSystemType : Uint4B +// +0x024 SubSystemMinorVersion : Uint2B +// +0x026 SubSystemMajorVersion : Uint2B +// +0x024 SubSystemVersion : Uint4B +// +0x028 MajorOperatingSystemVersion : Uint2B +// +0x02a MinorOperatingSystemVersion : Uint2B +// +0x028 OperatingSystemVersion : Uint4B +// +0x02c ImageCharacteristics : Uint2B +// +0x02e DllCharacteristics : Uint2B +// +0x030 Machine : Uint2B +// +0x032 ImageContainsCode : UChar +// +0x033 ImageFlags : UChar +// +0x033 ComPlusNativeReady : Pos 0, 1 Bit +// +0x033 ComPlusILOnly : Pos 1, 1 Bit +// +0x033 ImageDynamicallyRelocated : Pos 2, 1 Bit +// +0x033 ImageMappedFlat : Pos 3, 1 Bit +// +0x033 BaseBelow4gb : Pos 4, 1 Bit +// +0x033 ComPlusPrefer32bit : Pos 5, 1 Bit +// +0x033 Reserved : Pos 6, 2 Bits +// +0x034 LoaderFlags : Uint4B +// +0x038 ImageFileSize : Uint4B +// +0x03c CheckSum : Uint4B +type SECTION_IMAGE_INFORMATION struct { + TransferAddress uintptr + ZeroBits uint32 + MaximumStackSize uint64 + CommittedStackSize uint64 + SubSystemType uint32 + SubSystemMinorVersion uint16 + SubSystemMajorVersion uint16 + SubSystemVersion uint32 + MajorOperatingSystemVersion uint16 + MinorOperatingSystemVersion uint16 + OperatingSystemVersion uint32 + ImageCharacteristics uint16 + DllCharacteristics uint16 + Machine uint16 + ImageContainsCode uint8 + ImageFlags uint8 + ComPlusFlags uint8 + LoaderFlags uint32 + ImageFileSize uint32 + CheckSum uint32 +} + +func (si *SECTION_IMAGE_INFORMATION) ComPlusNativeReady() bool { + return (si.ComPlusFlags & (1 << 0)) == 1 +} + +func (si *SECTION_IMAGE_INFORMATION) ComPlusILOnly() bool { + return (si.ComPlusFlags & (1 << 1)) == 1 +} + +func (si *SECTION_IMAGE_INFORMATION) ImageDynamicallyRelocated() bool { + return (si.ComPlusFlags & (1 << 2)) == 1 +} + +func (si *SECTION_IMAGE_INFORMATION) ImageMappedFlat() bool { + return (si.ComPlusFlags & (1 << 3)) == 1 +} + +func (si *SECTION_IMAGE_INFORMATION) BaseBelow4gb() bool { + return (si.ComPlusFlags & (1 << 4)) == 1 +} + +func (si *SECTION_IMAGE_INFORMATION) ComPlusPrefer32bit() bool { + return (si.ComPlusFlags & (1 << 5)) == 1 +} + +// combase!_RTL_USER_PROCESS_INFORMATION +// +0x000 Length : Uint4B +// +0x008 Process : Ptr64 Void +// +0x010 Thread : Ptr64 Void +// +0x018 ClientId : _CLIENT_ID +// +0x028 ImageInformation : _SECTION_IMAGE_INFORMATION +type RTL_USER_PROCESS_INFORMATION struct { + Length uint32 + Process HANDLE + Thread HANDLE + ClientId CLIENT_ID + ImageInformation SECTION_IMAGE_INFORMATION +} diff --git a/platform/vendor/github.com/MaxRis/w32/gdi32.go b/platform/vendor/github.com/MaxRis/w32/gdi32.go new file mode 100644 index 0000000..39a81d6 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/gdi32.go @@ -0,0 +1,543 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modgdi32 = syscall.NewLazyDLL("gdi32.dll") + + procGetDeviceCaps = modgdi32.NewProc("GetDeviceCaps") + procGetCurrentObject = modgdi32.NewProc("GetCurrentObject") + procDeleteObject = modgdi32.NewProc("DeleteObject") + procCreateFontIndirect = modgdi32.NewProc("CreateFontIndirectW") + procAbortDoc = modgdi32.NewProc("AbortDoc") + procBitBlt = modgdi32.NewProc("BitBlt") + procPatBlt = modgdi32.NewProc("PatBlt") + procCloseEnhMetaFile = modgdi32.NewProc("CloseEnhMetaFile") + procCopyEnhMetaFile = modgdi32.NewProc("CopyEnhMetaFileW") + procCreateBrushIndirect = modgdi32.NewProc("CreateBrushIndirect") + procCreateCompatibleDC = modgdi32.NewProc("CreateCompatibleDC") + procCreateDC = modgdi32.NewProc("CreateDCW") + procCreateCompatibleBitmap = modgdi32.NewProc("CreateCompatibleBitmap") + procCreateDIBSection = modgdi32.NewProc("CreateDIBSection") + procCreateEnhMetaFile = modgdi32.NewProc("CreateEnhMetaFileW") + procCreateIC = modgdi32.NewProc("CreateICW") + procDeleteDC = modgdi32.NewProc("DeleteDC") + procDeleteEnhMetaFile = modgdi32.NewProc("DeleteEnhMetaFile") + procEllipse = modgdi32.NewProc("Ellipse") + procEndDoc = modgdi32.NewProc("EndDoc") + procEndPage = modgdi32.NewProc("EndPage") + procExtCreatePen = modgdi32.NewProc("ExtCreatePen") + procGetEnhMetaFile = modgdi32.NewProc("GetEnhMetaFileW") + procGetEnhMetaFileHeader = modgdi32.NewProc("GetEnhMetaFileHeader") + procGetObject = modgdi32.NewProc("GetObjectW") + procGetStockObject = modgdi32.NewProc("GetStockObject") + procGetTextExtentExPoint = modgdi32.NewProc("GetTextExtentExPointW") + procGetTextExtentPoint32 = modgdi32.NewProc("GetTextExtentPoint32W") + procGetTextMetrics = modgdi32.NewProc("GetTextMetricsW") + procLineTo = modgdi32.NewProc("LineTo") + procMoveToEx = modgdi32.NewProc("MoveToEx") + procPlayEnhMetaFile = modgdi32.NewProc("PlayEnhMetaFile") + procRectangle = modgdi32.NewProc("Rectangle") + procResetDC = modgdi32.NewProc("ResetDCW") + procSelectObject = modgdi32.NewProc("SelectObject") + procSetBkMode = modgdi32.NewProc("SetBkMode") + procSetBrushOrgEx = modgdi32.NewProc("SetBrushOrgEx") + procSetStretchBltMode = modgdi32.NewProc("SetStretchBltMode") + procSetTextColor = modgdi32.NewProc("SetTextColor") + procSetBkColor = modgdi32.NewProc("SetBkColor") + procStartDoc = modgdi32.NewProc("StartDocW") + procStartPage = modgdi32.NewProc("StartPage") + procStretchBlt = modgdi32.NewProc("StretchBlt") + procSetDIBitsToDevice = modgdi32.NewProc("SetDIBitsToDevice") + procChoosePixelFormat = modgdi32.NewProc("ChoosePixelFormat") + procDescribePixelFormat = modgdi32.NewProc("DescribePixelFormat") + procGetEnhMetaFilePixelFormat = modgdi32.NewProc("GetEnhMetaFilePixelFormat") + procGetPixelFormat = modgdi32.NewProc("GetPixelFormat") + procSetPixelFormat = modgdi32.NewProc("SetPixelFormat") + procSwapBuffers = modgdi32.NewProc("SwapBuffers") +) + +func GetDeviceCaps(hdc HDC, index int) int { + ret, _, _ := procGetDeviceCaps.Call( + uintptr(hdc), + uintptr(index)) + + return int(ret) +} + +func GetCurrentObject(hdc HDC, uObjectType uint32) HGDIOBJ { + ret, _, _ := procGetCurrentObject.Call( + uintptr(hdc), + uintptr(uObjectType)) + + return HGDIOBJ(ret) +} + +func DeleteObject(hObject HGDIOBJ) bool { + ret, _, _ := procDeleteObject.Call( + uintptr(hObject)) + + return ret != 0 +} + +func CreateFontIndirect(logFont *LOGFONT) HFONT { + ret, _, _ := procCreateFontIndirect.Call( + uintptr(unsafe.Pointer(logFont))) + + return HFONT(ret) +} + +func AbortDoc(hdc HDC) int { + ret, _, _ := procAbortDoc.Call( + uintptr(hdc)) + + return int(ret) +} + +func BitBlt(hdcDest HDC, nXDest, nYDest, nWidth, nHeight int, hdcSrc HDC, nXSrc, nYSrc int, dwRop uint) { + ret, _, _ := procBitBlt.Call( + uintptr(hdcDest), + uintptr(nXDest), + uintptr(nYDest), + uintptr(nWidth), + uintptr(nHeight), + uintptr(hdcSrc), + uintptr(nXSrc), + uintptr(nYSrc), + uintptr(dwRop)) + + if ret == 0 { + panic("BitBlt failed") + } +} + +func PatBlt(hdc HDC, nXLeft, nYLeft, nWidth, nHeight int, dwRop uint) { + ret, _, _ := procPatBlt.Call( + uintptr(hdc), + uintptr(nXLeft), + uintptr(nYLeft), + uintptr(nWidth), + uintptr(nHeight), + uintptr(dwRop)) + + if ret == 0 { + panic("PatBlt failed") + } +} + +func CloseEnhMetaFile(hdc HDC) HENHMETAFILE { + ret, _, _ := procCloseEnhMetaFile.Call( + uintptr(hdc)) + + return HENHMETAFILE(ret) +} + +func CopyEnhMetaFile(hemfSrc HENHMETAFILE, lpszFile *uint16) HENHMETAFILE { + ret, _, _ := procCopyEnhMetaFile.Call( + uintptr(hemfSrc), + uintptr(unsafe.Pointer(lpszFile))) + + return HENHMETAFILE(ret) +} + +func CreateBrushIndirect(lplb *LOGBRUSH) HBRUSH { + ret, _, _ := procCreateBrushIndirect.Call( + uintptr(unsafe.Pointer(lplb))) + + return HBRUSH(ret) +} + +func CreateCompatibleDC(hdc HDC) HDC { + ret, _, _ := procCreateCompatibleDC.Call( + uintptr(hdc)) + + if ret == 0 { + panic("Create compatible DC failed") + } + + return HDC(ret) +} + +func CreateDC(lpszDriver, lpszDevice, lpszOutput *uint16, lpInitData *DEVMODE) HDC { + ret, _, _ := procCreateDC.Call( + uintptr(unsafe.Pointer(lpszDriver)), + uintptr(unsafe.Pointer(lpszDevice)), + uintptr(unsafe.Pointer(lpszOutput)), + uintptr(unsafe.Pointer(lpInitData))) + + return HDC(ret) +} + +func CreateCompatibleBitmap(hdc HDC, width, height uint) HBITMAP { + ret, _, _ := procCreateCompatibleBitmap.Call( + uintptr(hdc), + uintptr(width), + uintptr(height)) + + return HBITMAP(ret) +} + +func CreateDIBSection(hdc HDC, pbmi *BITMAPINFO, iUsage uint, ppvBits *unsafe.Pointer, hSection HANDLE, dwOffset uint) HBITMAP { + ret, _, _ := procCreateDIBSection.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(pbmi)), + uintptr(iUsage), + uintptr(unsafe.Pointer(ppvBits)), + uintptr(hSection), + uintptr(dwOffset)) + + return HBITMAP(ret) +} + +func CreateEnhMetaFile(hdcRef HDC, lpFilename *uint16, lpRect *RECT, lpDescription *uint16) HDC { + ret, _, _ := procCreateEnhMetaFile.Call( + uintptr(hdcRef), + uintptr(unsafe.Pointer(lpFilename)), + uintptr(unsafe.Pointer(lpRect)), + uintptr(unsafe.Pointer(lpDescription))) + + return HDC(ret) +} + +func CreateIC(lpszDriver, lpszDevice, lpszOutput *uint16, lpdvmInit *DEVMODE) HDC { + ret, _, _ := procCreateIC.Call( + uintptr(unsafe.Pointer(lpszDriver)), + uintptr(unsafe.Pointer(lpszDevice)), + uintptr(unsafe.Pointer(lpszOutput)), + uintptr(unsafe.Pointer(lpdvmInit))) + + return HDC(ret) +} + +func DeleteDC(hdc HDC) bool { + ret, _, _ := procDeleteDC.Call( + uintptr(hdc)) + + return ret != 0 +} + +func DeleteEnhMetaFile(hemf HENHMETAFILE) bool { + ret, _, _ := procDeleteEnhMetaFile.Call( + uintptr(hemf)) + + return ret != 0 +} + +func Ellipse(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool { + ret, _, _ := procEllipse.Call( + uintptr(hdc), + uintptr(nLeftRect), + uintptr(nTopRect), + uintptr(nRightRect), + uintptr(nBottomRect)) + + return ret != 0 +} + +func EndDoc(hdc HDC) int { + ret, _, _ := procEndDoc.Call( + uintptr(hdc)) + + return int(ret) +} + +func EndPage(hdc HDC) int { + ret, _, _ := procEndPage.Call( + uintptr(hdc)) + + return int(ret) +} + +func ExtCreatePen(dwPenStyle, dwWidth uint, lplb *LOGBRUSH, dwStyleCount uint, lpStyle *uint) HPEN { + ret, _, _ := procExtCreatePen.Call( + uintptr(dwPenStyle), + uintptr(dwWidth), + uintptr(unsafe.Pointer(lplb)), + uintptr(dwStyleCount), + uintptr(unsafe.Pointer(lpStyle))) + + return HPEN(ret) +} + +func GetEnhMetaFile(lpszMetaFile *uint16) HENHMETAFILE { + ret, _, _ := procGetEnhMetaFile.Call( + uintptr(unsafe.Pointer(lpszMetaFile))) + + return HENHMETAFILE(ret) +} + +func GetEnhMetaFileHeader(hemf HENHMETAFILE, cbBuffer uint, lpemh *ENHMETAHEADER) uint { + ret, _, _ := procGetEnhMetaFileHeader.Call( + uintptr(hemf), + uintptr(cbBuffer), + uintptr(unsafe.Pointer(lpemh))) + + return uint(ret) +} + +func GetObject(hgdiobj HGDIOBJ, cbBuffer uintptr, lpvObject unsafe.Pointer) int { + ret, _, _ := procGetObject.Call( + uintptr(hgdiobj), + uintptr(cbBuffer), + uintptr(lpvObject)) + + return int(ret) +} + +func GetStockObject(fnObject int) HGDIOBJ { + ret, _, _ := procGetStockObject.Call( + uintptr(fnObject)) + + return HGDIOBJ(ret) +} + +func GetTextExtentExPoint(hdc HDC, lpszStr *uint16, cchString, nMaxExtent int, lpnFit, alpDx *int, lpSize *SIZE) bool { + ret, _, _ := procGetTextExtentExPoint.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lpszStr)), + uintptr(cchString), + uintptr(nMaxExtent), + uintptr(unsafe.Pointer(lpnFit)), + uintptr(unsafe.Pointer(alpDx)), + uintptr(unsafe.Pointer(lpSize))) + + return ret != 0 +} + +func GetTextExtentPoint32(hdc HDC, lpString *uint16, c int, lpSize *SIZE) bool { + ret, _, _ := procGetTextExtentPoint32.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lpString)), + uintptr(c), + uintptr(unsafe.Pointer(lpSize))) + + return ret != 0 +} + +func GetTextMetrics(hdc HDC, lptm *TEXTMETRIC) bool { + ret, _, _ := procGetTextMetrics.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lptm))) + + return ret != 0 +} + +func LineTo(hdc HDC, nXEnd, nYEnd int) bool { + ret, _, _ := procLineTo.Call( + uintptr(hdc), + uintptr(nXEnd), + uintptr(nYEnd)) + + return ret != 0 +} + +func MoveToEx(hdc HDC, x, y int, lpPoint *POINT) bool { + ret, _, _ := procMoveToEx.Call( + uintptr(hdc), + uintptr(x), + uintptr(y), + uintptr(unsafe.Pointer(lpPoint))) + + return ret != 0 +} + +func PlayEnhMetaFile(hdc HDC, hemf HENHMETAFILE, lpRect *RECT) bool { + ret, _, _ := procPlayEnhMetaFile.Call( + uintptr(hdc), + uintptr(hemf), + uintptr(unsafe.Pointer(lpRect))) + + return ret != 0 +} + +func Rectangle(hdc HDC, nLeftRect, nTopRect, nRightRect, nBottomRect int) bool { + ret, _, _ := procRectangle.Call( + uintptr(hdc), + uintptr(nLeftRect), + uintptr(nTopRect), + uintptr(nRightRect), + uintptr(nBottomRect)) + + return ret != 0 +} + +func ResetDC(hdc HDC, lpInitData *DEVMODE) HDC { + ret, _, _ := procResetDC.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lpInitData))) + + return HDC(ret) +} + +func SelectObject(hdc HDC, hgdiobj HGDIOBJ) HGDIOBJ { + ret, _, _ := procSelectObject.Call( + uintptr(hdc), + uintptr(hgdiobj)) + + if ret == 0 { + panic("SelectObject failed") + } + + return HGDIOBJ(ret) +} + +func SetBkMode(hdc HDC, iBkMode int) int { + ret, _, _ := procSetBkMode.Call( + uintptr(hdc), + uintptr(iBkMode)) + + if ret == 0 { + panic("SetBkMode failed") + } + + return int(ret) +} + +func SetBrushOrgEx(hdc HDC, nXOrg, nYOrg int, lppt *POINT) bool { + ret, _, _ := procSetBrushOrgEx.Call( + uintptr(hdc), + uintptr(nXOrg), + uintptr(nYOrg), + uintptr(unsafe.Pointer(lppt))) + + return ret != 0 +} + +func SetStretchBltMode(hdc HDC, iStretchMode int) int { + ret, _, _ := procSetStretchBltMode.Call( + uintptr(hdc), + uintptr(iStretchMode)) + + return int(ret) +} + +func SetTextColor(hdc HDC, crColor COLORREF) COLORREF { + ret, _, _ := procSetTextColor.Call( + uintptr(hdc), + uintptr(crColor)) + + if ret == CLR_INVALID { + panic("SetTextColor failed") + } + + return COLORREF(ret) +} + +func SetBkColor(hdc HDC, crColor COLORREF) COLORREF { + ret, _, _ := procSetBkColor.Call( + uintptr(hdc), + uintptr(crColor)) + + if ret == CLR_INVALID { + panic("SetBkColor failed") + } + + return COLORREF(ret) +} + +func StartDoc(hdc HDC, lpdi *DOCINFO) int { + ret, _, _ := procStartDoc.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(lpdi))) + + return int(ret) +} + +func StartPage(hdc HDC) int { + ret, _, _ := procStartPage.Call( + uintptr(hdc)) + + return int(ret) +} + +func StretchBlt(hdcDest HDC, nXOriginDest, nYOriginDest, nWidthDest, nHeightDest int, hdcSrc HDC, nXOriginSrc, nYOriginSrc, nWidthSrc, nHeightSrc int, dwRop uint) { + ret, _, _ := procStretchBlt.Call( + uintptr(hdcDest), + uintptr(nXOriginDest), + uintptr(nYOriginDest), + uintptr(nWidthDest), + uintptr(nHeightDest), + uintptr(hdcSrc), + uintptr(nXOriginSrc), + uintptr(nYOriginSrc), + uintptr(nWidthSrc), + uintptr(nHeightSrc), + uintptr(dwRop)) + + if ret == 0 { + panic("StretchBlt failed") + } +} + +func SetDIBitsToDevice(hdc HDC, xDest, yDest, dwWidth, dwHeight, xSrc, ySrc int, uStartScan, cScanLines uint, lpvBits []byte, lpbmi *BITMAPINFO, fuColorUse uint) int { + ret, _, _ := procSetDIBitsToDevice.Call( + uintptr(hdc), + uintptr(xDest), + uintptr(yDest), + uintptr(dwWidth), + uintptr(dwHeight), + uintptr(xSrc), + uintptr(ySrc), + uintptr(uStartScan), + uintptr(cScanLines), + uintptr(unsafe.Pointer(&lpvBits[0])), + uintptr(unsafe.Pointer(lpbmi)), + uintptr(fuColorUse)) + + return int(ret) +} + +func ChoosePixelFormat(hdc HDC, pfd *PIXELFORMATDESCRIPTOR) int { + ret, _, _ := procChoosePixelFormat.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(pfd)), + ) + return int(ret) +} + +func DescribePixelFormat(hdc HDC, iPixelFormat int, nBytes uint, pfd *PIXELFORMATDESCRIPTOR) int { + ret, _, _ := procDescribePixelFormat.Call( + uintptr(hdc), + uintptr(iPixelFormat), + uintptr(nBytes), + uintptr(unsafe.Pointer(pfd)), + ) + return int(ret) +} + +func GetEnhMetaFilePixelFormat(hemf HENHMETAFILE, cbBuffer uint32, pfd *PIXELFORMATDESCRIPTOR) uint { + ret, _, _ := procGetEnhMetaFilePixelFormat.Call( + uintptr(hemf), + uintptr(cbBuffer), + uintptr(unsafe.Pointer(pfd)), + ) + return uint(ret) +} + +func GetPixelFormat(hdc HDC) int { + ret, _, _ := procGetPixelFormat.Call( + uintptr(hdc), + ) + return int(ret) +} + +func SetPixelFormat(hdc HDC, iPixelFormat int, pfd *PIXELFORMATDESCRIPTOR) bool { + ret, _, _ := procSetPixelFormat.Call( + uintptr(hdc), + uintptr(iPixelFormat), + uintptr(unsafe.Pointer(pfd)), + ) + return ret == TRUE +} + +func SwapBuffers(hdc HDC) bool { + ret, _, _ := procSwapBuffers.Call(uintptr(hdc)) + return ret == TRUE +} diff --git a/platform/vendor/github.com/MaxRis/w32/gdiplus.go b/platform/vendor/github.com/MaxRis/w32/gdiplus.go new file mode 100644 index 0000000..f3a8fca --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/gdiplus.go @@ -0,0 +1,175 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "errors" + "fmt" + "syscall" + "unsafe" +) + +const ( + Ok = 0 + GenericError = 1 + InvalidParameter = 2 + OutOfMemory = 3 + ObjectBusy = 4 + InsufficientBuffer = 5 + NotImplemented = 6 + Win32Error = 7 + WrongState = 8 + Aborted = 9 + FileNotFound = 10 + ValueOverflow = 11 + AccessDenied = 12 + UnknownImageFormat = 13 + FontFamilyNotFound = 14 + FontStyleNotFound = 15 + NotTrueTypeFont = 16 + UnsupportedGdiplusVersion = 17 + GdiplusNotInitialized = 18 + PropertyNotFound = 19 + PropertyNotSupported = 20 + ProfileNotFound = 21 +) + +func GetGpStatus(s int32) string { + switch s { + case Ok: + return "Ok" + case GenericError: + return "GenericError" + case InvalidParameter: + return "InvalidParameter" + case OutOfMemory: + return "OutOfMemory" + case ObjectBusy: + return "ObjectBusy" + case InsufficientBuffer: + return "InsufficientBuffer" + case NotImplemented: + return "NotImplemented" + case Win32Error: + return "Win32Error" + case WrongState: + return "WrongState" + case Aborted: + return "Aborted" + case FileNotFound: + return "FileNotFound" + case ValueOverflow: + return "ValueOverflow" + case AccessDenied: + return "AccessDenied" + case UnknownImageFormat: + return "UnknownImageFormat" + case FontFamilyNotFound: + return "FontFamilyNotFound" + case FontStyleNotFound: + return "FontStyleNotFound" + case NotTrueTypeFont: + return "NotTrueTypeFont" + case UnsupportedGdiplusVersion: + return "UnsupportedGdiplusVersion" + case GdiplusNotInitialized: + return "GdiplusNotInitialized" + case PropertyNotFound: + return "PropertyNotFound" + case PropertyNotSupported: + return "PropertyNotSupported" + case ProfileNotFound: + return "ProfileNotFound" + } + return "Unknown Status Value" +} + +var ( + token uintptr + + modgdiplus = syscall.NewLazyDLL("gdiplus.dll") + + procGdipCreateBitmapFromFile = modgdiplus.NewProc("GdipCreateBitmapFromFile") + procGdipCreateBitmapFromHBITMAP = modgdiplus.NewProc("GdipCreateBitmapFromHBITMAP") + procGdipCreateHBITMAPFromBitmap = modgdiplus.NewProc("GdipCreateHBITMAPFromBitmap") + procGdipCreateBitmapFromResource = modgdiplus.NewProc("GdipCreateBitmapFromResource") + procGdipCreateBitmapFromStream = modgdiplus.NewProc("GdipCreateBitmapFromStream") + procGdipDisposeImage = modgdiplus.NewProc("GdipDisposeImage") + procGdiplusShutdown = modgdiplus.NewProc("GdiplusShutdown") + procGdiplusStartup = modgdiplus.NewProc("GdiplusStartup") +) + +func GdipCreateBitmapFromFile(filename string) (*uintptr, error) { + var bitmap *uintptr + ret, _, _ := procGdipCreateBitmapFromFile.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(filename))), + uintptr(unsafe.Pointer(&bitmap))) + + if ret != Ok { + return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromFile failed with status '%s' for file '%s'", GetGpStatus(int32(ret)), filename)) + } + + return bitmap, nil +} + +func GdipCreateBitmapFromResource(instance HINSTANCE, resId *uint16) (*uintptr, error) { + var bitmap *uintptr + ret, _, _ := procGdipCreateBitmapFromResource.Call( + uintptr(instance), + uintptr(unsafe.Pointer(resId)), + uintptr(unsafe.Pointer(&bitmap))) + + if ret != Ok { + return nil, errors.New(fmt.Sprintf("GdiCreateBitmapFromResource failed with status '%s'", GetGpStatus(int32(ret)))) + } + + return bitmap, nil +} + +func GdipCreateBitmapFromStream(stream *IStream) (*uintptr, error) { + var bitmap *uintptr + ret, _, _ := procGdipCreateBitmapFromStream.Call( + uintptr(unsafe.Pointer(stream)), + uintptr(unsafe.Pointer(&bitmap))) + + if ret != Ok { + return nil, errors.New(fmt.Sprintf("GdipCreateBitmapFromStream failed with status '%s'", GetGpStatus(int32(ret)))) + } + + return bitmap, nil +} + +func GdipCreateHBITMAPFromBitmap(bitmap *uintptr, background uint32) (HBITMAP, error) { + var hbitmap HBITMAP + ret, _, _ := procGdipCreateHBITMAPFromBitmap.Call( + uintptr(unsafe.Pointer(bitmap)), + uintptr(unsafe.Pointer(&hbitmap)), + uintptr(background)) + + if ret != Ok { + return 0, errors.New(fmt.Sprintf("GdipCreateHBITMAPFromBitmap failed with status '%s'", GetGpStatus(int32(ret)))) + } + + return hbitmap, nil +} + +func GdipDisposeImage(image *uintptr) { + procGdipDisposeImage.Call(uintptr(unsafe.Pointer(image))) +} + +func GdiplusShutdown() { + procGdiplusShutdown.Call(token) +} + +func GdiplusStartup(input *GdiplusStartupInput, output *GdiplusStartupOutput) { + ret, _, _ := procGdiplusStartup.Call( + uintptr(unsafe.Pointer(&token)), + uintptr(unsafe.Pointer(input)), + uintptr(unsafe.Pointer(output))) + + if ret != Ok { + panic("GdiplusStartup failed with status " + GetGpStatus(int32(ret))) + } +} diff --git a/platform/vendor/github.com/MaxRis/w32/idispatch.go b/platform/vendor/github.com/MaxRis/w32/idispatch.go new file mode 100644 index 0000000..41634a6 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/idispatch.go @@ -0,0 +1,43 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "unsafe" +) + +type pIDispatchVtbl struct { + pQueryInterface uintptr + pAddRef uintptr + pRelease uintptr + pGetTypeInfoCount uintptr + pGetTypeInfo uintptr + pGetIDsOfNames uintptr + pInvoke uintptr +} + +type IDispatch struct { + lpVtbl *pIDispatchVtbl +} + +func (this *IDispatch) QueryInterface(id *GUID) *IDispatch { + return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id) +} + +func (this *IDispatch) AddRef() int32 { + return ComAddRef((*IUnknown)(unsafe.Pointer(this))) +} + +func (this *IDispatch) Release() int32 { + return ComRelease((*IUnknown)(unsafe.Pointer(this))) +} + +func (this *IDispatch) GetIDsOfName(names []string) []int32 { + return ComGetIDsOfName(this, names) +} + +func (this *IDispatch) Invoke(dispid int32, dispatch int16, params ...interface{}) *VARIANT { + return ComInvoke(this, dispid, dispatch, params...) +} diff --git a/platform/vendor/github.com/MaxRis/w32/istream.go b/platform/vendor/github.com/MaxRis/w32/istream.go new file mode 100644 index 0000000..2b840c3 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/istream.go @@ -0,0 +1,31 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "unsafe" +) + +type pIStreamVtbl struct { + pQueryInterface uintptr + pAddRef uintptr + pRelease uintptr +} + +type IStream struct { + lpVtbl *pIStreamVtbl +} + +func (this *IStream) QueryInterface(id *GUID) *IDispatch { + return ComQueryInterface((*IUnknown)(unsafe.Pointer(this)), id) +} + +func (this *IStream) AddRef() int32 { + return ComAddRef((*IUnknown)(unsafe.Pointer(this))) +} + +func (this *IStream) Release() int32 { + return ComRelease((*IUnknown)(unsafe.Pointer(this))) +} diff --git a/platform/vendor/github.com/MaxRis/w32/iunknown.go b/platform/vendor/github.com/MaxRis/w32/iunknown.go new file mode 100644 index 0000000..d63ff1b --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/iunknown.go @@ -0,0 +1,27 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +type pIUnknownVtbl struct { + pQueryInterface uintptr + pAddRef uintptr + pRelease uintptr +} + +type IUnknown struct { + lpVtbl *pIUnknownVtbl +} + +func (this *IUnknown) QueryInterface(id *GUID) *IDispatch { + return ComQueryInterface(this, id) +} + +func (this *IUnknown) AddRef() int32 { + return ComAddRef(this) +} + +func (this *IUnknown) Release() int32 { + return ComRelease(this) +} diff --git a/platform/vendor/github.com/MaxRis/w32/kernel32.go b/platform/vendor/github.com/MaxRis/w32/kernel32.go new file mode 100644 index 0000000..28febbe --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/kernel32.go @@ -0,0 +1,388 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modkernel32 = syscall.NewLazyDLL("kernel32.dll") + + procGetModuleHandle = modkernel32.NewProc("GetModuleHandleW") + procMulDiv = modkernel32.NewProc("MulDiv") + procGetConsoleWindow = modkernel32.NewProc("GetConsoleWindow") + procGetCurrentThread = modkernel32.NewProc("GetCurrentThread") + procGetLogicalDrives = modkernel32.NewProc("GetLogicalDrives") + procGetUserDefaultLCID = modkernel32.NewProc("GetUserDefaultLCID") + procLstrlen = modkernel32.NewProc("lstrlenW") + procLstrcpy = modkernel32.NewProc("lstrcpyW") + procGlobalAlloc = modkernel32.NewProc("GlobalAlloc") + procGlobalFree = modkernel32.NewProc("GlobalFree") + procGlobalLock = modkernel32.NewProc("GlobalLock") + procGlobalUnlock = modkernel32.NewProc("GlobalUnlock") + procMoveMemory = modkernel32.NewProc("RtlMoveMemory") + procFindResource = modkernel32.NewProc("FindResourceW") + procSizeofResource = modkernel32.NewProc("SizeofResource") + procLockResource = modkernel32.NewProc("LockResource") + procLoadResource = modkernel32.NewProc("LoadResource") + procGetLastError = modkernel32.NewProc("GetLastError") + // procOpenProcess = modkernel32.NewProc("OpenProcess") + // procTerminateProcess = modkernel32.NewProc("TerminateProcess") + procCloseHandle = modkernel32.NewProc("CloseHandle") + procCreateToolhelp32Snapshot = modkernel32.NewProc("CreateToolhelp32Snapshot") + procModule32First = modkernel32.NewProc("Module32FirstW") + procModule32Next = modkernel32.NewProc("Module32NextW") + procGetSystemTimes = modkernel32.NewProc("GetSystemTimes") + procGetConsoleScreenBufferInfo = modkernel32.NewProc("GetConsoleScreenBufferInfo") + procSetConsoleTextAttribute = modkernel32.NewProc("SetConsoleTextAttribute") + procGetDiskFreeSpaceEx = modkernel32.NewProc("GetDiskFreeSpaceExW") + procGetProcessTimes = modkernel32.NewProc("GetProcessTimes") + procSetSystemTime = modkernel32.NewProc("SetSystemTime") + procGetSystemTime = modkernel32.NewProc("GetSystemTime") + procVirtualAllocEx = modkernel32.NewProc("VirtualAllocEx") + procVirtualFreeEx = modkernel32.NewProc("VirtualFreeEx") + procWriteProcessMemory = modkernel32.NewProc("WriteProcessMemory") + procReadProcessMemory = modkernel32.NewProc("ReadProcessMemory") + procQueryPerformanceCounter = modkernel32.NewProc("QueryPerformanceCounter") + procQueryPerformanceFrequency = modkernel32.NewProc("QueryPerformanceFrequency") +) + +func GetModuleHandle(modulename string) HINSTANCE { + var mn uintptr + if modulename == "" { + mn = 0 + } else { + mn = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(modulename))) + } + ret, _, _ := procGetModuleHandle.Call(mn) + return HINSTANCE(ret) +} + +func MulDiv(number, numerator, denominator int) int { + ret, _, _ := procMulDiv.Call( + uintptr(number), + uintptr(numerator), + uintptr(denominator)) + + return int(ret) +} + +func GetConsoleWindow() HWND { + ret, _, _ := procGetConsoleWindow.Call() + + return HWND(ret) +} + +func GetCurrentThread() HANDLE { + ret, _, _ := procGetCurrentThread.Call() + + return HANDLE(ret) +} + +func GetLogicalDrives() uint32 { + ret, _, _ := procGetLogicalDrives.Call() + + return uint32(ret) +} + +func GetUserDefaultLCID() uint32 { + ret, _, _ := procGetUserDefaultLCID.Call() + + return uint32(ret) +} + +func Lstrlen(lpString *uint16) int { + ret, _, _ := procLstrlen.Call(uintptr(unsafe.Pointer(lpString))) + + return int(ret) +} + +func Lstrcpy(buf []uint16, lpString *uint16) { + procLstrcpy.Call( + uintptr(unsafe.Pointer(&buf[0])), + uintptr(unsafe.Pointer(lpString))) +} + +func GlobalAlloc(uFlags uint, dwBytes uint32) HGLOBAL { + ret, _, _ := procGlobalAlloc.Call( + uintptr(uFlags), + uintptr(dwBytes)) + + if ret == 0 { + panic("GlobalAlloc failed") + } + + return HGLOBAL(ret) +} + +func GlobalFree(hMem HGLOBAL) { + ret, _, _ := procGlobalFree.Call(uintptr(hMem)) + + if ret != 0 { + panic("GlobalFree failed") + } +} + +func GlobalLock(hMem HGLOBAL) unsafe.Pointer { + ret, _, _ := procGlobalLock.Call(uintptr(hMem)) + + if ret == 0 { + panic("GlobalLock failed") + } + + return unsafe.Pointer(ret) +} + +func GlobalUnlock(hMem HGLOBAL) bool { + ret, _, _ := procGlobalUnlock.Call(uintptr(hMem)) + + return ret != 0 +} + +func MoveMemory(destination, source unsafe.Pointer, length uint32) { + procMoveMemory.Call( + uintptr(unsafe.Pointer(destination)), + uintptr(source), + uintptr(length)) +} + +func FindResource(hModule HMODULE, lpName, lpType *uint16) (HRSRC, error) { + ret, _, _ := procFindResource.Call( + uintptr(hModule), + uintptr(unsafe.Pointer(lpName)), + uintptr(unsafe.Pointer(lpType))) + + if ret == 0 { + return 0, syscall.GetLastError() + } + + return HRSRC(ret), nil +} + +func SizeofResource(hModule HMODULE, hResInfo HRSRC) uint32 { + ret, _, _ := procSizeofResource.Call( + uintptr(hModule), + uintptr(hResInfo)) + + if ret == 0 { + panic("SizeofResource failed") + } + + return uint32(ret) +} + +func LockResource(hResData HGLOBAL) unsafe.Pointer { + ret, _, _ := procLockResource.Call(uintptr(hResData)) + + if ret == 0 { + panic("LockResource failed") + } + + return unsafe.Pointer(ret) +} + +func LoadResource(hModule HMODULE, hResInfo HRSRC) HGLOBAL { + ret, _, _ := procLoadResource.Call( + uintptr(hModule), + uintptr(hResInfo)) + + if ret == 0 { + panic("LoadResource failed") + } + + return HGLOBAL(ret) +} + +func GetLastError() uint32 { + ret, _, _ := procGetLastError.Call() + return uint32(ret) +} + +// func OpenProcess(desiredAccess uint32, inheritHandle bool, processId uint32) HANDLE { +// inherit := 0 +// if inheritHandle { +// inherit = 1 +// } + +// ret, _, _ := procOpenProcess.Call( +// uintptr(desiredAccess), +// uintptr(inherit), +// uintptr(processId)) +// return HANDLE(ret) +// } + +// func TerminateProcess(hProcess HANDLE, uExitCode uint) bool { +// ret, _, _ := procTerminateProcess.Call( +// uintptr(hProcess), +// uintptr(uExitCode)) +// return ret != 0 +// } + +func CloseHandle(object HANDLE) bool { + ret, _, _ := procCloseHandle.Call( + uintptr(object)) + return ret != 0 +} + +func CreateToolhelp32Snapshot(flags, processId uint32) HANDLE { + ret, _, _ := procCreateToolhelp32Snapshot.Call( + uintptr(flags), + uintptr(processId)) + + if ret <= 0 { + return HANDLE(0) + } + + return HANDLE(ret) +} + +func Module32First(snapshot HANDLE, me *MODULEENTRY32) bool { + ret, _, _ := procModule32First.Call( + uintptr(snapshot), + uintptr(unsafe.Pointer(me))) + + return ret != 0 +} + +func Module32Next(snapshot HANDLE, me *MODULEENTRY32) bool { + ret, _, _ := procModule32Next.Call( + uintptr(snapshot), + uintptr(unsafe.Pointer(me))) + + return ret != 0 +} + +func GetSystemTimes(lpIdleTime, lpKernelTime, lpUserTime *FILETIME) bool { + ret, _, _ := procGetSystemTimes.Call( + uintptr(unsafe.Pointer(lpIdleTime)), + uintptr(unsafe.Pointer(lpKernelTime)), + uintptr(unsafe.Pointer(lpUserTime))) + + return ret != 0 +} + +func GetProcessTimes(hProcess HANDLE, lpCreationTime, lpExitTime, lpKernelTime, lpUserTime *FILETIME) bool { + ret, _, _ := procGetProcessTimes.Call( + uintptr(hProcess), + uintptr(unsafe.Pointer(lpCreationTime)), + uintptr(unsafe.Pointer(lpExitTime)), + uintptr(unsafe.Pointer(lpKernelTime)), + uintptr(unsafe.Pointer(lpUserTime))) + + return ret != 0 +} + +func GetConsoleScreenBufferInfo(hConsoleOutput HANDLE) *CONSOLE_SCREEN_BUFFER_INFO { + var csbi CONSOLE_SCREEN_BUFFER_INFO + ret, _, _ := procGetConsoleScreenBufferInfo.Call( + uintptr(hConsoleOutput), + uintptr(unsafe.Pointer(&csbi))) + if ret == 0 { + return nil + } + return &csbi +} + +func SetConsoleTextAttribute(hConsoleOutput HANDLE, wAttributes uint16) bool { + ret, _, _ := procSetConsoleTextAttribute.Call( + uintptr(hConsoleOutput), + uintptr(wAttributes)) + return ret != 0 +} + +func GetDiskFreeSpaceEx(dirName string) (r bool, + freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64) { + ret, _, _ := procGetDiskFreeSpaceEx.Call( + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(dirName))), + uintptr(unsafe.Pointer(&freeBytesAvailable)), + uintptr(unsafe.Pointer(&totalNumberOfBytes)), + uintptr(unsafe.Pointer(&totalNumberOfFreeBytes))) + return ret != 0, + freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes +} + +func GetSystemTime() *SYSTEMTIME { + var time SYSTEMTIME + procGetSystemTime.Call( + uintptr(unsafe.Pointer(&time))) + return &time +} + +func SetSystemTime(time *SYSTEMTIME) bool { + ret, _, _ := procSetSystemTime.Call( + uintptr(unsafe.Pointer(time))) + return ret != 0 +} + +func VirtualAllocEx(hProcess HANDLE, lpAddress, dwSize uintptr, flAllocationType, flProtect uint32) uintptr { + ret, _, _ := procVirtualAllocEx.Call( + uintptr(hProcess), + lpAddress, + dwSize, + uintptr(flAllocationType), + uintptr(flProtect), + ) + + return ret +} + +func VirtualFreeEx(hProcess HANDLE, lpAddress, dwSize uintptr, dwFreeType uint32) bool { + ret, _, _ := procVirtualFreeEx.Call( + uintptr(hProcess), + lpAddress, + dwSize, + uintptr(dwFreeType), + ) + + return ret != 0 +} + +func WriteProcessMemory(hProcess HANDLE, lpBaseAddress, lpBuffer, nSize uintptr) (int, bool) { + var nBytesWritten int + ret, _, _ := procWriteProcessMemory.Call( + uintptr(hProcess), + lpBaseAddress, + lpBuffer, + nSize, + uintptr(unsafe.Pointer(&nBytesWritten)), + ) + + return nBytesWritten, ret != 0 +} + +func ReadProcessMemory(hProcess HANDLE, lpBaseAddress, nSize uintptr) (lpBuffer []uint16, lpNumberOfBytesRead int, ok bool) { + + var nBytesRead int + buf := make([]uint16, nSize) + ret, _, _ := procReadProcessMemory.Call( + uintptr(hProcess), + lpBaseAddress, + uintptr(unsafe.Pointer(&buf[0])), + nSize, + uintptr(unsafe.Pointer(&nBytesRead)), + ) + + return buf, nBytesRead, ret != 0 +} + +func QueryPerformanceCounter() uint64 { + result := uint64(0) + procQueryPerformanceCounter.Call( + uintptr(unsafe.Pointer(&result)), + ) + + return result +} + +func QueryPerformanceFrequency() uint64 { + result := uint64(0) + procQueryPerformanceFrequency.Call( + uintptr(unsafe.Pointer(&result)), + ) + + return result +} diff --git a/platform/vendor/github.com/MaxRis/w32/ole32.go b/platform/vendor/github.com/MaxRis/w32/ole32.go new file mode 100644 index 0000000..a7f79b5 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/ole32.go @@ -0,0 +1,63 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modole32 = syscall.NewLazyDLL("ole32.dll") + + procCoInitializeEx = modole32.NewProc("CoInitializeEx") + procCoInitialize = modole32.NewProc("CoInitialize") + procCoUninitialize = modole32.NewProc("CoUninitialize") + procCreateStreamOnHGlobal = modole32.NewProc("CreateStreamOnHGlobal") +) + +func CoInitializeEx(coInit uintptr) HRESULT { + ret, _, _ := procCoInitializeEx.Call( + 0, + coInit) + + switch uint32(ret) { + case E_INVALIDARG: + panic("CoInitializeEx failed with E_INVALIDARG") + case E_OUTOFMEMORY: + panic("CoInitializeEx failed with E_OUTOFMEMORY") + case E_UNEXPECTED: + panic("CoInitializeEx failed with E_UNEXPECTED") + } + + return HRESULT(ret) +} + +func CoInitialize() { + procCoInitialize.Call(0) +} + +func CoUninitialize() { + procCoUninitialize.Call() +} + +func CreateStreamOnHGlobal(hGlobal HGLOBAL, fDeleteOnRelease bool) *IStream { + stream := new(IStream) + ret, _, _ := procCreateStreamOnHGlobal.Call( + uintptr(hGlobal), + uintptr(BoolToBOOL(fDeleteOnRelease)), + uintptr(unsafe.Pointer(&stream))) + + switch uint32(ret) { + case E_INVALIDARG: + panic("CreateStreamOnHGlobal failed with E_INVALIDARG") + case E_OUTOFMEMORY: + panic("CreateStreamOnHGlobal failed with E_OUTOFMEMORY") + case E_UNEXPECTED: + panic("CreateStreamOnHGlobal failed with E_UNEXPECTED") + } + + return stream +} diff --git a/platform/vendor/github.com/MaxRis/w32/oleaut32.go b/platform/vendor/github.com/MaxRis/w32/oleaut32.go new file mode 100644 index 0000000..0eeeab7 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/oleaut32.go @@ -0,0 +1,48 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modoleaut32 = syscall.NewLazyDLL("oleaut32") + + procVariantInit = modoleaut32.NewProc("VariantInit") + procSysAllocString = modoleaut32.NewProc("SysAllocString") + procSysFreeString = modoleaut32.NewProc("SysFreeString") + procSysStringLen = modoleaut32.NewProc("SysStringLen") + procCreateDispTypeInfo = modoleaut32.NewProc("CreateDispTypeInfo") + procCreateStdDispatch = modoleaut32.NewProc("CreateStdDispatch") +) + +func VariantInit(v *VARIANT) { + hr, _, _ := procVariantInit.Call(uintptr(unsafe.Pointer(v))) + if hr != 0 { + panic("Invoke VariantInit error.") + } + return +} + +func SysAllocString(v string) (ss *int16) { + pss, _, _ := procSysAllocString.Call(uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(v)))) + ss = (*int16)(unsafe.Pointer(pss)) + return +} + +func SysFreeString(v *int16) { + hr, _, _ := procSysFreeString.Call(uintptr(unsafe.Pointer(v))) + if hr != 0 { + panic("Invoke SysFreeString error.") + } + return +} + +func SysStringLen(v *int16) uint { + l, _, _ := procSysStringLen.Call(uintptr(unsafe.Pointer(v))) + return uint(l) +} diff --git a/platform/vendor/github.com/MaxRis/w32/opengl32.go b/platform/vendor/github.com/MaxRis/w32/opengl32.go new file mode 100644 index 0000000..7363bb1 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/opengl32.go @@ -0,0 +1,72 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modopengl32 = syscall.NewLazyDLL("opengl32.dll") + + procwglCreateContext = modopengl32.NewProc("wglCreateContext") + procwglCreateLayerContext = modopengl32.NewProc("wglCreateLayerContext") + procwglDeleteContext = modopengl32.NewProc("wglDeleteContext") + procwglGetProcAddress = modopengl32.NewProc("wglGetProcAddress") + procwglMakeCurrent = modopengl32.NewProc("wglMakeCurrent") + procwglShareLists = modopengl32.NewProc("wglShareLists") +) + +func WglCreateContext(hdc HDC) HGLRC { + ret, _, _ := procwglCreateContext.Call( + uintptr(hdc), + ) + + return HGLRC(ret) +} + +func WglCreateLayerContext(hdc HDC, iLayerPlane int) HGLRC { + ret, _, _ := procwglCreateLayerContext.Call( + uintptr(hdc), + uintptr(iLayerPlane), + ) + + return HGLRC(ret) +} + +func WglDeleteContext(hglrc HGLRC) bool { + ret, _, _ := procwglDeleteContext.Call( + uintptr(hglrc), + ) + + return ret == TRUE +} + +func WglGetProcAddress(szProc string) uintptr { + ret, _, _ := procwglGetProcAddress.Call( + uintptr(unsafe.Pointer(syscall.StringBytePtr(szProc))), + ) + + return ret +} + +func WglMakeCurrent(hdc HDC, hglrc HGLRC) bool { + ret, _, _ := procwglMakeCurrent.Call( + uintptr(hdc), + uintptr(hglrc), + ) + + return ret == TRUE +} + +func WglShareLists(hglrc1, hglrc2 HGLRC) bool { + ret, _, _ := procwglShareLists.Call( + uintptr(hglrc1), + uintptr(hglrc2), + ) + + return ret == TRUE +} diff --git a/platform/vendor/github.com/MaxRis/w32/psapi.go b/platform/vendor/github.com/MaxRis/w32/psapi.go new file mode 100644 index 0000000..bd1e126 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/psapi.go @@ -0,0 +1,25 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unsafe" +) + +var ( + modpsapi = syscall.NewLazyDLL("psapi.dll") + + procEnumProcesses = modpsapi.NewProc("EnumProcesses") +) + +func EnumProcesses(processIds []uint32, cb uint32, bytesReturned *uint32) bool { + ret, _, _ := procEnumProcesses.Call( + uintptr(unsafe.Pointer(&processIds[0])), + uintptr(cb), + uintptr(unsafe.Pointer(bytesReturned))) + + return ret != 0 +} diff --git a/platform/vendor/github.com/MaxRis/w32/shell32.go b/platform/vendor/github.com/MaxRis/w32/shell32.go new file mode 100644 index 0000000..0923b8b --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/shell32.go @@ -0,0 +1,153 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "errors" + "fmt" + "syscall" + "unsafe" +) + +var ( + modshell32 = syscall.NewLazyDLL("shell32.dll") + + procSHBrowseForFolder = modshell32.NewProc("SHBrowseForFolderW") + procSHGetPathFromIDList = modshell32.NewProc("SHGetPathFromIDListW") + procDragAcceptFiles = modshell32.NewProc("DragAcceptFiles") + procDragQueryFile = modshell32.NewProc("DragQueryFileW") + procDragQueryPoint = modshell32.NewProc("DragQueryPoint") + procDragFinish = modshell32.NewProc("DragFinish") + procShellExecute = modshell32.NewProc("ShellExecuteW") + procExtractIcon = modshell32.NewProc("ExtractIconW") +) + +func SHBrowseForFolder(bi *BROWSEINFO) uintptr { + ret, _, _ := procSHBrowseForFolder.Call(uintptr(unsafe.Pointer(bi))) + + return ret +} + +func SHGetPathFromIDList(idl uintptr) string { + buf := make([]uint16, 1024) + procSHGetPathFromIDList.Call( + idl, + uintptr(unsafe.Pointer(&buf[0]))) + + return syscall.UTF16ToString(buf) +} + +func DragAcceptFiles(hwnd HWND, accept bool) { + procDragAcceptFiles.Call( + uintptr(hwnd), + uintptr(BoolToBOOL(accept))) +} + +func DragQueryFile(hDrop HDROP, iFile uint) (fileName string, fileCount uint) { + ret, _, _ := procDragQueryFile.Call( + uintptr(hDrop), + uintptr(iFile), + 0, + 0) + + fileCount = uint(ret) + + if iFile != 0xFFFFFFFF { + buf := make([]uint16, fileCount+1) + + ret, _, _ := procDragQueryFile.Call( + uintptr(hDrop), + uintptr(iFile), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(fileCount+1)) + + if ret == 0 { + panic("Invoke DragQueryFile error.") + } + + fileName = syscall.UTF16ToString(buf) + } + + return +} + +func DragQueryPoint(hDrop HDROP) (x, y int, isClientArea bool) { + var pt POINT + ret, _, _ := procDragQueryPoint.Call( + uintptr(hDrop), + uintptr(unsafe.Pointer(&pt))) + + return int(pt.X), int(pt.Y), (ret == 1) +} + +func DragFinish(hDrop HDROP) { + procDragFinish.Call(uintptr(hDrop)) +} + +func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error { + var op, param, directory uintptr + if len(lpOperation) != 0 { + op = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpOperation))) + } + if len(lpParameters) != 0 { + param = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpParameters))) + } + if len(lpDirectory) != 0 { + directory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDirectory))) + } + + ret, _, _ := procShellExecute.Call( + uintptr(hwnd), + op, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))), + param, + directory, + uintptr(nShowCmd)) + + errorMsg := "" + if ret != 0 && ret <= 32 { + switch int(ret) { + case ERROR_FILE_NOT_FOUND: + errorMsg = "The specified file was not found." + case ERROR_PATH_NOT_FOUND: + errorMsg = "The specified path was not found." + case ERROR_BAD_FORMAT: + errorMsg = "The .exe file is invalid (non-Win32 .exe or error in .exe image)." + case SE_ERR_ACCESSDENIED: + errorMsg = "The operating system denied access to the specified file." + case SE_ERR_ASSOCINCOMPLETE: + errorMsg = "The file name association is incomplete or invalid." + case SE_ERR_DDEBUSY: + errorMsg = "The DDE transaction could not be completed because other DDE transactions were being processed." + case SE_ERR_DDEFAIL: + errorMsg = "The DDE transaction failed." + case SE_ERR_DDETIMEOUT: + errorMsg = "The DDE transaction could not be completed because the request timed out." + case SE_ERR_DLLNOTFOUND: + errorMsg = "The specified DLL was not found." + case SE_ERR_NOASSOC: + errorMsg = "There is no application associated with the given file name extension. This error will also be returned if you attempt to print a file that is not printable." + case SE_ERR_OOM: + errorMsg = "There was not enough memory to complete the operation." + case SE_ERR_SHARE: + errorMsg = "A sharing violation occurred." + default: + errorMsg = fmt.Sprintf("Unknown error occurred with error code %v", ret) + } + } else { + return nil + } + + return errors.New(errorMsg) +} + +func ExtractIcon(lpszExeFileName string, nIconIndex int) HICON { + ret, _, _ := procExtractIcon.Call( + 0, + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpszExeFileName))), + uintptr(nIconIndex)) + + return HICON(ret) +} diff --git a/platform/vendor/github.com/MaxRis/w32/typedef.go b/platform/vendor/github.com/MaxRis/w32/typedef.go new file mode 100644 index 0000000..118f76c --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/typedef.go @@ -0,0 +1,891 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "unsafe" +) + +// From MSDN: Windows Data Types +// http://msdn.microsoft.com/en-us/library/s3f49ktz.aspx +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa383751.aspx +// ATOM WORD +// BOOL int32 +// BOOLEAN byte +// BYTE byte +// CCHAR int8 +// CHAR int8 +// COLORREF DWORD +// DWORD uint32 +// DWORDLONG ULONGLONG +// DWORD_PTR ULONG_PTR +// DWORD32 uint32 +// DWORD64 uint64 +// FLOAT float32 +// HACCEL HANDLE +// HALF_PTR struct{} // ??? +// HANDLE PVOID +// HBITMAP HANDLE +// HBRUSH HANDLE +// HCOLORSPACE HANDLE +// HCONV HANDLE +// HCONVLIST HANDLE +// HCURSOR HANDLE +// HDC HANDLE +// HDDEDATA HANDLE +// HDESK HANDLE +// HDROP HANDLE +// HDWP HANDLE +// HENHMETAFILE HANDLE +// HFILE HANDLE +// HFONT HANDLE +// HGDIOBJ HANDLE +// HGLOBAL HANDLE +// HHOOK HANDLE +// HICON HANDLE +// HINSTANCE HANDLE +// HKEY HANDLE +// HKL HANDLE +// HLOCAL HANDLE +// HMENU HANDLE +// HMETAFILE HANDLE +// HMODULE HANDLE +// HPALETTE HANDLE +// HPEN HANDLE +// HRESULT int32 +// HRGN HANDLE +// HSZ HANDLE +// HWINSTA HANDLE +// HWND HANDLE +// INT int32 +// INT_PTR uintptr +// INT8 int8 +// INT16 int16 +// INT32 int32 +// INT64 int64 +// LANGID WORD +// LCID DWORD +// LCTYPE DWORD +// LGRPID DWORD +// LONG int32 +// LONGLONG int64 +// LONG_PTR uintptr +// LONG32 int32 +// LONG64 int64 +// LPARAM LONG_PTR +// LPBOOL *BOOL +// LPBYTE *BYTE +// LPCOLORREF *COLORREF +// LPCSTR *int8 +// LPCTSTR LPCWSTR +// LPCVOID unsafe.Pointer +// LPCWSTR *WCHAR +// LPDWORD *DWORD +// LPHANDLE *HANDLE +// LPINT *INT +// LPLONG *LONG +// LPSTR *CHAR +// LPTSTR LPWSTR +// LPVOID unsafe.Pointer +// LPWORD *WORD +// LPWSTR *WCHAR +// LRESULT LONG_PTR +// PBOOL *BOOL +// PBOOLEAN *BOOLEAN +// PBYTE *BYTE +// PCHAR *CHAR +// PCSTR *CHAR +// PCTSTR PCWSTR +// PCWSTR *WCHAR +// PDWORD *DWORD +// PDWORDLONG *DWORDLONG +// PDWORD_PTR *DWORD_PTR +// PDWORD32 *DWORD32 +// PDWORD64 *DWORD64 +// PFLOAT *FLOAT +// PHALF_PTR *HALF_PTR +// PHANDLE *HANDLE +// PHKEY *HKEY +// PINT_PTR *INT_PTR +// PINT8 *INT8 +// PINT16 *INT16 +// PINT32 *INT32 +// PINT64 *INT64 +// PLCID *LCID +// PLONG *LONG +// PLONGLONG *LONGLONG +// PLONG_PTR *LONG_PTR +// PLONG32 *LONG32 +// PLONG64 *LONG64 +// POINTER_32 struct{} // ??? +// POINTER_64 struct{} // ??? +// POINTER_SIGNED uintptr +// POINTER_UNSIGNED uintptr +// PSHORT *SHORT +// PSIZE_T *SIZE_T +// PSSIZE_T *SSIZE_T +// PSTR *CHAR +// PTBYTE *TBYTE +// PTCHAR *TCHAR +// PTSTR PWSTR +// PUCHAR *UCHAR +// PUHALF_PTR *UHALF_PTR +// PUINT *UINT +// PUINT_PTR *UINT_PTR +// PUINT8 *UINT8 +// PUINT16 *UINT16 +// PUINT32 *UINT32 +// PUINT64 *UINT64 +// PULONG *ULONG +// PULONGLONG *ULONGLONG +// PULONG_PTR *ULONG_PTR +// PULONG32 *ULONG32 +// PULONG64 *ULONG64 +// PUSHORT *USHORT +// PVOID unsafe.Pointer +// PWCHAR *WCHAR +// PWORD *WORD +// PWSTR *WCHAR +// QWORD uint64 +// SC_HANDLE HANDLE +// SC_LOCK LPVOID +// SERVICE_STATUS_HANDLE HANDLE +// SHORT int16 +// SIZE_T ULONG_PTR +// SSIZE_T LONG_PTR +// TBYTE WCHAR +// TCHAR WCHAR +// UCHAR uint8 +// UHALF_PTR struct{} // ??? +// UINT uint32 +// UINT_PTR uintptr +// UINT8 uint8 +// UINT16 uint16 +// UINT32 uint32 +// UINT64 uint64 +// ULONG uint32 +// ULONGLONG uint64 +// ULONG_PTR uintptr +// ULONG32 uint32 +// ULONG64 uint64 +// USHORT uint16 +// USN LONGLONG +// WCHAR uint16 +// WORD uint16 +// WPARAM UINT_PTR +type ( + ATOM uint16 + BOOL int32 + COLORREF uint32 + DWM_FRAME_COUNT uint64 + DWORD uint32 + HACCEL HANDLE + HANDLE uintptr + HBITMAP HANDLE + HBRUSH HANDLE + HCURSOR HANDLE + HDC HANDLE + HDROP HANDLE + HDWP HANDLE + HENHMETAFILE HANDLE + HFONT HANDLE + HGDIOBJ HANDLE + HGLOBAL HANDLE + HGLRC HANDLE + HHOOK HANDLE + HICON HANDLE + HIMAGELIST HANDLE + HINSTANCE HANDLE + HKEY HANDLE + HKL HANDLE + HMENU HANDLE + HMODULE HANDLE + HMONITOR HANDLE + HPEN HANDLE + HRESULT int32 + HRGN HANDLE + HRSRC HANDLE + HTHUMBNAIL HANDLE + HWND HANDLE + LPARAM uintptr + LPCVOID unsafe.Pointer + LRESULT uintptr + PVOID unsafe.Pointer + QPC_TIME uint64 + ULONG_PTR uintptr + WPARAM uintptr + TRACEHANDLE uintptr +) + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162805.aspx +type POINT struct { + X, Y int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897.aspx +type RECT struct { + Left, Top, Right, Bottom int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms633577.aspx +type WNDCLASSEX struct { + Size uint32 + Style uint32 + WndProc uintptr + ClsExtra int32 + WndExtra int32 + Instance HINSTANCE + Icon HICON + Cursor HCURSOR + Background HBRUSH + MenuName *uint16 + ClassName *uint16 + IconSm HICON +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644958.aspx +type MSG struct { + Hwnd HWND + Message uint32 + WParam uintptr + LParam uintptr + Time uint32 + Pt POINT +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145037.aspx +type LOGFONT struct { + Height int32 + Width int32 + Escapement int32 + Orientation int32 + Weight int32 + Italic byte + Underline byte + StrikeOut byte + CharSet byte + OutPrecision byte + ClipPrecision byte + Quality byte + PitchAndFamily byte + FaceName [LF_FACESIZE]uint16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646839.aspx +type OPENFILENAME struct { + StructSize uint32 + Owner HWND + Instance HINSTANCE + Filter *uint16 + CustomFilter *uint16 + MaxCustomFilter uint32 + FilterIndex uint32 + File *uint16 + MaxFile uint32 + FileTitle *uint16 + MaxFileTitle uint32 + InitialDir *uint16 + Title *uint16 + Flags uint32 + FileOffset uint16 + FileExtension uint16 + DefExt *uint16 + CustData uintptr + FnHook uintptr + TemplateName *uint16 + PvReserved unsafe.Pointer + DwReserved uint32 + FlagsEx uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773205.aspx +type BROWSEINFO struct { + Owner HWND + Root *uint16 + DisplayName *uint16 + Title *uint16 + Flags uint32 + CallbackFunc uintptr + LParam uintptr + Image int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373931.aspx +type GUID struct { + Data1 uint32 + Data2 uint16 + Data3 uint16 + Data4 [8]byte +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221627.aspx +type VARIANT struct { + VT uint16 // 2 + WReserved1 uint16 // 4 + WReserved2 uint16 // 6 + WReserved3 uint16 // 8 + Val int64 // 16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221416.aspx +type DISPPARAMS struct { + Rgvarg uintptr + RgdispidNamedArgs uintptr + CArgs uint32 + CNamedArgs uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms221133.aspx +type EXCEPINFO struct { + WCode uint16 + WReserved uint16 + BstrSource *uint16 + BstrDescription *uint16 + BstrHelpFile *uint16 + DwHelpContext uint32 + PvReserved uintptr + PfnDeferredFillIn uintptr + Scode int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145035.aspx +type LOGBRUSH struct { + LbStyle uint32 + LbColor COLORREF + LbHatch uintptr +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183565.aspx +type DEVMODE struct { + DmDeviceName [CCHDEVICENAME]uint16 + DmSpecVersion uint16 + DmDriverVersion uint16 + DmSize uint16 + DmDriverExtra uint16 + DmFields uint32 + DmOrientation int16 + DmPaperSize int16 + DmPaperLength int16 + DmPaperWidth int16 + DmScale int16 + DmCopies int16 + DmDefaultSource int16 + DmPrintQuality int16 + DmColor int16 + DmDuplex int16 + DmYResolution int16 + DmTTOption int16 + DmCollate int16 + DmFormName [CCHFORMNAME]uint16 + DmLogPixels uint16 + DmBitsPerPel uint32 + DmPelsWidth uint32 + DmPelsHeight uint32 + DmDisplayFlags uint32 + DmDisplayFrequency uint32 + DmICMMethod uint32 + DmICMIntent uint32 + DmMediaType uint32 + DmDitherType uint32 + DmReserved1 uint32 + DmReserved2 uint32 + DmPanningWidth uint32 + DmPanningHeight uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx +type BITMAPINFOHEADER struct { + BiSize uint32 + BiWidth int32 + BiHeight int32 + BiPlanes uint16 + BiBitCount uint16 + BiCompression uint32 + BiSizeImage uint32 + BiXPelsPerMeter int32 + BiYPelsPerMeter int32 + BiClrUsed uint32 + BiClrImportant uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162938.aspx +type RGBQUAD struct { + RgbBlue byte + RgbGreen byte + RgbRed byte + RgbReserved byte +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183375.aspx +type BITMAPINFO struct { + BmiHeader BITMAPINFOHEADER + BmiColors *RGBQUAD +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183371.aspx +type BITMAP struct { + BmType int32 + BmWidth int32 + BmHeight int32 + BmWidthBytes int32 + BmPlanes uint16 + BmBitsPixel uint16 + BmBits unsafe.Pointer +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183567.aspx +type DIBSECTION struct { + DsBm BITMAP + DsBmih BITMAPINFOHEADER + DsBitfields [3]uint32 + DshSection HANDLE + DsOffset uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162607.aspx +type ENHMETAHEADER struct { + IType uint32 + NSize uint32 + RclBounds RECT + RclFrame RECT + DSignature uint32 + NVersion uint32 + NBytes uint32 + NRecords uint32 + NHandles uint16 + SReserved uint16 + NDescription uint32 + OffDescription uint32 + NPalEntries uint32 + SzlDevice SIZE + SzlMillimeters SIZE + CbPixelFormat uint32 + OffPixelFormat uint32 + BOpenGL uint32 + SzlMicrometers SIZE +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145106.aspx +type SIZE struct { + CX, CY int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145132.aspx +type TEXTMETRIC struct { + TmHeight int32 + TmAscent int32 + TmDescent int32 + TmInternalLeading int32 + TmExternalLeading int32 + TmAveCharWidth int32 + TmMaxCharWidth int32 + TmWeight int32 + TmOverhang int32 + TmDigitizedAspectX int32 + TmDigitizedAspectY int32 + TmFirstChar uint16 + TmLastChar uint16 + TmDefaultChar uint16 + TmBreakChar uint16 + TmItalic byte + TmUnderlined byte + TmStruckOut byte + TmPitchAndFamily byte + TmCharSet byte +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd183574.aspx +type DOCINFO struct { + CbSize int32 + LpszDocName *uint16 + LpszOutput *uint16 + LpszDatatype *uint16 + FwType uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775514.aspx +type NMHDR struct { + HwndFrom HWND + IdFrom uintptr + Code uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774743.aspx +type LVCOLUMN struct { + Mask uint32 + Fmt int32 + Cx int32 + PszText *uint16 + CchTextMax int32 + ISubItem int32 + IImage int32 + IOrder int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774760.aspx +type LVITEM struct { + Mask uint32 + IItem int32 + ISubItem int32 + State uint32 + StateMask uint32 + PszText *uint16 + CchTextMax int32 + IImage int32 + LParam uintptr + IIndent int32 + IGroupId int32 + CColumns uint32 + PuColumns uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774754.aspx +type LVHITTESTINFO struct { + Pt POINT + Flags uint32 + IItem int32 + ISubItem int32 + IGroup int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774771.aspx +type NMITEMACTIVATE struct { + Hdr NMHDR + IItem int32 + ISubItem int32 + UNewState uint32 + UOldState uint32 + UChanged uint32 + PtAction POINT + LParam uintptr + UKeyFlags uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774773.aspx +type NMLISTVIEW struct { + Hdr NMHDR + IItem int32 + ISubItem int32 + UNewState uint32 + UOldState uint32 + UChanged uint32 + PtAction POINT + LParam uintptr +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774780.aspx +type NMLVDISPINFO struct { + Hdr NMHDR + Item LVITEM +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb775507.aspx +type INITCOMMONCONTROLSEX struct { + DwSize uint32 + DwICC uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb760256.aspx +type TOOLINFO struct { + CbSize uint32 + UFlags uint32 + Hwnd HWND + UId uintptr + Rect RECT + Hinst HINSTANCE + LpszText *uint16 + LParam uintptr + LpReserved unsafe.Pointer +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms645604.aspx +type TRACKMOUSEEVENT struct { + CbSize uint32 + DwFlags uint32 + HwndTrack HWND + DwHoverTime uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534067.aspx +type GdiplusStartupInput struct { + GdiplusVersion uint32 + DebugEventCallback uintptr + SuppressBackgroundThread BOOL + SuppressExternalCodecs BOOL +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms534068.aspx +type GdiplusStartupOutput struct { + NotificationHook uintptr + NotificationUnhook uintptr +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162768.aspx +type PAINTSTRUCT struct { + Hdc HDC + FErase BOOL + RcPaint RECT + FRestore BOOL + FIncUpdate BOOL + RgbReserved [32]byte +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms684225.aspx +type MODULEENTRY32 struct { + Size uint32 + ModuleID uint32 + ProcessID uint32 + GlblcntUsage uint32 + ProccntUsage uint32 + ModBaseAddr *uint8 + ModBaseSize uint32 + HModule HMODULE + SzModule [MAX_MODULE_NAME32 + 1]uint16 + SzExePath [MAX_PATH]uint16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724284.aspx +type FILETIME struct { + DwLowDateTime uint32 + DwHighDateTime uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119.aspx +type COORD struct { + X, Y int16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311.aspx +type SMALL_RECT struct { + Left, Top, Right, Bottom int16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093.aspx +type CONSOLE_SCREEN_BUFFER_INFO struct { + DwSize COORD + DwCursorPosition COORD + WAttributes uint16 + SrWindow SMALL_RECT + DwMaximumWindowSize COORD +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773244.aspx +type MARGINS struct { + CxLeftWidth, CxRightWidth, CyTopHeight, CyBottomHeight int32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969500.aspx +type DWM_BLURBEHIND struct { + DwFlags uint32 + fEnable BOOL + hRgnBlur HRGN + fTransitionOnMaximized BOOL +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969501.aspx +type DWM_PRESENT_PARAMETERS struct { + cbSize uint32 + fQueue BOOL + cRefreshStart DWM_FRAME_COUNT + cBuffer uint32 + fUseSourceRate BOOL + rateSource UNSIGNED_RATIO + cRefreshesPerFrame uint32 + eSampling DWM_SOURCE_FRAME_SAMPLING +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969502.aspx +type DWM_THUMBNAIL_PROPERTIES struct { + dwFlags uint32 + rcDestination RECT + rcSource RECT + opacity byte + fVisible BOOL + fSourceClientAreaOnly BOOL +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969503.aspx +type DWM_TIMING_INFO struct { + cbSize uint32 + rateRefresh UNSIGNED_RATIO + qpcRefreshPeriod QPC_TIME + rateCompose UNSIGNED_RATIO + qpcVBlank QPC_TIME + cRefresh DWM_FRAME_COUNT + cDXRefresh uint32 + qpcCompose QPC_TIME + cFrame DWM_FRAME_COUNT + cDXPresent uint32 + cRefreshFrame DWM_FRAME_COUNT + cFrameSubmitted DWM_FRAME_COUNT + cDXPresentSubmitted uint32 + cFrameConfirmed DWM_FRAME_COUNT + cDXPresentConfirmed uint32 + cRefreshConfirmed DWM_FRAME_COUNT + cDXRefreshConfirmed uint32 + cFramesLate DWM_FRAME_COUNT + cFramesOutstanding uint32 + cFrameDisplayed DWM_FRAME_COUNT + qpcFrameDisplayed QPC_TIME + cRefreshFrameDisplayed DWM_FRAME_COUNT + cFrameComplete DWM_FRAME_COUNT + qpcFrameComplete QPC_TIME + cFramePending DWM_FRAME_COUNT + qpcFramePending QPC_TIME + cFramesDisplayed DWM_FRAME_COUNT + cFramesComplete DWM_FRAME_COUNT + cFramesPending DWM_FRAME_COUNT + cFramesAvailable DWM_FRAME_COUNT + cFramesDropped DWM_FRAME_COUNT + cFramesMissed DWM_FRAME_COUNT + cRefreshNextDisplayed DWM_FRAME_COUNT + cRefreshNextPresented DWM_FRAME_COUNT + cRefreshesDisplayed DWM_FRAME_COUNT + cRefreshesPresented DWM_FRAME_COUNT + cRefreshStarted DWM_FRAME_COUNT + cPixelsReceived uint64 + cPixelsDrawn uint64 + cBuffersEmpty DWM_FRAME_COUNT +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd389402.aspx +type MilMatrix3x2D struct { + S_11, S_12, S_21, S_22 float64 + DX, DY float64 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa969505.aspx +type UNSIGNED_RATIO struct { + uiNumerator uint32 + uiDenominator uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms632603.aspx +type CREATESTRUCT struct { + CreateParams uintptr + Instance HINSTANCE + Menu HMENU + Parent HWND + Cy, Cx int32 + Y, X int32 + Style int32 + Name *uint16 + Class *uint16 + dwExStyle uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145065.aspx +type MONITORINFO struct { + CbSize uint32 + RcMonitor RECT + RcWork RECT + DwFlags uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd145066.aspx +type MONITORINFOEX struct { + MONITORINFO + SzDevice [CCHDEVICENAME]uint16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/dd368826.aspx +type PIXELFORMATDESCRIPTOR struct { + Size uint16 + Version uint16 + DwFlags uint32 + IPixelType byte + ColorBits byte + RedBits, RedShift byte + GreenBits, GreenShift byte + BlueBits, BlueShift byte + AlphaBits, AlphaShift byte + AccumBits byte + AccumRedBits byte + AccumGreenBits byte + AccumBlueBits byte + AccumAlphaBits byte + DepthBits, StencilBits byte + AuxBuffers byte + ILayerType byte + Reserved byte + DwLayerMask uint32 + DwVisibleMask uint32 + DwDamageMask uint32 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646270(v=vs.85).aspx +type INPUT struct { + Type uint32 + Mi MOUSEINPUT + Ki KEYBDINPUT + Hi HARDWAREINPUT +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646273(v=vs.85).aspx +type MOUSEINPUT struct { + Dx int32 + Dy int32 + MouseData uint32 + DwFlags uint32 + Time uint32 + DwExtraInfo uintptr +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646271(v=vs.85).aspx +type KEYBDINPUT struct { + WVk uint16 + WScan uint16 + DwFlags uint32 + Time uint32 + DwExtraInfo uintptr +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms646269(v=vs.85).aspx +type HARDWAREINPUT struct { + UMsg uint32 + WParamL uint16 + WParamH uint16 +} + +type KbdInput struct { + typ uint32 + ki KEYBDINPUT +} + +type MouseInput struct { + typ uint32 + mi MOUSEINPUT +} + +type HardwareInput struct { + typ uint32 + hi HARDWAREINPUT +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms724950(v=vs.85).aspx +type SYSTEMTIME struct { + Year uint16 + Month uint16 + DayOfWeek uint16 + Day uint16 + Hour uint16 + Minute uint16 + Second uint16 + Milliseconds uint16 +} + +// http://msdn.microsoft.com/en-us/library/windows/desktop/ms644967(v=vs.85).aspx +type KBDLLHOOKSTRUCT struct { + VkCode DWORD + ScanCode DWORD + Flags DWORD + Time DWORD + DwExtraInfo ULONG_PTR +} + +type HOOKPROC func(int, WPARAM, LPARAM) LRESULT + +// https://msdn.microsoft.com/en-us/library/windows/desktop/ms633498(v=vs.85).aspx +type WNDENUMPROC func(HWND, LPARAM) LRESULT diff --git a/platform/vendor/github.com/MaxRis/w32/user32.go b/platform/vendor/github.com/MaxRis/w32/user32.go new file mode 100644 index 0000000..9dbac36 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/user32.go @@ -0,0 +1,1046 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "fmt" + "syscall" + "unsafe" +) + +var ( + moduser32 = syscall.NewLazyDLL("user32.dll") + + procRegisterClassEx = moduser32.NewProc("RegisterClassExW") + procLoadIcon = moduser32.NewProc("LoadIconW") + procLoadCursor = moduser32.NewProc("LoadCursorW") + procShowWindow = moduser32.NewProc("ShowWindow") + procUpdateWindow = moduser32.NewProc("UpdateWindow") + procCreateWindowEx = moduser32.NewProc("CreateWindowExW") + procAdjustWindowRect = moduser32.NewProc("AdjustWindowRect") + procAdjustWindowRectEx = moduser32.NewProc("AdjustWindowRectEx") + procDestroyWindow = moduser32.NewProc("DestroyWindow") + procDefWindowProc = moduser32.NewProc("DefWindowProcW") + procDefDlgProc = moduser32.NewProc("DefDlgProcW") + procPostQuitMessage = moduser32.NewProc("PostQuitMessage") + procGetMessage = moduser32.NewProc("GetMessageW") + procTranslateMessage = moduser32.NewProc("TranslateMessage") + procDispatchMessage = moduser32.NewProc("DispatchMessageW") + procSendMessage = moduser32.NewProc("SendMessageW") + procSendMessageTimeout = moduser32.NewProc("SendMessageTimeout") + procPostMessage = moduser32.NewProc("PostMessageW") + procWaitMessage = moduser32.NewProc("WaitMessage") + procSetWindowText = moduser32.NewProc("SetWindowTextW") + procGetWindowTextLength = moduser32.NewProc("GetWindowTextLengthW") + procGetWindowText = moduser32.NewProc("GetWindowTextW") + procGetWindowRect = moduser32.NewProc("GetWindowRect") + procMoveWindow = moduser32.NewProc("MoveWindow") + procScreenToClient = moduser32.NewProc("ScreenToClient") + procCallWindowProc = moduser32.NewProc("CallWindowProcW") + procSetWindowLong = moduser32.NewProc("SetWindowLongW") + procSetWindowLongPtr = moduser32.NewProc("SetWindowLongW") + procGetWindowLong = moduser32.NewProc("GetWindowLongW") + procGetWindowLongPtr = moduser32.NewProc("GetWindowLongW") + procEnableWindow = moduser32.NewProc("EnableWindow") + procIsWindowEnabled = moduser32.NewProc("IsWindowEnabled") + procIsWindowVisible = moduser32.NewProc("IsWindowVisible") + procSetFocus = moduser32.NewProc("SetFocus") + procInvalidateRect = moduser32.NewProc("InvalidateRect") + procGetClientRect = moduser32.NewProc("GetClientRect") + procGetDC = moduser32.NewProc("GetDC") + procReleaseDC = moduser32.NewProc("ReleaseDC") + procSetCapture = moduser32.NewProc("SetCapture") + procReleaseCapture = moduser32.NewProc("ReleaseCapture") + procGetWindowThreadProcessId = moduser32.NewProc("GetWindowThreadProcessId") + procMessageBox = moduser32.NewProc("MessageBoxW") + procGetSystemMetrics = moduser32.NewProc("GetSystemMetrics") + procCopyRect = moduser32.NewProc("CopyRect") + procEqualRect = moduser32.NewProc("EqualRect") + procInflateRect = moduser32.NewProc("InflateRect") + procIntersectRect = moduser32.NewProc("IntersectRect") + procIsRectEmpty = moduser32.NewProc("IsRectEmpty") + procOffsetRect = moduser32.NewProc("OffsetRect") + procPtInRect = moduser32.NewProc("PtInRect") + procSetRect = moduser32.NewProc("SetRect") + procSetRectEmpty = moduser32.NewProc("SetRectEmpty") + procSubtractRect = moduser32.NewProc("SubtractRect") + procUnionRect = moduser32.NewProc("UnionRect") + procCreateDialogParam = moduser32.NewProc("CreateDialogParamW") + procDialogBoxParam = moduser32.NewProc("DialogBoxParamW") + procGetDlgItem = moduser32.NewProc("GetDlgItem") + procDrawIcon = moduser32.NewProc("DrawIcon") + procClientToScreen = moduser32.NewProc("ClientToScreen") + procIsDialogMessage = moduser32.NewProc("IsDialogMessageW") + procIsWindow = moduser32.NewProc("IsWindow") + procEndDialog = moduser32.NewProc("EndDialog") + procPeekMessage = moduser32.NewProc("PeekMessageW") + procTranslateAccelerator = moduser32.NewProc("TranslateAcceleratorW") + procSetWindowPos = moduser32.NewProc("SetWindowPos") + procFillRect = moduser32.NewProc("FillRect") + procDrawText = moduser32.NewProc("DrawTextW") + procAddClipboardFormatListener = moduser32.NewProc("AddClipboardFormatListener") + procRemoveClipboardFormatListener = moduser32.NewProc("RemoveClipboardFormatListener") + procOpenClipboard = moduser32.NewProc("OpenClipboard") + procCloseClipboard = moduser32.NewProc("CloseClipboard") + procEnumClipboardFormats = moduser32.NewProc("EnumClipboardFormats") + procGetClipboardData = moduser32.NewProc("GetClipboardData") + procSetClipboardData = moduser32.NewProc("SetClipboardData") + procEmptyClipboard = moduser32.NewProc("EmptyClipboard") + procGetClipboardFormatName = moduser32.NewProc("GetClipboardFormatNameW") + procIsClipboardFormatAvailable = moduser32.NewProc("IsClipboardFormatAvailable") + procBeginPaint = moduser32.NewProc("BeginPaint") + procEndPaint = moduser32.NewProc("EndPaint") + procGetKeyboardState = moduser32.NewProc("GetKeyboardState") + procMapVirtualKey = moduser32.NewProc("MapVirtualKeyExW") + procGetAsyncKeyState = moduser32.NewProc("GetAsyncKeyState") + procToAscii = moduser32.NewProc("ToAscii") + procSwapMouseButton = moduser32.NewProc("SwapMouseButton") + procGetCursorPos = moduser32.NewProc("GetCursorPos") + procSetCursorPos = moduser32.NewProc("SetCursorPos") + procSetCursor = moduser32.NewProc("SetCursor") + procCreateIcon = moduser32.NewProc("CreateIcon") + procDestroyIcon = moduser32.NewProc("DestroyIcon") + procMonitorFromPoint = moduser32.NewProc("MonitorFromPoint") + procMonitorFromRect = moduser32.NewProc("MonitorFromRect") + procMonitorFromWindow = moduser32.NewProc("MonitorFromWindow") + procGetMonitorInfo = moduser32.NewProc("GetMonitorInfoW") + procEnumDisplayMonitors = moduser32.NewProc("EnumDisplayMonitors") + procEnumDisplaySettingsEx = moduser32.NewProc("EnumDisplaySettingsExW") + procChangeDisplaySettingsEx = moduser32.NewProc("ChangeDisplaySettingsExW") + procSendInput = moduser32.NewProc("SendInput") + procSetWindowsHookEx = moduser32.NewProc("SetWindowsHookExW") + procUnhookWindowsHookEx = moduser32.NewProc("UnhookWindowsHookEx") + procCallNextHookEx = moduser32.NewProc("CallNextHookEx") + procSetForegroundWindow = moduser32.NewProc("SetForegroundWindow") + procFindWindowW = moduser32.NewProc("FindWindowW") + procFindWindowExW = moduser32.NewProc("FindWindowExW") + procGetClassName = moduser32.NewProc("GetClassNameW") + procEnumChildWindows = moduser32.NewProc("EnumChildWindows") + procSetTimer = moduser32.NewProc("SetTimer") + procKillTimer = moduser32.NewProc("KillTimer") + procRedrawWindow = moduser32.NewProc("RedrawWindow") +) + +func RegisterClassEx(wndClassEx *WNDCLASSEX) ATOM { + ret, _, _ := procRegisterClassEx.Call(uintptr(unsafe.Pointer(wndClassEx))) + return ATOM(ret) +} + +func LoadIcon(instance HINSTANCE, iconName *uint16) HICON { + ret, _, _ := procLoadIcon.Call( + uintptr(instance), + uintptr(unsafe.Pointer(iconName))) + + return HICON(ret) + +} + +func LoadCursor(instance HINSTANCE, cursorName *uint16) HCURSOR { + ret, _, _ := procLoadCursor.Call( + uintptr(instance), + uintptr(unsafe.Pointer(cursorName))) + + return HCURSOR(ret) + +} + +func GetClassNameW(hwnd HWND) string { + buf := make([]uint16, 255) + procGetClassName.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(255)) + + return syscall.UTF16ToString(buf) +} + +func SetForegroundWindow(hwnd HWND) bool { + ret, _, _ := procSetForegroundWindow.Call( + uintptr(hwnd)) + + return ret != 0 +} + +func ShowWindow(hwnd HWND, cmdshow int) bool { + ret, _, _ := procShowWindow.Call( + uintptr(hwnd), + uintptr(cmdshow)) + + return ret != 0 + +} + +func UpdateWindow(hwnd HWND) bool { + ret, _, _ := procUpdateWindow.Call( + uintptr(hwnd)) + return ret != 0 +} + +func CreateWindowEx(exStyle uint, className, windowName *uint16, + style uint, x, y, width, height int, parent HWND, menu HMENU, + instance HINSTANCE, param unsafe.Pointer) HWND { + ret, _, _ := procCreateWindowEx.Call( + uintptr(exStyle), + uintptr(unsafe.Pointer(className)), + uintptr(unsafe.Pointer(windowName)), + uintptr(style), + uintptr(x), + uintptr(y), + uintptr(width), + uintptr(height), + uintptr(parent), + uintptr(menu), + uintptr(instance), + uintptr(param)) + + return HWND(ret) +} + +func FindWindowExW(hwndParent, hwndChildAfter HWND, className, windowName *uint16) HWND { + ret, _, _ := procFindWindowExW.Call( + uintptr(hwndParent), + uintptr(hwndChildAfter), + uintptr(unsafe.Pointer(className)), + uintptr(unsafe.Pointer(windowName))) + + return HWND(ret) +} + +func FindWindowW(className, windowName *uint16) HWND { + ret, _, _ := procFindWindowW.Call( + uintptr(unsafe.Pointer(className)), + uintptr(unsafe.Pointer(windowName))) + + return HWND(ret) +} + +func EnumChildWindows(hWndParent HWND, lpEnumFunc WNDENUMPROC, lParam LPARAM) bool { + ret, _, _ := procEnumChildWindows.Call( + uintptr(hWndParent), + uintptr(syscall.NewCallback(lpEnumFunc)), + uintptr(lParam), + ) + + return ret != 0 +} + +func AdjustWindowRectEx(rect *RECT, style uint, menu bool, exStyle uint) bool { + ret, _, _ := procAdjustWindowRectEx.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(style), + uintptr(BoolToBOOL(menu)), + uintptr(exStyle)) + + return ret != 0 +} + +func AdjustWindowRect(rect *RECT, style uint, menu bool) bool { + ret, _, _ := procAdjustWindowRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(style), + uintptr(BoolToBOOL(menu))) + + return ret != 0 +} + +func DestroyWindow(hwnd HWND) bool { + ret, _, _ := procDestroyWindow.Call( + uintptr(hwnd)) + + return ret != 0 +} + +func DefWindowProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := procDefWindowProc.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam) + + return ret +} + +func DefDlgProc(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := procDefDlgProc.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam) + + return ret +} + +func PostQuitMessage(exitCode int) { + procPostQuitMessage.Call( + uintptr(exitCode)) +} + +func GetMessage(msg *MSG, hwnd HWND, msgFilterMin, msgFilterMax uint32) int { + ret, _, _ := procGetMessage.Call( + uintptr(unsafe.Pointer(msg)), + uintptr(hwnd), + uintptr(msgFilterMin), + uintptr(msgFilterMax)) + + return int(ret) +} + +func TranslateMessage(msg *MSG) bool { + ret, _, _ := procTranslateMessage.Call( + uintptr(unsafe.Pointer(msg))) + + return ret != 0 + +} + +func DispatchMessage(msg *MSG) uintptr { + ret, _, _ := procDispatchMessage.Call( + uintptr(unsafe.Pointer(msg))) + + return ret + +} + +func SendMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := procSendMessage.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam) + + return ret +} + +func SendMessageTimeout(hwnd HWND, msg uint32, wParam, lParam uintptr, fuFlags, uTimeout uint32) uintptr { + ret, _, _ := procSendMessageTimeout.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam, + uintptr(fuFlags), + uintptr(uTimeout)) + + return ret +} + +func PostMessage(hwnd HWND, msg uint32, wParam, lParam uintptr) bool { + ret, _, _ := procPostMessage.Call( + uintptr(hwnd), + uintptr(msg), + wParam, + lParam) + + return ret != 0 +} + +func WaitMessage() bool { + ret, _, _ := procWaitMessage.Call() + return ret != 0 +} + +func SetWindowText(hwnd HWND, text string) { + procSetWindowText.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text)))) +} + +func GetWindowTextLength(hwnd HWND) int { + ret, _, _ := procGetWindowTextLength.Call( + uintptr(hwnd)) + + return int(ret) +} + +func GetWindowText(hwnd HWND) string { + textLen := GetWindowTextLength(hwnd) + 1 + + buf := make([]uint16, textLen) + procGetWindowText.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(textLen)) + + return syscall.UTF16ToString(buf) +} + +func GetWindowRect(hwnd HWND) *RECT { + var rect RECT + procGetWindowRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&rect))) + + return &rect +} + +func MoveWindow(hwnd HWND, x, y, width, height int, repaint bool) bool { + ret, _, _ := procMoveWindow.Call( + uintptr(hwnd), + uintptr(x), + uintptr(y), + uintptr(width), + uintptr(height), + uintptr(BoolToBOOL(repaint))) + + return ret != 0 + +} + +func ScreenToClient(hwnd HWND, x, y int) (X, Y int, ok bool) { + pt := POINT{X: int32(x), Y: int32(y)} + ret, _, _ := procScreenToClient.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&pt))) + + return int(pt.X), int(pt.Y), ret != 0 +} + +func CallWindowProc(preWndProc uintptr, hwnd HWND, msg uint32, wParam, lParam uintptr) uintptr { + ret, _, _ := procCallWindowProc.Call( + preWndProc, + uintptr(hwnd), + uintptr(msg), + wParam, + lParam) + + return ret +} + +func SetWindowLong(hwnd HWND, index int, value uint32) uint32 { + ret, _, _ := procSetWindowLong.Call( + uintptr(hwnd), + uintptr(index), + uintptr(value)) + + return uint32(ret) +} + +func SetWindowLongPtr(hwnd HWND, index int, value uintptr) uintptr { + ret, _, _ := procSetWindowLongPtr.Call( + uintptr(hwnd), + uintptr(index), + value) + + return ret +} + +func GetWindowLong(hwnd HWND, index int) int32 { + ret, _, _ := procGetWindowLong.Call( + uintptr(hwnd), + uintptr(index)) + + return int32(ret) +} + +func GetWindowLongPtr(hwnd HWND, index int) uintptr { + ret, _, _ := procGetWindowLongPtr.Call( + uintptr(hwnd), + uintptr(index)) + + return ret +} + +func EnableWindow(hwnd HWND, b bool) bool { + ret, _, _ := procEnableWindow.Call( + uintptr(hwnd), + uintptr(BoolToBOOL(b))) + return ret != 0 +} + +func IsWindowEnabled(hwnd HWND) bool { + ret, _, _ := procIsWindowEnabled.Call( + uintptr(hwnd)) + + return ret != 0 +} + +func IsWindowVisible(hwnd HWND) bool { + ret, _, _ := procIsWindowVisible.Call( + uintptr(hwnd)) + + return ret != 0 +} + +func SetFocus(hwnd HWND) HWND { + ret, _, _ := procSetFocus.Call( + uintptr(hwnd)) + + return HWND(ret) +} + +func InvalidateRect(hwnd HWND, rect *RECT, erase bool) bool { + ret, _, _ := procInvalidateRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(rect)), + uintptr(BoolToBOOL(erase))) + + return ret != 0 +} + +func GetClientRect(hwnd HWND) *RECT { + var rect RECT + ret, _, _ := procGetClientRect.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&rect))) + + if ret == 0 { + panic(fmt.Sprintf("GetClientRect(%d) failed", hwnd)) + } + + return &rect +} + +func GetDC(hwnd HWND) HDC { + ret, _, _ := procGetDC.Call( + uintptr(hwnd)) + + return HDC(ret) +} + +func ReleaseDC(hwnd HWND, hDC HDC) bool { + ret, _, _ := procReleaseDC.Call( + uintptr(hwnd), + uintptr(hDC)) + + return ret != 0 +} + +func SetCapture(hwnd HWND) HWND { + ret, _, _ := procSetCapture.Call( + uintptr(hwnd)) + + return HWND(ret) +} + +func ReleaseCapture() bool { + ret, _, _ := procReleaseCapture.Call() + + return ret != 0 +} + +func GetWindowThreadProcessId(hwnd HWND) (HANDLE, int) { + var processId int + ret, _, _ := procGetWindowThreadProcessId.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&processId))) + + return HANDLE(ret), processId +} + +func MessageBox(hwnd HWND, title, caption string, flags uint) int { + ret, _, _ := procMessageBox.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(title))), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(caption))), + uintptr(flags)) + + return int(ret) +} + +func GetSystemMetrics(index int) int { + ret, _, _ := procGetSystemMetrics.Call( + uintptr(index)) + + return int(ret) +} + +func CopyRect(dst, src *RECT) bool { + ret, _, _ := procCopyRect.Call( + uintptr(unsafe.Pointer(dst)), + uintptr(unsafe.Pointer(src))) + + return ret != 0 +} + +func EqualRect(rect1, rect2 *RECT) bool { + ret, _, _ := procEqualRect.Call( + uintptr(unsafe.Pointer(rect1)), + uintptr(unsafe.Pointer(rect2))) + + return ret != 0 +} + +func InflateRect(rect *RECT, dx, dy int) bool { + ret, _, _ := procInflateRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(dx), + uintptr(dy)) + + return ret != 0 +} + +func IntersectRect(dst, src1, src2 *RECT) bool { + ret, _, _ := procIntersectRect.Call( + uintptr(unsafe.Pointer(dst)), + uintptr(unsafe.Pointer(src1)), + uintptr(unsafe.Pointer(src2))) + + return ret != 0 +} + +func IsRectEmpty(rect *RECT) bool { + ret, _, _ := procIsRectEmpty.Call( + uintptr(unsafe.Pointer(rect))) + + return ret != 0 +} + +func OffsetRect(rect *RECT, dx, dy int) bool { + ret, _, _ := procOffsetRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(dx), + uintptr(dy)) + + return ret != 0 +} + +func PtInRect(rect *RECT, x, y int) bool { + pt := POINT{X: int32(x), Y: int32(y)} + ret, _, _ := procPtInRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(unsafe.Pointer(&pt))) + + return ret != 0 +} + +func SetRect(rect *RECT, left, top, right, bottom int) bool { + ret, _, _ := procSetRect.Call( + uintptr(unsafe.Pointer(rect)), + uintptr(left), + uintptr(top), + uintptr(right), + uintptr(bottom)) + + return ret != 0 +} + +func SetRectEmpty(rect *RECT) bool { + ret, _, _ := procSetRectEmpty.Call( + uintptr(unsafe.Pointer(rect))) + + return ret != 0 +} + +func SubtractRect(dst, src1, src2 *RECT) bool { + ret, _, _ := procSubtractRect.Call( + uintptr(unsafe.Pointer(dst)), + uintptr(unsafe.Pointer(src1)), + uintptr(unsafe.Pointer(src2))) + + return ret != 0 +} + +func UnionRect(dst, src1, src2 *RECT) bool { + ret, _, _ := procUnionRect.Call( + uintptr(unsafe.Pointer(dst)), + uintptr(unsafe.Pointer(src1)), + uintptr(unsafe.Pointer(src2))) + + return ret != 0 +} + +func CreateDialog(hInstance HINSTANCE, lpTemplate *uint16, hWndParent HWND, lpDialogProc uintptr) HWND { + ret, _, _ := procCreateDialogParam.Call( + uintptr(hInstance), + uintptr(unsafe.Pointer(lpTemplate)), + uintptr(hWndParent), + lpDialogProc, + 0) + + return HWND(ret) +} + +func DialogBox(hInstance HINSTANCE, lpTemplateName *uint16, hWndParent HWND, lpDialogProc uintptr) int { + ret, _, _ := procDialogBoxParam.Call( + uintptr(hInstance), + uintptr(unsafe.Pointer(lpTemplateName)), + uintptr(hWndParent), + lpDialogProc, + 0) + + return int(ret) +} + +func GetDlgItem(hDlg HWND, nIDDlgItem int) HWND { + ret, _, _ := procGetDlgItem.Call( + uintptr(unsafe.Pointer(hDlg)), + uintptr(nIDDlgItem)) + + return HWND(ret) +} + +func DrawIcon(hDC HDC, x, y int, hIcon HICON) bool { + ret, _, _ := procDrawIcon.Call( + uintptr(unsafe.Pointer(hDC)), + uintptr(x), + uintptr(y), + uintptr(unsafe.Pointer(hIcon))) + + return ret != 0 +} + +func ClientToScreen(hwnd HWND, x, y int) (int, int) { + pt := POINT{X: int32(x), Y: int32(y)} + + procClientToScreen.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(&pt))) + + return int(pt.X), int(pt.Y) +} + +func IsDialogMessage(hwnd HWND, msg *MSG) bool { + ret, _, _ := procIsDialogMessage.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(msg))) + + return ret != 0 +} + +func IsWindow(hwnd HWND) bool { + ret, _, _ := procIsWindow.Call( + uintptr(hwnd)) + + return ret != 0 +} + +func EndDialog(hwnd HWND, nResult uintptr) bool { + ret, _, _ := procEndDialog.Call( + uintptr(hwnd), + nResult) + + return ret != 0 +} + +func PeekMessage(lpMsg *MSG, hwnd HWND, wMsgFilterMin, wMsgFilterMax, wRemoveMsg uint32) bool { + ret, _, _ := procPeekMessage.Call( + uintptr(unsafe.Pointer(lpMsg)), + uintptr(hwnd), + uintptr(wMsgFilterMin), + uintptr(wMsgFilterMax), + uintptr(wRemoveMsg)) + + return ret != 0 +} + +func TranslateAccelerator(hwnd HWND, hAccTable HACCEL, lpMsg *MSG) bool { + ret, _, _ := procTranslateAccelerator.Call( + uintptr(hwnd), + uintptr(hAccTable), + uintptr(unsafe.Pointer(lpMsg))) + + return ret != 0 +} + +func SetWindowPos(hwnd, hWndInsertAfter HWND, x, y, cx, cy int, uFlags uint) bool { + ret, _, _ := procSetWindowPos.Call( + uintptr(hwnd), + uintptr(hWndInsertAfter), + uintptr(x), + uintptr(y), + uintptr(cx), + uintptr(cy), + uintptr(uFlags)) + + return ret != 0 +} + +func FillRect(hDC HDC, lprc *RECT, hbr HBRUSH) bool { + ret, _, _ := procFillRect.Call( + uintptr(hDC), + uintptr(unsafe.Pointer(lprc)), + uintptr(hbr)) + + return ret != 0 +} + +func DrawText(hDC HDC, text string, uCount int, lpRect *RECT, uFormat uint) int { + ret, _, _ := procDrawText.Call( + uintptr(hDC), + uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(text))), + uintptr(uCount), + uintptr(unsafe.Pointer(lpRect)), + uintptr(uFormat)) + + return int(ret) +} + +func AddClipboardFormatListener(hwnd HWND) bool { + ret, _, _ := procAddClipboardFormatListener.Call( + uintptr(hwnd)) + return ret != 0 +} + +func RemoveClipboardFormatListener(hwnd HWND) bool { + ret, _, _ := procRemoveClipboardFormatListener.Call( + uintptr(hwnd)) + return ret != 0 +} + +func OpenClipboard(hWndNewOwner HWND) bool { + ret, _, _ := procOpenClipboard.Call( + uintptr(hWndNewOwner)) + return ret != 0 +} + +func CloseClipboard() bool { + ret, _, _ := procCloseClipboard.Call() + return ret != 0 +} + +func EnumClipboardFormats(format uint) uint { + ret, _, _ := procEnumClipboardFormats.Call( + uintptr(format)) + return uint(ret) +} + +func GetClipboardData(uFormat uint) HANDLE { + ret, _, _ := procGetClipboardData.Call( + uintptr(uFormat)) + return HANDLE(ret) +} + +func SetClipboardData(uFormat uint, hMem HANDLE) HANDLE { + ret, _, _ := procSetClipboardData.Call( + uintptr(uFormat), + uintptr(hMem)) + return HANDLE(ret) +} + +func EmptyClipboard() bool { + ret, _, _ := procEmptyClipboard.Call() + return ret != 0 +} + +func GetClipboardFormatName(format uint) (string, bool) { + cchMaxCount := 255 + buf := make([]uint16, cchMaxCount) + ret, _, _ := procGetClipboardFormatName.Call( + uintptr(format), + uintptr(unsafe.Pointer(&buf[0])), + uintptr(cchMaxCount)) + + if ret > 0 { + return syscall.UTF16ToString(buf), true + } + + return "Requested format does not exist or is predefined", false +} + +func IsClipboardFormatAvailable(format uint) bool { + ret, _, _ := procIsClipboardFormatAvailable.Call(uintptr(format)) + return ret != 0 +} + +func BeginPaint(hwnd HWND, paint *PAINTSTRUCT) HDC { + ret, _, _ := procBeginPaint.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(paint))) + return HDC(ret) +} + +func EndPaint(hwnd HWND, paint *PAINTSTRUCT) { + procEndPaint.Call( + uintptr(hwnd), + uintptr(unsafe.Pointer(paint))) +} + +func GetKeyboardState(lpKeyState *[]byte) bool { + ret, _, _ := procGetKeyboardState.Call( + uintptr(unsafe.Pointer(&(*lpKeyState)[0]))) + return ret != 0 +} + +func MapVirtualKeyEx(uCode, uMapType uint, dwhkl HKL) uint { + ret, _, _ := procMapVirtualKey.Call( + uintptr(uCode), + uintptr(uMapType), + uintptr(dwhkl)) + return uint(ret) +} + +func GetAsyncKeyState(vKey int) uint16 { + ret, _, _ := procGetAsyncKeyState.Call(uintptr(vKey)) + return uint16(ret) +} + +func ToAscii(uVirtKey, uScanCode uint, lpKeyState *byte, lpChar *uint16, uFlags uint) int { + ret, _, _ := procToAscii.Call( + uintptr(uVirtKey), + uintptr(uScanCode), + uintptr(unsafe.Pointer(lpKeyState)), + uintptr(unsafe.Pointer(lpChar)), + uintptr(uFlags)) + return int(ret) +} + +func SwapMouseButton(fSwap bool) bool { + ret, _, _ := procSwapMouseButton.Call( + uintptr(BoolToBOOL(fSwap))) + return ret != 0 +} + +func GetCursorPos() (x, y int, ok bool) { + pt := POINT{} + ret, _, _ := procGetCursorPos.Call(uintptr(unsafe.Pointer(&pt))) + return int(pt.X), int(pt.Y), ret != 0 +} + +func SetCursorPos(x, y int) bool { + ret, _, _ := procSetCursorPos.Call( + uintptr(x), + uintptr(y), + ) + return ret != 0 +} + +func SetCursor(cursor HCURSOR) HCURSOR { + ret, _, _ := procSetCursor.Call( + uintptr(cursor), + ) + return HCURSOR(ret) +} + +func CreateIcon(instance HINSTANCE, nWidth, nHeight int, cPlanes, cBitsPerPixel byte, ANDbits, XORbits *byte) HICON { + ret, _, _ := procCreateIcon.Call( + uintptr(instance), + uintptr(nWidth), + uintptr(nHeight), + uintptr(cPlanes), + uintptr(cBitsPerPixel), + uintptr(unsafe.Pointer(ANDbits)), + uintptr(unsafe.Pointer(XORbits)), + ) + return HICON(ret) +} + +func DestroyIcon(icon HICON) bool { + ret, _, _ := procDestroyIcon.Call( + uintptr(icon), + ) + return ret != 0 +} + +func MonitorFromPoint(x, y int, dwFlags uint32) HMONITOR { + ret, _, _ := procMonitorFromPoint.Call( + uintptr(x), + uintptr(y), + uintptr(dwFlags), + ) + return HMONITOR(ret) +} + +func MonitorFromRect(rc *RECT, dwFlags uint32) HMONITOR { + ret, _, _ := procMonitorFromRect.Call( + uintptr(unsafe.Pointer(rc)), + uintptr(dwFlags), + ) + return HMONITOR(ret) +} + +func MonitorFromWindow(hwnd HWND, dwFlags uint32) HMONITOR { + ret, _, _ := procMonitorFromWindow.Call( + uintptr(hwnd), + uintptr(dwFlags), + ) + return HMONITOR(ret) +} + +func GetMonitorInfo(hMonitor HMONITOR, lmpi *MONITORINFO) bool { + ret, _, _ := procGetMonitorInfo.Call( + uintptr(hMonitor), + uintptr(unsafe.Pointer(lmpi)), + ) + return ret != 0 +} + +func EnumDisplayMonitors(hdc HDC, clip *RECT, fnEnum, dwData uintptr) bool { + ret, _, _ := procEnumDisplayMonitors.Call( + uintptr(hdc), + uintptr(unsafe.Pointer(clip)), + fnEnum, + dwData, + ) + return ret != 0 +} + +func EnumDisplaySettingsEx(szDeviceName *uint16, iModeNum uint32, devMode *DEVMODE, dwFlags uint32) bool { + ret, _, _ := procEnumDisplaySettingsEx.Call( + uintptr(unsafe.Pointer(szDeviceName)), + uintptr(iModeNum), + uintptr(unsafe.Pointer(devMode)), + uintptr(dwFlags), + ) + return ret != 0 +} + +func ChangeDisplaySettingsEx(szDeviceName *uint16, devMode *DEVMODE, hwnd HWND, dwFlags uint32, lParam uintptr) int32 { + ret, _, _ := procChangeDisplaySettingsEx.Call( + uintptr(unsafe.Pointer(szDeviceName)), + uintptr(unsafe.Pointer(devMode)), + uintptr(hwnd), + uintptr(dwFlags), + lParam, + ) + return int32(ret) +} + +func SetWindowsHookEx(idHook int, lpfn HOOKPROC, hMod HINSTANCE, dwThreadId DWORD) HHOOK { + ret, _, _ := procSetWindowsHookEx.Call( + uintptr(idHook), + uintptr(syscall.NewCallback(lpfn)), + uintptr(hMod), + uintptr(dwThreadId), + ) + return HHOOK(ret) +} + +func UnhookWindowsHookEx(hhk HHOOK) bool { + ret, _, _ := procUnhookWindowsHookEx.Call( + uintptr(hhk), + ) + return ret != 0 +} + +func CallNextHookEx(hhk HHOOK, nCode int, wParam WPARAM, lParam LPARAM) LRESULT { + ret, _, _ := procCallNextHookEx.Call( + uintptr(hhk), + uintptr(nCode), + uintptr(wParam), + uintptr(lParam), + ) + return LRESULT(ret) +} + +func SetTimer(hwnd HWND, nIDEvent uint32, uElapse uint32, lpTimerProc uintptr) uintptr { + ret, _, _ := procSetTimer.Call( + uintptr(hwnd), + uintptr(nIDEvent), + uintptr(uElapse), + lpTimerProc, + ) + return ret +} + +func KillTimer(hwnd HWND, nIDEvent uint32) bool { + ret, _, _ := procKillTimer.Call( + uintptr(hwnd), + uintptr(nIDEvent), + ) + return ret != 0 +} + +// it will panic when the function fails +func RedrawWindow(hWnd HWND, lpRect *RECT, hrgnUpdate HRGN, flag uint32) { + ret, _, _ := procRedrawWindow.Call( + uintptr(hWnd), + uintptr(unsafe.Pointer(lpRect)), + uintptr(hrgnUpdate), + uintptr(flag), + ) + if ret!=0{ + panic("RedrawWindow fail") + } + return +} diff --git a/platform/vendor/github.com/MaxRis/w32/utils.go b/platform/vendor/github.com/MaxRis/w32/utils.go new file mode 100644 index 0000000..4fb5b6c --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/utils.go @@ -0,0 +1,201 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +import ( + "syscall" + "unicode/utf16" + "unsafe" +) + +func MakeIntResource(id uint16) *uint16 { + return (*uint16)(unsafe.Pointer(uintptr(id))) +} + +func LOWORD(dw uint32) uint16 { + return uint16(dw) +} + +func HIWORD(dw uint32) uint16 { + return uint16(dw >> 16 & 0xffff) +} + +func BoolToBOOL(value bool) BOOL { + if value { + return 1 + } + + return 0 +} + +func UTF16PtrToString(cstr *uint16) string { + if cstr != nil { + us := make([]uint16, 0, 256) + for p := uintptr(unsafe.Pointer(cstr)); ; p += 2 { + u := *(*uint16)(unsafe.Pointer(p)) + if u == 0 { + return string(utf16.Decode(us)) + } + us = append(us, u) + } + } + + return "" +} + +func ComAddRef(unknown *IUnknown) int32 { + ret, _, _ := syscall.Syscall(unknown.lpVtbl.pAddRef, 1, + uintptr(unsafe.Pointer(unknown)), + 0, + 0) + return int32(ret) +} + +func ComRelease(unknown *IUnknown) int32 { + ret, _, _ := syscall.Syscall(unknown.lpVtbl.pRelease, 1, + uintptr(unsafe.Pointer(unknown)), + 0, + 0) + return int32(ret) +} + +func ComQueryInterface(unknown *IUnknown, id *GUID) *IDispatch { + var disp *IDispatch + hr, _, _ := syscall.Syscall(unknown.lpVtbl.pQueryInterface, 3, + uintptr(unsafe.Pointer(unknown)), + uintptr(unsafe.Pointer(id)), + uintptr(unsafe.Pointer(&disp))) + if hr != 0 { + panic("Invoke QieryInterface error.") + } + return disp +} + +func ComGetIDsOfName(disp *IDispatch, names []string) []int32 { + wnames := make([]*uint16, len(names)) + dispid := make([]int32, len(names)) + for i := 0; i < len(names); i++ { + wnames[i] = syscall.StringToUTF16Ptr(names[i]) + } + hr, _, _ := syscall.Syscall6(disp.lpVtbl.pGetIDsOfNames, 6, + uintptr(unsafe.Pointer(disp)), + uintptr(unsafe.Pointer(IID_NULL)), + uintptr(unsafe.Pointer(&wnames[0])), + uintptr(len(names)), + uintptr(GetUserDefaultLCID()), + uintptr(unsafe.Pointer(&dispid[0]))) + if hr != 0 { + panic("Invoke GetIDsOfName error.") + } + return dispid +} + +func ComInvoke(disp *IDispatch, dispid int32, dispatch int16, params ...interface{}) (result *VARIANT) { + var dispparams DISPPARAMS + + if dispatch&DISPATCH_PROPERTYPUT != 0 { + dispnames := [1]int32{DISPID_PROPERTYPUT} + dispparams.RgdispidNamedArgs = uintptr(unsafe.Pointer(&dispnames[0])) + dispparams.CNamedArgs = 1 + } + var vargs []VARIANT + if len(params) > 0 { + vargs = make([]VARIANT, len(params)) + for i, v := range params { + //n := len(params)-i-1 + n := len(params) - i - 1 + VariantInit(&vargs[n]) + switch v.(type) { + case bool: + if v.(bool) { + vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0xffff} + } else { + vargs[n] = VARIANT{VT_BOOL, 0, 0, 0, 0} + } + case *bool: + vargs[n] = VARIANT{VT_BOOL | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*bool))))} + case byte: + vargs[n] = VARIANT{VT_I1, 0, 0, 0, int64(v.(byte))} + case *byte: + vargs[n] = VARIANT{VT_I1 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*byte))))} + case int16: + vargs[n] = VARIANT{VT_I2, 0, 0, 0, int64(v.(int16))} + case *int16: + vargs[n] = VARIANT{VT_I2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int16))))} + case uint16: + vargs[n] = VARIANT{VT_UI2, 0, 0, 0, int64(v.(int16))} + case *uint16: + vargs[n] = VARIANT{VT_UI2 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint16))))} + case int, int32: + vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(int))} + case *int, *int32: + vargs[n] = VARIANT{VT_I4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int))))} + case uint, uint32: + vargs[n] = VARIANT{VT_UI4, 0, 0, 0, int64(v.(uint))} + case *uint, *uint32: + vargs[n] = VARIANT{VT_UI4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint))))} + case int64: + vargs[n] = VARIANT{VT_I8, 0, 0, 0, v.(int64)} + case *int64: + vargs[n] = VARIANT{VT_I8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*int64))))} + case uint64: + vargs[n] = VARIANT{VT_UI8, 0, 0, 0, int64(v.(uint64))} + case *uint64: + vargs[n] = VARIANT{VT_UI8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*uint64))))} + case float32: + vargs[n] = VARIANT{VT_R4, 0, 0, 0, int64(v.(float32))} + case *float32: + vargs[n] = VARIANT{VT_R4 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float32))))} + case float64: + vargs[n] = VARIANT{VT_R8, 0, 0, 0, int64(v.(float64))} + case *float64: + vargs[n] = VARIANT{VT_R8 | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*float64))))} + case string: + vargs[n] = VARIANT{VT_BSTR, 0, 0, 0, int64(uintptr(unsafe.Pointer(SysAllocString(v.(string)))))} + case *string: + vargs[n] = VARIANT{VT_BSTR | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*string))))} + case *IDispatch: + vargs[n] = VARIANT{VT_DISPATCH, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*IDispatch))))} + case **IDispatch: + vargs[n] = VARIANT{VT_DISPATCH | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(**IDispatch))))} + case nil: + vargs[n] = VARIANT{VT_NULL, 0, 0, 0, 0} + case *VARIANT: + vargs[n] = VARIANT{VT_VARIANT | VT_BYREF, 0, 0, 0, int64(uintptr(unsafe.Pointer(v.(*VARIANT))))} + default: + panic("unknown type") + } + } + dispparams.Rgvarg = uintptr(unsafe.Pointer(&vargs[0])) + dispparams.CArgs = uint32(len(params)) + } + + var ret VARIANT + var excepInfo EXCEPINFO + VariantInit(&ret) + hr, _, _ := syscall.Syscall9(disp.lpVtbl.pInvoke, 8, + uintptr(unsafe.Pointer(disp)), + uintptr(dispid), + uintptr(unsafe.Pointer(IID_NULL)), + uintptr(GetUserDefaultLCID()), + uintptr(dispatch), + uintptr(unsafe.Pointer(&dispparams)), + uintptr(unsafe.Pointer(&ret)), + uintptr(unsafe.Pointer(&excepInfo)), + 0) + if hr != 0 { + if excepInfo.BstrDescription != nil { + bs := UTF16PtrToString(excepInfo.BstrDescription) + panic(bs) + } + } + for _, varg := range vargs { + if varg.VT == VT_BSTR && varg.Val != 0 { + SysFreeString(((*int16)(unsafe.Pointer(uintptr(varg.Val))))) + } + } + result = &ret + return +} diff --git a/platform/vendor/github.com/MaxRis/w32/vars.go b/platform/vendor/github.com/MaxRis/w32/vars.go new file mode 100644 index 0000000..2dab2e3 --- /dev/null +++ b/platform/vendor/github.com/MaxRis/w32/vars.go @@ -0,0 +1,13 @@ +// Copyright 2010-2012 The W32 Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package w32 + +var ( + IID_NULL = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}} + IID_IUnknown = &GUID{0x00000000, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}} + IID_IDispatch = &GUID{0x00020400, 0x0000, 0x0000, [8]byte{0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}} + IID_IConnectionPointContainer = &GUID{0xB196B284, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}} + IID_IConnectionPoint = &GUID{0xB196B286, 0xBAB4, 0x101A, [8]byte{0xB6, 0x9C, 0x00, 0xAA, 0x00, 0x34, 0x1D, 0x07}} +) diff --git a/platform/winproc.go b/platform/winproc.go new file mode 100644 index 0000000..e13ff69 --- /dev/null +++ b/platform/winproc.go @@ -0,0 +1,198 @@ +// +build windows,cgo + +package platform + +// #include "windows.h" +// +// /* Until we can specify the platform SDK and target version for Windows.h * +// * without breaking our ability to gracefully display an error message, these * +// * definitions will be copied from the platform SDK headers and made to work. * +// */ +// +// typedef BOOL (* InitializeProcThreadAttributeListProcType)(LPPROC_THREAD_ATTRIBUTE_LIST, DWORD, DWORD, PSIZE_T); +// typedef BOOL (* UpdateProcThreadAttributeProcType)( +// LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList, +// DWORD dwFlags, +// DWORD_PTR Attribute, +// PVOID lpValue, +// SIZE_T cbSize, +// PVOID lpPreviousValue, +// PSIZE_T lpReturnSize +// ); +// +// InitializeProcThreadAttributeListProcType pfnInitializeProcThreadAttributeList = NULL; +// UpdateProcThreadAttributeProcType pfnUpdateProcThreadAttribute = NULL; +// +// #define ProcThreadAttributePseudoConsole 22 +// +// #define PROC_THREAD_ATTRIBUTE_NUMBER 0x0000FFFF +// #define PROC_THREAD_ATTRIBUTE_THREAD 0x00010000 // Attribute may be used with thread creation +// #define PROC_THREAD_ATTRIBUTE_INPUT 0x00020000 // Attribute is input only +// #define PROC_THREAD_ATTRIBUTE_ADDITIVE 0x00040000 // Attribute may be "accumulated," e.g. bitmasks, counters, etc. +// +// #define ProcThreadAttributeValue(Number, Thread, Input, Additive) \ +// (((Number) & PROC_THREAD_ATTRIBUTE_NUMBER) | \ +// ((Thread != FALSE) ? PROC_THREAD_ATTRIBUTE_THREAD : 0) | \ +// ((Input != FALSE) ? PROC_THREAD_ATTRIBUTE_INPUT : 0) | \ +// ((Additive != FALSE) ? PROC_THREAD_ATTRIBUTE_ADDITIVE : 0)) +// +// #define PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE ProcThreadAttributeValue (ProcThreadAttributePseudoConsole, FALSE, TRUE, FALSE) +// +// typedef struct _STARTUPINFOEXW { +// STARTUPINFOW StartupInfo; +// LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList; +// } STARTUPINFOEXW, *LPSTARTUPINFOEXW; +// +// HMODULE hLibKernel32_Proc = NULL; +// +// DWORD initProcKernFuncs() +// { +// hLibKernel32_Proc = LoadLibrary( "kernel32.dll" ); +// if( hLibKernel32_Proc == NULL ) +// { +// return -1; +// } +// +// pfnInitializeProcThreadAttributeList = (InitializeProcThreadAttributeListProcType) GetProcAddress(hLibKernel32_Proc, "InitializeProcThreadAttributeList" ); +// if( pfnInitializeProcThreadAttributeList == NULL ) +// { +// return -1; +// } +// +// pfnUpdateProcThreadAttribute = (UpdateProcThreadAttributeProcType) GetProcAddress(hLibKernel32_Proc, "UpdateProcThreadAttribute" ); +// if( pfnUpdateProcThreadAttribute == NULL ) +// { +// return -1; +// } +// +// return 0; +// } +// +// DWORD createGuestProcHelper( uintptr_t hpc, LPCWSTR imagePath, uintptr_t * hProcess, DWORD * dwProcessID ) +// { +// STARTUPINFOEXW si; +// ZeroMemory( &si, sizeof(si) ); +// si.StartupInfo.cb = sizeof(si); +// +// SIZE_T bytesRequired; +// (*pfnInitializeProcThreadAttributeList)( NULL, 1, 0, &bytesRequired ); +// +// si.lpAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, bytesRequired); +// if( !si.lpAttributeList ) +// { +// return E_OUTOFMEMORY; +// } +// +// if (!(*pfnInitializeProcThreadAttributeList)(si.lpAttributeList, 1, 0, &bytesRequired)) +// { +// HeapFree(GetProcessHeap(), 0, si.lpAttributeList); +// return HRESULT_FROM_WIN32(GetLastError()); +// } +// +// if (!(*pfnUpdateProcThreadAttribute)(si.lpAttributeList, +// 0, +// PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE, +// (PVOID) hpc, +// sizeof(hpc), +// NULL, +// NULL)) +// { +// HeapFree(GetProcessHeap(), 0, si.lpAttributeList); +// return HRESULT_FROM_WIN32(GetLastError()); +// } +// +// bytesRequired = (wcslen(imagePath) + 1) * sizeof(wchar_t); // +1 null terminator +// PWSTR cmdLineMutable = (PWSTR)HeapAlloc(GetProcessHeap(), 0, bytesRequired); +// +// if (!cmdLineMutable) +// { +// HeapFree(GetProcessHeap(), 0, si.lpAttributeList); +// return E_OUTOFMEMORY; +// } +// +// wcscpy_s(cmdLineMutable, bytesRequired, imagePath); +// +// PROCESS_INFORMATION pi; +// ZeroMemory(&pi, sizeof(pi)); +// +// if (!CreateProcessW(NULL, +// cmdLineMutable, +// NULL, +// NULL, +// FALSE, +// EXTENDED_STARTUPINFO_PRESENT, +// NULL, +// NULL, +// &si.StartupInfo, +// &pi)) +// { +// HeapFree(GetProcessHeap(), 0, si.lpAttributeList); +// HeapFree(GetProcessHeap(), 0, cmdLineMutable); +// return HRESULT_FROM_WIN32(GetLastError()); +// } +// +// *hProcess = (uintptr_t) pi.hProcess; +// *dwProcessID = pi.dwProcessId; +// +// HeapFree(GetProcessHeap(), 0, si.lpAttributeList); +// HeapFree(GetProcessHeap(), 0, cmdLineMutable); +// return S_OK; +// } +// +// int hr_succeeded( DWORD hResult ); +import "C" +import ( + "errors" + "syscall" + "unicode/utf16" + "fmt" +) + +var procsInitSucceeded = false + +func init() { + ret := int(C.initProcKernFuncs()) + procsInitSucceeded = (ret == 0) +} + +type winProcess struct { + hproc uintptr + processID uint32 +} + +func createPtyChildProcess(imagePath string, hcon uintptr) (*winProcess, error) { + path16 := utf16.Encode([]rune(imagePath)) + + cpath16 := C.calloc(C.size_t(len(path16)+1), 2) + pp := (*[0xffff]uint16)(cpath16) + copy(pp[:], path16) + + hproc := C.uintptr_t(0) + dwProcessID := C.DWORD(0) + + hr := C.createGuestProcHelper(C.uintptr_t(hcon), (C.LPCWSTR)(cpath16), &hproc, &dwProcessID) + + C.free(cpath16) + + if int(C.hr_succeeded(hr)) == 0 { + return nil, errors.New("Failed to create process: " + imagePath) + } + + return &winProcess{ + hproc: uintptr(hproc), + processID: uint32(dwProcessID), + }, nil +} + +func (process *winProcess) Wait() error { + rc := uint(C.WaitForSingleObject(C.HANDLE(process.hproc), C.INFINITE)) + if rc == C.WAIT_OBJECT_0 { + return nil + } + + return fmt.Errorf("error 0x%.8X while waiting for external process ID = %d ", uint(C.GetLastError()), process.processID) +} + +func (process *winProcess) Close() error { + return syscall.CloseHandle(syscall.Handle(process.hproc)) +} diff --git a/platform/winpty.go b/platform/winpty.go new file mode 100644 index 0000000..ebeeec2 --- /dev/null +++ b/platform/winpty.go @@ -0,0 +1,231 @@ +// +build windows,cgo + +package platform + +import ( + "errors" + "syscall" + "time" + + "github.com/MaxRis/w32" +) + +// #include "windows.h" +// +// /* Until we can specify the platform SDK and target version for Windows.h * +// * without breaking our ability to gracefully display an error message, these * +// * definitions will be copied from the platform SDK headers and made to work. * +// */ +// +// typedef HRESULT (* CreatePseudoConsoleProcType)( COORD, HANDLE, HANDLE, DWORD, uintptr_t * ); +// typedef HRESULT (* ResizePseudoConsoleProcType)( uintptr_t, COORD ); +// typedef HRESULT (* ClosePseudoConsoleProcType)( uintptr_t ); +// +// +// CreatePseudoConsoleProcType pfnCreatePseudoConsole = NULL; +// ResizePseudoConsoleProcType pfnResizePseudoConsole = NULL; +// ClosePseudoConsoleProcType pfnClosePseudoConsole = NULL; +// +// HMODULE hLibKernel32_Kern = NULL; +// +// DWORD initPtyKernFuncs() +// { +// hLibKernel32_Kern = LoadLibrary( "kernel32.dll" ); +// if( hLibKernel32_Kern == NULL ) +// { +// return -1; +// } +// +// pfnCreatePseudoConsole = (CreatePseudoConsoleProcType) GetProcAddress(hLibKernel32_Kern, "CreatePseudoConsole" ); +// if( pfnCreatePseudoConsole == NULL ) +// { +// return -1; +// } +// +// pfnResizePseudoConsole = (ResizePseudoConsoleProcType) GetProcAddress(hLibKernel32_Kern, "ResizePseudoConsole" ); +// if( pfnResizePseudoConsole == NULL ) +// { +// return -1; +// } +// +// pfnClosePseudoConsole = (ClosePseudoConsoleProcType) GetProcAddress(hLibKernel32_Kern, "ClosePseudoConsole" ); +// if( pfnClosePseudoConsole == NULL ) +// { +// return -1; +// } +// +// return 0; +// } +// +// DWORD createPtyHelper( int xSize, int ySize, HANDLE input, HANDLE output, DWORD flags, uintptr_t * phPC ) +// { +// COORD size; +// size.X = xSize; +// size.Y = ySize; +// return (DWORD) (*pfnCreatePseudoConsole)( size, input, output, flags, phPC ); +// } +// +// DWORD resizePtyHelper( uintptr_t hpc, int xSize, int ySize ) +// { +// COORD size; +// size.X = xSize; +// size.Y = ySize; +// return (DWORD) (*pfnResizePseudoConsole)( hpc, size ); +// } +// +// DWORD closePtyHelper( uintptr_t hpc ) +// { +// return (DWORD) (*pfnClosePseudoConsole)( hpc ); +// } +// +// int hr_succeeded( DWORD hResult ) +// { +// return SUCCEEDED( hResult ); +// } +import "C" + +var ptyInitSucceeded = false + +func init() { + ret := int(C.initPtyKernFuncs()) + ptyInitSucceeded = (ret == 0) +} + +type winConPty struct { + inPipe syscall.Handle + outPipe syscall.Handle + innerInPipe syscall.Handle + innerOutPipe syscall.Handle + hcon uintptr + platformDependentSettings PlatformDependentSettings +} + +func (pty *winConPty) Read(p []byte) (n int, err error) { + return syscall.Read(pty.inPipe, p) +} + +func (pty *winConPty) Write(p []byte) (n int, err error) { + return syscall.Write(pty.outPipe, p) +} + +func (pty *winConPty) Close() error { + C.closePtyHelper(C.uintptr_t(pty.hcon)) + + err := syscall.CloseHandle(pty.inPipe) + if err != nil { + return err + } + err = syscall.CloseHandle(pty.outPipe) + if err != nil { + return err + } + err = syscall.CloseHandle(pty.innerInPipe) + if err != nil { + return err + } + err = syscall.CloseHandle(pty.innerOutPipe) + if err != nil { + return err + } + + pty.hcon = 0 + + return nil +} + +func (pty *winConPty) CreateGuestProcess(imagePath string) (Process, error) { + process, err := createPtyChildProcess(imagePath, pty.hcon) + + if err == nil { + setupChildConsole(C.DWORD(process.processID), C.STD_OUTPUT_HANDLE, C.ENABLE_PROCESSED_OUTPUT|C.ENABLE_WRAP_AT_EOL_OUTPUT) + } + + return process, err +} + +func setupChildConsole(processID C.DWORD, nStdHandle C.DWORD, mode uint) bool { + C.FreeConsole() + defer C.AttachConsole(^C.DWORD(0)) // attach to parent process console + + // process may not be ready so we'll do retries + const maxWaitMilliSeconds = 5000 + const waitStepMilliSeconds = 200 + count := maxWaitMilliSeconds / waitStepMilliSeconds + + for { + if r := C.AttachConsole(processID); r != 0 { + break // success + } + lastError := C.GetLastError() + if lastError != C.ERROR_GEN_FAILURE || count <= 0 { + return false + } + + time.Sleep(time.Millisecond * time.Duration(waitStepMilliSeconds)) + count-- + } + + h := C.GetStdHandle(nStdHandle) + C.SetConsoleMode(h, C.DWORD(mode)) + C.FreeConsole() + + return true +} + +func (pty *winConPty) Resize(x, y int) error { + cret := C.resizePtyHelper(C.uintptr_t(pty.hcon), C.int(x), C.int(y)) + + if int(C.hr_succeeded(cret)) == 0 { + return errors.New("Failed to resize ConPTY") + } + + return nil +} + +func (pty *winConPty) GetPlatformDependentSettings() PlatformDependentSettings { + return pty.platformDependentSettings +} + +// NewPty creates a new instance of a Pty implementation for Windows on a newly allocated ConPTY +func NewPty(x, y int) (pty Pty, err error) { + if !ptyInitSucceeded { + w32.MessageBox(0, "Aminal requires APIs that are only available on Windows 10 1809 (October 2018 Update) or above. Please upgrade", "Aminal", 0) + return nil, errors.New("Windows PseudoConsole API unavailable on this version of Windows") + } + pty = nil + + var inputReadSide, inputWriteSide syscall.Handle + var outputReadSide, outputWriteSide syscall.Handle + + err = syscall.CreatePipe(&inputReadSide, &inputWriteSide, nil, 0) + if err != nil { + return + } + + err = syscall.CreatePipe(&outputReadSide, &outputWriteSide, nil, 0) + if err != nil { + return + } + + var hc C.uintptr_t + + cret := C.createPtyHelper(C.int(x), C.int(y), C.HANDLE(inputReadSide), C.HANDLE(outputWriteSide), 0, &hc) + ret := int(cret) + + if ret != 0 { + return nil, errors.New("Failed to allocate a ConPTY instance") + } + + pty = &winConPty{ + inPipe: outputReadSide, + outPipe: inputWriteSide, + innerInPipe: inputReadSide, + innerOutPipe: outputWriteSide, + hcon: uintptr(hc), + platformDependentSettings: PlatformDependentSettings{ + OSCTerminators: map[rune]struct{}{0x00: {}}, + }, + } + + return pty, nil +} diff --git a/terminal/osc.go b/terminal/osc.go index 0a0b44e..6393018 100644 --- a/terminal/osc.go +++ b/terminal/osc.go @@ -12,7 +12,7 @@ func oscHandler(pty chan rune, terminal *Terminal) error { for { b := <-pty - if b == 0x07 || b == 0x5c { + if terminal.IsOSCTerminator(b) { params = append(params, param) break } diff --git a/terminal/sixel.go b/terminal/sixel.go index 476046d..1faefbd 100644 --- a/terminal/sixel.go +++ b/terminal/sixel.go @@ -17,7 +17,10 @@ func sixelHandler(pty chan rune, terminal *Terminal) error { for { b := <-pty if b == 0x1b { // terminated by ESC bell or ESC \ - _ = <-pty // swallow \ or bell + t := <-pty + if t != 0x07 && t != 0x5c { + return fmt.Errorf("Incorrect terminator in sixel sequence: 0x%02X [%c]", t, t) + } break } if b >= 33 { diff --git a/terminal/terminal.go b/terminal/terminal.go index 72d4d7a..b5c2a01 100644 --- a/terminal/terminal.go +++ b/terminal/terminal.go @@ -4,13 +4,11 @@ import ( "bufio" "fmt" "io" - "os" "sync" - "syscall" - "unsafe" "github.com/liamg/aminal/buffer" "github.com/liamg/aminal/config" + "github.com/liamg/aminal/platform" "go.uber.org/zap" ) @@ -32,23 +30,24 @@ const ( ) type Terminal struct { - program uint32 - buffers []*buffer.Buffer - activeBuffer *buffer.Buffer - lock sync.Mutex - pty *os.File - logger *zap.SugaredLogger - title string - size Winsize - config *config.Config - titleHandlers []chan bool - modes Modes - mouseMode MouseMode - bracketedPasteMode bool - isDirty bool - charWidth float32 - charHeight float32 - lastBuffer uint8 + program uint32 + buffers []*buffer.Buffer + activeBuffer *buffer.Buffer + lock sync.Mutex + pty platform.Pty + logger *zap.SugaredLogger + title string + size Winsize + config *config.Config + titleHandlers []chan bool + modes Modes + mouseMode MouseMode + bracketedPasteMode bool + isDirty bool + charWidth float32 + charHeight float32 + lastBuffer uint8 + platformDependentSettings platform.PlatformDependentSettings } type Modes struct { @@ -64,21 +63,21 @@ type Winsize struct { y uint16 //ignored, but necessary for ioctl calls } -func New(pty *os.File, logger *zap.SugaredLogger, config *config.Config) *Terminal { +func New(pty platform.Pty, logger *zap.SugaredLogger, config *config.Config) *Terminal { t := &Terminal{ buffers: []*buffer.Buffer{ buffer.NewBuffer(1, 1, buffer.CellAttributes{ FgColour: config.ColourScheme.Foreground, BgColour: config.ColourScheme.Background, - }), + }, config.MaxLines), buffer.NewBuffer(1, 1, buffer.CellAttributes{ FgColour: config.ColourScheme.Foreground, BgColour: config.ColourScheme.Background, - }), + }, config.MaxLines), buffer.NewBuffer(1, 1, buffer.CellAttributes{ FgColour: config.ColourScheme.Foreground, BgColour: config.ColourScheme.Background, - }), + }, config.MaxLines), }, pty: pty, logger: logger, @@ -87,6 +86,7 @@ func New(pty *os.File, logger *zap.SugaredLogger, config *config.Config) *Termin modes: Modes{ ShowCursor: true, }, + platformDependentSettings: pty.GetPlatformDependentSettings(), } t.activeBuffer = t.buffers[0] return t @@ -123,6 +123,11 @@ func (terminal *Terminal) GetMouseMode() MouseMode { return terminal.mouseMode } +func (terminal *Terminal) IsOSCTerminator(char rune) bool { + _, ok := terminal.platformDependentSettings.OSCTerminators[char] + return ok +} + func (terminal *Terminal) UseMainBuffer() { terminal.activeBuffer = terminal.buffers[MainBuffer] terminal.SetSize(uint(terminal.size.Width), uint(terminal.size.Height)) @@ -280,9 +285,8 @@ func (terminal *Terminal) SetSize(newCols uint, newLines uint) error { terminal.size.Width = uint16(newCols) terminal.size.Height = uint16(newLines) - _, _, err := syscall.Syscall(syscall.SYS_IOCTL, uintptr(terminal.pty.Fd()), - uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(&terminal.size))) - if err != 0 { + err := terminal.pty.Resize(int(newCols), int(newLines)) + if err != nil { return fmt.Errorf("Failed to set terminal size vai ioctl: Error no %d", err) } diff --git a/vendor/github.com/riywo/loginshell/loginshell.go b/vendor/github.com/riywo/loginshell/loginshell.go index d8d256d..f7d71ea 100644 --- a/vendor/github.com/riywo/loginshell/loginshell.go +++ b/vendor/github.com/riywo/loginshell/loginshell.go @@ -17,15 +17,29 @@ func Shell() (string, error) { return LinuxShell() case "darwin": return DarwinShell() + case "windows": + return WindowsShell() } return "", errors.New("Undefined GOOS: " + runtime.GOOS) } +func WindowsShell() (string, error) { + consoleApp := os.Getenv("COMSPEC") + if consoleApp == "" { + consoleApp = "cmd.exe" + } + return consoleApp, nil +} + func LinuxShell() (string, error) { user, err := user.Current() - if err != nil { return "", err } + if err != nil { + return "", err + } out, err := exec.Command("getent", "passwd", user.Uid).Output() - if err != nil { return "", err } + if err != nil { + return "", err + } ent := strings.Split(strings.TrimSuffix(string(out), "\n"), ":") return ent[6], nil @@ -34,11 +48,15 @@ func LinuxShell() (string, error) { func DarwinShell() (string, error) { dir := "Local/Default/Users/" + os.Getenv("USER") out, err := exec.Command("dscl", "localhost", "-read", dir, "UserShell").Output() - if err != nil { return "", err } + if err != nil { + return "", err + } re := regexp.MustCompile("UserShell: (/[^ ]+)\n") matched := re.FindStringSubmatch(string(out)) shell := matched[1] - if shell == "" { return "", errors.New(fmt.Sprintf("Invalid output: %s", string(out))) } + if shell == "" { + return "", errors.New(fmt.Sprintf("Invalid output: %s", string(out))) + } return shell, nil } diff --git a/vendor/github.com/riywo/loginshell/loginshell_test.go b/vendor/github.com/riywo/loginshell/loginshell_test.go index c7f169c..78f0610 100644 --- a/vendor/github.com/riywo/loginshell/loginshell_test.go +++ b/vendor/github.com/riywo/loginshell/loginshell_test.go @@ -4,6 +4,7 @@ import ( "testing" "os" "fmt" + "runtime" ) func TestShell(t *testing.T) { @@ -12,8 +13,14 @@ func TestShell(t *testing.T) { t.Error(err) } - currentShell := os.Getenv("SHELL") - if shell != currentShell { - t.Error(fmt.Sprintf("Output: %s, Current login shell: %s", shell, currentShell)) + if runtime.GOOS == "windows" { + if shell == "" { + t.Error("Output is empty!") + } + } else { + currentShell := os.Getenv("SHELL") + if shell != currentShell { + t.Error(fmt.Sprintf("Output: %s, Current login shell: %s", shell, currentShell)) + } } } diff --git a/windows.md b/windows.md new file mode 100644 index 0000000..14d333a --- /dev/null +++ b/windows.md @@ -0,0 +1,30 @@ + +### Windows dev env setup and build instructions: + +1. Setup choco package manager https://chocolatey.org/docs/installation +2. Use `choco` to install golang and mingw +```choco install golang mingw``` + + +### Setting aminal GoLang build env and directories structures for the project: + +``` +cd %YOUR_PROJECT_WORKING_DIR% +mkdir go\src\github.com\liamg +cd go\src\github.com\liamg +git clone git@github.com:jumptrading/aminal-mirror.git +move aminal-mirror aminal + +set GOPATH=%YOUR_PROJECT_WORKING_DIR%\go +set GOBIN=%GOPATH%/bin +set PATH=%GOBIN%;%PATH% + +cd aminal +go get +windres -o aminal.syso aminal.rc +go build +go install +``` + +Look for the aminal.exe built binary under your %GOBIN% path +