hayai/vendor/github.com/TheTitanrain/w32/create_process.go
2024-12-21 17:26:50 +01:00

153 lines
3.1 KiB
Go

// 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
}