Ejemplo n.º 1
0
// Load
//
// If there is an error, it will be of type *Error.
func (mgc *Magic) Load(files ...string) (bool, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return false, mgc.error()
	}

	var cfiles *C.char
	runtime.KeepAlive(cfiles)
	defer C.free(unsafe.Pointer(cfiles))

	// Assemble the list of custom Magic files into a colon-separated
	// list that is required by the underlying Magic library, otherwise
	// defer to the default list of paths provided by the Magic library.
	if len(files) > 0 {
		cfiles = C.CString(strings.Join(files, ":"))
	} else {
		cfiles = C.magic_getpath_wrapper()
	}

	if rv := C.magic_load_wrapper(mgc.cookie, cfiles, C.int(mgc.flags)); rv < 0 {
		return false, mgc.error()
	}
	mgc.path = strings.Split(C.GoString(cfiles), ":")
	return true, nil
}
Ejemplo n.º 2
0
// File
//
// If there is an error, it will be of type *Error.
func (mgc *Magic) File(filename string) (string, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return "", mgc.error()
	}

	cfilename := C.CString(filename)
	runtime.KeepAlive(cfilename)
	defer C.free(unsafe.Pointer(cfilename))

	cstring := C.magic_file_wrapper(mgc.cookie, cfilename, C.int(mgc.flags))
	if cstring == nil {
		rv, err := Version()
		if err != nil && err.(*Error).Errno != int(syscall.ENOSYS) {
			return "", err
		}

		// Handle the case when the "ERROR" flag is set regardless
		// of the current version of the underlying Magic library.
		//
		// Prior to version 5.15 the correct behaviour that concerns
		// the following IEEE 1003.1 standards was broken:
		//
		//   http://pubs.opengroup.org/onlinepubs/007904975/utilities/file.html
		//   http://pubs.opengroup.org/onlinepubs/9699919799/utilities/file.html
		//
		// This is an attempt to mitigate the problem and correct
		// it to achieve the desired behaviour as per the standards.
		if mgc.flags&ERROR != 0 {
			return "", mgc.error()
		} else if rv < 515 {
			C.magic_errno(mgc.cookie)
			cstring = C.magic_error(mgc.cookie)
		}
	}

	// XXX(kwilczynski): This case should not happen, ever.
	if cstring == nil {
		return "", &Error{-1, "unknown result or nil pointer"}
	}

	// Depending on the version of the underlying
	// Magic library the magic_file() function can
	// fail and either yield no results or return
	// the "(null)" string instead.  Often this
	// would indicate that an older version of
	// the Magic library is in use.
	s := C.GoString(cstring)
	if s == "" || s == "(null)" {
		return "", &Error{-1, "empty or invalid result"}
	}
	return s, nil
}
Ejemplo n.º 3
0
func CreateJobObject(sa *syscall.SecurityAttributes, name *uint16) (syscall.Handle, error) {
	r1, _, e1 := procCreateJobObjectW.Call(
		uintptr(unsafe.Pointer(sa)),
		uintptr(unsafe.Pointer(name)))
	runtime.KeepAlive(sa)
	runtime.KeepAlive(name)
	if int(r1) == 0 {
		return syscall.InvalidHandle, os.NewSyscallError("CreateJobObject", e1)
	}
	return syscall.Handle(r1), nil
}
Ejemplo n.º 4
0
func SetUserObjectSecurity(obj syscall.Handle, sid uint32, desc []byte) error {
	r1, _, e1 := procSetUserObjectSecurity.Call(
		uintptr(obj),
		uintptr(unsafe.Pointer(&sid)),
		uintptr(unsafe.Pointer(&desc[0])))
	runtime.KeepAlive(&sid)
	runtime.KeepAlive(&desc)
	if int(r1) == 0 {
		return os.NewSyscallError("SetUserObjectSecurity", e1)
	}
	return nil
}
Ejemplo n.º 5
0
func AddAccessAllowedAce(acl *Acl, revision, mask uint32, sid *syscall.SID) error {
	r1, _, e1 := procAddAccessAllowedAce.Call(
		uintptr(unsafe.Pointer(acl)),
		uintptr(revision),
		uintptr(mask),
		uintptr(unsafe.Pointer(sid)))
	runtime.KeepAlive(acl)
	runtime.KeepAlive(sid)
	if int(r1) == 0 {
		return os.NewSyscallError("AddAccessAllowedAce", e1)
	}
	return nil
}
Ejemplo n.º 6
0
func SetSecurityDescriptorDacl(sd []byte, present bool, acl *Acl, defaulted bool) error {
	r1, _, e1 := procSetSecurityDescriptorDacl.Call(
		uintptr(unsafe.Pointer(&sd[0])),
		uintptr(boolToUint32(present)),
		uintptr(unsafe.Pointer(acl)),
		uintptr(boolToUint32(defaulted)))
	runtime.KeepAlive(sd)
	runtime.KeepAlive(acl)
	if int(r1) == 0 {
		return os.NewSyscallError("SetSecurityDescriptorDacl", e1)
	}
	return nil
}
Ejemplo n.º 7
0
func CreateWindowStation(winsta *uint16, flags, desiredAccess uint32, sa *syscall.SecurityAttributes) (Hwinsta, error) {
	r1, _, e1 := procCreateWindowStationW.Call(
		uintptr(unsafe.Pointer(winsta)),
		uintptr(flags),
		uintptr(desiredAccess),
		uintptr(unsafe.Pointer(sa)))
	runtime.KeepAlive(winsta)
	runtime.KeepAlive(sa)
	if int(r1) == 0 {
		return Hwinsta(r1), os.NewSyscallError("CreateWindowStation", e1)
	}
	return Hwinsta(r1), nil
}
Ejemplo n.º 8
0
func AddAce(acl *Acl, revision, startIndex uint32, ace *Ace, size uint32) error {
	r1, _, e1 := procAddAce.Call(
		uintptr(unsafe.Pointer(acl)),
		uintptr(revision),
		uintptr(startIndex),
		uintptr(unsafe.Pointer(ace)),
		uintptr(size))
	runtime.KeepAlive(acl)
	runtime.KeepAlive(ace)
	if int(r1) == 0 {
		return os.NewSyscallError("AddAce", e1)
	}
	return nil
}
Ejemplo n.º 9
0
func f(x *big, start int64) {
	if delta := inuse() - start; delta < 9<<20 {
		println("after alloc: expected delta at least 9MB, got: ", delta)
	}
	runtime.KeepAlive(x)
	x = nil
	if delta := inuse() - start; delta > 1<<20 {
		println("after drop: expected delta below 1MB, got: ", delta)
	}
	x = new(big)
	if delta := inuse() - start; delta < 9<<20 {
		println("second alloc: expected delta at least 9MB, got: ", delta)
	}
	runtime.KeepAlive(x)
}
Ejemplo n.º 10
0
func CreateDesktop(desktop, device *uint16, devmode uintptr, flags, desiredAccess uint32, sa *syscall.SecurityAttributes) (Hdesk, error) {
	r1, _, e1 := procCreateDesktopW.Call(
		uintptr(unsafe.Pointer(desktop)),
		uintptr(unsafe.Pointer(device)),
		devmode,
		uintptr(flags),
		uintptr(desiredAccess),
		uintptr(unsafe.Pointer(sa)))
	runtime.KeepAlive(desktop)
	runtime.KeepAlive(device)
	runtime.KeepAlive(sa)
	if int(r1) == 0 {
		return Hdesk(r1), os.NewSyscallError("CreateDesktop", e1)
	}
	return Hdesk(r1), nil
}
Ejemplo n.º 11
0
func (pd *pollDesc) evict() {
	pd.closing = true
	if pd.fd != nil {
		syscall.StopIO(pd.fd.sysfd)
		runtime.KeepAlive(pd.fd)
	}
}
Ejemplo n.º 12
0
func LogonUser(username *uint16, domain *uint16, password *uint16, logonType uint32, logonProvider uint32) (token syscall.Handle, err error) {
	r1, _, e1 := procLogonUserW.Call(
		uintptr(unsafe.Pointer(username)),
		uintptr(unsafe.Pointer(domain)),
		uintptr(unsafe.Pointer(password)),
		uintptr(logonType),
		uintptr(logonProvider),
		uintptr(unsafe.Pointer(&token)))
	runtime.KeepAlive(username)
	runtime.KeepAlive(domain)
	runtime.KeepAlive(password)
	if int(r1) == 0 {
		return syscall.InvalidHandle, os.NewSyscallError("LogonUser", e1)
	}
	return
}
Ejemplo n.º 13
0
// FlagsSlice returns a slice containing each distinct flag that
// is currently set and included as a part of the current value
// (bitmask) of flags.  Results are sorted in an ascending order.
// If there is an error, it will be of type *Error.
func (mgc *Magic) FlagsSlice() ([]int, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return []int{}, mgc.error()
	}

	if mgc.flags == 0 {
		return []int{0}, nil
	}

	var n int
	var flags []int

	// Split current value (bitmask) into a list
	// of distinct flags (bits) currently set.
	for i := mgc.flags; i > 0; i = i - n {
		n = int(math.Log2(float64(i)))
		n = int(math.Pow(2, float64(n)))
		flags = append(flags, n)
	}
	sort.Ints(flags)
	return flags, nil
}
Ejemplo n.º 14
0
func InitializeSecurityDescriptor(sd []byte) error {
	r1, _, e1 := procInitializeSecurityDescriptor.Call(
		uintptr(unsafe.Pointer(&sd[0])),
		SECURITY_DESCRIPTOR_REVISION)
	runtime.KeepAlive(sd)
	if int(r1) == 0 {
		return os.NewSyscallError("InitializeSecurityDescriptor", e1)
	}
	return nil
}
Ejemplo n.º 15
0
func (pd *pollDesc) init(fd *netFD) error {
	serverInit.Do(runtime_pollServerInit)
	ctx, errno := runtime_pollOpen(uintptr(fd.sysfd))
	runtime.KeepAlive(fd)
	if errno != 0 {
		return syscall.Errno(errno)
	}
	pd.runtimeCtx = ctx
	return nil
}
Ejemplo n.º 16
0
// Flags returns a value (bitmask) representing current flags set.
// If there is an error, it will be of type *Error.
func (mgc *Magic) Flags() (int, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return -1, mgc.error()
	}
	return mgc.flags, nil
}
Ejemplo n.º 17
0
func GetUserObjectSecurity_Ex(obj syscall.Handle, sid uint32, desc []byte) (uint32, error) {
	var nLength uint32
	var nptr uintptr
	if desc != nil {
		nptr = uintptr(unsafe.Pointer(&desc[0]))
	}
	r1, _, e1 := procGetUserObjectSecurity.Call(
		uintptr(obj),
		uintptr(unsafe.Pointer(&sid)),
		nptr,
		uintptr(len(desc)),
		uintptr(unsafe.Pointer(&nLength)))
	runtime.KeepAlive(&sid)
	runtime.KeepAlive(&nLength)
	if int(r1) == 0 {
		return nLength, os.NewSyscallError("GetUserObjectSecurity", e1)
	}
	return nLength, nil
}
Ejemplo n.º 18
0
func LoadUserProfile(token syscall.Handle, pinfo *ProfileInfo) error {
	r1, _, e1 := procLoadUserProfileW.Call(
		uintptr(token),
		uintptr(unsafe.Pointer(pinfo)))
	runtime.KeepAlive(pinfo)
	if int(r1) == 0 {
		return os.NewSyscallError("LoadUserProfile", e1)
	}
	return nil
}
Ejemplo n.º 19
0
func InitializeAcl(acl *Acl, length, revision uint32) error {
	r1, _, e1 := procInitializeAcl.Call(
		uintptr(unsafe.Pointer(acl)),
		uintptr(length),
		uintptr(revision))
	runtime.KeepAlive(acl)
	if int(r1) == 0 {
		return os.NewSyscallError("InitializeAcl", e1)
	}
	return nil
}
Ejemplo n.º 20
0
func GetAce(acl *Acl, index uint32) (*Ace, error) {
	var result *Ace
	r1, _, e1 := procGetAce.Call(
		uintptr(unsafe.Pointer(acl)),
		uintptr(index),
		uintptr(unsafe.Pointer(&result)))
	runtime.KeepAlive(acl)
	if int(r1) == 0 {
		return nil, os.NewSyscallError("GetAce", e1)
	}
	return result, nil
}
Ejemplo n.º 21
0
// New opens and initializes Magic library.
//
// Optionally, a multiple distinct Magic database files can
// be provided to load, otherwise a default database (usually
// available system-wide) will be loaded.  Alternatively, the
// "MAGIC" environment variable can be used to name any desired
// Magic database files to be loaded, but it must be set prior
// to calling this function for it to take effect.
//
// Remember to call Close to release initialized resources
// and close currently opened Magic library, or use Open which
// will ensure that Close is called once the closure finishes.
//
// If there is an error originating from the underlying Magic
// library, it will be of type *Error.
func New(files ...string) (*Magic, error) {
	mgc, err := open()
	if err != nil {
		return nil, err
	}
	runtime.KeepAlive(mgc.magic)

	if _, err := mgc.Load(files...); err != nil {
		return nil, err
	}
	return mgc, nil
}
Ejemplo n.º 22
0
func GetAclInformation(acl *Acl, info unsafe.Pointer, length uint32, class uint32) error {
	r1, _, e1 := procGetAclInformation.Call(
		uintptr(unsafe.Pointer(acl)),
		uintptr(info),
		uintptr(length),
		uintptr(class))
	runtime.KeepAlive(acl)
	if int(r1) == 0 {
		return os.NewSyscallError("GetAclInformation", e1)
	}
	return nil
}
Ejemplo n.º 23
0
// open opens and initializes underlying Magic library and sets the
// finalizer on the object accordingly.
func open() (*Magic, error) {
	// Can only fail allocating memory in this particular case.
	rv := C.magic_open(C.int(NONE))
	if rv == nil {
		errno := syscall.ENOMEM
		return nil, &Error{int(errno), "failed to initialize Magic library"}
	}

	mgc := &Magic{&magic{flags: NONE, cookie: rv}}
	runtime.SetFinalizer(mgc.magic, (*magic).close)
	runtime.KeepAlive(mgc.magic)
	return mgc, nil
}
Ejemplo n.º 24
0
// Check
//
// If there is an error, it will be of type *Error.
func (mgc *Magic) Check(files ...string) (bool, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return false, mgc.error()
	}

	var cfiles *C.char
	runtime.KeepAlive(cfiles)
	defer C.free(unsafe.Pointer(cfiles))

	if len(files) > 0 {
		cfiles = C.CString(strings.Join(files, ":"))
	}

	if rv := C.magic_check_wrapper(mgc.cookie, cfiles, C.int(mgc.flags)); rv < 0 {
		return false, mgc.error()
	}
	return true, nil
}
Ejemplo n.º 25
0
func GetUserObjectInformation(obj syscall.Handle, index int, info unsafe.Pointer, length uint32) (uint32, error) {
	var nLength uint32
	r1, _, e1 := procGetUserObjectInformationW.Call(
		uintptr(obj),
		uintptr(index),
		uintptr(info),
		uintptr(length),
		uintptr(unsafe.Pointer(&nLength)))
	runtime.KeepAlive(&nLength)
	if int(r1) == 0 {
		return nLength, os.NewSyscallError("GetUserObjectInformation", e1)
	}
	return 0, nil
}
Ejemplo n.º 26
0
func QueryInformationJobObject(job syscall.Handle, infoclass uint32, info unsafe.Pointer, length uint32) (uint32, error) {
	var nLength uint32
	r1, _, e1 := procQueryInformationJobObject.Call(
		uintptr(job),
		uintptr(infoclass),
		uintptr(info),
		uintptr(length),
		uintptr(unsafe.Pointer(&nLength)))
	runtime.KeepAlive(&nLength)
	if int(r1) == 0 {
		return nLength, os.NewSyscallError("QueryInformationJobObject", e1)
	}
	return nLength, nil
}
Ejemplo n.º 27
0
// Descriptor
//
// If there is an error, it will be of type *Error.
func (mgc *Magic) Descriptor(fd uintptr) (string, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return "", mgc.error()
	}

	cstring := C.magic_descriptor_wrapper(mgc.cookie, C.int(fd), C.int(mgc.flags))
	if cstring == nil {
		return "", mgc.error()
	}
	return C.GoString(cstring), nil
}
Ejemplo n.º 28
0
// blockUntilWaitable attempts to block until a call to p.Wait will
// succeed immediately, and returns whether it has done so.
// It does not actually call p.Wait.
func (p *Process) blockUntilWaitable() (bool, error) {
	// The waitid system call expects a pointer to a siginfo_t,
	// which is 128 bytes on all GNU/Linux systems.
	// On Darwin, it requires greater than or equal to 64 bytes
	// for darwin/{386,arm} and 104 bytes for darwin/amd64.
	// We don't care about the values it returns.
	var siginfo [128]byte
	psig := &siginfo[0]
	_, _, e := syscall.Syscall6(syscall.SYS_WAITID, _P_PID, uintptr(p.Pid), uintptr(unsafe.Pointer(psig)), syscall.WEXITED|syscall.WNOWAIT, 0, 0)
	runtime.KeepAlive(psig)
	if e != 0 {
		return false, NewSyscallError("waitid", e)
	}
	return true, nil
}
Ejemplo n.º 29
0
func (p *Process) signal(sig Signal) error {
	handle := atomic.LoadUintptr(&p.handle)
	if handle == uintptr(syscall.InvalidHandle) {
		return syscall.EINVAL
	}
	if p.done() {
		return errors.New("os: process already finished")
	}
	if sig == Kill {
		err := terminateProcess(p.Pid, 1)
		runtime.KeepAlive(p)
		return err
	}
	// TODO(rsc): Handle Interrupt too?
	return syscall.Errno(syscall.EWINDOWS)
}
Ejemplo n.º 30
0
// Buffer
//
// If there is an error, it will be of type *Error.
func (mgc *Magic) Buffer(buffer []byte) (string, error) {
	mgc.Lock()
	defer mgc.Unlock()
	runtime.KeepAlive(mgc.magic)

	if mgc.cookie == nil {
		return "", mgc.error()
	}

	p, length := unsafe.Pointer(&buffer[0]), C.size_t(len(buffer))

	cstring := C.magic_buffer_wrapper(mgc.cookie, p, length, C.int(mgc.flags))
	if cstring == nil {
		return "", mgc.error()
	}
	return C.GoString(cstring), nil
}