package win32api import ( "fmt" "syscall" "unsafe" ) func WTSGetActiveConsoleSessionId() (DWORD, error) { WTGet, err := getProcAddr("kernel32.dll", "WTSGetActiveConsoleSessionId") if err != nil { return 0, err } res, _, _ := syscall.Syscall(WTGet, 0, 0, 0, 0) return DWORD(res), nil } func CloseHandle(hObject HANDLE) error { CH, err := getProcAddr("kernel32.dll", "CloseHandle") if err != nil { return err } if r, _, errno := syscall.Syscall(CH, 1, uintptr(hObject), 0, 0); r == 0 { return error(errno) } return nil } func GetLastError() DWORD { last := syscall.GetLastError() if last == nil { return 0 } if errno, ok := last.(syscall.Errno); ok { return DWORD(errno) } return 0 } func SetLastError(dwErrCode DWORD) error { proc, err := getProcAddr("kernel32.dll", "SetLastError") if err != nil { return err } syscall.Syscall(proc, 1, uintptr(dwErrCode), 0, 0) return nil } func FormatMessage(dwMessageId DWORD) (string, error) { proc, err := getProcAddr("kernel32.dll", "FormatMessageW") if err != nil { return "", err } buf := make([]uint16, 2048) flags := FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS r, _, errno := syscall.Syscall9(proc, 7, uintptr(flags), 0, uintptr(dwMessageId), 0, uintptr(unsafe.Pointer(&buf[0])), uintptr(len(buf)), 0, 0, 0, ) if r == 0 { if errno != 0 { return "", error(errno) } return "", syscall.EINVAL } return syscall.UTF16ToString(buf[:r]), nil } func CreateToolhelp32Snapshot(dwFlags, th32ProcessID DWORD) (HANDLE, error) { CTS, err := getProcAddr("kernel32.dll", "CreateToolhelp32Snapshot") if err != nil { return 0, err } r, _, errno := syscall.Syscall(CTS, 2, uintptr(dwFlags), uintptr(th32ProcessID), 0) if int(r) == -1 { return HANDLE(r), error(errno) } return HANDLE(r), nil } func Process32First(hSnapshot HANDLE, lppe *PROCESSENTRY32) error { PN, err := getProcAddr("kernel32.dll", "Process32First") if err != nil { return err } r, _, errno := syscall.Syscall(PN, 2, uintptr(hSnapshot), uintptr(unsafe.Pointer(lppe)), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func Process32Next(hSnapshot HANDLE, lppe *PROCESSENTRY32) error { PN, err := getProcAddr("kernel32.dll", "Process32Next") if err != nil { return err } r, _, errno := syscall.Syscall(PN, 2, uintptr(hSnapshot), uintptr(unsafe.Pointer(lppe)), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func Thread32First(hSnapshot HANDLE, lpte *THREADENTRY32) error { proc, err := getProcAddr("kernel32.dll", "Thread32First") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hSnapshot), uintptr(unsafe.Pointer(lpte)), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func Thread32Next(hSnapshot HANDLE, lpte *THREADENTRY32) error { proc, err := getProcAddr("kernel32.dll", "Thread32Next") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hSnapshot), uintptr(unsafe.Pointer(lpte)), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func Module32First(hSnapshot HANDLE, lpme *MODULEENTRY32W) error { proc, err := getProcAddr("kernel32.dll", "Module32FirstW") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hSnapshot), uintptr(unsafe.Pointer(lpme)), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func Module32Next(hSnapshot HANDLE, lpme *MODULEENTRY32W) error { proc, err := getProcAddr("kernel32.dll", "Module32NextW") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hSnapshot), uintptr(unsafe.Pointer(lpme)), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func OpenThread(dwDesiredAccess DWORD, bInheritHandle bool, dwThreadID DWORD) (HANDLE, error) { proc, err := getProcAddr("kernel32.dll", "OpenThread") if err != nil { return 0, err } inherit := uintptr(0) if bInheritHandle { inherit = 1 } r, _, errno := syscall.Syscall(proc, 3, uintptr(dwDesiredAccess), inherit, uintptr(dwThreadID)) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return HANDLE(r), nil } func SuspendThread(hThread HANDLE) (DWORD, error) { proc, err := getProcAddr("kernel32.dll", "SuspendThread") if err != nil { return 0, err } r, _, errno := syscall.Syscall(proc, 1, uintptr(hThread), 0, 0) result := DWORD(r) if result == 0xFFFFFFFF { if errno != 0 { return result, error(errno) } return result, syscall.EINVAL } return result, nil } func ResumeThread(hThread HANDLE) (DWORD, error) { proc, err := getProcAddr("kernel32.dll", "ResumeThread") if err != nil { return 0, err } r, _, errno := syscall.Syscall(proc, 1, uintptr(hThread), 0, 0) result := DWORD(r) if result == 0xFFFFFFFF { if errno != 0 { return result, error(errno) } return result, syscall.EINVAL } return result, nil } func GetThreadContext(hThread HANDLE, lpContext unsafe.Pointer) error { if lpContext == nil { return syscall.EINVAL } proc, err := getProcAddr("kernel32.dll", "GetThreadContext") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hThread), uintptr(lpContext), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func SetThreadContext(hThread HANDLE, lpContext unsafe.Pointer) error { if lpContext == nil { return syscall.EINVAL } proc, err := getProcAddr("kernel32.dll", "SetThreadContext") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hThread), uintptr(lpContext), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func DebugActiveProcess(dwProcessId DWORD) error { proc, err := getProcAddr("kernel32.dll", "DebugActiveProcess") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 1, uintptr(dwProcessId), 0, 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func DebugActiveProcessStop(dwProcessId DWORD) error { proc, err := getProcAddr("kernel32.dll", "DebugActiveProcessStop") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 1, uintptr(dwProcessId), 0, 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func WaitForDebugEvent(lpDebugEvent unsafe.Pointer, dwMilliseconds DWORD) error { if lpDebugEvent == nil { return syscall.EINVAL } proc, err := getProcAddr("kernel32.dll", "WaitForDebugEvent") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(lpDebugEvent), uintptr(dwMilliseconds), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func ContinueDebugEvent(dwProcessId, dwThreadId, dwContinueStatus DWORD) error { proc, err := getProcAddr("kernel32.dll", "ContinueDebugEvent") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 3, uintptr(dwProcessId), uintptr(dwThreadId), uintptr(dwContinueStatus)) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func DebugEventCodeName(code DWORD) string { switch code { case EXCEPTION_DEBUG_EVENT: return "EXCEPTION_DEBUG_EVENT" case CREATE_THREAD_DEBUG_EVENT: return "CREATE_THREAD_DEBUG_EVENT" case CREATE_PROCESS_DEBUG_EVENT: return "CREATE_PROCESS_DEBUG_EVENT" case EXIT_THREAD_DEBUG_EVENT: return "EXIT_THREAD_DEBUG_EVENT" case EXIT_PROCESS_DEBUG_EVENT: return "EXIT_PROCESS_DEBUG_EVENT" case LOAD_DLL_DEBUG_EVENT: return "LOAD_DLL_DEBUG_EVENT" case UNLOAD_DLL_DEBUG_EVENT: return "UNLOAD_DLL_DEBUG_EVENT" case OUTPUT_DEBUG_STRING_EVENT: return "OUTPUT_DEBUG_STRING_EVENT" case RIP_EVENT: return "RIP_EVENT" default: return fmt.Sprintf("UNKNOWN_DEBUG_EVENT(%d)", code) } } func DecodeDebugEvent(raw []byte) (DebugEventInfo, error) { if len(raw) < int(unsafe.Sizeof(DEBUG_EVENT_HEADER{})) { return DebugEventInfo{}, syscall.EINVAL } header := *(*DEBUG_EVENT_HEADER)(unsafe.Pointer(&raw[0])) return DebugEventInfo{ Header: header, CodeName: DebugEventCodeName(header.DwDebugEventCode), }, nil } func WaitForDebugEventInfo(raw []byte, dwMilliseconds DWORD) (DebugEventInfo, error) { if len(raw) == 0 { return DebugEventInfo{}, syscall.EINVAL } if err := WaitForDebugEvent(unsafe.Pointer(&raw[0]), dwMilliseconds); err != nil { return DebugEventInfo{}, err } return DecodeDebugEvent(raw) } func CreateRemoteThread(hProcess HANDLE, lpThreadAttributes *syscall.SecurityAttributes, dwStackSize uintptr, lpStartAddress uintptr, lpParameter uintptr, dwCreationFlags DWORD, lpThreadID *DWORD) (HANDLE, error) { proc, err := getProcAddr("kernel32.dll", "CreateRemoteThread") if err != nil { return 0, err } r, _, errno := syscall.Syscall9( proc, 7, uintptr(hProcess), uintptr(unsafe.Pointer(lpThreadAttributes)), dwStackSize, lpStartAddress, lpParameter, uintptr(dwCreationFlags), uintptr(unsafe.Pointer(lpThreadID)), 0, 0, ) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return HANDLE(r), nil } func GetProcessId(Process HANDLE) uint32 { GPI, err := getProcAddr("kernel32.dll", "GetProcessId") if err != nil { return 0 } r, _, _ := syscall.Syscall(GPI, 1, uintptr(Process), 0, 0) return uint32(r) } func ProcessIdToSessionId(dwProcessId DWORD) (DWORD, error) { proc, err := getProcAddr("kernel32.dll", "ProcessIdToSessionId") if err != nil { return 0, err } var sessionID DWORD r, _, errno := syscall.Syscall(proc, 2, uintptr(dwProcessId), uintptr(unsafe.Pointer(&sessionID)), 0) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return sessionID, nil } func ReadProcessMemory(hProcess HANDLE, lpBaseAddress uintptr, lpBuffer []byte, lpNumberOfBytesRead *uintptr) error { proc, err := getProcAddr("kernel32.dll", "ReadProcessMemory") if err != nil { return err } var bufferPtr uintptr if len(lpBuffer) > 0 { bufferPtr = uintptr(unsafe.Pointer(&lpBuffer[0])) } r, _, errno := syscall.Syscall6( proc, 5, uintptr(hProcess), lpBaseAddress, bufferPtr, uintptr(len(lpBuffer)), uintptr(unsafe.Pointer(lpNumberOfBytesRead)), 0, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func WriteProcessMemory(hProcess HANDLE, lpBaseAddress uintptr, lpBuffer []byte, lpNumberOfBytesWritten *uintptr) error { proc, err := getProcAddr("kernel32.dll", "WriteProcessMemory") if err != nil { return err } var bufferPtr uintptr if len(lpBuffer) > 0 { bufferPtr = uintptr(unsafe.Pointer(&lpBuffer[0])) } r, _, errno := syscall.Syscall6( proc, 5, uintptr(hProcess), lpBaseAddress, bufferPtr, uintptr(len(lpBuffer)), uintptr(unsafe.Pointer(lpNumberOfBytesWritten)), 0, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func VirtualQueryEx(hProcess HANDLE, lpAddress uintptr, lpBuffer *MEMORY_BASIC_INFORMATION, dwLength uintptr) (uintptr, error) { if lpBuffer == nil { return 0, syscall.EINVAL } proc, err := getProcAddr("kernel32.dll", "VirtualQueryEx") if err != nil { return 0, err } r, _, errno := syscall.Syscall6( proc, 4, uintptr(hProcess), lpAddress, uintptr(unsafe.Pointer(lpBuffer)), dwLength, 0, 0, ) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return r, nil } func VirtualProtectEx(hProcess HANDLE, lpAddress uintptr, dwSize uintptr, flNewProtect DWORD, lpflOldProtect *DWORD) error { if lpflOldProtect == nil { return syscall.EINVAL } proc, err := getProcAddr("kernel32.dll", "VirtualProtectEx") if err != nil { return err } r, _, errno := syscall.Syscall6( proc, 5, uintptr(hProcess), lpAddress, dwSize, uintptr(flNewProtect), uintptr(unsafe.Pointer(lpflOldProtect)), 0, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func VirtualAllocEx(hProcess HANDLE, lpAddress uintptr, dwSize uintptr, flAllocationType, flProtect DWORD) (uintptr, error) { proc, err := getProcAddr("kernel32.dll", "VirtualAllocEx") if err != nil { return 0, err } r, _, errno := syscall.Syscall6( proc, 5, uintptr(hProcess), lpAddress, dwSize, uintptr(flAllocationType), uintptr(flProtect), 0, ) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return r, nil } func VirtualFreeEx(hProcess HANDLE, lpAddress uintptr, dwSize uintptr, dwFreeType DWORD) error { proc, err := getProcAddr("kernel32.dll", "VirtualFreeEx") if err != nil { return err } r, _, errno := syscall.Syscall6( proc, 4, uintptr(hProcess), lpAddress, dwSize, uintptr(dwFreeType), 0, 0, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func OpenProcess(dwDesiredAccess DWORD, bInheritHandle bool, dwProcessId DWORD) (HANDLE, error) { proc, err := getProcAddr("kernel32.dll", "OpenProcess") if err != nil { return 0, err } inherit := uintptr(0) if bInheritHandle { inherit = 1 } r, _, errno := syscall.Syscall(proc, 3, uintptr(dwDesiredAccess), inherit, uintptr(dwProcessId)) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return HANDLE(r), nil } func TerminateProcess(hProcess HANDLE, uExitCode DWORD) error { proc, err := getProcAddr("kernel32.dll", "TerminateProcess") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hProcess), uintptr(uExitCode), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func CreateProcess(lpApplicationName, lpCommandLine string, lpProcessAttributes, lpThreadAttributes *syscall.SecurityAttributes, bInheritHandles bool, dwCreationFlags DWORD, lpEnvironment HANDLE, lpCurrentDirectory string, lpStartupInfo *StartupInfo, lpProcessInformation *ProcessInformation) error { proc, err := getProcAddr("kernel32.dll", "CreateProcessW") if err != nil { return err } var applicationName uintptr if len(lpApplicationName) > 0 { applicationName = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpApplicationName))) } var commandLine uintptr if len(lpCommandLine) > 0 { commandLine = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpCommandLine))) } var currentDirectory uintptr if len(lpCurrentDirectory) > 0 { currentDirectory = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpCurrentDirectory))) } inheritHandles := uintptr(0) if bInheritHandles { inheritHandles = 1 } r, _, errno := syscall.Syscall12(proc, 10, applicationName, commandLine, uintptr(unsafe.Pointer(lpProcessAttributes)), uintptr(unsafe.Pointer(lpThreadAttributes)), inheritHandles, uintptr(dwCreationFlags), uintptr(lpEnvironment), currentDirectory, uintptr(unsafe.Pointer(lpStartupInfo)), uintptr(unsafe.Pointer(lpProcessInformation)), 0, 0, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func WaitForSingleObject(hHandle HANDLE, dwMilliseconds DWORD) (DWORD, error) { proc, err := getProcAddr("kernel32.dll", "WaitForSingleObject") if err != nil { return 0, err } r, _, errno := syscall.Syscall(proc, 2, uintptr(hHandle), uintptr(dwMilliseconds), 0) result := DWORD(r) if result == WAIT_FAILED { if errno != 0 { return result, error(errno) } return result, syscall.EINVAL } return result, nil } func WaitForMultipleObjects(handles []HANDLE, bWaitAll bool, dwMilliseconds DWORD) (DWORD, error) { if len(handles) == 0 { return WAIT_FAILED, fmt.Errorf("handles must not be empty") } if len(handles) > int(MAXIMUM_WAIT_OBJECTS) { return WAIT_FAILED, fmt.Errorf("too many handles: %d > %d", len(handles), MAXIMUM_WAIT_OBJECTS) } proc, err := getProcAddr("kernel32.dll", "WaitForMultipleObjects") if err != nil { return 0, err } waitAll := uintptr(0) if bWaitAll { waitAll = 1 } r, _, errno := syscall.Syscall6(proc, 4, uintptr(len(handles)), uintptr(unsafe.Pointer(&handles[0])), waitAll, uintptr(dwMilliseconds), 0, 0, ) result := DWORD(r) if result == WAIT_FAILED { if errno != 0 { return result, error(errno) } return result, syscall.EINVAL } return result, nil } func GetExitCodeProcess(hProcess HANDLE) (DWORD, error) { proc, err := getProcAddr("kernel32.dll", "GetExitCodeProcess") if err != nil { return 0, err } var code DWORD r, _, errno := syscall.Syscall(proc, 2, uintptr(hProcess), uintptr(unsafe.Pointer(&code)), 0) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return code, nil } func GetTickCount() (uint32, error) { GTC, err := getProcAddr("kernel32.dll", "GetTickCount") if err != nil { return 0, err } r, _, _ := syscall.Syscall(GTC, 0, 0, 0, 0) return uint32(r), nil } func GlobalMemoryStatusEx(data *MEMORYSTATUSEX) (bool, error) { (*data).DwLength = DWORD(unsafe.Sizeof(*data)) GMS, err := getProcAddr("kernel32.dll", "GlobalMemoryStatusEx") if err != nil { return false, err } r, _, errno := syscall.Syscall(GMS, 1, uintptr(unsafe.Pointer(data)), 0, 0) if r == 0 { if errno != 0 { return false, error(errno) } return false, syscall.EINVAL } return true, nil } func LockFileEx(hFile HANDLE, dwFlags DWORD, dwReserved DWORD, nNumberOfBytesToLockLow DWORD, nNumberOfBytesToLockHigh DWORD, lpOverlapped *syscall.Overlapped) (bool, error) { Lck, err := getProcAddr("kernel32.dll", "LockFileEx") if err != nil { return false, err } r, _, errno := syscall.Syscall6(Lck, 6, uintptr(hFile), uintptr(dwFlags), uintptr(dwReserved), uintptr(nNumberOfBytesToLockLow), uintptr(nNumberOfBytesToLockHigh), uintptr(unsafe.Pointer(lpOverlapped))) if r == 0 { if errno != 0 { return false, error(errno) } return false, syscall.EINVAL } return true, nil } func OpenFileById(hVolumeHint HANDLE, lpFileId *FILE_ID_DESCRIPTOR, dwDesiredAccess DWORD, dwShareMode DWORD, lpSecurityAttributes *syscall.SecurityAttributes, dwFlagsAndAttributes DWORD) (HANDLE, error) { ofb, err := getProcAddr("kernel32.dll", "OpenFileById") if err != nil { return 0, err } r, _, errno := syscall.Syscall6(ofb, 6, uintptr(hVolumeHint), uintptr(unsafe.Pointer(lpFileId)), uintptr(dwDesiredAccess), uintptr(dwShareMode), uintptr(unsafe.Pointer(lpSecurityAttributes)), uintptr(dwFlagsAndAttributes)) if HANDLE(r) == HANDLE(syscall.InvalidHandle) { if errno != 0 { return HANDLE(r), error(errno) } return HANDLE(r), syscall.EINVAL } return HANDLE(r), nil } func CreateEventW(lpEventAttributes *syscall.SecurityAttributes, bManualReset bool, bInitialState bool, lpName LPCWSTR) (HANDLE, error) { var intBManualReset, intBInitialState int if bManualReset { intBManualReset = 1 } if bInitialState { intBInitialState = 1 } Lck, err := getProcAddr("kernel32.dll", "CreateEventW") if err != nil { return 0, err } r, _, errno := syscall.Syscall6(Lck, 4, uintptr(unsafe.Pointer(lpEventAttributes)), uintptr(intBManualReset), uintptr(intBInitialState), uintptr(unsafe.Pointer(lpName)), 0, 0) if HANDLE(r) == 0 { if errno != 0 { return HANDLE(r), error(errno) } return HANDLE(r), syscall.EINVAL } return HANDLE(r), nil } func GetLogicalDriveStringsW(nBufferLength DWORD, lpBuffer LPWSTR) error { glds, err := getProcAddr("kernel32.dll", "GetLogicalDriveStringsW") if err != nil { return err } r, _, errno := syscall.Syscall(glds, 2, uintptr(nBufferLength), uintptr(unsafe.Pointer(lpBuffer)), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func GetVolumeInformationW(lpRootPathName LPCWSTR, lpVolumeNameBuffer LPWSTR, nVolumeNameSize DWORD, lpVolumeSerialNumber LPDWORD, lpMaximumComponentLength LPDWORD, lpFileSystemFlags LPDWORD, lpFileSystemNameBuffer LPWSTR, nFileSystemNameSize DWORD) error { glds, err := getProcAddr("kernel32.dll", "GetVolumeInformationW") if err != nil { return err } r, _, errno := syscall.Syscall9(glds, 8, uintptr(unsafe.Pointer(lpRootPathName)), uintptr(unsafe.Pointer(lpVolumeNameBuffer)), uintptr(nVolumeNameSize), uintptr(unsafe.Pointer(lpVolumeSerialNumber)), uintptr(unsafe.Pointer(lpMaximumComponentLength)), uintptr(unsafe.Pointer(lpFileSystemFlags)), uintptr(unsafe.Pointer(lpFileSystemNameBuffer)), uintptr(nFileSystemNameSize), 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func DeviceIoControl(hDevice HANDLE, dwIoControlCode DWORD, lpInBuffer LPVOID, nInBufferSize DWORD, lpOutBuffer LPVOID, nOutBufferSize DWORD, lpBytesReturned LPDWORD, lpOverlapped *syscall.Overlapped) (bool, error) { dic, err := getProcAddr("kernel32.dll", "DeviceIoControl") if err != nil { return false, err } r, _, errno := syscall.Syscall9(dic, 8, uintptr(hDevice), uintptr(dwIoControlCode), uintptr(unsafe.Pointer(lpInBuffer)), uintptr(nInBufferSize), uintptr(unsafe.Pointer(lpOutBuffer)), uintptr(nOutBufferSize), uintptr(unsafe.Pointer(lpBytesReturned)), uintptr(unsafe.Pointer(lpOverlapped)), 0) if r == 0 { if errno != 0 { return false, error(errno) } else { return false, syscall.EINVAL } } return true, nil } func DeviceIoControlPtr(hDevice HANDLE, dwIoControlCode DWORD, lpInBuffer uintptr, nInBufferSize DWORD, lpOutBuffer uintptr, nOutBufferSize DWORD, lpBytesReturned LPDWORD, lpOverlapped *syscall.Overlapped) (bool, error) { dic, err := getProcAddr("kernel32.dll", "DeviceIoControl") if err != nil { return false, err } r, _, errno := syscall.Syscall9(dic, 8, uintptr(hDevice), uintptr(dwIoControlCode), lpInBuffer, uintptr(nInBufferSize), lpOutBuffer, uintptr(nOutBufferSize), uintptr(unsafe.Pointer(lpBytesReturned)), uintptr(unsafe.Pointer(lpOverlapped)), 0) if r == 0 { if errno != 0 { return false, error(errno) } else { return false, syscall.EINVAL } } return true, nil } func GlobalLock(hMem HGLOBAL) (unsafe.Pointer, error) { gl, err := getProcAddr("kernel32.dll", "GlobalLock") if err != nil { return nil, err } r, _, errno := syscall.Syscall(gl, 1, uintptr(hMem), 0, 0) if r == 0 { if errno != 0 { return nil, error(errno) } return nil, syscall.EINVAL } return unsafe.Pointer(r), nil } func GlobalUnlock(hMem HGLOBAL) error { gu, err := getProcAddr("kernel32.dll", "GlobalUnlock") if err != nil { return err } if err := SetLastError(0); err != nil { return err } r, _, errno := syscall.Syscall(gu, 1, uintptr(hMem), 0, 0) if r == 0 { if errno == 0 { return nil } if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func GlobalSize(hMem HGLOBAL) (DWORD, error) { gs, err := getProcAddr("kernel32.dll", "GlobalSize") if err != nil { return 0, err } r, _, errno := syscall.Syscall(gs, 1, uintptr(hMem), 0, 0) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return DWORD(r), nil } func GlobalAlloc(uFlags DWORD, dwBytes uintptr) (HGLOBAL, error) { ga, err := getProcAddr("kernel32.dll", "GlobalAlloc") if err != nil { return 0, err } r, _, errno := syscall.Syscall(ga, 2, uintptr(uFlags), dwBytes, 0) if r == 0 { if errno != 0 { return 0, error(errno) } return 0, syscall.EINVAL } return HGLOBAL(r), nil } func GlobalFree(hMem HGLOBAL) error { gf, err := getProcAddr("kernel32.dll", "GlobalFree") if err != nil { return err } r, _, errno := syscall.Syscall(gf, 1, uintptr(hMem), 0, 0) if r != 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func RtlMoveMemory(Destination, Source unsafe.Pointer, Length uintptr) error { rmv, err := getProcAddr("kernel32.dll", "RtlMoveMemory") if err != nil { return err } syscall.Syscall(rmv, 3, uintptr(unsafe.Pointer(Destination)), uintptr(unsafe.Pointer(Source)), Length) return nil } func GetModuleHandle(lpModuleName *uint16) (HINSTANCE, error) { proc, err := getProcAddr("kernel32.dll", "GetModuleHandleW") if err != nil { return 0, err } r, _, err := syscall.Syscall(proc, 1, uintptr(unsafe.Pointer(lpModuleName)), 0, 0) if r == 0 { return 0, err } return HINSTANCE(r), nil } func GetCurrentProcessId() DWORD { proc, err := getProcAddr("kernel32.dll", "GetCurrentProcessId") if err != nil { return 0 } r, _, _ := syscall.Syscall(proc, 0, 0, 0, 0) return DWORD(r) } func GetCurrentThreadId() DWORD { proc, err := getProcAddr("kernel32.dll", "GetCurrentThreadId") if err != nil { return 0 } r, _, _ := syscall.Syscall(proc, 0, 0, 0, 0) return DWORD(r) } func GetComputerName() (string, error) { proc, err := getProcAddr("kernel32.dll", "GetComputerNameW") if err != nil { return "", err } size := uint32(64) for { buf := make([]uint16, size) n := uint32(len(buf)) r, _, errno := syscall.Syscall(proc, 2, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0) if r != 0 { return syscall.UTF16ToString(buf), nil } if errno == syscall.ERROR_MORE_DATA || errno == syscall.ERROR_INSUFFICIENT_BUFFER { if n > size { size = n } else { size *= 2 } continue } if errno != 0 { return "", error(errno) } return "", syscall.EINVAL } } func GetTempPath() (string, error) { proc, err := getProcAddr("kernel32.dll", "GetTempPathW") if err != nil { return "", err } size := uint32(syscall.MAX_PATH + 1) for { buf := make([]uint16, size) r, _, errno := syscall.Syscall(proc, 2, uintptr(size), uintptr(unsafe.Pointer(&buf[0])), 0) if r == 0 { if errno != 0 { return "", error(errno) } return "", syscall.EINVAL } needed := uint32(r) if needed < size { return syscall.UTF16ToString(buf[:needed]), nil } size = needed + 1 } } func GetSystemDirectory() (string, error) { proc, err := getProcAddr("kernel32.dll", "GetSystemDirectoryW") if err != nil { return "", err } size := uint32(syscall.MAX_PATH + 1) for { buf := make([]uint16, size) r, _, errno := syscall.Syscall(proc, 2, uintptr(unsafe.Pointer(&buf[0])), uintptr(size), 0) if r == 0 { if errno != 0 { return "", error(errno) } return "", syscall.EINVAL } needed := uint32(r) if needed < size { return syscall.UTF16ToString(buf[:needed]), nil } size = needed + 1 } } func GetWindowsDirectory() (string, error) { proc, err := getProcAddr("kernel32.dll", "GetWindowsDirectoryW") if err != nil { return "", err } size := uint32(syscall.MAX_PATH + 1) for { buf := make([]uint16, size) r, _, errno := syscall.Syscall(proc, 2, uintptr(unsafe.Pointer(&buf[0])), uintptr(size), 0) if r == 0 { if errno != 0 { return "", error(errno) } return "", syscall.EINVAL } needed := uint32(r) if needed < size { return syscall.UTF16ToString(buf[:needed]), nil } size = needed + 1 } } func QueryFullProcessImageName(hProcess HANDLE, dwFlags DWORD) (string, error) { proc, err := getProcAddr("kernel32.dll", "QueryFullProcessImageNameW") if err != nil { return "", err } size := uint32(syscall.MAX_PATH + 1) for { buf := make([]uint16, size) n := size r, _, errno := syscall.Syscall6(proc, 4, uintptr(hProcess), uintptr(dwFlags), uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0, ) if r != 0 { return syscall.UTF16ToString(buf[:n]), nil } if errno == syscall.ERROR_INSUFFICIENT_BUFFER { size *= 2 if size > 32768 { return "", fmt.Errorf("query full process image name buffer overflow") } continue } if errno != 0 { return "", error(errno) } return "", syscall.EINVAL } } func CreateFile(lpFileName string, dwDesiredAccess, dwShareMode DWORD, lpSecurityAttributes *syscall.SecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes DWORD, hTemplateFile HANDLE) (HANDLE, error) { proc, err := getProcAddr("kernel32.dll", "CreateFileW") if err != nil { return 0, err } r, _, errno := syscall.Syscall9(proc, 7, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFileName))), uintptr(dwDesiredAccess), uintptr(dwShareMode), uintptr(unsafe.Pointer(lpSecurityAttributes)), uintptr(dwCreationDisposition), uintptr(dwFlagsAndAttributes), uintptr(hTemplateFile), 0, 0, ) handle := HANDLE(r) if handle == HANDLE(syscall.InvalidHandle) { if errno != 0 { return handle, error(errno) } return handle, syscall.EINVAL } return handle, nil } func ReadFile(hFile HANDLE, lpBuffer []byte, lpNumberOfBytesRead *DWORD, lpOverlapped *syscall.Overlapped) error { proc, err := getProcAddr("kernel32.dll", "ReadFile") if err != nil { return err } var bufferPtr uintptr if len(lpBuffer) > 0 { bufferPtr = uintptr(unsafe.Pointer(&lpBuffer[0])) } r, _, errno := syscall.Syscall6(proc, 5, uintptr(hFile), bufferPtr, uintptr(len(lpBuffer)), uintptr(unsafe.Pointer(lpNumberOfBytesRead)), uintptr(unsafe.Pointer(lpOverlapped)), 0, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func WriteFile(hFile HANDLE, lpBuffer []byte, lpNumberOfBytesWritten *DWORD, lpOverlapped *syscall.Overlapped) error { proc, err := getProcAddr("kernel32.dll", "WriteFile") if err != nil { return err } var bufferPtr uintptr if len(lpBuffer) > 0 { bufferPtr = uintptr(unsafe.Pointer(&lpBuffer[0])) } r, _, errno := syscall.Syscall6(proc, 5, uintptr(hFile), bufferPtr, uintptr(len(lpBuffer)), uintptr(unsafe.Pointer(lpNumberOfBytesWritten)), uintptr(unsafe.Pointer(lpOverlapped)), 0, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func DeleteFile(path string) error { proc, err := getProcAddr("kernel32.dll", "DeleteFileW") if err != nil { return err } r, _, errno := syscall.Syscall(proc, 1, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), 0, 0) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func CopyFile(existingFileName, newFileName string, bFailIfExists bool) error { proc, err := getProcAddr("kernel32.dll", "CopyFileW") if err != nil { return err } failIfExists := uintptr(0) if bFailIfExists { failIfExists = 1 } r, _, errno := syscall.Syscall(proc, 3, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(existingFileName))), uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(newFileName))), failIfExists, ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func GetFileAttributes(path string) (DWORD, error) { proc, err := getProcAddr("kernel32.dll", "GetFileAttributesW") if err != nil { return 0, err } r, _, errno := syscall.Syscall(proc, 1, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), 0, 0) attr := DWORD(r) if attr == INVALID_FILE_ATTRIBUTES { if errno != 0 { return attr, error(errno) } return attr, syscall.EINVAL } return attr, nil } func MoveFileEx(existingFileName, newFileName string, dwFlags DWORD) error { proc, err := getProcAddr("kernel32.dll", "MoveFileExW") if err != nil { return err } var newFilePtr uintptr if len(newFileName) > 0 { newFilePtr = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(newFileName))) } r, _, errno := syscall.Syscall(proc, 3, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(existingFileName))), newFilePtr, uintptr(dwFlags), ) if r == 0 { if errno != 0 { return error(errno) } return syscall.EINVAL } return nil } func GetFullPathName(path string) (string, error) { proc, err := getProcAddr("kernel32.dll", "GetFullPathNameW") if err != nil { return "", err } size := uint32(syscall.MAX_PATH + 1) for { buf := make([]uint16, size) r, _, errno := syscall.Syscall6(proc, 4, uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(path))), uintptr(size), uintptr(unsafe.Pointer(&buf[0])), 0, 0, 0, ) if r == 0 { if errno != 0 { return "", error(errno) } return "", syscall.EINVAL } needed := uint32(r) if needed < size { return syscall.UTF16ToString(buf[:needed]), nil } size = needed + 1 } }