1// Copyright 2010-2012 The W32 Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style 3// license that can be found in the LICENSE file. 4 5// +build windows 6 7package w32 8 9import ( 10 "errors" 11 "fmt" 12 "syscall" 13 "unsafe" 14) 15 16var ( 17 modadvapi32 = syscall.NewLazyDLL("advapi32.dll") 18 19 procRegCreateKeyEx = modadvapi32.NewProc("RegCreateKeyExW") 20 procRegOpenKeyEx = modadvapi32.NewProc("RegOpenKeyExW") 21 procRegCloseKey = modadvapi32.NewProc("RegCloseKey") 22 procRegGetValue = modadvapi32.NewProc("RegGetValueW") 23 procRegEnumKeyEx = modadvapi32.NewProc("RegEnumKeyExW") 24 // procRegSetKeyValue = modadvapi32.NewProc("RegSetKeyValueW") 25 procRegSetValueEx = modadvapi32.NewProc("RegSetValueExW") 26 procOpenEventLog = modadvapi32.NewProc("OpenEventLogW") 27 procReadEventLog = modadvapi32.NewProc("ReadEventLogW") 28 procCloseEventLog = modadvapi32.NewProc("CloseEventLog") 29 procOpenSCManager = modadvapi32.NewProc("OpenSCManagerW") 30 procCloseServiceHandle = modadvapi32.NewProc("CloseServiceHandle") 31 procOpenService = modadvapi32.NewProc("OpenServiceW") 32 procStartService = modadvapi32.NewProc("StartServiceW") 33 procControlService = modadvapi32.NewProc("ControlService") 34) 35 36func RegCreateKey(hKey HKEY, subKey string) HKEY { 37 var result HKEY 38 ret, _, _ := procRegCreateKeyEx.Call( 39 uintptr(hKey), 40 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), 41 uintptr(0), 42 uintptr(0), 43 uintptr(0), 44 uintptr(KEY_ALL_ACCESS), 45 uintptr(0), 46 uintptr(unsafe.Pointer(&result)), 47 uintptr(0)) 48 _ = ret 49 return result 50} 51 52func RegOpenKeyEx(hKey HKEY, subKey string, samDesired uint32) HKEY { 53 var result HKEY 54 ret, _, _ := procRegOpenKeyEx.Call( 55 uintptr(hKey), 56 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), 57 uintptr(0), 58 uintptr(samDesired), 59 uintptr(unsafe.Pointer(&result))) 60 61 if ret != ERROR_SUCCESS { 62 panic(fmt.Sprintf("RegOpenKeyEx(%d, %s, %d) failed", hKey, subKey, samDesired)) 63 } 64 return result 65} 66 67func RegCloseKey(hKey HKEY) error { 68 var err error 69 ret, _, _ := procRegCloseKey.Call( 70 uintptr(hKey)) 71 72 if ret != ERROR_SUCCESS { 73 err = errors.New("RegCloseKey failed") 74 } 75 return err 76} 77 78func RegGetRaw(hKey HKEY, subKey string, value string) []byte { 79 var bufLen uint32 80 var valptr unsafe.Pointer 81 if len(value) > 0 { 82 valptr = unsafe.Pointer(syscall.StringToUTF16Ptr(value)) 83 } 84 procRegGetValue.Call( 85 uintptr(hKey), 86 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), 87 uintptr(valptr), 88 uintptr(RRF_RT_ANY), 89 0, 90 0, 91 uintptr(unsafe.Pointer(&bufLen))) 92 93 if bufLen == 0 { 94 return nil 95 } 96 97 buf := make([]byte, bufLen) 98 ret, _, _ := procRegGetValue.Call( 99 uintptr(hKey), 100 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), 101 uintptr(valptr), 102 uintptr(RRF_RT_ANY), 103 0, 104 uintptr(unsafe.Pointer(&buf[0])), 105 uintptr(unsafe.Pointer(&bufLen))) 106 107 if ret != ERROR_SUCCESS { 108 return nil 109 } 110 111 return buf 112} 113 114func RegSetBinary(hKey HKEY, subKey string, value []byte) (errno int) { 115 var lptr, vptr unsafe.Pointer 116 if len(subKey) > 0 { 117 lptr = unsafe.Pointer(syscall.StringToUTF16Ptr(subKey)) 118 } 119 if len(value) > 0 { 120 vptr = unsafe.Pointer(&value[0]) 121 } 122 ret, _, _ := procRegSetValueEx.Call( 123 uintptr(hKey), 124 uintptr(lptr), 125 uintptr(0), 126 uintptr(REG_BINARY), 127 uintptr(vptr), 128 uintptr(len(value))) 129 130 return int(ret) 131} 132 133func RegGetString(hKey HKEY, subKey string, value string) string { 134 var bufLen uint32 135 procRegGetValue.Call( 136 uintptr(hKey), 137 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), 138 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), 139 uintptr(RRF_RT_REG_SZ), 140 0, 141 0, 142 uintptr(unsafe.Pointer(&bufLen))) 143 144 if bufLen == 0 { 145 return "" 146 } 147 148 buf := make([]uint16, bufLen) 149 ret, _, _ := procRegGetValue.Call( 150 uintptr(hKey), 151 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), 152 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(value))), 153 uintptr(RRF_RT_REG_SZ), 154 0, 155 uintptr(unsafe.Pointer(&buf[0])), 156 uintptr(unsafe.Pointer(&bufLen))) 157 158 if ret != ERROR_SUCCESS { 159 return "" 160 } 161 162 return syscall.UTF16ToString(buf) 163} 164 165/* 166func RegSetKeyValue(hKey HKEY, subKey string, valueName string, dwType uint32, data uintptr, cbData uint16) (errno int) { 167 ret, _, _ := procRegSetKeyValue.Call( 168 uintptr(hKey), 169 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(subKey))), 170 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(valueName))), 171 uintptr(dwType), 172 data, 173 uintptr(cbData)) 174 175 return int(ret) 176} 177*/ 178 179func RegEnumKeyEx(hKey HKEY, index uint32) string { 180 var bufLen uint32 = 255 181 buf := make([]uint16, bufLen) 182 procRegEnumKeyEx.Call( 183 uintptr(hKey), 184 uintptr(index), 185 uintptr(unsafe.Pointer(&buf[0])), 186 uintptr(unsafe.Pointer(&bufLen)), 187 0, 188 0, 189 0, 190 0) 191 return syscall.UTF16ToString(buf) 192} 193 194func OpenEventLog(servername string, sourcename string) HANDLE { 195 ret, _, _ := procOpenEventLog.Call( 196 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(servername))), 197 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(sourcename)))) 198 199 return HANDLE(ret) 200} 201 202func ReadEventLog(eventlog HANDLE, readflags, recordoffset uint32, buffer []byte, numberofbytestoread uint32, bytesread, minnumberofbytesneeded *uint32) bool { 203 ret, _, _ := procReadEventLog.Call( 204 uintptr(eventlog), 205 uintptr(readflags), 206 uintptr(recordoffset), 207 uintptr(unsafe.Pointer(&buffer[0])), 208 uintptr(numberofbytestoread), 209 uintptr(unsafe.Pointer(bytesread)), 210 uintptr(unsafe.Pointer(minnumberofbytesneeded))) 211 212 return ret != 0 213} 214 215func CloseEventLog(eventlog HANDLE) bool { 216 ret, _, _ := procCloseEventLog.Call( 217 uintptr(eventlog)) 218 219 return ret != 0 220} 221 222func OpenSCManager(lpMachineName, lpDatabaseName string, dwDesiredAccess uint32) (HANDLE, error) { 223 var p1, p2 uintptr 224 if len(lpMachineName) > 0 { 225 p1 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpMachineName))) 226 } 227 if len(lpDatabaseName) > 0 { 228 p2 = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpDatabaseName))) 229 } 230 ret, _, _ := procOpenSCManager.Call( 231 p1, 232 p2, 233 uintptr(dwDesiredAccess)) 234 235 if ret == 0 { 236 return 0, syscall.GetLastError() 237 } 238 239 return HANDLE(ret), nil 240} 241 242func CloseServiceHandle(hSCObject HANDLE) error { 243 ret, _, _ := procCloseServiceHandle.Call(uintptr(hSCObject)) 244 if ret == 0 { 245 return syscall.GetLastError() 246 } 247 return nil 248} 249 250func OpenService(hSCManager HANDLE, lpServiceName string, dwDesiredAccess uint32) (HANDLE, error) { 251 ret, _, _ := procOpenService.Call( 252 uintptr(hSCManager), 253 uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceName))), 254 uintptr(dwDesiredAccess)) 255 256 if ret == 0 { 257 return 0, syscall.GetLastError() 258 } 259 260 return HANDLE(ret), nil 261} 262 263func StartService(hService HANDLE, lpServiceArgVectors []string) error { 264 l := len(lpServiceArgVectors) 265 var ret uintptr 266 if l == 0 { 267 ret, _, _ = procStartService.Call( 268 uintptr(hService), 269 0, 270 0) 271 } else { 272 lpArgs := make([]uintptr, l) 273 for i := 0; i < l; i++ { 274 lpArgs[i] = uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(lpServiceArgVectors[i]))) 275 } 276 277 ret, _, _ = procStartService.Call( 278 uintptr(hService), 279 uintptr(l), 280 uintptr(unsafe.Pointer(&lpArgs[0]))) 281 } 282 283 if ret == 0 { 284 return syscall.GetLastError() 285 } 286 287 return nil 288} 289 290func ControlService(hService HANDLE, dwControl uint32, lpServiceStatus *SERVICE_STATUS) bool { 291 if lpServiceStatus == nil { 292 panic("ControlService:lpServiceStatus cannot be nil") 293 } 294 295 ret, _, _ := procControlService.Call( 296 uintptr(hService), 297 uintptr(dwControl), 298 uintptr(unsafe.Pointer(lpServiceStatus))) 299 300 return ret != 0 301} 302