github.com/scalingdata/go-ole@v1.2.0/safearray_windows.go (about) 1 // +build windows 2 3 package ole 4 5 import ( 6 "unsafe" 7 ) 8 9 var ( 10 procSafeArrayAccessData, _ = modoleaut32.FindProc("SafeArrayAccessData") 11 procSafeArrayAllocData, _ = modoleaut32.FindProc("SafeArrayAllocData") 12 procSafeArrayAllocDescriptor, _ = modoleaut32.FindProc("SafeArrayAllocDescriptor") 13 procSafeArrayAllocDescriptorEx, _ = modoleaut32.FindProc("SafeArrayAllocDescriptorEx") 14 procSafeArrayCopy, _ = modoleaut32.FindProc("SafeArrayCopy") 15 procSafeArrayCopyData, _ = modoleaut32.FindProc("SafeArrayCopyData") 16 procSafeArrayCreate, _ = modoleaut32.FindProc("SafeArrayCreate") 17 procSafeArrayCreateEx, _ = modoleaut32.FindProc("SafeArrayCreateEx") 18 procSafeArrayCreateVector, _ = modoleaut32.FindProc("SafeArrayCreateVector") 19 procSafeArrayCreateVectorEx, _ = modoleaut32.FindProc("SafeArrayCreateVectorEx") 20 procSafeArrayDestroy, _ = modoleaut32.FindProc("SafeArrayDestroy") 21 procSafeArrayDestroyData, _ = modoleaut32.FindProc("SafeArrayDestroyData") 22 procSafeArrayDestroyDescriptor, _ = modoleaut32.FindProc("SafeArrayDestroyDescriptor") 23 procSafeArrayGetDim, _ = modoleaut32.FindProc("SafeArrayGetDim") 24 procSafeArrayGetElement, _ = modoleaut32.FindProc("SafeArrayGetElement") 25 procSafeArrayGetElemsize, _ = modoleaut32.FindProc("SafeArrayGetElemsize") 26 procSafeArrayGetIID, _ = modoleaut32.FindProc("SafeArrayGetIID") 27 procSafeArrayGetLBound, _ = modoleaut32.FindProc("SafeArrayGetLBound") 28 procSafeArrayGetUBound, _ = modoleaut32.FindProc("SafeArrayGetUBound") 29 procSafeArrayGetVartype, _ = modoleaut32.FindProc("SafeArrayGetVartype") 30 procSafeArrayLock, _ = modoleaut32.FindProc("SafeArrayLock") 31 procSafeArrayPtrOfIndex, _ = modoleaut32.FindProc("SafeArrayPtrOfIndex") 32 procSafeArrayUnaccessData, _ = modoleaut32.FindProc("SafeArrayUnaccessData") 33 procSafeArrayUnlock, _ = modoleaut32.FindProc("SafeArrayUnlock") 34 procSafeArrayPutElement, _ = modoleaut32.FindProc("SafeArrayPutElement") 35 //procSafeArrayRedim, _ = modoleaut32.FindProc("SafeArrayRedim") // TODO 36 //procSafeArraySetIID, _ = modoleaut32.FindProc("SafeArraySetIID") // TODO 37 procSafeArrayGetRecordInfo, _ = modoleaut32.FindProc("SafeArrayGetRecordInfo") 38 procSafeArraySetRecordInfo, _ = modoleaut32.FindProc("SafeArraySetRecordInfo") 39 ) 40 41 // safeArrayAccessData returns raw array pointer. 42 // 43 // AKA: SafeArrayAccessData in Windows API. 44 // Todo: Test 45 func safeArrayAccessData(safearray *SafeArray) (element uintptr, err error) { 46 err = convertHresultToError( 47 procSafeArrayAccessData.Call( 48 uintptr(unsafe.Pointer(safearray)), 49 uintptr(unsafe.Pointer(&element)))) 50 return 51 } 52 53 // safeArrayUnaccessData releases raw array. 54 // 55 // AKA: SafeArrayUnaccessData in Windows API. 56 func safeArrayUnaccessData(safearray *SafeArray) (err error) { 57 err = convertHresultToError(procSafeArrayUnaccessData.Call(uintptr(unsafe.Pointer(safearray)))) 58 return 59 } 60 61 // safeArrayAllocData allocates SafeArray. 62 // 63 // AKA: SafeArrayAllocData in Windows API. 64 func safeArrayAllocData(safearray *SafeArray) (err error) { 65 err = convertHresultToError(procSafeArrayAllocData.Call(uintptr(unsafe.Pointer(safearray)))) 66 return 67 } 68 69 // safeArrayAllocDescriptor allocates SafeArray. 70 // 71 // AKA: SafeArrayAllocDescriptor in Windows API. 72 func safeArrayAllocDescriptor(dimensions uint32) (safearray *SafeArray, err error) { 73 err = convertHresultToError( 74 procSafeArrayAllocDescriptor.Call(uintptr(dimensions), uintptr(unsafe.Pointer(&safearray)))) 75 return 76 } 77 78 // safeArrayAllocDescriptorEx allocates SafeArray. 79 // 80 // AKA: SafeArrayAllocDescriptorEx in Windows API. 81 func safeArrayAllocDescriptorEx(variantType VT, dimensions uint32) (safearray *SafeArray, err error) { 82 err = convertHresultToError( 83 procSafeArrayAllocDescriptorEx.Call( 84 uintptr(variantType), 85 uintptr(dimensions), 86 uintptr(unsafe.Pointer(&safearray)))) 87 return 88 } 89 90 // safeArrayCopy returns copy of SafeArray. 91 // 92 // AKA: SafeArrayCopy in Windows API. 93 func safeArrayCopy(original *SafeArray) (safearray *SafeArray, err error) { 94 err = convertHresultToError( 95 procSafeArrayCopy.Call( 96 uintptr(unsafe.Pointer(original)), 97 uintptr(unsafe.Pointer(&safearray)))) 98 return 99 } 100 101 // safeArrayCopyData duplicates SafeArray into another SafeArray object. 102 // 103 // AKA: SafeArrayCopyData in Windows API. 104 func safeArrayCopyData(original *SafeArray, duplicate *SafeArray) (err error) { 105 err = convertHresultToError( 106 procSafeArrayCopyData.Call( 107 uintptr(unsafe.Pointer(original)), 108 uintptr(unsafe.Pointer(duplicate)))) 109 return 110 } 111 112 // safeArrayCreate creates SafeArray. 113 // 114 // AKA: SafeArrayCreate in Windows API. 115 func safeArrayCreate(variantType VT, dimensions uint32, bounds *SafeArrayBound) (safearray *SafeArray, err error) { 116 sa, _, err := procSafeArrayCreate.Call( 117 uintptr(variantType), 118 uintptr(dimensions), 119 uintptr(unsafe.Pointer(bounds))) 120 safearray = (*SafeArray)(unsafe.Pointer(&sa)) 121 return 122 } 123 124 // safeArrayCreateEx creates SafeArray. 125 // 126 // AKA: SafeArrayCreateEx in Windows API. 127 func safeArrayCreateEx(variantType VT, dimensions uint32, bounds *SafeArrayBound, extra uintptr) (safearray *SafeArray, err error) { 128 sa, _, err := procSafeArrayCreateEx.Call( 129 uintptr(variantType), 130 uintptr(dimensions), 131 uintptr(unsafe.Pointer(bounds)), 132 extra) 133 safearray = (*SafeArray)(unsafe.Pointer(sa)) 134 return 135 } 136 137 // safeArrayCreateVector creates SafeArray. 138 // 139 // AKA: SafeArrayCreateVector in Windows API. 140 func safeArrayCreateVector(variantType VT, lowerBound int32, length uint32) (safearray *SafeArray, err error) { 141 sa, _, err := procSafeArrayCreateVector.Call( 142 uintptr(variantType), 143 uintptr(lowerBound), 144 uintptr(length)) 145 safearray = (*SafeArray)(unsafe.Pointer(sa)) 146 return 147 } 148 149 // safeArrayCreateVectorEx creates SafeArray. 150 // 151 // AKA: SafeArrayCreateVectorEx in Windows API. 152 func safeArrayCreateVectorEx(variantType VT, lowerBound int32, length uint32, extra uintptr) (safearray *SafeArray, err error) { 153 sa, _, err := procSafeArrayCreateVectorEx.Call( 154 uintptr(variantType), 155 uintptr(lowerBound), 156 uintptr(length), 157 extra) 158 safearray = (*SafeArray)(unsafe.Pointer(sa)) 159 return 160 } 161 162 // safeArrayDestroy destroys SafeArray object. 163 // 164 // AKA: SafeArrayDestroy in Windows API. 165 func safeArrayDestroy(safearray *SafeArray) (err error) { 166 err = convertHresultToError(procSafeArrayDestroy.Call(uintptr(unsafe.Pointer(safearray)))) 167 return 168 } 169 170 // safeArrayDestroyData destroys SafeArray object. 171 // 172 // AKA: SafeArrayDestroyData in Windows API. 173 func safeArrayDestroyData(safearray *SafeArray) (err error) { 174 err = convertHresultToError(procSafeArrayDestroyData.Call(uintptr(unsafe.Pointer(safearray)))) 175 return 176 } 177 178 // safeArrayDestroyDescriptor destroys SafeArray object. 179 // 180 // AKA: SafeArrayDestroyDescriptor in Windows API. 181 func safeArrayDestroyDescriptor(safearray *SafeArray) (err error) { 182 err = convertHresultToError(procSafeArrayDestroyDescriptor.Call(uintptr(unsafe.Pointer(safearray)))) 183 return 184 } 185 186 // safeArrayGetDim is the amount of dimensions in the SafeArray. 187 // 188 // SafeArrays may have multiple dimensions. Meaning, it could be 189 // multidimensional array. 190 // 191 // AKA: SafeArrayGetDim in Windows API. 192 func safeArrayGetDim(safearray *SafeArray) (dimensions *uint32, err error) { 193 l, _, err := procSafeArrayGetDim.Call(uintptr(unsafe.Pointer(safearray))) 194 dimensions = (*uint32)(unsafe.Pointer(l)) 195 return 196 } 197 198 // safeArrayGetElementSize is the element size in bytes. 199 // 200 // AKA: SafeArrayGetElemsize in Windows API. 201 func safeArrayGetElementSize(safearray *SafeArray) (length *uint32, err error) { 202 l, _, err := procSafeArrayGetElemsize.Call(uintptr(unsafe.Pointer(safearray))) 203 length = (*uint32)(unsafe.Pointer(l)) 204 return 205 } 206 207 // safeArrayGetElement retrieves element at given index. 208 func safeArrayGetElement(safearray *SafeArray, index int64) (element uintptr, err error) { 209 err = convertHresultToError( 210 procSafeArrayGetElement.Call( 211 uintptr(unsafe.Pointer(safearray)), 212 uintptr(unsafe.Pointer(&index)), 213 uintptr(unsafe.Pointer(&element)))) 214 return 215 } 216 217 // safeArrayGetElement retrieves element at given index and converts to string. 218 func safeArrayGetElementString(safearray *SafeArray, index int64) (str string, err error) { 219 var element *int16 220 err = convertHresultToError( 221 procSafeArrayGetElement.Call( 222 uintptr(unsafe.Pointer(safearray)), 223 uintptr(unsafe.Pointer(&index)), 224 uintptr(unsafe.Pointer(&element)))) 225 str = BstrToString(*(**uint16)(unsafe.Pointer(&element))) 226 SysFreeString(element) 227 return 228 } 229 230 // safeArrayGetIID is the InterfaceID of the elements in the SafeArray. 231 // 232 // AKA: SafeArrayGetIID in Windows API. 233 func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) { 234 err = convertHresultToError( 235 procSafeArrayGetIID.Call( 236 uintptr(unsafe.Pointer(safearray)), 237 uintptr(unsafe.Pointer(&guid)))) 238 return 239 } 240 241 // safeArrayGetLBound returns lower bounds of SafeArray. 242 // 243 // SafeArrays may have multiple dimensions. Meaning, it could be 244 // multidimensional array. 245 // 246 // AKA: SafeArrayGetLBound in Windows API. 247 func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int64, err error) { 248 err = convertHresultToError( 249 procSafeArrayGetLBound.Call( 250 uintptr(unsafe.Pointer(safearray)), 251 uintptr(dimension), 252 uintptr(unsafe.Pointer(&lowerBound)))) 253 return 254 } 255 256 // safeArrayGetUBound returns upper bounds of SafeArray. 257 // 258 // SafeArrays may have multiple dimensions. Meaning, it could be 259 // multidimensional array. 260 // 261 // AKA: SafeArrayGetUBound in Windows API. 262 func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int64, err error) { 263 err = convertHresultToError( 264 procSafeArrayGetUBound.Call( 265 uintptr(unsafe.Pointer(safearray)), 266 uintptr(dimension), 267 uintptr(unsafe.Pointer(&upperBound)))) 268 return 269 } 270 271 // safeArrayGetVartype returns data type of SafeArray. 272 // 273 // AKA: SafeArrayGetVartype in Windows API. 274 func safeArrayGetVartype(safearray *SafeArray) (varType uint16, err error) { 275 err = convertHresultToError( 276 procSafeArrayGetVartype.Call( 277 uintptr(unsafe.Pointer(safearray)), 278 uintptr(unsafe.Pointer(&varType)))) 279 return 280 } 281 282 // safeArrayLock locks SafeArray for reading to modify SafeArray. 283 // 284 // This must be called during some calls to ensure that another process does not 285 // read or write to the SafeArray during editing. 286 // 287 // AKA: SafeArrayLock in Windows API. 288 func safeArrayLock(safearray *SafeArray) (err error) { 289 err = convertHresultToError(procSafeArrayLock.Call(uintptr(unsafe.Pointer(safearray)))) 290 return 291 } 292 293 // safeArrayUnlock unlocks SafeArray for reading. 294 // 295 // AKA: SafeArrayUnlock in Windows API. 296 func safeArrayUnlock(safearray *SafeArray) (err error) { 297 err = convertHresultToError(procSafeArrayUnlock.Call(uintptr(unsafe.Pointer(safearray)))) 298 return 299 } 300 301 // safeArrayPutElement stores the data element at the specified location in the 302 // array. 303 // 304 // AKA: SafeArrayPutElement in Windows API. 305 func safeArrayPutElement(safearray *SafeArray, index int64, element uintptr) (err error) { 306 err = convertHresultToError( 307 procSafeArrayPutElement.Call( 308 uintptr(unsafe.Pointer(safearray)), 309 uintptr(unsafe.Pointer(&index)), 310 uintptr(unsafe.Pointer(element)))) 311 return 312 } 313 314 // safeArrayGetRecordInfo accesses IRecordInfo info for custom types. 315 // 316 // AKA: SafeArrayGetRecordInfo in Windows API. 317 // 318 // XXX: Must implement IRecordInfo interface for this to return. 319 func safeArrayGetRecordInfo(safearray *SafeArray) (recordInfo interface{}, err error) { 320 err = convertHresultToError( 321 procSafeArrayGetRecordInfo.Call( 322 uintptr(unsafe.Pointer(safearray)), 323 uintptr(unsafe.Pointer(&recordInfo)))) 324 return 325 } 326 327 // safeArraySetRecordInfo mutates IRecordInfo info for custom types. 328 // 329 // AKA: SafeArraySetRecordInfo in Windows API. 330 // 331 // XXX: Must implement IRecordInfo interface for this to return. 332 func safeArraySetRecordInfo(safearray *SafeArray, recordInfo interface{}) (err error) { 333 err = convertHresultToError( 334 procSafeArraySetRecordInfo.Call( 335 uintptr(unsafe.Pointer(safearray)), 336 uintptr(unsafe.Pointer(&recordInfo)))) 337 return 338 }