agent/util/ramflag/ramflag_windows.go (70 lines of code) (raw):

package ramflag import ( "errors" "syscall" "unsafe" "golang.org/x/sys/windows" ) type ATOM uint16 var ( ErrNameLimitExceeded = errors.New("The RAM flag name is too long") _libKernel32 = windows.NewLazySystemDLL("kernel32.dll") _libUser32 = windows.NewLazySystemDLL("user32.dll") _procGlobalFindAtom = _libKernel32.NewProc("GlobalFindAtomW") _procGlobalAddAtom = _libKernel32.NewProc("GlobalAddAtomW") _procGlobalDeleteAtom = _libKernel32.NewProc("GlobalDeleteAtom") ) func init() { // According to https://stackoverflow.com/q/3577077, user32.dll must be loaded // before calling GlobalFindAtom* functions in kernel32.dll, otherwise error // 0x5 (AccessDenied) would be raised. _libUser32.Load() } func globalFindAtom(lpString string) (ATOM, error) { p0, err := windows.UTF16PtrFromString(lpString) if err != nil { return ATOM(0), err } r1, _, errno := syscall.Syscall(_procGlobalFindAtom.Addr(), 1, uintptr(unsafe.Pointer(p0)), 0, 0) if errno != windows.ERROR_SUCCESS { return ATOM(r1), errno } return ATOM(r1), nil } func globalAddAtom(lpString string) (ATOM, error) { p0, err := windows.UTF16PtrFromString(lpString) if err != nil { return ATOM(0), err } r1, _, errno := syscall.Syscall(_procGlobalAddAtom.Addr(), 1, uintptr(unsafe.Pointer(p0)), 0, 0) if errno != windows.ERROR_SUCCESS { return ATOM(r1), errno } return ATOM(r1), nil } func globalDeleteAtom(atom ATOM) error { _, _, errno := syscall.Syscall(_procGlobalDeleteAtom.Addr(), 1, uintptr(atom), 0, 0) if errno != windows.ERROR_SUCCESS { return errno } return nil } func IsExist(name string) (bool, error) { if _, err := globalFindAtom(name); err != nil { return false, nil } return true, nil } func Create(name string) error { if _, err := globalAddAtom(name); err != nil { return err } return nil } func Delete(name string) error { atom, err := globalFindAtom(name) if err != nil { return err } if err := globalDeleteAtom(atom); err != nil { return err } return nil }