github.com/hspan/go-ole@v0.0.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 int32, pv unsafe.Pointer) error {
   209  	return convertHresultToError(
   210  		procSafeArrayGetElement.Call(
   211  			uintptr(unsafe.Pointer(safearray)),
   212  			uintptr(unsafe.Pointer(&index)),
   213  			uintptr(pv)))
   214  }
   215  
   216  // safeArrayGetElementString retrieves element at given index and converts to string.
   217  func safeArrayGetElementString(safearray *SafeArray, index int32) (str string, err error) {
   218  	var element *int16
   219  	err = convertHresultToError(
   220  		procSafeArrayGetElement.Call(
   221  			uintptr(unsafe.Pointer(safearray)),
   222  			uintptr(unsafe.Pointer(&index)),
   223  			uintptr(unsafe.Pointer(&element))))
   224  	str = BstrToString(*(**uint16)(unsafe.Pointer(&element)))
   225  	SysFreeString(element)
   226  	return
   227  }
   228  
   229  // safeArrayGetIID is the InterfaceID of the elements in the SafeArray.
   230  //
   231  // AKA: SafeArrayGetIID in Windows API.
   232  func safeArrayGetIID(safearray *SafeArray) (guid *GUID, err error) {
   233  	err = convertHresultToError(
   234  		procSafeArrayGetIID.Call(
   235  			uintptr(unsafe.Pointer(safearray)),
   236  			uintptr(unsafe.Pointer(&guid))))
   237  	return
   238  }
   239  
   240  // safeArrayGetLBound returns lower bounds of SafeArray.
   241  //
   242  // SafeArrays may have multiple dimensions. Meaning, it could be
   243  // multidimensional array.
   244  //
   245  // AKA: SafeArrayGetLBound in Windows API.
   246  func safeArrayGetLBound(safearray *SafeArray, dimension uint32) (lowerBound int32, err error) {
   247  	err = convertHresultToError(
   248  		procSafeArrayGetLBound.Call(
   249  			uintptr(unsafe.Pointer(safearray)),
   250  			uintptr(dimension),
   251  			uintptr(unsafe.Pointer(&lowerBound))))
   252  	return
   253  }
   254  
   255  // safeArrayGetUBound returns upper bounds of SafeArray.
   256  //
   257  // SafeArrays may have multiple dimensions. Meaning, it could be
   258  // multidimensional array.
   259  //
   260  // AKA: SafeArrayGetUBound in Windows API.
   261  func safeArrayGetUBound(safearray *SafeArray, dimension uint32) (upperBound int32, err error) {
   262  	err = convertHresultToError(
   263  		procSafeArrayGetUBound.Call(
   264  			uintptr(unsafe.Pointer(safearray)),
   265  			uintptr(dimension),
   266  			uintptr(unsafe.Pointer(&upperBound))))
   267  	return
   268  }
   269  
   270  // safeArrayGetVartype returns data type of SafeArray.
   271  //
   272  // AKA: SafeArrayGetVartype in Windows API.
   273  func safeArrayGetVartype(safearray *SafeArray) (varType uint16, err error) {
   274  	err = convertHresultToError(
   275  		procSafeArrayGetVartype.Call(
   276  			uintptr(unsafe.Pointer(safearray)),
   277  			uintptr(unsafe.Pointer(&varType))))
   278  	return
   279  }
   280  
   281  // safeArrayLock locks SafeArray for reading to modify SafeArray.
   282  //
   283  // This must be called during some calls to ensure that another process does not
   284  // read or write to the SafeArray during editing.
   285  //
   286  // AKA: SafeArrayLock in Windows API.
   287  func safeArrayLock(safearray *SafeArray) (err error) {
   288  	err = convertHresultToError(procSafeArrayLock.Call(uintptr(unsafe.Pointer(safearray))))
   289  	return
   290  }
   291  
   292  // safeArrayUnlock unlocks SafeArray for reading.
   293  //
   294  // AKA: SafeArrayUnlock in Windows API.
   295  func safeArrayUnlock(safearray *SafeArray) (err error) {
   296  	err = convertHresultToError(procSafeArrayUnlock.Call(uintptr(unsafe.Pointer(safearray))))
   297  	return
   298  }
   299  
   300  // safeArrayPutElement stores the data element at the specified location in the
   301  // array.
   302  //
   303  // AKA: SafeArrayPutElement in Windows API.
   304  func safeArrayPutElement(safearray *SafeArray, index int64, element uintptr) (err error) {
   305  	err = convertHresultToError(
   306  		procSafeArrayPutElement.Call(
   307  			uintptr(unsafe.Pointer(safearray)),
   308  			uintptr(unsafe.Pointer(&index)),
   309  			uintptr(unsafe.Pointer(element))))
   310  	return
   311  }
   312  
   313  // safeArrayGetRecordInfo accesses IRecordInfo info for custom types.
   314  //
   315  // AKA: SafeArrayGetRecordInfo in Windows API.
   316  //
   317  // XXX: Must implement IRecordInfo interface for this to return.
   318  func safeArrayGetRecordInfo(safearray *SafeArray) (recordInfo interface{}, err error) {
   319  	err = convertHresultToError(
   320  		procSafeArrayGetRecordInfo.Call(
   321  			uintptr(unsafe.Pointer(safearray)),
   322  			uintptr(unsafe.Pointer(&recordInfo))))
   323  	return
   324  }
   325  
   326  // safeArraySetRecordInfo mutates IRecordInfo info for custom types.
   327  //
   328  // AKA: SafeArraySetRecordInfo in Windows API.
   329  //
   330  // XXX: Must implement IRecordInfo interface for this to return.
   331  func safeArraySetRecordInfo(safearray *SafeArray, recordInfo interface{}) (err error) {
   332  	err = convertHresultToError(
   333  		procSafeArraySetRecordInfo.Call(
   334  			uintptr(unsafe.Pointer(safearray)),
   335  			uintptr(unsafe.Pointer(&recordInfo))))
   336  	return
   337  }