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  }