| // Copyright 2010-2012 The W32 Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package w32 |
| |
| import ( |
| "errors" |
| "fmt" |
| "syscall" |
| "unsafe" |
| ) |
| |
| var ( |
| modadvapi32 = syscall.NewLazyDLL("advapi32.dll") |
| |
| procRegCreateKeyEx = modadvapi32.NewProc("RegCreateKeyExW") |
| procRegOpenKeyEx = modadvapi32.NewProc("RegOpenKeyExW") |
| procRegCloseKey = modadvapi32.NewProc("RegCloseKey") |
| procRegGetValue = modadvapi32.NewProc("RegGetValueW") |
| procRegEnumKeyEx = modadvapi32.NewProc("RegEnumKeyExW") |
| // procRegSetKeyValue = modadvapi32.NewProc("RegSetKeyValueW") |
| procRegSetValueEx = modadvapi32.NewProc("RegSetValueExW") |
| procOpenEventLog = modadvapi32.NewProc("OpenEventLogW") |
| procReadEventLog = modadvapi32.NewProc("ReadEventLogW") |
| procCloseEventLog = modadvapi32.NewProc("CloseEventLog") |
| procOpenSCManager = modadvapi32.NewProc("OpenSCManagerW") |
| procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") |
| procOpenService = modadvapi32.NewProc("OpenServiceW") |
| procStartService = modadvapi32.NewProc("StartServiceW") |
| procControlService = modadvapi32.NewProc("ControlService") |
| ) |
| |
| func RegCreateKey(hKey HKEY, subKey string) HKEY { |
| var result HKEY |
| ret, _, _ := procRegCreateKeyEx.Call( |
| uintptr(hKey), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), |
| uintptr(0), |
| uintptr(0), |
| uintptr(0), |
| uintptr(KEY_ALL_ACCESS), |
| uintptr(0), |
| uintptr(unsafe.Pointer(&result)), |
| uintptr(0)) |
| _ = ret |
| return result |
| } |
| |
| func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY { |
| var result HKEY |
| ret, _, _ := procRegOpenKeyEx.Call( |
| uintptr(hKey), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), |
| uintptr(0), |
| uintptr(samDesired), |
| uintptr(unsafe.Pointer(&result))) |
| |
| if ret != ERROR_SUCCESS { |
| panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired)) |
| } |
| return result |
| } |
| |
| func RegCloseKey(hKey HKEY) error { |
| var err error |
| ret, _, _ := procRegCloseKey.Call( |
| uintptr(hKey)) |
| |
| if ret != ERROR_SUCCESS { |
| err = errors.New("RegCloseKey failed") |
| } |
| return err |
| } |
| |
| func RegGetRaw(hKey HKEY, subKey string, value string) []byte { |
| var bufLen uint32 |
| var valptr unsafe.Pointer |
| if len(value) > 0 { |
| valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value)) |
| } |
| procRegGetValue.Call( |
| uintptr(hKey), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), |
| uintptr(valptr), |
| uintptr(RRF_RT_ANY), |
| 0, |
| 0, |
| uintptr(unsafe.Pointer(&bufLen))) |
| |
| if bufLen == 0 { |
| return nil |
| } |
| |
| buf := make([]byte, bufLen) |
| ret, _, _ := procRegGetValue.Call( |
| uintptr(hKey), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), |
| uintptr(valptr), |
| uintptr(RRF_RT_ANY), |
| 0, |
| uintptr(unsafe.Pointer(&buf[0])), |
| uintptr(unsafe.Pointer(&bufLen))) |
| |
| if ret != ERROR_SUCCESS { |
| return nil |
| } |
| |
| return buf |
| } |
| |
| func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) { |
| var lptr, vptr unsafe.Pointer |
| if len(subKey) > 0 { |
| lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) |
| } |
| if len(value) > 0 { |
| vptr = unsafe.Pointer(&value[0]) |
| } |
| ret, _, _ := procRegSetValueEx.Call( |
| uintptr(hKey), |
| uintptr(lptr), |
| uintptr(0), |
| uintptr(REG_BINARY), |
| uintptr(vptr), |
| uintptr(len(value))) |
| |
| return int(ret) |
| } |
| |
| func RegGetString(hKey HKEY, subKey string, value string) string { |
| var bufLen uint32 |
| procRegGetValue.Call( |
| uintptr(hKey), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), |
| uintptr(RRF_RT_REG_SZ), |
| 0, |
| 0, |
| uintptr(unsafe.Pointer(&bufLen))) |
| |
| if bufLen == 0 { |
| return "" |
| } |
| |
| buf := make([]uint16, bufLen) |
| ret, _, _ := procRegGetValue.Call( |
| uintptr(hKey), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), |
| uintptr(RRF_RT_REG_SZ), |
| 0, |
| uintptr(unsafe.Pointer(&buf[0])), |
| uintptr(unsafe.Pointer(&bufLen))) |
| |
| if ret != ERROR_SUCCESS { |
| return "" |
| } |
| |
| return syscall.UTF16ToString(buf) |
| } |
| |
| /* |
| func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType uint32, data uintptr, cbData uint16) (errno int) { |
| ret, _, _ := procRegSetKeyValue.Call( |
| uintptr(hKey), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))), |
| uintptr(dwType), |
| data, |
| uintptr(cbData)) |
| |
| return int(ret) |
| } |
| */ |
| |
| func RegEnumKeyEx(hKey HKEY, index uint32) string { |
| var bufLen uint32 = 255 |
| buf := make([]uint16, bufLen) |
| procRegEnumKeyEx.Call( |
| uintptr(hKey), |
| uintptr(index), |
| uintptr(unsafe.Pointer(&buf[0])), |
| uintptr(unsafe.Pointer(&bufLen)), |
| 0, |
| 0, |
| 0, |
| 0) |
| return syscall.UTF16ToString(buf) |
| } |
| |
| func OpenEventLog(servername string, sourcename string) HANDLE { |
| ret, _, _ := procOpenEventLog.Call( |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename)))) |
| |
| return HANDLE(ret) |
| } |
| |
| func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool { |
| ret, _, _ := procReadEventLog.Call( |
| uintptr(eventlog), |
| uintptr(readflags), |
| uintptr(recordoffset), |
| uintptr(unsafe.Pointer(&buffer[0])), |
| uintptr(numberofbytestoread), |
| uintptr(unsafe.Pointer(bytesread)), |
| uintptr(unsafe.Pointer(minnumberofbytesneeded))) |
| |
| return ret != 0 |
| } |
| |
| func CloseEventLog(eventlog HANDLE) bool { |
| ret, _, _ := procCloseEventLog.Call( |
| uintptr(eventlog)) |
| |
| return ret != 0 |
| } |
| |
| func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) { |
| var p1, p2 uintptr |
| if len(lpMachineName) > 0 { |
| p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName))) |
| } |
| if len(lpDatabaseName) > 0 { |
| p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName))) |
| } |
| ret, _, _ := procOpenSCManager.Call( |
| p1, |
| p2, |
| uintptr(dwDesiredAccess)) |
| |
| if ret == 0 { |
| return 0, syscall.GetLastError() |
| } |
| |
| return HANDLE(ret), nil |
| } |
| |
| func CloseServiceHandle(hSCObject HANDLE) error { |
| ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject)) |
| if ret == 0 { |
| return syscall.GetLastError() |
| } |
| return nil |
| } |
| |
| func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) { |
| ret, _, _ := procOpenService.Call( |
| uintptr(hSCManager), |
| uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))), |
| uintptr(dwDesiredAccess)) |
| |
| if ret == 0 { |
| return 0, syscall.GetLastError() |
| } |
| |
| return HANDLE(ret), nil |
| } |
| |
| func StartService(hService HANDLE, lpServiceArgVectors []string) error { |
| l := len(lpServiceArgVectors) |
| var ret uintptr |
| if l == 0 { |
| ret, _, _ = procStartService.Call( |
| uintptr(hService), |
| 0, |
| 0) |
| } else { |
| lpArgs := make([]uintptr, l) |
| for i := 0; i < l; i++ { |
| lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i]))) |
| } |
| |
| ret, _, _ = procStartService.Call( |
| uintptr(hService), |
| uintptr(l), |
| uintptr(unsafe.Pointer(&lpArgs[0]))) |
| } |
| |
| if ret == 0 { |
| return syscall.GetLastError() |
| } |
| |
| return nil |
| } |
| |
| func ControlService(hService HANDLE, dwControl uint32, lpServiceStatus *SERVICE_STATUS) bool { |
| if lpServiceStatus == nil { |
| panic("ControlService:lpServiceStatus cannot be nil") |
| } |
| |
| ret, _, _ := procControlService.Call( |
| uintptr(hService), |
| uintptr(dwControl), |
| uintptr(unsafe.Pointer(lpServiceStatus))) |
| |
| return ret != 0 |
| } |