36#include <osl/thread.h>
38#include <rtl/string.hxx>
39#include <rtl/ustring.hxx>
50using namespace css::uno;
68int __stdcall
DllMgr_call32(FARPROC,
void const * stack, std::size_t size);
69double __stdcall
DllMgr_callFp(FARPROC,
void const * stack, std::size_t size);
75char * address(std::vector< char > & blob) {
76 return blob.empty() ? 0 : &blob[0];
81 source.convertToString(
82 target, osl_getThreadTextEncoding(),
83 (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
84 RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
89ErrCode convert(
char const * source, sal_Int32 length, OUString * target) {
91 rtl_convertStringToUString(
92 &target->pData, source, length, osl_getThreadTextEncoding(),
93 (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
94 RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
95 RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
100struct UnmarshalData {
101 UnmarshalData(
SbxVariable * theVariable,
void * theBuffer):
102 variable(theVariable), buffer(theBuffer) {}
108struct StringData:
public UnmarshalData {
109 StringData(
SbxVariable * theVariable,
void * theBuffer,
bool theSpecial):
110 UnmarshalData(theVariable, theBuffer), special(theSpecial) {}
117 MarshalData() =
default;
118 MarshalData(
const MarshalData&) =
delete;
119 const MarshalData& operator=(
const MarshalData&) =
delete;
121 std::vector< char > * newBlob() {
122 blobs_.push_back(std::vector< char >());
123 return &blobs_.back();
126 std::vector< UnmarshalData > unmarshal;
128 std::vector< StringData > unmarshalStrings;
131 std::vector< std::vector< char > > blobs_;
134std::size_t align(std::size_t address, std::size_t alignment) {
136 return (address + (alignment - 1)) & ~(alignment - 1);
140 std::vector< char > & blob, std::size_t alignment, std::size_t offset,
143 std::vector< char >::size_type
n = blob.size();
144 n = align(n - offset, alignment) + offset;
145 blob.resize(n + add);
146 return address(blob) +
n;
149template<
typename T >
void add(
150 std::vector< char > & blob, T
const & data, std::size_t alignment,
153 *
reinterpret_cast< T *
>(align(blob, alignment, offset,
sizeof (T))) = data;
157 assert(variable != 0);
174 for (sal_uInt32 i = 0;
i <
props->Count(); ++
i)
176 n = std::max(n, alignment(
props->Get(i)));
190 sal_Int32 dims =
arr->GetDims();
191 std::vector< sal_Int32 > low(dims);
192 for (sal_Int32 i = 0;
i < dims; ++
i) {
194 arr->GetDim(i + 1, low[i], up);
196 return alignment(
arr->Get(&low[0]));
202 std::vector< char > & blob, std::size_t offset, MarshalData & data);
205 SbxVariable * variable,
bool special, MarshalData & data,
void ** buffer)
207 assert(variable != 0 && buffer != 0);
210 if (e != ERRCODE_NONE) {
213 std::vector< char > * blob = data.newBlob();
215 blob->begin(), str.getStr(), str.getStr() + str.getLength() + 1);
216 *buffer = address(*blob);
217 data.unmarshalStrings.push_back(StringData(variable, *buffer, special));
222 SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
225 assert(variable != 0);
229 for (sal_uInt32 i = 0;
i <
props->Count(); ++
i)
231 ErrCode e = marshal(
false,
props->Get(i),
false, blob, offset, data);
232 if (e != ERRCODE_NONE) {
240 SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
243 assert(variable != 0);
246 sal_Int32 dims =
arr->GetDims();
247 std::vector< sal_Int32 > low(dims);
248 std::vector< sal_Int32 >
up(dims);
249 for (sal_Int32 i = 0;
i < dims; ++
i) {
250 arr->GetDim(i + 1, low[i], up[i]);
252 for (std::vector< sal_Int32 > idx = low;;) {
253 ErrCode e = marshal(
false,
arr->Get(&idx[0]),
false, blob, offset, data);
254 if (e != ERRCODE_NONE) {
257 sal_Int32
i = dims - 1;
258 while (idx[i] == up[i]) {
273 std::vector< char > & blob, std::size_t offset, MarshalData & data)
275 assert(variable != 0);
286 add(blob, variable->
GetInteger(), outer ? 4 : 2, offset);
289 add(blob, variable->
GetLong(), 4, offset);
292 add(blob, variable->
GetSingle(), 4, offset);
295 add(blob, variable->
GetDouble(), outer ? 4 : 8, offset);
300 ErrCode e = marshalString(variable, special, data, &p);
301 if (e != ERRCODE_NONE) {
304 add(blob, p, 4, offset);
309 align(blob, outer ? 4 : alignment(variable), offset, 0);
310 ErrCode e = marshalStruct(variable, blob, offset, data);
311 if (e != ERRCODE_NONE) {
317 add(blob, variable->
GetBool(), outer ? 4 : 1, offset);
320 add(blob, variable->
GetByte(), outer ? 4 : 1, offset);
327 ErrCode e = marshalArray(variable, blob, offset, data);
328 if (e != ERRCODE_NONE) {
341 add(blob, variable->
data(), 4, offset);
346 ErrCode e = marshalString(variable, special, data, &p);
347 if (e != ERRCODE_NONE) {
350 std::vector< char > * blob2 = data.newBlob();
351 add(*blob2, p, 4, 0);
352 add(blob, address(*blob2), 4, offset);
357 std::vector< char > * blob2 = data.newBlob();
358 ErrCode e = marshalStruct(variable, *blob2, 0, data);
359 if (e != ERRCODE_NONE) {
362 void *
p = address(*blob2);
364 data.unmarshal.push_back(UnmarshalData(variable, p));
366 add(blob, p, 4, offset);
374 std::vector< char > * blob2 = data.newBlob();
375 ErrCode e = marshalArray(variable, *blob2, 0, data);
376 if (e != ERRCODE_NONE) {
379 void *
p = address(*blob2);
381 data.unmarshal.push_back(UnmarshalData(variable, p));
383 add(blob, p, 4, offset);
389template<
typename T > T read(
void const ** pointer) {
390 T
const *
p =
static_cast< T
const *
>(*pointer);
391 *pointer =
static_cast< void const *
>(
p + 1);
395void const * unmarshal(
SbxVariable * variable,
void const * data) {
396 assert(variable != 0);
400 variable->
PutInteger(read< sal_Int16 >(&data));
403 variable->
PutLong(read< sal_Int32 >(&data));
406 variable->
PutSingle(read< float >(&data));
409 variable->
PutDouble(read< double >(&data));
412 read< char * >(&data);
416 data =
reinterpret_cast< void const *
>(
418 reinterpret_cast< sal_uIntPtr
>(data),
419 alignment(variable)));
423 for (sal_uInt32 i = 0;
i <
props->Count(); ++
i)
425 data = unmarshal(
props->Get(i), data);
430 variable->
PutBool(read< sal_Bool >(&data));
433 variable->
PutByte(read< sal_uInt8 >(&data));
442 sal_Int32 dims =
arr->GetDims();
443 std::vector< sal_Int32 > low(dims);
444 std::vector< sal_Int32 >
up(dims);
445 for (sal_Int32 i = 0;
i < dims; ++
i) {
446 arr->GetDim(i + 1, low[i], up[i]);
448 for (std::vector< sal_Int32 > idx = low;;) {
449 data = unmarshal(
arr->Get(&idx[0]), data);
450 sal_Int32
i = dims - 1;
451 while (idx[i] == up[i]) {
467 if (data.buffer != 0) {
468 char const *
p =
static_cast< char const *
>(data.buffer);
471 len =
static_cast< sal_Int32
>(
result.GetULong());
477 len = rtl_str_getLength(p);
480 if (e != ERRCODE_NONE) {
484 data.variable->PutString(str);
494 OUString
const & dll, ProcData
const & proc,
SbxArray * arguments,
497 std::vector< char > stack;
503 bool special = dll.equalsIgnoreAsciiCase(
"KERNEL32.DLL") &&
504 (proc.name == OString(
"GetLogicalDriveStringsA"));
505 for (sal_uInt32 i = 1;
i < (arguments == 0 ? 0 : arguments->
Count()); ++
i)
507 ErrCode e = marshal(
true, arguments->Get(i), special && i == 2, stack, stack.size(),
509 if (e != ERRCODE_NONE) {
512 align(stack, 4, 0, 0);
514 switch (
result.GetType()) {
520 static_cast< sal_Int16
>(
525 static_cast< sal_Int32
>(
530 static_cast< float >(
539 char const * s1 =
reinterpret_cast< char const *
>(
543 if (e != ERRCODE_NONE) {
555 bool(
DllMgr_call32(proc.proc, address(stack), stack.size())));
566 for (sal_uInt32 i = 1;
i < (arguments == 0 ? 0 : arguments->Count()); ++
i)
571 for (
auto& rUnmarshalData : data.unmarshal)
573 unmarshal(rUnmarshalData.variable, rUnmarshalData.buffer);
575 for (
const auto& rStringData : data.unmarshalStrings)
577 ErrCode e = unmarshalString(rStringData, result);
578 if (e != ERRCODE_NONE) {
585ErrCode getProcData(HMODULE handle, OUString
const & name, ProcData * proc)
588 if ( !
name.isEmpty() && name[0] ==
'@' ) {
590 if (n <= 0 || n > 0xFFFF) {
593 FARPROC
p = GetProcAddress(handle,
reinterpret_cast< LPCSTR
>(n));
595 proc->name = OString(
"#") + OString::number(n);
602 if (e != ERRCODE_NONE) {
605 FARPROC
p = GetProcAddress(handle, name8.getStr());
611 sal_Int32
i = name8.indexOf(
'#');
613 name8 = name8.copy(0, i);
614 p = GetProcAddress(handle, name8.getStr());
621 OString real(OString(
"_") + name8);
622 p = GetProcAddress(handle, real.getStr());
628 real = name8 + OString(
"A");
629 p = GetProcAddress(handle, real.getStr());
641 typedef std::map< OUString, ProcData > Procs;
648 ErrCode getProc(OUString
const & name, ProcData * proc);
655 if (handle != 0 && !FreeLibrary(handle)) {
656 SAL_WARN(
"basic",
"FreeLibrary(" << handle <<
") failed with " << GetLastError());
660ErrCode Dll::getProc(OUString
const & name, ProcData * proc) {
661 Procs::iterator
i(procs.find(name));
662 if (i != procs.end()) {
666 ErrCode e = getProcData(handle, name, proc);
667 if (e == ERRCODE_NONE) {
668 procs.emplace(name, *proc);
673OUString fullDllName(OUString
const & name) {
675 if (full.indexOf(
'.') == -1) {
685 typedef std::map< OUString, rtl::Reference< Dll > >
Dlls;
698 Dlls::iterator
i(
dlls.find(name));
699 if (i ==
dlls.end()) {
700 i =
dlls.emplace(name,
new Dll).first;
701 HMODULE
h = LoadLibraryW(o3tl::toW(
name.getStr()));
706 i->second->handle =
h;
708 return i->second.get();
712 std::u16string_view function, std::u16string_view library,
715 if (cdeclConvention) {
718 OUString dllName(fullDllName(OUString(library)));
719 Dll * dll = impl_->getDll(dllName);
724 ErrCode e = dll->getProc(OUString(function), &proc);
725 if (e != ERRCODE_NONE) {
728 return call(dllName, proc, arguments, result);
732 impl_->dlls.erase(library);
737SbiDllMgr::~SbiDllMgr() {}
ErrCode Call(std::u16string_view function, std::u16string_view library, SbxArray *arguments, SbxVariable &result, bool cdeclConvention)
void FreeDll(OUString const &library)
static bool isVBAEnabled()
SbxFlagBits GetFlags() const
SbxArray * GetProperties()
OUString GetOUString() const
SbxBase * GetObject() const
sal_uInt8 GetByte() const
bool PutInteger(sal_Int16)
sal_Int32 GetLong() const
sal_Int16 GetInteger() const
virtual SbxDataType GetType() const override
int __stdcall DllMgr_call32(FARPROC, void const *stack, std::size_t size)
double __stdcall DllMgr_callFp(FARPROC, void const *stack, std::size_t size)
DECL_LISTENERMULTIPLEXER_END void SAL_CALL up(const css::awt::SpinEvent &rEvent) override
#define SAL_WARN(area, stream)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
#define ERRCODE_BASIC_PROC_UNDEFINED
#define ERRCODE_BASIC_BAD_ARGUMENT
#define ERRCODE_BASIC_NOT_IMPLEMENTED
#define ERRCODE_BASIC_BAD_DLL_LOAD
std::map< OUString, ::rtl::Reference< Dll > > Dlls
const Impl & operator=(const Impl &)=delete
Dll * getDll(OUString const &name)
Impl(const Impl &)=delete
std::map< OUString, rtl::Reference< Dll > > Dlls