summaryrefslogtreecommitdiff
path: root/packages/w32/create_process.go
diff options
context:
space:
mode:
Diffstat (limited to 'packages/w32/create_process.go')
-rw-r--r--packages/w32/create_process.go152
1 files changed, 152 insertions, 0 deletions
diff --git a/packages/w32/create_process.go b/packages/w32/create_process.go
new file mode 100644
index 0000000..9caf9ff
--- /dev/null
+++ b/packages/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
+
+}