123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339 |
- #include "il2cpp-config.h"
- #include "il2cpp-object-internals.h"
- #include "vm/Array.h"
- #include "vm/COM.h"
- #include "vm/Exception.h"
- #include "vm/PlatformInvoke.h"
- #include "vm/Reflection.h"
- #include "os/COM.h"
- namespace il2cpp
- {
- namespace vm
- {
- void COM::MarshalVariant(Il2CppObject* obj, Il2CppVariant* variant)
- {
- IL2CPP_ASSERT(variant);
- os::COM::VariantInit(variant);
- if (!obj)
- return;
- if (obj->klass == il2cpp_defaults.sbyte_class)
- {
- variant->n1.n2.type = IL2CPP_VT_I1;
- variant->n1.n2.n3.cVal = *static_cast<int8_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.byte_class)
- {
- variant->n1.n2.type = IL2CPP_VT_UI1;
- variant->n1.n2.n3.bVal = *static_cast<uint8_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.int16_class)
- {
- variant->n1.n2.type = IL2CPP_VT_I2;
- variant->n1.n2.n3.iVal = *static_cast<int16_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.uint16_class)
- {
- variant->n1.n2.type = IL2CPP_VT_UI2;
- variant->n1.n2.n3.uiVal = *static_cast<uint16_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.int32_class)
- {
- variant->n1.n2.type = IL2CPP_VT_I4;
- variant->n1.n2.n3.lVal = *static_cast<int32_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.uint32_class)
- {
- variant->n1.n2.type = IL2CPP_VT_UI4;
- variant->n1.n2.n3.ulVal = *static_cast<uint32_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.int64_class)
- {
- variant->n1.n2.type = IL2CPP_VT_I8;
- variant->n1.n2.n3.llVal = *static_cast<int64_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.uint64_class)
- {
- variant->n1.n2.type = IL2CPP_VT_UI8;
- variant->n1.n2.n3.ullVal = *static_cast<uint64_t*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.single_class)
- {
- variant->n1.n2.type = IL2CPP_VT_R4;
- variant->n1.n2.n3.fltVal = *static_cast<float*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.double_class)
- {
- variant->n1.n2.type = IL2CPP_VT_R8;
- variant->n1.n2.n3.dblVal = *static_cast<double*>(Object::Unbox(obj));
- }
- else if (obj->klass == il2cpp_defaults.boolean_class)
- {
- variant->n1.n2.type = IL2CPP_VT_BOOL;
- variant->n1.n2.n3.boolVal = *static_cast<bool*>(Object::Unbox(obj)) ? IL2CPP_VARIANT_TRUE : IL2CPP_VARIANT_FALSE;
- }
- else if (obj->klass == il2cpp_defaults.string_class)
- {
- variant->n1.n2.type = IL2CPP_VT_BSTR;
- variant->n1.n2.n3.bstrVal = PlatformInvoke::MarshalCSharpStringToCppBString(reinterpret_cast<Il2CppString*>(obj));
- }
- else if (obj->klass == il2cpp_defaults.dbnull_class)
- {
- variant->n1.n2.type = IL2CPP_VT_NULL;
- }
- else if (obj->klass == il2cpp_defaults.error_wrapper_class)
- {
- variant->n1.n2.type = IL2CPP_VT_ERROR;
- variant->n1.n2.n3.scode = reinterpret_cast<Il2CppErrorWrapper*>(obj)->errorCode;
- }
- else if (obj->klass == il2cpp_defaults.missing_class)
- {
- variant->n1.n2.type = IL2CPP_VT_ERROR;
- variant->n1.n2.n3.scode = IL2CPP_DISP_E_PARAMNOTFOUND;
- }
- else
- {
- Exception::Raise(IL2CPP_E_INVALIDARG, true);
- }
- }
- Il2CppObject* COM::MarshalVariantResult(const Il2CppVariant* variant)
- {
- IL2CPP_ASSERT(variant);
- switch (variant->n1.n2.type)
- {
- case IL2CPP_VT_EMPTY:
- return NULL;
- case IL2CPP_VT_NULL:
- return Reflection::GetDBNullObject();
- case IL2CPP_VT_ERROR:
- {
- int32_t val = variant->n1.n2.n3.scode;
- return Object::Box(il2cpp_defaults.int32_class, &val);
- }
- case IL2CPP_VT_I1:
- {
- char val = variant->n1.n2.n3.cVal;
- return Object::Box(il2cpp_defaults.sbyte_class, &val);
- }
- case IL2CPP_VT_UI1:
- {
- uint8_t val = variant->n1.n2.n3.bVal;
- return Object::Box(il2cpp_defaults.byte_class, &val);
- }
- case IL2CPP_VT_I2:
- {
- int16_t val = variant->n1.n2.n3.iVal;
- return Object::Box(il2cpp_defaults.int16_class, &val);
- }
- case IL2CPP_VT_UI2:
- {
- uint16_t val = variant->n1.n2.n3.uiVal;
- return Object::Box(il2cpp_defaults.uint16_class, &val);
- }
- case IL2CPP_VT_I4:
- {
- int32_t val = variant->n1.n2.n3.lVal;
- return Object::Box(il2cpp_defaults.int32_class, &val);
- }
- case IL2CPP_VT_UI4:
- {
- uint32_t val = variant->n1.n2.n3.ulVal;
- return Object::Box(il2cpp_defaults.uint32_class, &val);
- }
- case IL2CPP_VT_I8:
- {
- int64_t val = variant->n1.n2.n3.llVal;
- return Object::Box(il2cpp_defaults.int64_class, &val);
- }
- case IL2CPP_VT_UI8:
- {
- uint64_t val = variant->n1.n2.n3.ullVal;
- return Object::Box(il2cpp_defaults.uint64_class, &val);
- }
- case IL2CPP_VT_R4:
- {
- float val = variant->n1.n2.n3.fltVal;
- return Object::Box(il2cpp_defaults.single_class, &val);
- }
- case IL2CPP_VT_R8:
- {
- double val = variant->n1.n2.n3.dblVal;
- return Object::Box(il2cpp_defaults.double_class, &val);
- }
- case IL2CPP_VT_BOOL:
- {
- IL2CPP_ASSERT(variant->n1.n2.n3.boolVal == IL2CPP_VARIANT_FALSE || variant->n1.n2.n3.boolVal == IL2CPP_VARIANT_TRUE);
- bool value = variant->n1.n2.n3.boolVal != IL2CPP_VARIANT_FALSE;
- return Object::Box(il2cpp_defaults.boolean_class, &value);
- }
- case IL2CPP_VT_BSTR:
- return reinterpret_cast<Il2CppObject*>(PlatformInvoke::MarshalCppBStringToCSharpStringResult(variant->n1.n2.n3.bstrVal));
- default:
- Exception::Raise(IL2CPP_E_INVALIDARG, true);
- return NULL;
- }
- }
- void COM::DestroyVariant(Il2CppVariant* variant)
- {
- const il2cpp_hresult_t hr = os::COM::VariantClear(variant);
- vm::Exception::RaiseIfFailed(hr, true);
- }
- Il2CppSafeArray* COM::MarshalSafeArray(uint16_t variantType, Il2CppArray* managedArray)
- {
- if (!managedArray)
- return NULL;
- Il2CppSafeArrayBound bounds[1];
- bounds[0].element_count = Array::GetLength(managedArray);
- bounds[0].lower_bound = 0;
- Il2CppSafeArray* safeArray = os::COM::SafeArrayCreate(variantType, 1, bounds);
- if (!safeArray)
- Exception::Raise(IL2CPP_E_OUTOFMEMORY, true);
- void* data;
- il2cpp_hresult_t hr = os::COM::SafeArrayAccessData(safeArray, &data);
- if (IL2CPP_HR_FAILED(hr))
- {
- os::COM::SafeArrayDestroy(safeArray);
- Exception::Raise(hr, true);
- }
- ::memcpy(data, Array::GetFirstElementAddress(managedArray), Array::GetByteLength(managedArray));
- hr = os::COM::SafeArrayUnaccessData(safeArray);
- if (IL2CPP_HR_FAILED(hr))
- {
- os::COM::SafeArrayDestroy(safeArray);
- Exception::Raise(hr, true);
- }
- return safeArray;
- }
- Il2CppArray* COM::MarshalSafeArrayResult(uint16_t variantType, Il2CppClass* type, Il2CppSafeArray* safeArray)
- {
- if (!safeArray)
- return NULL;
- uint16_t actualVariantType;
- il2cpp_hresult_t hr = os::COM::SafeArrayGetVartype(safeArray, &actualVariantType);
- vm::Exception::RaiseIfFailed(hr, true);
- if (actualVariantType != variantType)
- Exception::Raise(IL2CPP_E_INVALIDARG, true);
- const uint32_t actualDimentionCount = os::COM::SafeArrayGetDim(safeArray);
- if (actualDimentionCount != 1)
- Exception::Raise(IL2CPP_E_INVALIDARG, true);
- int32_t lowerBound;
- hr = os::COM::SafeArrayGetLBound(safeArray, 1, &lowerBound);
- vm::Exception::RaiseIfFailed(hr, true);
- int32_t upperBound;
- hr = os::COM::SafeArrayGetUBound(safeArray, 1, &upperBound);
- vm::Exception::RaiseIfFailed(hr, true);
- const il2cpp_array_size_t size = static_cast<il2cpp_array_size_t>(upperBound - lowerBound + 1);
- Il2CppArray* managedArray = Array::New(type, size);
- void* data;
- hr = os::COM::SafeArrayAccessData(safeArray, &data);
- vm::Exception::RaiseIfFailed(hr, true);
- ::memcpy(Array::GetFirstElementAddress(managedArray), data, Array::GetByteLength(managedArray));
- hr = os::COM::SafeArrayUnaccessData(safeArray);
- vm::Exception::RaiseIfFailed(hr, true);
- return managedArray;
- }
- Il2CppSafeArray* COM::MarshalSafeArrayBString(Il2CppArray* managedArray)
- {
- if (!managedArray)
- return NULL;
- const uint32_t size = Array::GetLength(managedArray);
- Il2CppSafeArrayBound bounds[1];
- bounds[0].element_count = size;
- bounds[0].lower_bound = 0;
- Il2CppSafeArray* safeArray = os::COM::SafeArrayCreate(IL2CPP_VT_BSTR, 1, bounds);
- if (!safeArray)
- Exception::Raise(IL2CPP_E_OUTOFMEMORY, true);
- Il2CppChar** data;
- il2cpp_hresult_t hr = os::COM::SafeArrayAccessData(safeArray, reinterpret_cast<void**>(&data));
- if (IL2CPP_HR_FAILED(hr))
- {
- os::COM::SafeArrayDestroy(safeArray);
- Exception::Raise(hr, true);
- }
- for (uint32_t i = 0; i < size; ++i)
- {
- Il2CppString* managedString = il2cpp_array_get(managedArray, Il2CppString*, i);
- hr = PlatformInvoke::MarshalCSharpStringToCppBStringNoThrow(managedString, data + i);
- if (IL2CPP_HR_FAILED(hr))
- {
- os::COM::SafeArrayUnaccessData(safeArray);
- os::COM::SafeArrayDestroy(safeArray);
- Exception::Raise(hr, true);
- }
- }
- hr = os::COM::SafeArrayUnaccessData(safeArray);
- if (IL2CPP_HR_FAILED(hr))
- {
- os::COM::SafeArrayDestroy(safeArray);
- Exception::Raise(hr, true);
- }
- return safeArray;
- }
- Il2CppArray* COM::MarshalSafeArrayBStringResult(Il2CppClass* type, Il2CppSafeArray* safeArray)
- {
- if (!safeArray)
- return NULL;
- uint16_t actualVariantType;
- il2cpp_hresult_t hr = os::COM::SafeArrayGetVartype(safeArray, &actualVariantType);
- vm::Exception::RaiseIfFailed(hr, true);
- if (actualVariantType != IL2CPP_VT_BSTR)
- Exception::Raise(IL2CPP_E_INVALIDARG, true);
- const uint32_t actualDimentionCount = os::COM::SafeArrayGetDim(safeArray);
- if (actualDimentionCount != 1)
- Exception::Raise(IL2CPP_E_INVALIDARG, true);
- int32_t lowerBound;
- hr = os::COM::SafeArrayGetLBound(safeArray, 1, &lowerBound);
- vm::Exception::RaiseIfFailed(hr, true);
- int32_t upperBound;
- hr = os::COM::SafeArrayGetUBound(safeArray, 1, &upperBound);
- vm::Exception::RaiseIfFailed(hr, true);
- const il2cpp_array_size_t size = static_cast<il2cpp_array_size_t>(upperBound - lowerBound + 1);
- Il2CppArray* managedArray = Array::New(il2cpp_defaults.string_class, size);
- Il2CppChar** data;
- hr = os::COM::SafeArrayAccessData(safeArray, reinterpret_cast<void**>(&data));
- vm::Exception::RaiseIfFailed(hr, true);
- for (il2cpp_array_size_t i = 0; i < size; ++i)
- il2cpp_array_setref(managedArray, i, PlatformInvoke::MarshalCppBStringToCSharpStringResult(data[i]));
- hr = os::COM::SafeArrayUnaccessData(safeArray);
- vm::Exception::RaiseIfFailed(hr, true);
- return managedArray;
- }
- } /* namespace vm */
- } /* namespace il2cpp */
|