ErrCode marshalStruct(
SbxVariable const * variable, std::vector< char > & blob, std::size_t offset,
MarshalData & data)
{
assert(variable != nullptr);
SbxObject* pobj = dynamic_cast<SbxObject*>(variable->GetObject());
assert(pobj);
SbxArray* props = pobj->GetProperties(); for (sal_uInt32 i = 0; i < props->Count(); ++i)
{
ErrCode e = marshal(false, props->Get(i), false, blob, offset, data); if (e != ERRCODE_NONE) { return e;
}
} return ERRCODE_NONE;
}
ErrCode marshalArray(
SbxVariable const * variable, std::vector< char > & blob, std::size_t offset,
MarshalData & data)
{
assert(variable != nullptr);
SbxDimArray * arr = dynamic_cast<SbxDimArray*>( variable->GetObject() );
assert(arr);
sal_Int32 dims = arr->GetDims();
std::vector< sal_Int32 > low(dims);
std::vector< sal_Int32 > up(dims); for (sal_Int32 i = 0; i < dims; ++i) {
arr->GetDim(i + 1, low[i], up[i]);
} for (std::vector< sal_Int32 > idx = low;;) {
ErrCode e = marshal(false, arr->Get(idx.data()), false, blob, offset, data); if (e != ERRCODE_NONE) { return e;
}
sal_Int32 i = dims - 1; while (idx[i] == up[i]) {
idx[i] = low[i]; if (i == 0) { return ERRCODE_NONE;
}
--i;
}
++idx[i];
}
}
// 8-aligned structs are only 4-aligned on stack, so alignment of members in // such structs must take that into account via "offset"
ErrCode marshal( bool outer, SbxVariable * variable, bool special,
std::vector< char > & blob, std::size_t offset, MarshalData & data)
{
assert(variable != nullptr);
// For DWORD GetLogicalDriveStringsA(DWORD nBufferLength, LPSTR lpBuffer) // from kernel32, upon return, filled lpBuffer length is result DWORD, which // requires special handling in unmarshalString; other functions might // require similar treatment, too: bool special =
o3tl::equalsIgnoreAsciiCase(dll, u"KERNEL32.DLL") &&
(proc.name == "GetLogicalDriveStringsA"); for (sal_uInt32 i = 1; i < (arguments == nullptr ? 0 : arguments->Count()); ++i)
{
ErrCode e = marshal(true, arguments->Get(i), special && i == 2, stack, stack.size(),
data); if (e != ERRCODE_NONE) { return e;
}
align(stack, 8, 0, 0);
}
stack.resize(20*8);
// We fake all calls as being to a varargs function, // as this means any floating-point argument among the first four // ones will end up in a XMM register where the callee expects it.
sal_Int64 iRetVal = 0; double dRetVal = 0.0;
switch (result.GetType()) { case SbxEMPTY: case SbxINTEGER: case SbxLONG: case SbxSTRING: case SbxOBJECT: case SbxBOOL: case SbxBYTE:
{ auto p = reinterpret_cast<sal_Int64 (*)(...)>(proc.proc); autoconst st = reinterpret_cast<double *>(stack.data());
iRetVal
= p(st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], st[8], st[9], st[10],
st[11], st[12], st[13], st[14], st[15], st[16], st[17], st[18], st[19]); break;
} case SbxSINGLE: case SbxDOUBLE:
{ auto p = reinterpret_cast<double (*)(...)>(proc.proc); autoconst st = reinterpret_cast<double*>(stack.data());
dRetVal
= p(st[0], st[1], st[2], st[3], st[4], st[5], st[6], st[7], st[8], st[9], st[10],
st[11], st[12], st[13], st[14], st[15], st[16], st[17], st[18], st[19]); break;
} default: break;
}
switch (result.GetType()) { case SbxEMPTY: break; case SbxINTEGER:
result.PutInteger(static_cast< sal_Int16 >(iRetVal)); break; case SbxLONG:
result.PutLong(static_cast< sal_Int32 >(iRetVal)); break; case SbxSINGLE:
result.PutSingle(static_cast< float >(dRetVal)); break; case SbxDOUBLE:
result.PutDouble(dRetVal); break; case SbxSTRING:
{ charconst * s1 = reinterpret_cast< charconst * >(iRetVal);
OUString s2;
ErrCode e = convert(s1, rtl_str_getLength(s1), &s2); if (e != ERRCODE_NONE) { return e;
}
result.PutString(s2); break;
} case SbxOBJECT: //TODO break; case SbxBOOL:
result.PutBool(bool(iRetVal)); break; case SbxBYTE:
result.PutByte(static_cast< sal_uInt8 >(iRetVal)); break; default:
assert(false); break;
} for (sal_uInt32 i = 1; i < (arguments == nullptr ? 0 : arguments->Count()); ++i)
{
arguments->Get(i)->ResetFlag(SbxFlagBits::Reference); //TODO: skipped for errors?!?
} for (autoconst& elem : data.unmarshal)
{
unmarshal(elem.variable, elem.buffer);
} for (autoconst& elem : data.unmarshalStrings)
{
ErrCode e = unmarshalString(elem, result); if (e != ERRCODE_NONE) { return e;
}
} return ERRCODE_NONE;
}
ErrCode getProcData(HMODULE handle, OUString const & name, ProcData * proc)
{
assert(proc != nullptr); if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"???
sal_IntPtr n = o3tl::toInt32(name.subView(1)); //TODO: handle bad input if (n <= 0 || n > 0xFFFF) { return ERRCODE_BASIC_BAD_ARGUMENT; //TODO: more specific errcode?
}
FARPROC p = GetProcAddress(handle, reinterpret_cast< LPCSTR >(n)); if (p != nullptr) {
proc->name = "#" + OString::number(n);
proc->proc = p; return ERRCODE_NONE;
}
} else {
OString name8;
ErrCode e = convert(name, &name8); if (e != ERRCODE_NONE) { return e;
}
FARPROC p = GetProcAddress(handle, name8.getStr()); if (p != nullptr) {
proc->name = name8;
proc->proc = p; return ERRCODE_NONE;
}
sal_Int32 i = name8.indexOf('#'); if (i != -1) {
name8 = name8.copy(0, i);
p = GetProcAddress(handle, name8.getStr()); if (p != nullptr) {
proc->name = name8;
proc->proc = p; return ERRCODE_NONE;
}
}
OString real("_" + name8);
p = GetProcAddress(handle, real.getStr()); if (p != nullptr) {
proc->name = real;
proc->proc = p; return ERRCODE_NONE;
}
real = name8 + "A";
p = GetProcAddress(handle, real.getStr()); if (p != nullptr) {
proc->name = real;
proc->proc = p; return ERRCODE_NONE;
}
} return ERRCODE_BASIC_PROC_UNDEFINED;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.