init
This commit is contained in:
+79
@@ -0,0 +1,79 @@
|
||||
package win32api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
|
||||
"golang.org/x/sys/windows"
|
||||
)
|
||||
|
||||
func DuplicateTokenEx(hExistingToken HANDLE, dwDesiredAccess DWORD,
|
||||
lpTokenAttributes uintptr, ImpersonationLevel int,
|
||||
TokenType TOKEN_TYPE, phNewToken *TOKEN) error {
|
||||
|
||||
advapi32, err := syscall.LoadLibrary("advapi32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Advapi32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(advapi32)
|
||||
Dup, err := syscall.GetProcAddress(syscall.Handle(advapi32), "DuplicateTokenEx")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load WTSQueryUserToken API")
|
||||
}
|
||||
r, _, errno := syscall.Syscall6(uintptr(Dup), 6, uintptr(hExistingToken), uintptr(dwDesiredAccess), lpTokenAttributes, uintptr(ImpersonationLevel),
|
||||
uintptr(TokenType), uintptr(unsafe.Pointer(phNewToken)))
|
||||
if r == 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateProcessAsUser(hToken TOKEN, lpApplicationName, lpCommandLine string,
|
||||
lpProcessAttributes, lpThreadAttributes, bInheritHandles uintptr,
|
||||
dwCreationFlags uint16, lpEnvironment HANDLE, lpCurrentDirectory string,
|
||||
lpStartupInfo *StartupInfo, lpProcessInformation *ProcessInformation) error {
|
||||
var (
|
||||
commandLine uintptr = 0
|
||||
workingDir uintptr = 0
|
||||
)
|
||||
advapi32, err := syscall.LoadLibrary("advapi32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Advapi32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(advapi32)
|
||||
CPAU, err := syscall.GetProcAddress(syscall.Handle(advapi32), "CreateProcessAsUserW")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load CreateProcessAsUserW API")
|
||||
}
|
||||
if len(lpCommandLine) > 0 {
|
||||
commandLine = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpCommandLine)))
|
||||
}
|
||||
if len(lpCurrentDirectory) > 0 {
|
||||
workingDir = uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpCurrentDirectory)))
|
||||
}
|
||||
r, _, errno := syscall.Syscall12(uintptr(CPAU), 11, uintptr(hToken), uintptr(unsafe.Pointer(windows.StringToUTF16Ptr(lpApplicationName))),
|
||||
commandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, uintptr(dwCreationFlags), uintptr(lpEnvironment),
|
||||
workingDir, uintptr(unsafe.Pointer(lpStartupInfo)), uintptr(unsafe.Pointer(lpProcessInformation)), 0)
|
||||
if r == 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func GetTokenInformation(TokenHandle HANDLE, TokenInformationClass, TokenInformation,
|
||||
TokenInformationLength uintptr, ReturnLength *uintptr) error {
|
||||
advapi32, err := syscall.LoadLibrary("advapi32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Advapi32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(advapi32)
|
||||
GTI, err := syscall.GetProcAddress(syscall.Handle(advapi32), "GetTokenInformation")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load GetTokenInformation API")
|
||||
}
|
||||
if r, _, errno := syscall.Syscall6(uintptr(GTI), 5, uintptr(TokenHandle), TokenInformationClass,
|
||||
TokenInformation, TokenInformationLength, uintptr(unsafe.Pointer(ReturnLength)), 0); r == 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package win32api
|
||||
|
||||
type TOKEN_LINKED_TOKEN struct {
|
||||
LinkedToken TOKEN
|
||||
}
|
||||
+284
@@ -0,0 +1,284 @@
|
||||
package win32api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func WTSGetActiveConsoleSessionId() (DWORD, error) {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return 0, errors.New("Can't Load Kernel32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
WTGet, err := syscall.GetProcAddress(syscall.Handle(kernel32), "WTSGetActiveConsoleSessionId")
|
||||
if err != nil {
|
||||
return 0, errors.New("Can't Load WTSGetActiveConsoleSessionId API")
|
||||
}
|
||||
res, _, _ := syscall.Syscall(uintptr(WTGet), 0, 0, 0, 0)
|
||||
return DWORD(res), nil
|
||||
}
|
||||
|
||||
func CloseHandle(hObject HANDLE) error {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Kernel32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
CH, err := syscall.GetProcAddress(syscall.Handle(kernel32), "CloseHandle")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load CloseHandle API")
|
||||
}
|
||||
if r, _, errno := syscall.Syscall(uintptr(CH), 1, uintptr(hObject), 0, 0); r == 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateToolhelp32Snapshot(dwFlags, th32ProcessID DWORD) (HANDLE, error) {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return 0, errors.New("Can't Load Kernel32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
CTS, err := syscall.GetProcAddress(syscall.Handle(kernel32), "CreateToolhelp32Snapshot")
|
||||
if err != nil {
|
||||
return 0, errors.New("Can't Load CreateToolhelp32Snapshot API")
|
||||
}
|
||||
r, _, errno := syscall.Syscall(uintptr(CTS), 2, uintptr(dwFlags), uintptr(th32ProcessID), 0)
|
||||
if int(r) == -1 {
|
||||
return 0, error(errno)
|
||||
}
|
||||
return HANDLE(r), nil
|
||||
}
|
||||
|
||||
func Process32Next(hSnapshot HANDLE, lppe *PROCESSENTRY32) error {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Kernel32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
PN, err := syscall.GetProcAddress(syscall.Handle(kernel32), "Process32Next")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Process32Next API")
|
||||
}
|
||||
r, _, errno := syscall.Syscall(uintptr(PN), 2, uintptr(hSnapshot), uintptr(unsafe.Pointer(lppe)), 0)
|
||||
if r == 0 {
|
||||
if errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return syscall.EINVAL
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetProcessId(Process HANDLE) uint32 {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
GPI, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GetProcessId")
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
r, _, _ := syscall.Syscall(uintptr(GPI), 1, uintptr(Process), 0, 0)
|
||||
return uint32(r)
|
||||
}
|
||||
|
||||
func GetTickCount() (uint32, error) {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
GTC, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GetTickCount")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
r, _, _ := syscall.Syscall(uintptr(GTC), 0, 0, 0, 0)
|
||||
return uint32(r), nil
|
||||
}
|
||||
|
||||
func GlobalMemoryStatusEx(data *MEMORYSTATUSEX) (bool, error) {
|
||||
(*data).DwLength = DWORD(unsafe.Sizeof(*data))
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
GMS, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GlobalMemoryStatusEx")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
r, _, errno := syscall.Syscall(uintptr(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) {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
Lck, err := syscall.GetProcAddress(syscall.Handle(kernel32), "LockFileEx")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
r, _, errno := syscall.Syscall6(uintptr(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) {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
ofb, err := syscall.GetProcAddress(syscall.Handle(kernel32), "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 r == syscall.INVALID_FILE_ATTRIBUTES {
|
||||
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
|
||||
}
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
Lck, err := syscall.GetProcAddress(syscall.Handle(kernel32), "CreateEventW")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
r, _, errno := syscall.Syscall6(uintptr(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 {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
glds, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GetLogicalDriveStringsW")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _, errno := syscall.Syscall(uintptr(glds), 2, uintptr(nBufferLength), uintptr(unsafe.Pointer(lpBuffer)), 0)
|
||||
if errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetVolumeInformationW(lpRootPathName LPCWSTR, lpVolumeNameBuffer LPWSTR, nVolumeNameSize DWORD,
|
||||
lpVolumeSerialNumber LPDWORD, lpMaximumComponentLength LPDWORD, lpFileSystemFlags LPDWORD,
|
||||
lpFileSystemNameBuffer LPWSTR, nFileSystemNameSize DWORD) error {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
glds, err := syscall.GetProcAddress(syscall.Handle(kernel32), "GetVolumeInformationW")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, _, errno := syscall.Syscall9(uintptr(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 errno != 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func DeviceIoControl(hDevice HANDLE, dwIoControlCode DWORD, lpInBuffer LPVOID, nInBufferSize DWORD, lpOutBuffer LPVOID,
|
||||
nOutBufferSize DWORD, lpBytesReturned LPDWORD, lpOverlapped *syscall.Overlapped) (bool, error) {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
dic, err := syscall.GetProcAddress(syscall.Handle(kernel32), "DeviceIoControl")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
r, _, errno := syscall.Syscall9(uintptr(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) {
|
||||
kernel32, err := syscall.LoadLibrary("kernel32.dll")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer syscall.FreeLibrary(kernel32)
|
||||
dic, err := syscall.GetProcAddress(syscall.Handle(kernel32), "DeviceIoControl")
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
r, _, errno := syscall.Syscall9(uintptr(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
|
||||
}
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
package win32api
|
||||
|
||||
import "syscall"
|
||||
|
||||
type Ulong int32
|
||||
type Ulong_ptr uintptr
|
||||
|
||||
const (
|
||||
LOCKFILE_EXCLUSIVE_LOCK DWORD = 0x00000002
|
||||
LOCKFILE_FAIL_IMMEDIATELY DWORD = 0x00000001
|
||||
)
|
||||
|
||||
type PROCESSENTRY32 struct {
|
||||
DwSize Ulong
|
||||
CntUsage Ulong
|
||||
Th32ProcessID Ulong
|
||||
Th32DefaultHeapID Ulong_ptr
|
||||
Th32ModuleID Ulong
|
||||
CntThreads Ulong
|
||||
Th32ParentProcessID Ulong
|
||||
PcPriClassBase Ulong
|
||||
DwFlags Ulong
|
||||
SzExeFile [260]byte
|
||||
}
|
||||
|
||||
type MEMORYSTATUSEX struct {
|
||||
DwLength DWORD
|
||||
DwMemoryLoad DWORD
|
||||
UllTotalPhys DWORDLONG
|
||||
UllAvailPhys DWORDLONG
|
||||
UllTotalPageFile DWORDLONG
|
||||
UllAvailPageFile DWORDLONG
|
||||
UllTotalVirtual DWORDLONG
|
||||
UllAvailVirtual DWORDLONG
|
||||
UllAvailExtendedVirtual DWORDLONG
|
||||
}
|
||||
|
||||
type USN_JOURNAL_DATA struct {
|
||||
UsnJournalID DWORDLONG
|
||||
FirstUsn USN
|
||||
NextUsn USN
|
||||
LowestValidUsn USN
|
||||
MaxUsn USN
|
||||
MaximumSize DWORDLONG
|
||||
AllocationDelta DWORDLONG
|
||||
}
|
||||
|
||||
type READ_USN_JOURNAL_DATA struct {
|
||||
StartUsn USN
|
||||
ReasonMask DWORD
|
||||
ReturnOnlyOnClose DWORD
|
||||
Timeout DWORDLONG
|
||||
BytesToWaitFor DWORDLONG
|
||||
UsnJournalID DWORDLONG
|
||||
}
|
||||
|
||||
type USN_RECORD struct {
|
||||
RecordLength DWORD
|
||||
MajorVersion WORD
|
||||
MinorVersion WORD
|
||||
FileReferenceNumber DWORDLONG
|
||||
ParentFileReferenceNumber DWORDLONG
|
||||
Usn USN
|
||||
TimeStamp LARGE_INTEGER
|
||||
Reason DWORD
|
||||
SourceInfo DWORD
|
||||
SecurityId DWORD
|
||||
FileAttributes DWORD
|
||||
FileNameLength WORD
|
||||
FileNameOffset WORD
|
||||
FileName [1]WCHAR
|
||||
}
|
||||
|
||||
type MFT_ENUM_DATA struct {
|
||||
StartFileReferenceNumber DWORDLONG
|
||||
LowUsn USN
|
||||
HighUsn USN
|
||||
}
|
||||
|
||||
const (
|
||||
FSCTL_ENUM_USN_DATA = 0x900B3
|
||||
FSCTL_QUERY_USN_JOURNAL = 0x900F4
|
||||
FSCTL_READ_USN_JOURNAL = 0x900BB
|
||||
O_RDONLY = syscall.O_RDONLY
|
||||
O_RDWR = syscall.O_RDWR
|
||||
O_CREAT = syscall.O_CREAT
|
||||
O_WRONLY = syscall.O_WRONLY
|
||||
GENERIC_READ = syscall.GENERIC_READ
|
||||
GENERIC_WRITE = syscall.GENERIC_WRITE
|
||||
FILE_APPEND_DATA = syscall.FILE_APPEND_DATA
|
||||
FILE_SHARE_READ = syscall.FILE_SHARE_READ
|
||||
FILE_SHARE_WRITE = syscall.FILE_SHARE_WRITE
|
||||
ERROR_FILE_NOT_FOUND = syscall.ERROR_FILE_NOT_FOUND
|
||||
O_APPEND = syscall.O_APPEND
|
||||
O_CLOEXEC = syscall.O_CLOEXEC
|
||||
O_EXCL = syscall.O_EXCL
|
||||
O_TRUNC = syscall.O_TRUNC
|
||||
CREATE_ALWAYS = syscall.CREATE_ALWAYS
|
||||
CREATE_NEW = syscall.CREATE_NEW
|
||||
OPEN_ALWAYS = syscall.OPEN_ALWAYS
|
||||
TRUNCATE_EXISTING = syscall.TRUNCATE_EXISTING
|
||||
OPEN_EXISTING = syscall.OPEN_EXISTING
|
||||
FILE_ATTRIBUTE_NORMAL = syscall.FILE_ATTRIBUTE_NORMAL
|
||||
FILE_FLAG_BACKUP_SEMANTICS = syscall.FILE_FLAG_BACKUP_SEMANTICS
|
||||
FILE_ATTRIBUTE_DIRECTORY = syscall.FILE_ATTRIBUTE_DIRECTORY
|
||||
MAX_LONG_PATH = syscall.MAX_LONG_PATH
|
||||
)
|
||||
|
||||
type FILE_ID_DESCRIPTOR struct {
|
||||
DwSize DWORD
|
||||
Type DWORD
|
||||
FileId DWORDLONG
|
||||
ObjectId DWORDLONG
|
||||
ExtendedFileId DWORDLONG
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package win32api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strconv"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func ShellExecute(hwnd HWND, lpOperation, lpFile, lpParameters, lpDirectory string, nShowCmd int) error {
|
||||
shell32, err := syscall.LoadLibrary("shell32.dll")
|
||||
var op, param, directory uintptr
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Shell32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(shell32)
|
||||
ShellExecute, err := syscall.GetProcAddress(syscall.Handle(shell32), "ShellExecuteW")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load ShellExecute API")
|
||||
}
|
||||
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)))
|
||||
}
|
||||
r, _, _ := syscall.Syscall6(uintptr(ShellExecute), 6,
|
||||
uintptr(hwnd),
|
||||
op,
|
||||
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpFile))),
|
||||
param,
|
||||
directory,
|
||||
uintptr(nShowCmd))
|
||||
if r < 32 {
|
||||
return errors.New("ERROR:" + strconv.Itoa(int(r)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
/**
|
||||
func ShellExecuteEX2(hwnd HWND, lpVerb, lpFile, lpParameters, lpDirectory string, nShow int) error {
|
||||
var newcmd SHELLEXECUTEINFOW
|
||||
newcmd.cbSize = DWORD(unsafe.Sizeof(newcmd))
|
||||
newcmd.hwnd = hwnd
|
||||
newcmd.lpVerb = lpVerb
|
||||
newcmd.lpFile = lpFile
|
||||
newcmd.lpParameters = lpParameters
|
||||
newcmd.lpDirectory = lpDirectory
|
||||
newcmd.nShow = nShow
|
||||
shell32, err := syscall.LoadLibrary("shell32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Shell32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(shell32)
|
||||
ShellExecuteEx, err := syscall.GetProcAddress(syscall.Handle(shell32), "ShellExecuteExW")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load ShellExecuteEx API")
|
||||
}
|
||||
r, _, _ := syscall.Syscall6(ShellExecuteEx, 1, uintptr(unsafe.Pointer(&newcmd)), 0, 0, 0, 0, 0)
|
||||
fmt.Println(strconv.Itoa(int(r)))
|
||||
fmt.Println(strconv.Itoa(int(newcmd.hInstApp)))
|
||||
if r != 0 {
|
||||
return errors.New("Error Recured")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
*/
|
||||
|
||||
func ShellExecuteEx(muzika *SHELLEXECUTEINFOW) error {
|
||||
shell32, err := syscall.LoadLibrary("shell32.dll")
|
||||
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Shell32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(shell32)
|
||||
ShellExecuteEx, err := syscall.GetProcAddress(syscall.Handle(shell32), "ShellExecuteExW")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load ShellExecuteEx API")
|
||||
}
|
||||
r, _, errno := syscall.Syscall6(ShellExecuteEx, 1, uintptr(unsafe.Pointer(muzika)), 0, 0, 0, 0, 0)
|
||||
if r == 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package win32api
|
||||
|
||||
type SHELLEXECUTEINFOW struct {
|
||||
CbSize DWORD
|
||||
FMask ULONG
|
||||
Hwnd HWND
|
||||
LpVerb uintptr
|
||||
LpFile uintptr
|
||||
LpParameters uintptr
|
||||
LpDirectory uintptr
|
||||
NShow int
|
||||
HInstApp HINSTANCE
|
||||
LpIDList LPVOID
|
||||
LpClass uintptr
|
||||
HkeyClass HKEY
|
||||
DwHotKey DWORD
|
||||
UnionorHMonitor HANDLE
|
||||
HProcess HANDLE
|
||||
}
|
||||
|
||||
type UNION struct {
|
||||
HIcon HANDLE
|
||||
HMonitor HANDLE
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
package win32api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func Keybd_event(keyname string, keydown bool) error {
|
||||
var key int
|
||||
var down uintptr
|
||||
if !keydown {
|
||||
down = KEYEVENTF_KEYUP
|
||||
}
|
||||
switch keyname {
|
||||
case "shift":
|
||||
key = VK_SHIFT
|
||||
case "lshift":
|
||||
key = VK_LSHIFT
|
||||
case "rshift":
|
||||
key = VK_RSHIFT
|
||||
case "a":
|
||||
key = VK_A
|
||||
}
|
||||
user32, err := syscall.LoadLibrary("user32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load User32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(user32)
|
||||
keyevent, err := syscall.GetProcAddress(syscall.Handle(user32), "keybd_event")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Keybd_event API")
|
||||
}
|
||||
syscall.Syscall6(keyevent, 4, uintptr(key), uintptr(key), down, 0, 0, 0)
|
||||
return nil
|
||||
}
|
||||
|
||||
func Keybd_event_origin(key, keyenv, down, extra uintptr) error {
|
||||
user32, err := syscall.LoadLibrary("user32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load User32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(user32)
|
||||
keyevent, err := syscall.GetProcAddress(syscall.Handle(user32), "keybd_event")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Keybd_event API")
|
||||
}
|
||||
syscall.Syscall6(keyevent, 4, key, keyenv, down, extra, 0, 0)
|
||||
return nil
|
||||
}
|
||||
+180
@@ -0,0 +1,180 @@
|
||||
package win32api
|
||||
|
||||
const (
|
||||
VK_SHIFT = 0x10
|
||||
VK_CTRL = 0x11
|
||||
VK_ALT = 0x12
|
||||
VK_LSHIFT = 0xA0
|
||||
VK_RSHIFT = 0xA1
|
||||
VK_LCONTROL = 0xA2
|
||||
VK_RCONTROL = 0xA3
|
||||
KEYEVENTF_KEYUP = 0x0002
|
||||
)
|
||||
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_ENTER = 0x0D
|
||||
VK_PAUSE = 0x13
|
||||
VK_CAPITAL = 0x14
|
||||
VK_KANA = 0x15
|
||||
VK_HANGUEL = 0x15
|
||||
VK_HANGUL = 0x15
|
||||
VK_JUNJA = 0x17
|
||||
VK_FINAL = 0x18
|
||||
VK_HANJA = 0x19
|
||||
VK_KANJI = 0x19
|
||||
VK_ESC = 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_0 = 0x30
|
||||
VK_1 = 0x31
|
||||
VK_2 = 0x32
|
||||
VK_3 = 0x33
|
||||
VK_4 = 0x34
|
||||
VK_5 = 0x35
|
||||
VK_6 = 0x36
|
||||
VK_7 = 0x37
|
||||
VK_8 = 0x38
|
||||
VK_9 = 0x39
|
||||
VK_A = 0x41
|
||||
VK_B = 0x42
|
||||
VK_C = 0x43
|
||||
VK_D = 0x44
|
||||
VK_E = 0x45
|
||||
VK_F = 0x46
|
||||
VK_G = 0x47
|
||||
VK_H = 0x48
|
||||
VK_I = 0x49
|
||||
VK_J = 0x4A
|
||||
VK_K = 0x4B
|
||||
VK_L = 0x4C
|
||||
VK_M = 0x4D
|
||||
VK_N = 0x4E
|
||||
VK_O = 0x4F
|
||||
VK_P = 0x50
|
||||
VK_Q = 0x51
|
||||
VK_R = 0x52
|
||||
VK_S = 0x53
|
||||
VK_T = 0x54
|
||||
VK_U = 0x55
|
||||
VK_V = 0x56
|
||||
VK_W = 0x57
|
||||
VK_X = 0x58
|
||||
VK_Y = 0x59
|
||||
VK_Z = 0x5A
|
||||
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_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_102 = 0xE2
|
||||
VK_PROCESSKEY = 0xE5
|
||||
VK_PACKET = 0xE7
|
||||
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
|
||||
)
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package win32api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
/*
|
||||
BOOL CreateEnvironmentBlock(
|
||||
LPVOID *lpEnvironment,
|
||||
HANDLE hToken,
|
||||
BOOL bInherit
|
||||
);
|
||||
*/
|
||||
|
||||
func CreateEnvironmentBlock(lpEnvironment *HANDLE, hToken TOKEN, bInherit uintptr) error {
|
||||
userenv, err := syscall.LoadLibrary("userenv.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Userenv API")
|
||||
}
|
||||
defer syscall.FreeLibrary(userenv)
|
||||
Dup, err := syscall.GetProcAddress(syscall.Handle(userenv), "CreateEnvironmentBlock")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load WTSQueryUserToken API")
|
||||
}
|
||||
r, _, errno := syscall.Syscall6(uintptr(Dup), 3, uintptr(unsafe.Pointer(lpEnvironment)), uintptr(hToken), bInherit, 0, 0, 0)
|
||||
if r == 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
+146
@@ -0,0 +1,146 @@
|
||||
package win32api
|
||||
|
||||
import (
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
type (
|
||||
ATOM uint16
|
||||
BOOL int32
|
||||
COLORREF uint32
|
||||
DWM_FRAME_COUNT uint64
|
||||
DWORD uint32
|
||||
LPDWORD *uint32
|
||||
DWORDLONG uint64
|
||||
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
|
||||
LPVOID unsafe.Pointer
|
||||
LRESULT uintptr
|
||||
LPCWSTR *uint16
|
||||
PVOID unsafe.Pointer
|
||||
QPC_TIME uint64
|
||||
ULONG uint32
|
||||
ULONG_PTR uintptr
|
||||
WPARAM uintptr
|
||||
WTS_CONNECTSTATE_CLASS int
|
||||
TRACEHANDLE uintptr
|
||||
TOKEN HANDLE
|
||||
LPWSTR *uint16
|
||||
TOKEN_TYPE int
|
||||
SW int
|
||||
SECURITY_IMPERSONATION_LEVEL int
|
||||
WCHAR uint16
|
||||
WORD uint16
|
||||
USN int64
|
||||
LARGE_INTEGER LONGLONG
|
||||
LONGLONG int64
|
||||
)
|
||||
|
||||
type WTS_SESSION_INFO struct {
|
||||
SessionID HANDLE
|
||||
WinStationName *uint16
|
||||
State WTS_CONNECTSTATE_CLASS
|
||||
}
|
||||
|
||||
const (
|
||||
WTS_CURRENT_SERVER_HANDLE uintptr = 0
|
||||
)
|
||||
const (
|
||||
WTSActive WTS_CONNECTSTATE_CLASS = iota
|
||||
WTSConnected
|
||||
WTSConnectQuery
|
||||
WTSShadow
|
||||
WTSDisconnected
|
||||
WTSIdle
|
||||
WTSListen
|
||||
WTSReset
|
||||
WTSDown
|
||||
WTSInit
|
||||
)
|
||||
const (
|
||||
SecurityAnonymous SECURITY_IMPERSONATION_LEVEL = iota
|
||||
SecurityIdentification
|
||||
SecurityImpersonation
|
||||
SecurityDelegation
|
||||
)
|
||||
const (
|
||||
TokenPrimary TOKEN_TYPE = iota + 1
|
||||
TokenImpersonazion
|
||||
)
|
||||
const (
|
||||
SW_HIDE SW = 0
|
||||
SW_SHOWNORMAL = 1
|
||||
SW_NORMAL = 1
|
||||
SW_SHOWMINIMIZED = 2
|
||||
SW_SHOWMAXIMIZED = 3
|
||||
SW_MAXIMIZE = 3
|
||||
SW_SHOWNOACTIVATE = 4
|
||||
SW_SHOW = 5
|
||||
SW_MINIMIZE = 6
|
||||
SW_SHOWMINNOACTIVE = 7
|
||||
SW_SHOWNA = 8
|
||||
SW_RESTORE = 9
|
||||
SW_SHOWDEFAULT = 10
|
||||
SW_MAX = 1
|
||||
)
|
||||
const (
|
||||
CREATE_UNICODE_ENVIRONMENT uint16 = 0x00000400
|
||||
CREATE_NO_WINDOW = 0x08000000
|
||||
CREATE_NEW_CONSOLE = 0x00000010
|
||||
)
|
||||
|
||||
type StartupInfo 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
|
||||
_ *byte
|
||||
StdInput HANDLE
|
||||
StdOutput HANDLE
|
||||
StdErr HANDLE
|
||||
}
|
||||
|
||||
type ProcessInformation struct {
|
||||
Process HANDLE
|
||||
Thread HANDLE
|
||||
ProcessId uint32
|
||||
ThreadId uint32
|
||||
}
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
package win32api
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func WTSQueryUserToken(SessionId HANDLE, phToken *HANDLE) error {
|
||||
wtsapi32, err := syscall.LoadLibrary("wtsapi32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Wtsapi32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(wtsapi32)
|
||||
WTGet, err := syscall.GetProcAddress(syscall.Handle(wtsapi32), "WTSQueryUserToken")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load WTSQueryUserToken API")
|
||||
}
|
||||
r, _, errno := syscall.Syscall(uintptr(WTGet), 2, uintptr(SessionId), uintptr(unsafe.Pointer(phToken)), 0)
|
||||
if r == 0 {
|
||||
return error(errno)
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func WTSEnumerateSessions(hServer HANDLE, Reserved, Version DWORD, ppSessionInfo *HANDLE, pCount *int) error {
|
||||
wtsapi32, err := syscall.LoadLibrary("wtsapi32.dll")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load Wtsapi32 API")
|
||||
}
|
||||
defer syscall.FreeLibrary(wtsapi32)
|
||||
WT, err := syscall.GetProcAddress(syscall.Handle(wtsapi32), "WTSEnumerateSessionsW")
|
||||
if err != nil {
|
||||
return errors.New("Can't Load WTSQueryUserToken API")
|
||||
}
|
||||
r, _, errno := syscall.Syscall6(uintptr(WT), 5, uintptr(hServer), uintptr(Reserved), uintptr(Version), uintptr(unsafe.Pointer(ppSessionInfo)), uintptr(unsafe.Pointer(pCount)), 0)
|
||||
if r == 0 {
|
||||
return error(errno)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user