WIP: Save agent roles integration work before CHORUS rebrand
- Agent roles and coordination features - Chat API integration testing - New configuration and workspace management 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
		
							
								
								
									
										8
									
								
								vendor/github.com/elastic/gosigar/sys/windows/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								vendor/github.com/elastic/gosigar/sys/windows/doc.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| // Package windows contains various Windows system call. | ||||
| package windows | ||||
|  | ||||
| // Use "go generate -v -x ." to generate the source. | ||||
|  | ||||
| // Add -trace to enable debug prints around syscalls. | ||||
| //go:generate go run $GOROOT/src/syscall/mksyscall_windows.go -systemdll=true -output zsyscall_windows.go syscall_windows.go | ||||
| //go:generate go run fix_generated.go -input zsyscall_windows.go | ||||
							
								
								
									
										132
									
								
								vendor/github.com/elastic/gosigar/sys/windows/ntquery.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								vendor/github.com/elastic/gosigar/sys/windows/ntquery.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,132 @@ | ||||
| // +build windows | ||||
|  | ||||
| package windows | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"io" | ||||
| 	"runtime" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| // On both 32-bit and 64-bit systems NtQuerySystemInformation expects the | ||||
| // size of SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION to be 48. | ||||
| const sizeofSystemProcessorPerformanceInformation = 48 | ||||
|  | ||||
| // ProcessBasicInformation is an equivalent representation of | ||||
| // PROCESS_BASIC_INFORMATION in the Windows API. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx | ||||
| type ProcessBasicInformation struct { | ||||
| 	ExitStatus                   uint | ||||
| 	PebBaseAddress               uintptr | ||||
| 	AffinityMask                 uint | ||||
| 	BasePriority                 uint | ||||
| 	UniqueProcessID              uint | ||||
| 	InheritedFromUniqueProcessID uint | ||||
| } | ||||
|  | ||||
| // NtQueryProcessBasicInformation queries basic information about the process | ||||
| // associated with the given handle (provided by OpenProcess). It uses the | ||||
| // NtQueryInformationProcess function to collect the data. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684280(v=vs.85).aspx | ||||
| func NtQueryProcessBasicInformation(handle syscall.Handle) (ProcessBasicInformation, error) { | ||||
| 	var processBasicInfo ProcessBasicInformation | ||||
| 	processBasicInfoPtr := (*byte)(unsafe.Pointer(&processBasicInfo)) | ||||
| 	size := uint32(unsafe.Sizeof(processBasicInfo)) | ||||
| 	ntStatus, _ := _NtQueryInformationProcess(handle, 0, processBasicInfoPtr, size, nil) | ||||
| 	if ntStatus != 0 { | ||||
| 		return ProcessBasicInformation{}, errors.Errorf("NtQueryInformationProcess failed, NTSTATUS=0x%X", ntStatus) | ||||
| 	} | ||||
|  | ||||
| 	return processBasicInfo, nil | ||||
| } | ||||
|  | ||||
| // SystemProcessorPerformanceInformation contains CPU performance information | ||||
| // for a single CPU. | ||||
| type SystemProcessorPerformanceInformation struct { | ||||
| 	IdleTime   time.Duration // Amount of time spent idle. | ||||
| 	KernelTime time.Duration // Kernel time does NOT include time spent in idle. | ||||
| 	UserTime   time.Duration // Amount of time spent executing in user mode. | ||||
| } | ||||
|  | ||||
| // _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION is an equivalent representation of | ||||
| // SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION in the Windows API. This struct is | ||||
| // used internally with NtQuerySystemInformation call and is not exported. The | ||||
| // exported equivalent is SystemProcessorPerformanceInformation. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx | ||||
| type _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION struct { | ||||
| 	IdleTime   int64 | ||||
| 	KernelTime int64 | ||||
| 	UserTime   int64 | ||||
| 	Reserved1  [2]int64 | ||||
| 	Reserved2  uint32 | ||||
| } | ||||
|  | ||||
| // NtQuerySystemProcessorPerformanceInformation queries CPU performance | ||||
| // information for each CPU. It uses the NtQuerySystemInformation function to | ||||
| // collect the SystemProcessorPerformanceInformation. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx | ||||
| func NtQuerySystemProcessorPerformanceInformation() ([]SystemProcessorPerformanceInformation, error) { | ||||
| 	// NTSTATUS code for success. | ||||
| 	// https://msdn.microsoft.com/en-us/library/cc704588.aspx | ||||
| 	const STATUS_SUCCESS = 0 | ||||
|  | ||||
| 	// From the _SYSTEM_INFORMATION_CLASS enum. | ||||
| 	// http://processhacker.sourceforge.net/doc/ntexapi_8h.html#ad5d815b48e8f4da1ef2eb7a2f18a54e0 | ||||
| 	const systemProcessorPerformanceInformation = 8 | ||||
|  | ||||
| 	// Create a buffer large enough to hold an entry for each processor. | ||||
| 	b := make([]byte, runtime.NumCPU()*sizeofSystemProcessorPerformanceInformation) | ||||
|  | ||||
| 	// Query the performance information. Note that this function uses 0 to | ||||
| 	// indicate success. Most other Windows functions use non-zero for success. | ||||
| 	var returnLength uint32 | ||||
| 	ntStatus, _ := _NtQuerySystemInformation(systemProcessorPerformanceInformation, &b[0], uint32(len(b)), &returnLength) | ||||
| 	if ntStatus != STATUS_SUCCESS { | ||||
| 		return nil, errors.Errorf("NtQuerySystemInformation failed, NTSTATUS=0x%X, bufLength=%v, returnLength=%v", ntStatus, len(b), returnLength) | ||||
| 	} | ||||
|  | ||||
| 	return readSystemProcessorPerformanceInformationBuffer(b) | ||||
| } | ||||
|  | ||||
| // readSystemProcessorPerformanceInformationBuffer reads from a buffer | ||||
| // containing SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION data. The buffer should | ||||
| // contain one entry for each CPU. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724509(v=vs.85).aspx | ||||
| func readSystemProcessorPerformanceInformationBuffer(b []byte) ([]SystemProcessorPerformanceInformation, error) { | ||||
| 	n := len(b) / sizeofSystemProcessorPerformanceInformation | ||||
| 	r := bytes.NewReader(b) | ||||
|  | ||||
| 	rtn := make([]SystemProcessorPerformanceInformation, 0, n) | ||||
| 	for i := 0; i < n; i++ { | ||||
| 		_, err := r.Seek(int64(i*sizeofSystemProcessorPerformanceInformation), io.SeekStart) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrapf(err, "failed to seek to cpuN=%v in buffer", i) | ||||
| 		} | ||||
|  | ||||
| 		times := make([]uint64, 3) | ||||
| 		for j := range times { | ||||
| 			err := binary.Read(r, binary.LittleEndian, ×[j]) | ||||
| 			if err != nil { | ||||
| 				return nil, errors.Wrapf(err, "failed reading cpu times for cpuN=%v", i) | ||||
| 			} | ||||
| 		} | ||||
|  | ||||
| 		idleTime := time.Duration(times[0] * 100) | ||||
| 		kernelTime := time.Duration(times[1] * 100) | ||||
| 		userTime := time.Duration(times[2] * 100) | ||||
|  | ||||
| 		rtn = append(rtn, SystemProcessorPerformanceInformation{ | ||||
| 			IdleTime:   idleTime, | ||||
| 			KernelTime: kernelTime - idleTime, // Subtract out idle time from kernel time. | ||||
| 			UserTime:   userTime, | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	return rtn, nil | ||||
| } | ||||
							
								
								
									
										272
									
								
								vendor/github.com/elastic/gosigar/sys/windows/privileges.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										272
									
								
								vendor/github.com/elastic/gosigar/sys/windows/privileges.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,272 @@ | ||||
| // +build windows | ||||
|  | ||||
| package windows | ||||
|  | ||||
| import ( | ||||
| 	"bytes" | ||||
| 	"encoding/binary" | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"runtime" | ||||
| 	"strings" | ||||
| 	"sync" | ||||
| 	"syscall" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| 	"golang.org/x/sys/windows" | ||||
| ) | ||||
|  | ||||
| // Cache of privilege names to LUIDs. | ||||
| var ( | ||||
| 	privNames     = make(map[string]int64) | ||||
| 	privNameMutex sync.Mutex | ||||
| ) | ||||
|  | ||||
| const ( | ||||
| 	// SeDebugPrivilege is the name of the privilege used to debug programs. | ||||
| 	SeDebugPrivilege = "SeDebugPrivilege" | ||||
| ) | ||||
|  | ||||
| // Errors returned by AdjustTokenPrivileges. | ||||
| const ( | ||||
| 	ERROR_NOT_ALL_ASSIGNED syscall.Errno = 1300 | ||||
| ) | ||||
|  | ||||
| // Attribute bits for privileges. | ||||
| const ( | ||||
| 	_SE_PRIVILEGE_ENABLED_BY_DEFAULT uint32 = 0x00000001 | ||||
| 	_SE_PRIVILEGE_ENABLED            uint32 = 0x00000002 | ||||
| 	_SE_PRIVILEGE_REMOVED            uint32 = 0x00000004 | ||||
| 	_SE_PRIVILEGE_USED_FOR_ACCESS    uint32 = 0x80000000 | ||||
| ) | ||||
|  | ||||
| // Privilege contains information about a single privilege associated with a | ||||
| // Token. | ||||
| type Privilege struct { | ||||
| 	LUID             int64  `json:"-"` // Locally unique identifier (guaranteed only until the system is restarted). | ||||
| 	Name             string `json:"-"` | ||||
| 	EnabledByDefault bool   `json:"enabled_by_default,omitempty"` | ||||
| 	Enabled          bool   `json:"enabled"` | ||||
| 	Removed          bool   `json:"removed,omitempty"` | ||||
| 	Used             bool   `json:"used,omitempty"` | ||||
| } | ||||
|  | ||||
| func (p Privilege) String() string { | ||||
| 	var buf bytes.Buffer | ||||
| 	buf.WriteString(p.Name) | ||||
| 	buf.WriteString("=(") | ||||
|  | ||||
| 	opts := make([]string, 0, 4) | ||||
| 	if p.EnabledByDefault { | ||||
| 		opts = append(opts, "Default") | ||||
| 	} | ||||
| 	if p.Enabled { | ||||
| 		opts = append(opts, "Enabled") | ||||
| 	} | ||||
| 	if !p.EnabledByDefault && !p.Enabled { | ||||
| 		opts = append(opts, "Disabled") | ||||
| 	} | ||||
| 	if p.Removed { | ||||
| 		opts = append(opts, "Removed") | ||||
| 	} | ||||
| 	if p.Used { | ||||
| 		opts = append(opts, "Used") | ||||
| 	} | ||||
|  | ||||
| 	buf.WriteString(strings.Join(opts, ", ")) | ||||
| 	buf.WriteString(")") | ||||
|  | ||||
| 	// Example: SeDebugPrivilege=(Default, Enabled) | ||||
| 	return buf.String() | ||||
| } | ||||
|  | ||||
| // User represent the information about a Windows account. | ||||
| type User struct { | ||||
| 	SID     string | ||||
| 	Account string | ||||
| 	Domain  string | ||||
| 	Type    uint32 | ||||
| } | ||||
|  | ||||
| func (u User) String() string { | ||||
| 	return fmt.Sprintf(`User:%v\%v, SID:%v, Type:%v`, u.Domain, u.Account, u.SID, u.Type) | ||||
| } | ||||
|  | ||||
| // DebugInfo contains general debug info about the current process. | ||||
| type DebugInfo struct { | ||||
| 	OSVersion    Version              // OS version info. | ||||
| 	Arch         string               // Architecture of the machine. | ||||
| 	NumCPU       int                  // Number of CPUs. | ||||
| 	User         User                 // User that this process is running as. | ||||
| 	ProcessPrivs map[string]Privilege // Privileges held by the process. | ||||
| } | ||||
|  | ||||
| func (d DebugInfo) String() string { | ||||
| 	bytes, _ := json.Marshal(d) | ||||
| 	return string(bytes) | ||||
| } | ||||
|  | ||||
| // LookupPrivilegeName looks up a privilege name given a LUID value. | ||||
| func LookupPrivilegeName(systemName string, luid int64) (string, error) { | ||||
| 	buf := make([]uint16, 256) | ||||
| 	bufSize := uint32(len(buf)) | ||||
| 	err := _LookupPrivilegeName(systemName, &luid, &buf[0], &bufSize) | ||||
| 	if err != nil { | ||||
| 		return "", errors.Wrapf(err, "LookupPrivilegeName failed for luid=%v", luid) | ||||
| 	} | ||||
|  | ||||
| 	return syscall.UTF16ToString(buf), nil | ||||
| } | ||||
|  | ||||
| // mapPrivileges maps privilege names to LUID values. | ||||
| func mapPrivileges(names []string) ([]int64, error) { | ||||
| 	var privileges []int64 | ||||
| 	privNameMutex.Lock() | ||||
| 	defer privNameMutex.Unlock() | ||||
| 	for _, name := range names { | ||||
| 		p, ok := privNames[name] | ||||
| 		if !ok { | ||||
| 			err := _LookupPrivilegeValue("", name, &p) | ||||
| 			if err != nil { | ||||
| 				return nil, errors.Wrapf(err, "LookupPrivilegeValue failed on '%v'", name) | ||||
| 			} | ||||
| 			privNames[name] = p | ||||
| 		} | ||||
| 		privileges = append(privileges, p) | ||||
| 	} | ||||
| 	return privileges, nil | ||||
| } | ||||
|  | ||||
| // EnableTokenPrivileges enables the specified privileges in the given | ||||
| // Token. The token must have TOKEN_ADJUST_PRIVILEGES access. If the token | ||||
| // does not already contain the privilege it cannot be enabled. | ||||
| func EnableTokenPrivileges(token syscall.Token, privileges ...string) error { | ||||
| 	privValues, err := mapPrivileges(privileges) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
|  | ||||
| 	var b bytes.Buffer | ||||
| 	binary.Write(&b, binary.LittleEndian, uint32(len(privValues))) | ||||
| 	for _, p := range privValues { | ||||
| 		binary.Write(&b, binary.LittleEndian, p) | ||||
| 		binary.Write(&b, binary.LittleEndian, uint32(_SE_PRIVILEGE_ENABLED)) | ||||
| 	} | ||||
|  | ||||
| 	success, err := _AdjustTokenPrivileges(token, false, &b.Bytes()[0], uint32(b.Len()), nil, nil) | ||||
| 	if !success { | ||||
| 		return err | ||||
| 	} | ||||
| 	if err == ERROR_NOT_ALL_ASSIGNED { | ||||
| 		return errors.Wrap(err, "error not all privileges were assigned") | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // GetTokenPrivileges returns a list of privileges associated with a token. | ||||
| // The provided token must have at a minimum TOKEN_QUERY access. This is a | ||||
| // wrapper around the GetTokenInformation function. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx | ||||
| func GetTokenPrivileges(token syscall.Token) (map[string]Privilege, error) { | ||||
| 	// Determine the required buffer size. | ||||
| 	var size uint32 | ||||
| 	syscall.GetTokenInformation(token, syscall.TokenPrivileges, nil, 0, &size) | ||||
|  | ||||
| 	// This buffer will receive a TOKEN_PRIVILEGE structure. | ||||
| 	b := bytes.NewBuffer(make([]byte, size)) | ||||
| 	err := syscall.GetTokenInformation(token, syscall.TokenPrivileges, &b.Bytes()[0], uint32(b.Len()), &size) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "GetTokenInformation failed") | ||||
| 	} | ||||
|  | ||||
| 	var privilegeCount uint32 | ||||
| 	err = binary.Read(b, binary.LittleEndian, &privilegeCount) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "failed to read PrivilegeCount") | ||||
| 	} | ||||
|  | ||||
| 	rtn := make(map[string]Privilege, privilegeCount) | ||||
| 	for i := 0; i < int(privilegeCount); i++ { | ||||
| 		var luid int64 | ||||
| 		err = binary.Read(b, binary.LittleEndian, &luid) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrap(err, "failed to read LUID value") | ||||
| 		} | ||||
|  | ||||
| 		var attributes uint32 | ||||
| 		err = binary.Read(b, binary.LittleEndian, &attributes) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrap(err, "failed to read attributes") | ||||
| 		} | ||||
|  | ||||
| 		name, err := LookupPrivilegeName("", luid) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrapf(err, "LookupPrivilegeName failed for LUID=%v", luid) | ||||
| 		} | ||||
|  | ||||
| 		rtn[name] = Privilege{ | ||||
| 			LUID:             luid, | ||||
| 			Name:             name, | ||||
| 			EnabledByDefault: (attributes & _SE_PRIVILEGE_ENABLED_BY_DEFAULT) > 0, | ||||
| 			Enabled:          (attributes & _SE_PRIVILEGE_ENABLED) > 0, | ||||
| 			Removed:          (attributes & _SE_PRIVILEGE_REMOVED) > 0, | ||||
| 			Used:             (attributes & _SE_PRIVILEGE_USED_FOR_ACCESS) > 0, | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return rtn, nil | ||||
| } | ||||
|  | ||||
| // GetTokenUser returns the User associated with the given Token. | ||||
| func GetTokenUser(token syscall.Token) (User, error) { | ||||
| 	tokenUser, err := token.GetTokenUser() | ||||
| 	if err != nil { | ||||
| 		return User{}, errors.Wrap(err, "GetTokenUser failed") | ||||
| 	} | ||||
|  | ||||
| 	var user User | ||||
| 	user.SID, err = tokenUser.User.Sid.String() | ||||
| 	if err != nil { | ||||
| 		return user, errors.Wrap(err, "ConvertSidToStringSid failed") | ||||
| 	} | ||||
|  | ||||
| 	user.Account, user.Domain, user.Type, err = tokenUser.User.Sid.LookupAccount("") | ||||
| 	if err != nil { | ||||
| 		return user, errors.Wrap(err, "LookupAccountSid failed") | ||||
| 	} | ||||
|  | ||||
| 	return user, nil | ||||
| } | ||||
|  | ||||
| // GetDebugInfo returns general debug info about the current process. | ||||
| func GetDebugInfo() (*DebugInfo, error) { | ||||
| 	h, err := windows.GetCurrentProcess() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	var token syscall.Token | ||||
| 	err = syscall.OpenProcessToken(syscall.Handle(h), syscall.TOKEN_QUERY, &token) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	privs, err := GetTokenPrivileges(token) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	user, err := GetTokenUser(token) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	return &DebugInfo{ | ||||
| 		User:         user, | ||||
| 		ProcessPrivs: privs, | ||||
| 		OSVersion:    GetWindowsVersion(), | ||||
| 		Arch:         runtime.GOARCH, | ||||
| 		NumCPU:       runtime.NumCPU(), | ||||
| 	}, nil | ||||
| } | ||||
							
								
								
									
										630
									
								
								vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										630
									
								
								vendor/github.com/elastic/gosigar/sys/windows/syscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,630 @@ | ||||
| package windows | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"strings" | ||||
| 	"syscall" | ||||
| 	"time" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"github.com/pkg/errors" | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	sizeofUint32                  = 4 | ||||
| 	sizeofProcessEntry32          = uint32(unsafe.Sizeof(ProcessEntry32{})) | ||||
| 	sizeofProcessMemoryCountersEx = uint32(unsafe.Sizeof(ProcessMemoryCountersEx{})) | ||||
| 	sizeofMemoryStatusEx          = uint32(unsafe.Sizeof(MemoryStatusEx{})) | ||||
| ) | ||||
|  | ||||
| // Process-specific access rights. Others are declared in the syscall package. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx | ||||
| const ( | ||||
| 	PROCESS_QUERY_LIMITED_INFORMATION uint32 = 0x1000 | ||||
| 	PROCESS_VM_READ                   uint32 = 0x0010 | ||||
| ) | ||||
|  | ||||
| // error codes for GetVolumeInformation function | ||||
| const ( | ||||
| 	ERROR_INVALID_FUNCTION syscall.Errno = 1 | ||||
| 	ERROR_NOT_READY        syscall.Errno = 21 | ||||
| ) | ||||
|  | ||||
| // SizeOfRtlUserProcessParameters gives the size | ||||
| // of the RtlUserProcessParameters struct. | ||||
| const SizeOfRtlUserProcessParameters = unsafe.Sizeof(RtlUserProcessParameters{}) | ||||
|  | ||||
| // MAX_PATH is the maximum length for a path in Windows. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365247(v=vs.85).aspx | ||||
| const MAX_PATH = 260 | ||||
|  | ||||
| // DriveType represents a type of drive (removable, fixed, CD-ROM, RAM disk, or | ||||
| // network drive). | ||||
| type DriveType uint32 | ||||
|  | ||||
| // Drive types as returned by GetDriveType. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939(v=vs.85).aspx | ||||
| const ( | ||||
| 	DRIVE_UNKNOWN DriveType = iota | ||||
| 	DRIVE_NO_ROOT_DIR | ||||
| 	DRIVE_REMOVABLE | ||||
| 	DRIVE_FIXED | ||||
| 	DRIVE_REMOTE | ||||
| 	DRIVE_CDROM | ||||
| 	DRIVE_RAMDISK | ||||
| ) | ||||
|  | ||||
| // UnicodeString is Go's equivalent for the _UNICODE_STRING struct. | ||||
| type UnicodeString struct { | ||||
| 	Size          uint16 | ||||
| 	MaximumLength uint16 | ||||
| 	Buffer        uintptr | ||||
| } | ||||
|  | ||||
| // RtlUserProcessParameters is Go's equivalent for the | ||||
| // _RTL_USER_PROCESS_PARAMETERS struct. | ||||
| // A few undocumented fields are exposed. | ||||
| type RtlUserProcessParameters struct { | ||||
| 	Reserved1              [16]byte | ||||
| 	Reserved2              [5]uintptr | ||||
| 	CurrentDirectoryPath   UnicodeString | ||||
| 	CurrentDirectoryHandle uintptr | ||||
| 	DllPath                UnicodeString | ||||
| 	ImagePathName          UnicodeString | ||||
| 	CommandLine            UnicodeString | ||||
| } | ||||
|  | ||||
| func (dt DriveType) String() string { | ||||
| 	names := map[DriveType]string{ | ||||
| 		DRIVE_UNKNOWN:     "unknown", | ||||
| 		DRIVE_NO_ROOT_DIR: "invalid", | ||||
| 		DRIVE_REMOVABLE:   "removable", | ||||
| 		DRIVE_FIXED:       "fixed", | ||||
| 		DRIVE_REMOTE:      "remote", | ||||
| 		DRIVE_CDROM:       "cdrom", | ||||
| 		DRIVE_RAMDISK:     "ramdisk", | ||||
| 	} | ||||
|  | ||||
| 	name, found := names[dt] | ||||
| 	if !found { | ||||
| 		return "unknown DriveType value" | ||||
| 	} | ||||
| 	return name | ||||
| } | ||||
|  | ||||
| // Flags that can be used with CreateToolhelp32Snapshot. | ||||
| const ( | ||||
| 	TH32CS_INHERIT      uint32 = 0x80000000 // Indicates that the snapshot handle is to be inheritable. | ||||
| 	TH32CS_SNAPHEAPLIST uint32 = 0x00000001 // Includes all heaps of the process specified in th32ProcessID in the snapshot. | ||||
| 	TH32CS_SNAPMODULE   uint32 = 0x00000008 // Includes all modules of the process specified in th32ProcessID in the snapshot. | ||||
| 	TH32CS_SNAPMODULE32 uint32 = 0x00000010 // Includes all 32-bit modules of the process specified in th32ProcessID in the snapshot when called from a 64-bit process. | ||||
| 	TH32CS_SNAPPROCESS  uint32 = 0x00000002 // Includes all processes in the system in the snapshot. | ||||
| 	TH32CS_SNAPTHREAD   uint32 = 0x00000004 // Includes all threads in the system in the snapshot. | ||||
| ) | ||||
|  | ||||
| // ProcessEntry32 is an equivalent representation of PROCESSENTRY32 in the | ||||
| // Windows API. It contains a process's information. Do not modify or reorder. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684839(v=vs.85).aspx | ||||
| type ProcessEntry32 struct { | ||||
| 	size              uint32 | ||||
| 	CntUsage          uint32 | ||||
| 	ProcessID         uint32 | ||||
| 	DefaultHeapID     uintptr | ||||
| 	ModuleID          uint32 | ||||
| 	CntThreads        uint32 | ||||
| 	ParentProcessID   uint32 | ||||
| 	PriorityClassBase int32 | ||||
| 	Flags             uint32 | ||||
| 	exeFile           [MAX_PATH]uint16 | ||||
| } | ||||
|  | ||||
| // ExeFile returns the name of the executable file for the process. It does | ||||
| // not contain the full path. | ||||
| func (p ProcessEntry32) ExeFile() string { | ||||
| 	return syscall.UTF16ToString(p.exeFile[:]) | ||||
| } | ||||
|  | ||||
| func (p ProcessEntry32) String() string { | ||||
| 	return fmt.Sprintf("{CntUsage:%v ProcessID:%v DefaultHeapID:%v ModuleID:%v "+ | ||||
| 		"CntThreads:%v ParentProcessID:%v PriorityClassBase:%v Flags:%v ExeFile:%v", | ||||
| 		p.CntUsage, p.ProcessID, p.DefaultHeapID, p.ModuleID, p.CntThreads, | ||||
| 		p.ParentProcessID, p.PriorityClassBase, p.Flags, p.ExeFile()) | ||||
| } | ||||
|  | ||||
| // MemoryStatusEx is an equivalent representation of MEMORYSTATUSEX in the | ||||
| // Windows API. It contains information about the current state of both physical | ||||
| // and virtual memory, including extended memory. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366770 | ||||
| type MemoryStatusEx struct { | ||||
| 	length               uint32 | ||||
| 	MemoryLoad           uint32 | ||||
| 	TotalPhys            uint64 | ||||
| 	AvailPhys            uint64 | ||||
| 	TotalPageFile        uint64 | ||||
| 	AvailPageFile        uint64 | ||||
| 	TotalVirtual         uint64 | ||||
| 	AvailVirtual         uint64 | ||||
| 	AvailExtendedVirtual uint64 | ||||
| } | ||||
|  | ||||
| // ProcessMemoryCountersEx is an equivalent representation of | ||||
| // PROCESS_MEMORY_COUNTERS_EX in the Windows API. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684874(v=vs.85).aspx | ||||
| type ProcessMemoryCountersEx struct { | ||||
| 	cb                         uint32 | ||||
| 	PageFaultCount             uint32 | ||||
| 	PeakWorkingSetSize         uintptr | ||||
| 	WorkingSetSize             uintptr | ||||
| 	QuotaPeakPagedPoolUsage    uintptr | ||||
| 	QuotaPagedPoolUsage        uintptr | ||||
| 	QuotaPeakNonPagedPoolUsage uintptr | ||||
| 	QuotaNonPagedPoolUsage     uintptr | ||||
| 	PagefileUsage              uintptr | ||||
| 	PeakPagefileUsage          uintptr | ||||
| 	PrivateUsage               uintptr | ||||
| } | ||||
|  | ||||
| // GetLogicalDriveStrings returns a list of drives in the system. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364975(v=vs.85).aspx | ||||
| func GetLogicalDriveStrings() ([]string, error) { | ||||
| 	// Determine the size of the buffer required to receive all drives. | ||||
| 	bufferLength, err := _GetLogicalDriveStringsW(0, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed to get buffer length") | ||||
| 	} | ||||
| 	if bufferLength < 0 { | ||||
| 		return nil, errors.New("GetLogicalDriveStringsW returned an invalid buffer length") | ||||
| 	} | ||||
|  | ||||
| 	buffer := make([]uint16, bufferLength) | ||||
| 	_, err = _GetLogicalDriveStringsW(uint32(len(buffer)), &buffer[0]) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "GetLogicalDriveStringsW failed") | ||||
| 	} | ||||
|  | ||||
| 	return UTF16SliceToStringSlice(buffer), nil | ||||
| } | ||||
|  | ||||
| // GetAccessPaths returns the list of access paths for volumes in the system. | ||||
| func GetAccessPaths() ([]string, error) { | ||||
| 	volumes, err := GetVolumes() | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "GetVolumes failed") | ||||
| 	} | ||||
|  | ||||
| 	var paths []string | ||||
| 	for _, volumeName := range volumes { | ||||
| 		volumePaths, err := GetVolumePathsForVolume(volumeName) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrapf(err, "failed to get list of access paths for volume '%s'", volumeName) | ||||
| 		} | ||||
| 		if len(volumePaths) == 0 { | ||||
| 			continue | ||||
| 		} | ||||
|  | ||||
| 		// Get only the first path | ||||
| 		paths = append(paths, volumePaths[0]) | ||||
| 	} | ||||
|  | ||||
| 	return paths, nil | ||||
| } | ||||
|  | ||||
| // GetVolumes returs the list of volumes in the system. | ||||
| // https://docs.microsoft.com/es-es/windows/desktop/api/fileapi/nf-fileapi-findfirstvolumew | ||||
| func GetVolumes() ([]string, error) { | ||||
| 	buffer := make([]uint16, MAX_PATH+1) | ||||
|  | ||||
| 	var volumes []string | ||||
|  | ||||
| 	h, err := _FindFirstVolume(&buffer[0], uint32(len(buffer))) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "FindFirstVolumeW failed") | ||||
| 	} | ||||
| 	defer _FindVolumeClose(h) | ||||
|  | ||||
| 	for { | ||||
| 		volumes = append(volumes, syscall.UTF16ToString(buffer)) | ||||
|  | ||||
| 		err = _FindNextVolume(h, &buffer[0], uint32(len(buffer))) | ||||
| 		if err != nil { | ||||
| 			if errors.Cause(err) == syscall.ERROR_NO_MORE_FILES { | ||||
| 				break | ||||
| 			} | ||||
| 			return nil, errors.Wrap(err, "FindNextVolumeW failed") | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return volumes, nil | ||||
| } | ||||
|  | ||||
| // GetVolumePathsForVolume returns the list of volume paths for a volume. | ||||
| // https://docs.microsoft.com/en-us/windows/desktop/api/FileAPI/nf-fileapi-getvolumepathnamesforvolumenamew | ||||
| func GetVolumePathsForVolume(volumeName string) ([]string, error) { | ||||
| 	var length uint32 | ||||
| 	err := _GetVolumePathNamesForVolumeName(volumeName, nil, 0, &length) | ||||
| 	if errors.Cause(err) != syscall.ERROR_MORE_DATA { | ||||
| 		return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed to get needed buffer length") | ||||
| 	} | ||||
| 	if length == 0 { | ||||
| 		// Not mounted, no paths, that's ok | ||||
| 		return nil, nil | ||||
| 	} | ||||
|  | ||||
| 	buffer := make([]uint16, length*(MAX_PATH+1)) | ||||
| 	err = _GetVolumePathNamesForVolumeName(volumeName, &buffer[0], length, &length) | ||||
| 	if err != nil { | ||||
| 		return nil, errors.Wrap(err, "GetVolumePathNamesForVolumeNameW failed") | ||||
| 	} | ||||
|  | ||||
| 	return UTF16SliceToStringSlice(buffer), nil | ||||
| } | ||||
|  | ||||
| // GlobalMemoryStatusEx retrieves information about the system's current usage | ||||
| // of both physical and virtual memory. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa366589(v=vs.85).aspx | ||||
| func GlobalMemoryStatusEx() (MemoryStatusEx, error) { | ||||
| 	memoryStatusEx := MemoryStatusEx{length: sizeofMemoryStatusEx} | ||||
| 	err := _GlobalMemoryStatusEx(&memoryStatusEx) | ||||
| 	if err != nil { | ||||
| 		return MemoryStatusEx{}, errors.Wrap(err, "GlobalMemoryStatusEx failed") | ||||
| 	} | ||||
|  | ||||
| 	return memoryStatusEx, nil | ||||
| } | ||||
|  | ||||
| // GetProcessMemoryInfo retrieves information about the memory usage of the | ||||
| // specified process. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683219(v=vs.85).aspx | ||||
| func GetProcessMemoryInfo(handle syscall.Handle) (ProcessMemoryCountersEx, error) { | ||||
| 	processMemoryCountersEx := ProcessMemoryCountersEx{cb: sizeofProcessMemoryCountersEx} | ||||
| 	err := _GetProcessMemoryInfo(handle, &processMemoryCountersEx, processMemoryCountersEx.cb) | ||||
| 	if err != nil { | ||||
| 		return ProcessMemoryCountersEx{}, errors.Wrap(err, "GetProcessMemoryInfo failed") | ||||
| 	} | ||||
|  | ||||
| 	return processMemoryCountersEx, nil | ||||
| } | ||||
|  | ||||
| // GetProcessImageFileName Retrieves the name of the executable file for the | ||||
| // specified process. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms683217(v=vs.85).aspx | ||||
| func GetProcessImageFileName(handle syscall.Handle) (string, error) { | ||||
| 	buffer := make([]uint16, MAX_PATH) | ||||
| 	_, err := _GetProcessImageFileName(handle, &buffer[0], uint32(len(buffer))) | ||||
| 	if err != nil { | ||||
| 		return "", errors.Wrap(err, "GetProcessImageFileName failed") | ||||
| 	} | ||||
|  | ||||
| 	return syscall.UTF16ToString(buffer), nil | ||||
| } | ||||
|  | ||||
| // GetSystemTimes retrieves system timing information. On a multiprocessor | ||||
| // system, the values returned are the sum of the designated times across all | ||||
| // processors. The returned kernel time does not include the system idle time. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724400(v=vs.85).aspx | ||||
| func GetSystemTimes() (idle, kernel, user time.Duration, err error) { | ||||
| 	var idleTime, kernelTime, userTime syscall.Filetime | ||||
| 	err = _GetSystemTimes(&idleTime, &kernelTime, &userTime) | ||||
| 	if err != nil { | ||||
| 		return 0, 0, 0, errors.Wrap(err, "GetSystemTimes failed") | ||||
| 	} | ||||
|  | ||||
| 	idle = FiletimeToDuration(&idleTime) | ||||
| 	kernel = FiletimeToDuration(&kernelTime) // Kernel time includes idle time so we subtract it out. | ||||
| 	user = FiletimeToDuration(&userTime) | ||||
|  | ||||
| 	return idle, kernel - idle, user, nil | ||||
| } | ||||
|  | ||||
| // FiletimeToDuration converts a Filetime to a time.Duration. Do not use this | ||||
| // method to convert a Filetime to an actual clock time, for that use | ||||
| // Filetime.Nanosecond(). | ||||
| func FiletimeToDuration(ft *syscall.Filetime) time.Duration { | ||||
| 	n := int64(ft.HighDateTime)<<32 + int64(ft.LowDateTime) // in 100-nanosecond intervals | ||||
| 	return time.Duration(n * 100) | ||||
| } | ||||
|  | ||||
| // GetDriveType Determines whether a disk drive is a removable, fixed, CD-ROM, | ||||
| // RAM disk, or network drive. A trailing backslash is required on the | ||||
| // rootPathName. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364939 | ||||
| func GetDriveType(rootPathName string) (DriveType, error) { | ||||
| 	rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName) | ||||
| 	if err != nil { | ||||
| 		return DRIVE_UNKNOWN, errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName) | ||||
| 	} | ||||
|  | ||||
| 	dt, err := _GetDriveType(rootPathNamePtr) | ||||
| 	if err != nil { | ||||
| 		return DRIVE_UNKNOWN, errors.Wrapf(err, "GetDriveType failed for rootPathName=%v", rootPathName) | ||||
| 	} | ||||
|  | ||||
| 	return dt, nil | ||||
| } | ||||
|  | ||||
| // GetFilesystemType returns file system type information at the given root path. | ||||
| // https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getvolumeinformationw | ||||
| func GetFilesystemType(rootPathName string) (string, error) { | ||||
| 	rootPathNamePtr, err := syscall.UTF16PtrFromString(rootPathName) | ||||
| 	var systemType = "unavailable" | ||||
| 	if err != nil { | ||||
| 		return "", errors.Wrapf(err, "UTF16PtrFromString failed for rootPathName=%v", rootPathName) | ||||
| 	} | ||||
| 	buffer := make([]uint16, MAX_PATH+1) | ||||
| 	// _GetVolumeInformation will fail for external drives like CD-ROM or other type with error codes as ERROR_NOT_READY. ERROR_INVALID_FUNCTION, ERROR_INVALID_PARAMETER, etc., these types of errors will be ignored | ||||
| 	success, err := _GetVolumeInformation(rootPathNamePtr, nil, 0, nil, nil, nil, &buffer[0], MAX_PATH) | ||||
| 	if success { | ||||
| 		systemType = strings.ToLower(syscall.UTF16ToString(buffer)) | ||||
| 	} | ||||
| 	return systemType, nil | ||||
| } | ||||
|  | ||||
| // EnumProcesses retrieves the process identifier for each process object in the | ||||
| // system. This function can return a max of 65536 PIDs. If there are more | ||||
| // processes than that then this will not return them all. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682629(v=vs.85).aspx | ||||
| func EnumProcesses() ([]uint32, error) { | ||||
| 	enumProcesses := func(size int) ([]uint32, error) { | ||||
| 		var ( | ||||
| 			pids         = make([]uint32, size) | ||||
| 			sizeBytes    = len(pids) * sizeofUint32 | ||||
| 			bytesWritten uint32 | ||||
| 		) | ||||
|  | ||||
| 		err := _EnumProcesses(&pids[0], uint32(sizeBytes), &bytesWritten) | ||||
|  | ||||
| 		pidsWritten := int(bytesWritten) / sizeofUint32 | ||||
| 		if int(bytesWritten)%sizeofUint32 != 0 || pidsWritten > len(pids) { | ||||
| 			return nil, errors.Errorf("EnumProcesses returned an invalid bytesWritten value of %v", bytesWritten) | ||||
| 		} | ||||
| 		pids = pids[:pidsWritten] | ||||
|  | ||||
| 		return pids, err | ||||
| 	} | ||||
|  | ||||
| 	// Retry the EnumProcesses call with larger arrays if needed. | ||||
| 	size := 2048 | ||||
| 	var pids []uint32 | ||||
| 	for tries := 0; tries < 5; tries++ { | ||||
| 		var err error | ||||
| 		pids, err = enumProcesses(size) | ||||
| 		if err != nil { | ||||
| 			return nil, errors.Wrap(err, "EnumProcesses failed") | ||||
| 		} | ||||
|  | ||||
| 		if len(pids) < size { | ||||
| 			break | ||||
| 		} | ||||
|  | ||||
| 		// Increase the size the pids array and retry the enumProcesses call | ||||
| 		// because the array wasn't large enough to hold all of the processes. | ||||
| 		size *= 2 | ||||
| 	} | ||||
|  | ||||
| 	return pids, nil | ||||
| } | ||||
|  | ||||
| // GetDiskFreeSpaceEx retrieves information about the amount of space that is | ||||
| // available on a disk volume, which is the total amount of space, the total | ||||
| // amount of free space, and the total amount of free space available to the | ||||
| // user that is associated with the calling thread. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/aa364937(v=vs.85).aspx | ||||
| func GetDiskFreeSpaceEx(directoryName string) (freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes uint64, err error) { | ||||
| 	directoryNamePtr, err := syscall.UTF16PtrFromString(directoryName) | ||||
| 	if err != nil { | ||||
| 		return 0, 0, 0, errors.Wrapf(err, "UTF16PtrFromString failed for directoryName=%v", directoryName) | ||||
| 	} | ||||
|  | ||||
| 	err = _GetDiskFreeSpaceEx(directoryNamePtr, &freeBytesAvailable, &totalNumberOfBytes, &totalNumberOfFreeBytes) | ||||
| 	if err != nil { | ||||
| 		return 0, 0, 0, err | ||||
| 	} | ||||
|  | ||||
| 	return freeBytesAvailable, totalNumberOfBytes, totalNumberOfFreeBytes, nil | ||||
| } | ||||
|  | ||||
| // CreateToolhelp32Snapshot takes a snapshot of the specified processes, as well | ||||
| // as the heaps, modules, and threads used by these processes. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms682489(v=vs.85).aspx | ||||
| func CreateToolhelp32Snapshot(flags, pid uint32) (syscall.Handle, error) { | ||||
| 	h, err := _CreateToolhelp32Snapshot(flags, pid) | ||||
| 	if err != nil { | ||||
| 		return syscall.InvalidHandle, err | ||||
| 	} | ||||
| 	if h == syscall.InvalidHandle { | ||||
| 		return syscall.InvalidHandle, syscall.GetLastError() | ||||
| 	} | ||||
|  | ||||
| 	return h, nil | ||||
| } | ||||
|  | ||||
| // Process32First retrieves information about the first process encountered in a | ||||
| // system snapshot. | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684834 | ||||
| func Process32First(handle syscall.Handle) (ProcessEntry32, error) { | ||||
| 	processEntry32 := ProcessEntry32{size: sizeofProcessEntry32} | ||||
| 	err := _Process32First(handle, &processEntry32) | ||||
| 	if err != nil { | ||||
| 		return ProcessEntry32{}, errors.Wrap(err, "Process32First failed") | ||||
| 	} | ||||
|  | ||||
| 	return processEntry32, nil | ||||
| } | ||||
|  | ||||
| // Process32Next retrieves information about the next process recorded in a | ||||
| // system snapshot. When there are no more processes to iterate then | ||||
| // syscall.ERROR_NO_MORE_FILES is returned (use errors.Cause() to unwrap). | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms684836 | ||||
| func Process32Next(handle syscall.Handle) (ProcessEntry32, error) { | ||||
| 	processEntry32 := ProcessEntry32{size: sizeofProcessEntry32} | ||||
| 	err := _Process32Next(handle, &processEntry32) | ||||
| 	if err != nil { | ||||
| 		return ProcessEntry32{}, errors.Wrap(err, "Process32Next failed") | ||||
| 	} | ||||
|  | ||||
| 	return processEntry32, nil | ||||
| } | ||||
|  | ||||
| // UTF16SliceToStringSlice converts slice of uint16 containing a list of UTF16 | ||||
| // strings to a slice of strings. | ||||
| func UTF16SliceToStringSlice(buffer []uint16) []string { | ||||
| 	// Split the uint16 slice at null-terminators. | ||||
| 	var startIdx int | ||||
| 	var stringsUTF16 [][]uint16 | ||||
| 	for i, value := range buffer { | ||||
| 		if value == 0 { | ||||
| 			stringsUTF16 = append(stringsUTF16, buffer[startIdx:i]) | ||||
| 			startIdx = i + 1 | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	// Convert the utf16 slices to strings. | ||||
| 	result := make([]string, 0, len(stringsUTF16)) | ||||
| 	for _, stringUTF16 := range stringsUTF16 { | ||||
| 		if len(stringUTF16) > 0 { | ||||
| 			result = append(result, syscall.UTF16ToString(stringUTF16)) | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	return result | ||||
| } | ||||
|  | ||||
| func GetUserProcessParams(handle syscall.Handle, pbi ProcessBasicInformation) (params RtlUserProcessParameters, err error) { | ||||
| 	const is32bitProc = unsafe.Sizeof(uintptr(0)) == 4 | ||||
|  | ||||
| 	// Offset of params field within PEB structure. | ||||
| 	// This structure is different in 32 and 64 bit. | ||||
| 	paramsOffset := 0x20 | ||||
| 	if is32bitProc { | ||||
| 		paramsOffset = 0x10 | ||||
| 	} | ||||
|  | ||||
| 	// Read the PEB from the target process memory | ||||
| 	pebSize := paramsOffset + 8 | ||||
| 	peb := make([]byte, pebSize) | ||||
| 	nRead, err := ReadProcessMemory(handle, pbi.PebBaseAddress, peb) | ||||
| 	if err != nil { | ||||
| 		return params, err | ||||
| 	} | ||||
| 	if nRead != uintptr(pebSize) { | ||||
| 		return params, errors.Errorf("PEB: short read (%d/%d)", nRead, pebSize) | ||||
| 	} | ||||
|  | ||||
| 	// Get the RTL_USER_PROCESS_PARAMETERS struct pointer from the PEB | ||||
| 	paramsAddr := *(*uintptr)(unsafe.Pointer(&peb[paramsOffset])) | ||||
|  | ||||
| 	// Read the RTL_USER_PROCESS_PARAMETERS from the target process memory | ||||
| 	paramsBuf := make([]byte, SizeOfRtlUserProcessParameters) | ||||
| 	nRead, err = ReadProcessMemory(handle, paramsAddr, paramsBuf) | ||||
| 	if err != nil { | ||||
| 		return params, err | ||||
| 	} | ||||
| 	if nRead != uintptr(SizeOfRtlUserProcessParameters) { | ||||
| 		return params, errors.Errorf("RTL_USER_PROCESS_PARAMETERS: short read (%d/%d)", nRead, SizeOfRtlUserProcessParameters) | ||||
| 	} | ||||
|  | ||||
| 	params = *(*RtlUserProcessParameters)(unsafe.Pointer(¶msBuf[0])) | ||||
| 	return params, nil | ||||
| } | ||||
|  | ||||
| // ReadProcessUnicodeString returns a zero-terminated UTF-16 string from another | ||||
| // process's memory. | ||||
| func ReadProcessUnicodeString(handle syscall.Handle, s *UnicodeString) ([]byte, error) { | ||||
| 	// Allocate an extra UTF-16 null character at the end in case the read string | ||||
| 	// is not terminated. | ||||
| 	extra := 2 | ||||
| 	if s.Size&1 != 0 { | ||||
| 		extra = 3 // If size is odd, need 3 nulls to terminate. | ||||
| 	} | ||||
| 	buf := make([]byte, int(s.Size)+extra) | ||||
| 	nRead, err := ReadProcessMemory(handle, s.Buffer, buf[:s.Size]) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	if nRead != uintptr(s.Size) { | ||||
| 		return nil, errors.Errorf("unicode string: short read: (%d/%d)", nRead, s.Size) | ||||
| 	} | ||||
| 	return buf, nil | ||||
| } | ||||
|  | ||||
| // ByteSliceToStringSlice uses CommandLineToArgv API to split an UTF-16 command | ||||
| // line string into a list of parameters. | ||||
| func ByteSliceToStringSlice(utf16 []byte) ([]string, error) { | ||||
| 	n := len(utf16) | ||||
| 	// Discard odd byte | ||||
| 	if n&1 != 0 { | ||||
| 		n-- | ||||
| 		utf16 = utf16[:n] | ||||
| 	} | ||||
| 	if n == 0 { | ||||
| 		return nil, nil | ||||
| 	} | ||||
| 	terminated := false | ||||
| 	for i := 0; i < n && !terminated; i += 2 { | ||||
| 		terminated = utf16[i] == 0 && utf16[i+1] == 0 | ||||
| 	} | ||||
| 	if !terminated { | ||||
| 		// Append a null uint16 at the end if terminator is missing | ||||
| 		utf16 = append(utf16, 0, 0) | ||||
| 	} | ||||
| 	var numArgs int32 | ||||
| 	argsWide, err := syscall.CommandLineToArgv((*uint16)(unsafe.Pointer(&utf16[0])), &numArgs) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
|  | ||||
| 	// Free memory allocated for CommandLineToArgvW arguments. | ||||
| 	defer syscall.LocalFree((syscall.Handle)(unsafe.Pointer(argsWide))) | ||||
|  | ||||
| 	args := make([]string, numArgs) | ||||
| 	for idx := range args { | ||||
| 		args[idx] = syscall.UTF16ToString(argsWide[idx][:]) | ||||
| 	} | ||||
| 	return args, nil | ||||
| } | ||||
|  | ||||
| // ReadProcessMemory reads from another process memory. The Handle needs to have | ||||
| // the PROCESS_VM_READ right. | ||||
| // A zero-byte read is a no-op, no error is returned. | ||||
| func ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, dest []byte) (numRead uintptr, err error) { | ||||
| 	n := len(dest) | ||||
| 	if n == 0 { | ||||
| 		return 0, nil | ||||
| 	} | ||||
| 	if err = _ReadProcessMemory(handle, baseAddress, uintptr(unsafe.Pointer(&dest[0])), uintptr(n), &numRead); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return numRead, nil | ||||
| } | ||||
|  | ||||
| func GetTickCount64() (uptime uint64, err error) { | ||||
| 	if uptime, err = _GetTickCount64(); err != nil { | ||||
| 		return 0, err | ||||
| 	} | ||||
| 	return uptime, nil | ||||
| } | ||||
|  | ||||
| // Windows API calls | ||||
| //sys   _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) = kernel32.GlobalMemoryStatusEx | ||||
| //sys   _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) = kernel32.GetLogicalDriveStringsW | ||||
| //sys   _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) = psapi.GetProcessMemoryInfo | ||||
| //sys   _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) = psapi.GetProcessImageFileNameW | ||||
| //sys   _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) = kernel32.GetSystemTimes | ||||
| //sys   _GetDriveType(rootPathName *uint16) (dt DriveType, err error) = kernel32.GetDriveTypeW | ||||
| //sys   _GetVolumeInformation(rootPathName *uint16, volumeName *uint16, volumeNameSize uint32, volumeSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemName *uint16, fileSystemNameSize uint32) (success bool, err error) [true] = kernel32.GetVolumeInformationW | ||||
| //sys   _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) = psapi.EnumProcesses | ||||
| //sys   _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) = kernel32.GetDiskFreeSpaceExW | ||||
| //sys   _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32FirstW | ||||
| //sys   _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) = kernel32.Process32NextW | ||||
| //sys   _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) = kernel32.CreateToolhelp32Snapshot | ||||
| //sys   _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQuerySystemInformation | ||||
| //sys   _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) = ntdll.NtQueryInformationProcess | ||||
| //sys   _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) = advapi32.LookupPrivilegeNameW | ||||
| //sys   _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) = advapi32.LookupPrivilegeValueW | ||||
| //sys   _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) [true] = advapi32.AdjustTokenPrivileges | ||||
| //sys   _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) = kernel32.FindFirstVolumeW | ||||
| //sys  _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) = kernel32.FindNextVolumeW | ||||
| //sys  _FindVolumeClose(handle syscall.Handle) (err error) = kernel32.FindVolumeClose | ||||
| //sys  _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) = kernel32.GetVolumePathNamesForVolumeNameW | ||||
| //sys  _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) = kernel32.ReadProcessMemory | ||||
| //sys  _GetTickCount64() (uptime uint64, err error) = kernel32.GetTickCount64 | ||||
							
								
								
									
										43
									
								
								vendor/github.com/elastic/gosigar/sys/windows/version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								vendor/github.com/elastic/gosigar/sys/windows/version.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,43 @@ | ||||
| // +build windows | ||||
|  | ||||
| package windows | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"syscall" | ||||
| ) | ||||
|  | ||||
| // Version identifies a Windows version by major, minor, and build number. | ||||
| type Version struct { | ||||
| 	Major int | ||||
| 	Minor int | ||||
| 	Build int | ||||
| } | ||||
|  | ||||
| // GetWindowsVersion returns the Windows version information. Applications not | ||||
| // manifested for Windows 8.1 or Windows 10 will return the Windows 8 OS version | ||||
| // value (6.2). | ||||
| // | ||||
| // For a table of version numbers see: | ||||
| // https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx | ||||
| func GetWindowsVersion() Version { | ||||
| 	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724439(v=vs.85).aspx | ||||
| 	ver, err := syscall.GetVersion() | ||||
| 	if err != nil { | ||||
| 		// GetVersion should never return an error. | ||||
| 		panic(fmt.Errorf("GetVersion failed: %v", err)) | ||||
| 	} | ||||
|  | ||||
| 	return Version{ | ||||
| 		Major: int(ver & 0xFF), | ||||
| 		Minor: int(ver >> 8 & 0xFF), | ||||
| 		Build: int(ver >> 16), | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // IsWindowsVistaOrGreater returns true if the Windows version is Vista or | ||||
| // greater. | ||||
| func (v Version) IsWindowsVistaOrGreater() bool { | ||||
| 	// Vista is 6.0. | ||||
| 	return v.Major >= 6 && v.Minor >= 0 | ||||
| } | ||||
							
								
								
									
										299
									
								
								vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										299
									
								
								vendor/github.com/elastic/gosigar/sys/windows/zsyscall_windows.go
									
									
									
										generated
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,299 @@ | ||||
| // Code generated by 'go generate'; DO NOT EDIT. | ||||
|  | ||||
| package windows | ||||
|  | ||||
| import ( | ||||
| 	"syscall" | ||||
| 	"unsafe" | ||||
|  | ||||
| 	"golang.org/x/sys/windows" | ||||
| ) | ||||
|  | ||||
| var _ unsafe.Pointer | ||||
|  | ||||
| // Do the interface allocations only once for common | ||||
| // Errno values. | ||||
| const ( | ||||
| 	errnoERROR_IO_PENDING = 997 | ||||
| ) | ||||
|  | ||||
| var ( | ||||
| 	errERROR_IO_PENDING error = syscall.Errno(errnoERROR_IO_PENDING) | ||||
| 	errERROR_EINVAL     error = syscall.EINVAL | ||||
| ) | ||||
|  | ||||
| // errnoErr returns common boxed Errno values, to prevent | ||||
| // allocations at runtime. | ||||
| func errnoErr(e syscall.Errno) error { | ||||
| 	switch e { | ||||
| 	case 0: | ||||
| 		return errERROR_EINVAL | ||||
| 	case errnoERROR_IO_PENDING: | ||||
| 		return errERROR_IO_PENDING | ||||
| 	} | ||||
| 	// TODO: add more here, after collecting data on the common | ||||
| 	// error values see on Windows. (perhaps when running | ||||
| 	// all.bat?) | ||||
| 	return e | ||||
| } | ||||
|  | ||||
| var ( | ||||
| 	modadvapi32 = windows.NewLazySystemDLL("advapi32.dll") | ||||
| 	modkernel32 = windows.NewLazySystemDLL("kernel32.dll") | ||||
| 	modntdll    = windows.NewLazySystemDLL("ntdll.dll") | ||||
| 	modpsapi    = windows.NewLazySystemDLL("psapi.dll") | ||||
|  | ||||
| 	procAdjustTokenPrivileges            = modadvapi32.NewProc("AdjustTokenPrivileges") | ||||
| 	procLookupPrivilegeNameW             = modadvapi32.NewProc("LookupPrivilegeNameW") | ||||
| 	procLookupPrivilegeValueW            = modadvapi32.NewProc("LookupPrivilegeValueW") | ||||
| 	procCreateToolhelp32Snapshot         = modkernel32.NewProc("CreateToolhelp32Snapshot") | ||||
| 	procFindFirstVolumeW                 = modkernel32.NewProc("FindFirstVolumeW") | ||||
| 	procFindNextVolumeW                  = modkernel32.NewProc("FindNextVolumeW") | ||||
| 	procFindVolumeClose                  = modkernel32.NewProc("FindVolumeClose") | ||||
| 	procGetDiskFreeSpaceExW              = modkernel32.NewProc("GetDiskFreeSpaceExW") | ||||
| 	procGetDriveTypeW                    = modkernel32.NewProc("GetDriveTypeW") | ||||
| 	procGetLogicalDriveStringsW          = modkernel32.NewProc("GetLogicalDriveStringsW") | ||||
| 	procGetSystemTimes                   = modkernel32.NewProc("GetSystemTimes") | ||||
| 	procGetTickCount64                   = modkernel32.NewProc("GetTickCount64") | ||||
| 	procGetVolumeInformationW            = modkernel32.NewProc("GetVolumeInformationW") | ||||
| 	procGetVolumePathNamesForVolumeNameW = modkernel32.NewProc("GetVolumePathNamesForVolumeNameW") | ||||
| 	procGlobalMemoryStatusEx             = modkernel32.NewProc("GlobalMemoryStatusEx") | ||||
| 	procProcess32FirstW                  = modkernel32.NewProc("Process32FirstW") | ||||
| 	procProcess32NextW                   = modkernel32.NewProc("Process32NextW") | ||||
| 	procReadProcessMemory                = modkernel32.NewProc("ReadProcessMemory") | ||||
| 	procNtQueryInformationProcess        = modntdll.NewProc("NtQueryInformationProcess") | ||||
| 	procNtQuerySystemInformation         = modntdll.NewProc("NtQuerySystemInformation") | ||||
| 	procEnumProcesses                    = modpsapi.NewProc("EnumProcesses") | ||||
| 	procGetProcessImageFileNameW         = modpsapi.NewProc("GetProcessImageFileNameW") | ||||
| 	procGetProcessMemoryInfo             = modpsapi.NewProc("GetProcessMemoryInfo") | ||||
| ) | ||||
|  | ||||
| func _AdjustTokenPrivileges(token syscall.Token, releaseAll bool, input *byte, outputSize uint32, output *byte, requiredSize *uint32) (success bool, err error) { | ||||
| 	var _p0 uint32 | ||||
| 	if releaseAll { | ||||
| 		_p0 = 1 | ||||
| 	} | ||||
| 	r0, _, e1 := syscall.Syscall6(procAdjustTokenPrivileges.Addr(), 6, uintptr(token), uintptr(_p0), uintptr(unsafe.Pointer(input)), uintptr(outputSize), uintptr(unsafe.Pointer(output)), uintptr(unsafe.Pointer(requiredSize))) | ||||
| 	success = r0 != 0 | ||||
| 	if true { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _LookupPrivilegeName(systemName string, luid *int64, buffer *uint16, size *uint32) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(systemName) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return __LookupPrivilegeName(_p0, luid, buffer, size) | ||||
| } | ||||
|  | ||||
| func __LookupPrivilegeName(systemName *uint16, luid *int64, buffer *uint16, size *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procLookupPrivilegeNameW.Addr(), 4, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(luid)), uintptr(unsafe.Pointer(buffer)), uintptr(unsafe.Pointer(size)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _LookupPrivilegeValue(systemName string, name string, luid *int64) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(systemName) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	var _p1 *uint16 | ||||
| 	_p1, err = syscall.UTF16PtrFromString(name) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return __LookupPrivilegeValue(_p0, _p1, luid) | ||||
| } | ||||
|  | ||||
| func __LookupPrivilegeValue(systemName *uint16, name *uint16, luid *int64) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procLookupPrivilegeValueW.Addr(), 3, uintptr(unsafe.Pointer(systemName)), uintptr(unsafe.Pointer(name)), uintptr(unsafe.Pointer(luid))) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _CreateToolhelp32Snapshot(flags uint32, processID uint32) (handle syscall.Handle, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall(procCreateToolhelp32Snapshot.Addr(), 2, uintptr(flags), uintptr(processID), 0) | ||||
| 	handle = syscall.Handle(r0) | ||||
| 	if handle == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _FindFirstVolume(volumeName *uint16, size uint32) (handle syscall.Handle, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall(procFindFirstVolumeW.Addr(), 2, uintptr(unsafe.Pointer(volumeName)), uintptr(size), 0) | ||||
| 	handle = syscall.Handle(r0) | ||||
| 	if handle == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _FindNextVolume(handle syscall.Handle, volumeName *uint16, size uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procFindNextVolumeW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(volumeName)), uintptr(size)) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _FindVolumeClose(handle syscall.Handle) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procFindVolumeClose.Addr(), 1, uintptr(handle), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetDiskFreeSpaceEx(directoryName *uint16, freeBytesAvailable *uint64, totalNumberOfBytes *uint64, totalNumberOfFreeBytes *uint64) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procGetDiskFreeSpaceExW.Addr(), 4, uintptr(unsafe.Pointer(directoryName)), uintptr(unsafe.Pointer(freeBytesAvailable)), uintptr(unsafe.Pointer(totalNumberOfBytes)), uintptr(unsafe.Pointer(totalNumberOfFreeBytes)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetDriveType(rootPathName *uint16) (dt DriveType, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall(procGetDriveTypeW.Addr(), 1, uintptr(unsafe.Pointer(rootPathName)), 0, 0) | ||||
| 	dt = DriveType(r0) | ||||
| 	if dt == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetLogicalDriveStringsW(bufferLength uint32, buffer *uint16) (length uint32, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall(procGetLogicalDriveStringsW.Addr(), 2, uintptr(bufferLength), uintptr(unsafe.Pointer(buffer)), 0) | ||||
| 	length = uint32(r0) | ||||
| 	if length == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetSystemTimes(idleTime *syscall.Filetime, kernelTime *syscall.Filetime, userTime *syscall.Filetime) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procGetSystemTimes.Addr(), 3, uintptr(unsafe.Pointer(idleTime)), uintptr(unsafe.Pointer(kernelTime)), uintptr(unsafe.Pointer(userTime))) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetTickCount64() (uptime uint64, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall(procGetTickCount64.Addr(), 0, 0, 0, 0) | ||||
| 	uptime = uint64(r0) | ||||
| 	if uptime == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetVolumeInformation(rootPathName *uint16, volumeName *uint16, volumeNameSize uint32, volumeSerialNumber *uint32, maximumComponentLength *uint32, fileSystemFlags *uint32, fileSystemName *uint16, fileSystemNameSize uint32) (success bool, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall9(procGetVolumeInformationW.Addr(), 8, uintptr(unsafe.Pointer(rootPathName)), uintptr(unsafe.Pointer(volumeName)), uintptr(volumeNameSize), uintptr(unsafe.Pointer(volumeSerialNumber)), uintptr(unsafe.Pointer(maximumComponentLength)), uintptr(unsafe.Pointer(fileSystemFlags)), uintptr(unsafe.Pointer(fileSystemName)), uintptr(fileSystemNameSize), 0) | ||||
| 	success = r0 != 0 | ||||
| 	if true { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetVolumePathNamesForVolumeName(volumeName string, buffer *uint16, bufferSize uint32, length *uint32) (err error) { | ||||
| 	var _p0 *uint16 | ||||
| 	_p0, err = syscall.UTF16PtrFromString(volumeName) | ||||
| 	if err != nil { | ||||
| 		return | ||||
| 	} | ||||
| 	return __GetVolumePathNamesForVolumeName(_p0, buffer, bufferSize, length) | ||||
| } | ||||
|  | ||||
| func __GetVolumePathNamesForVolumeName(volumeName *uint16, buffer *uint16, bufferSize uint32, length *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procGetVolumePathNamesForVolumeNameW.Addr(), 4, uintptr(unsafe.Pointer(volumeName)), uintptr(unsafe.Pointer(buffer)), uintptr(bufferSize), uintptr(unsafe.Pointer(length)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GlobalMemoryStatusEx(buffer *MemoryStatusEx) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procGlobalMemoryStatusEx.Addr(), 1, uintptr(unsafe.Pointer(buffer)), 0, 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _Process32First(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procProcess32FirstW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _Process32Next(handle syscall.Handle, processEntry32 *ProcessEntry32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procProcess32NextW.Addr(), 2, uintptr(handle), uintptr(unsafe.Pointer(processEntry32)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _ReadProcessMemory(handle syscall.Handle, baseAddress uintptr, buffer uintptr, size uintptr, numRead *uintptr) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall6(procReadProcessMemory.Addr(), 5, uintptr(handle), uintptr(baseAddress), uintptr(buffer), uintptr(size), uintptr(unsafe.Pointer(numRead)), 0) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _NtQueryInformationProcess(processHandle syscall.Handle, processInformationClass uint32, processInformation *byte, processInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall6(procNtQueryInformationProcess.Addr(), 5, uintptr(processHandle), uintptr(processInformationClass), uintptr(unsafe.Pointer(processInformation)), uintptr(processInformationLength), uintptr(unsafe.Pointer(returnLength)), 0) | ||||
| 	ntstatus = uint32(r0) | ||||
| 	if ntstatus == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _NtQuerySystemInformation(systemInformationClass uint32, systemInformation *byte, systemInformationLength uint32, returnLength *uint32) (ntstatus uint32, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall6(procNtQuerySystemInformation.Addr(), 4, uintptr(systemInformationClass), uintptr(unsafe.Pointer(systemInformation)), uintptr(systemInformationLength), uintptr(unsafe.Pointer(returnLength)), 0, 0) | ||||
| 	ntstatus = uint32(r0) | ||||
| 	if ntstatus == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _EnumProcesses(processIds *uint32, sizeBytes uint32, bytesReturned *uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procEnumProcesses.Addr(), 3, uintptr(unsafe.Pointer(processIds)), uintptr(sizeBytes), uintptr(unsafe.Pointer(bytesReturned))) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetProcessImageFileName(handle syscall.Handle, outImageFileName *uint16, size uint32) (length uint32, err error) { | ||||
| 	r0, _, e1 := syscall.Syscall(procGetProcessImageFileNameW.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(outImageFileName)), uintptr(size)) | ||||
| 	length = uint32(r0) | ||||
| 	if length == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
|  | ||||
| func _GetProcessMemoryInfo(handle syscall.Handle, psmemCounters *ProcessMemoryCountersEx, cb uint32) (err error) { | ||||
| 	r1, _, e1 := syscall.Syscall(procGetProcessMemoryInfo.Addr(), 3, uintptr(handle), uintptr(unsafe.Pointer(psmemCounters)), uintptr(cb)) | ||||
| 	if r1 == 0 { | ||||
| 		err = errnoErr(e1) | ||||
| 	} | ||||
| 	return | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 anthonyrawlins
					anthonyrawlins