[Libreoffice-commits] .: 4 commits - avmedia/source basic/source .gitignore sfx2/source
Tor Lillqvist
tml at kemper.freedesktop.org
Mon Jan 24 10:55:31 PST 2011
.gitignore | 4
avmedia/source/win/player.cxx | 3
basic/source/runtime/dllmgr-none.cxx | 64 ++
basic/source/runtime/dllmgr-x64.cxx | 772 +++++++++++++++++++++++++++++++++++
basic/source/runtime/dllmgr-x86.cxx | 722 ++++++++++++++++++++++++++++++++
basic/source/runtime/dllmgr.cxx | 741 ---------------------------------
basic/source/runtime/makefile.mk | 22
basic/source/runtime/wnt-x86.asm | 56 ++
basic/source/runtime/wnt.asm | 56 --
sfx2/source/bastyp/progress.cxx | 2
10 files changed, 1635 insertions(+), 807 deletions(-)
New commits:
commit d9d430de93fae2a47bac6b143e2579cca1714bfe
Author: Tor Lillqvist <tlillqvist at novell.com>
Date: Mon Jan 24 20:50:35 2011 +0200
Add x64 Windows implementation of SbiDllMgr
Work in progress. The passing of struct parameters is for sure
incorrect, for instance: A temporary copy needs to be allocated and
its address passed.
No assembly involved. The idea is to call the external function as if
it was a varargs one, and passing the four first qword-size parameters
as if they were doubles, thus nicely causing them to be both in the
integer and floating-point parameter registers, from either of which
the callee will get them, depending on their actual expected type.
Rename existing files a bit for clarity.
diff --git a/basic/source/runtime/dllmgr-none.cxx b/basic/source/runtime/dllmgr-none.cxx
new file mode 100644
index 0000000..db32b64
--- /dev/null
+++ b/basic/source/runtime/dllmgr-none.cxx
@@ -0,0 +1,64 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_basic.hxx"
+#include "sal/config.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <list>
+#include <map>
+#include <vector>
+
+#include "basic/sbx.hxx"
+#include "basic/sbxvar.hxx"
+#include "osl/thread.h"
+#include "rtl/ref.hxx"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "tools/svwin.h"
+
+#include "dllmgr.hxx"
+
+struct SbiDllMgr::Impl {};
+
+SbError SbiDllMgr::Call(
+ rtl::OUString const &, rtl::OUString const &, SbxArray *, SbxVariable &,
+ bool)
+{
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+}
+
+void SbiDllMgr::FreeDll(rtl::OUString const &) {}
+
+SbiDllMgr::SbiDllMgr(): impl_(new Impl) {}
+
+SbiDllMgr::~SbiDllMgr() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/runtime/dllmgr-x64.cxx b/basic/source/runtime/dllmgr-x64.cxx
new file mode 100644
index 0000000..aa3ce5e
--- /dev/null
+++ b/basic/source/runtime/dllmgr-x64.cxx
@@ -0,0 +1,772 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_basic.hxx"
+#include "sal/config.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <list>
+#include <map>
+#include <vector>
+
+#include "basic/sbx.hxx"
+#include "basic/sbxvar.hxx"
+#include "osl/thread.h"
+#include "rtl/ref.hxx"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "tools/svwin.h"
+
+#undef max
+
+#include "dllmgr.hxx"
+
+/* Open issues:
+
+ Missing support for functions returning structs (see TODO in call()).
+
+ Missing support for additional data types (64 bit integers, Any, ...; would
+ trigger OSL_ASSERT(false) in various switches).
+
+ It is assumed that the variables passed into SbiDllMgr::Call to represent
+ the arguments and return value have types that exactly match the Declare
+ statement; it would be better if this code had access to the function
+ signature from the Declare statement, so that it could convert the passed
+ variables accordingly.
+*/
+
+namespace {
+
+char * address(std::vector< char > & blob) {
+ return blob.empty() ? 0 : &blob[0];
+}
+
+SbError convert(rtl::OUString const & source, rtl::OString * target) {
+ return
+ source.convertToString(
+ target, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+}
+
+SbError convert(char const * source, sal_Int32 length, rtl::OUString * target) {
+ return
+ rtl_convertStringToUString(
+ &target->pData, source, length, osl_getThreadTextEncoding(),
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+}
+
+struct UnmarshalData {
+ UnmarshalData(SbxVariable * theVariable, void * theBuffer):
+ variable(theVariable), buffer(theBuffer) {}
+
+ SbxVariable * variable;
+ void * buffer;
+};
+
+struct StringData: public UnmarshalData {
+ StringData(SbxVariable * theVariable, void * theBuffer, bool theSpecial):
+ UnmarshalData(theVariable, theBuffer), special(theSpecial) {}
+
+ bool special;
+};
+
+class MarshalData: private boost::noncopyable {
+public:
+ std::vector< char > * newBlob() {
+ blobs_.push_front(std::vector< char >());
+ return &blobs_.front();
+ }
+
+ std::vector< UnmarshalData > unmarshal;
+
+ std::vector< StringData > unmarshalStrings;
+
+private:
+ std::list< std::vector< char > > blobs_;
+};
+
+std::size_t align(std::size_t address, std::size_t alignment) {
+ // alignment = 2^k for some k >= 0
+ return (address + (alignment - 1)) & ~(alignment - 1);
+}
+
+char * align(
+ std::vector< char > & blob, std::size_t alignment, std::size_t offset,
+ std::size_t add)
+{
+ std::vector< char >::size_type n = blob.size();
+ n = align(n - offset, alignment) + offset; //TODO: overflow in align()
+ blob.resize(n + add); //TODO: overflow
+ return address(blob) + n;
+}
+
+template< typename T > void add(
+ std::vector< char > & blob, T const & data, std::size_t alignment,
+ std::size_t offset)
+{
+ *reinterpret_cast< T * >(align(blob, alignment, offset, sizeof (T))) = data;
+}
+
+std::size_t alignment(SbxVariable * variable) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ return 2;
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxSTRING:
+ return 4;
+ case SbxDOUBLE:
+ return 8;
+ case SbxOBJECT:
+ {
+ std::size_t n = 1;
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ n = std::max(n, alignment(props->Get(i)));
+ }
+ return n;
+ }
+ case SbxBOOL:
+ case SbxBYTE:
+ return 1;
+ default:
+ OSL_ASSERT(false);
+ return 1;
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ for (int i = 0; i < dims; ++i) {
+ INT32 up;
+ arr->GetDim32(i + 1, low[i], up);
+ }
+ return alignment(arr->Get32(&low[0]));
+ }
+}
+
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data);
+
+SbError marshalString(
+ SbxVariable * variable, bool special, MarshalData & data, void ** buffer)
+{
+ OSL_ASSERT(variable != 0 && buffer != 0);
+ rtl::OString str;
+ SbError e = convert(variable->GetString(), &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ std::vector< char > * blob = data.newBlob();
+ blob->insert(blob->begin(), str.getStr(), str.getStr() + str.getLength());
+ *buffer = address(*blob);
+ data.unmarshalStrings.push_back(StringData(variable, *buffer, special));
+ return ERRCODE_NONE;
+}
+
+SbError marshalStruct(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ SbError e = marshal(false, props->Get(i), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+SbError marshalArray(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ SbError e = marshal(
+ false, arr->Get32(&idx[0]), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ int 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"
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetFlags() & SBX_REFERENCE) == 0) {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ add(blob, variable->GetInteger(), outer ? 8 : 2, offset);
+ break;
+ case SbxLONG:
+ add(blob, variable->GetLong(), outer ? 8 : 4, offset);
+ break;
+ case SbxSINGLE:
+ add(blob, variable->GetSingle(), outer ? 8 : 4, offset);
+ break;
+ case SbxDOUBLE:
+ add(blob, variable->GetDouble(), 8, offset);
+ break;
+ case SbxSTRING:
+ {
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(blob, p, 8, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ align(blob, outer ? 8 : alignment(variable), offset, 0);
+ SbError e = marshalStruct(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ break;
+ }
+ case SbxBOOL:
+ add(blob, variable->GetBool(), outer ? 8 : 1, offset);
+ break;
+ case SbxBYTE:
+ add(blob, variable->GetByte(), outer ? 8 : 1, offset);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ SbError e = marshalArray(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ } else {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ case SbxBOOL:
+ case SbxBYTE:
+ add(blob, variable->data(), 8, offset);
+ break;
+ case SbxSTRING:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(*blob2, p, 8, 0);
+ add(blob, address(*blob2), 8, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalStruct(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 8, offset);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalArray(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 8, offset);
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+template< typename T > T read(void const ** pointer) {
+ T const * p = static_cast< T const * >(*pointer);
+ *pointer = static_cast< void const * >(p + 1);
+ return *p;
+}
+
+void const * unmarshal(SbxVariable * variable, void const * data) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ variable->PutInteger(read< sal_Int16 >(&data));
+ break;
+ case SbxLONG:
+ variable->PutLong(read< sal_Int32 >(&data));
+ break;
+ case SbxSINGLE:
+ variable->PutSingle(read< float >(&data));
+ break;
+ case SbxDOUBLE:
+ variable->PutDouble(read< double >(&data));
+ break;
+ case SbxSTRING:
+ read< char * >(&data); // handled by unmarshalString
+ break;
+ case SbxOBJECT:
+ {
+ data = reinterpret_cast< void const * >(
+ align(
+ reinterpret_cast< sal_uIntPtr >(data),
+ alignment(variable)));
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ data = unmarshal(props->Get(i), data);
+ }
+ break;
+ }
+ case SbxBOOL:
+ variable->PutBool(read< sal_Bool >(&data));
+ break;
+ case SbxBYTE:
+ variable->PutByte(read< sal_uInt8 >(&data));
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ data = unmarshal(arr->Get32(&idx[0]), data);
+ int i = dims - 1;
+ while (idx[i] == up[i]) {
+ idx[i] = low[i];
+ if (i == 0) {
+ goto done;
+ }
+ --i;
+ }
+ ++idx[i];
+ }
+ done:;
+ }
+ return data;
+}
+
+SbError unmarshalString(StringData const & data, SbxVariable & result) {
+ rtl::OUString str;
+ if (data.buffer != 0) {
+ char const * p = static_cast< char const * >(data.buffer);
+ sal_Int32 len;
+ if (data.special) {
+ len = static_cast< sal_Int32 >(result.GetULong());
+ if (len < 0) { // i.e., DWORD result >= 2^31
+ return ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+ }
+ } else {
+ len = rtl_str_getLength(p);
+ }
+ SbError e = convert(p, len, &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ data.variable->PutString(String(str));
+ return ERRCODE_NONE;
+}
+
+struct ProcData {
+ rtl::OString name;
+ FARPROC proc;
+};
+
+SbError call(
+ rtl::OUString const & dll, ProcData const & proc, SbxArray * arguments,
+ SbxVariable & result)
+{
+ if (arguments->Count() > 20)
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+
+ std::vector< char > stack;
+ MarshalData data;
+
+ // 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 =
+ dll.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("KERNEL32.DLL")) &&
+ (proc.name ==
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("GetLogicalDriveStringsA")));
+ for (int i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ SbError 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_Int32 (*proc_i)(double d, ...) = (sal_Int32 (*)(double, ...)) proc.proc;
+ double (*proc_d)(double d, ...) = (double (*)(double, ...)) proc.proc;
+
+ sal_Int64 iRetVal;
+ double dRetVal;
+
+ switch (result.GetType()) {
+ case SbxEMPTY:
+ case SbxINTEGER:
+ case SbxLONG:
+ case SbxSTRING:
+ case SbxOBJECT:
+ case SbxBOOL:
+ case SbxBYTE:
+ iRetVal =
+ proc_i(*(double *)&stack[0*8],
+ *(double *)&stack[1*8],
+ *(double *)&stack[2*8],
+ *(double *)&stack[3*8],
+ *(sal_uInt64 *)&stack[4*8],
+ *(sal_uInt64 *)&stack[5*8],
+ *(sal_uInt64 *)&stack[6*8],
+ *(sal_uInt64 *)&stack[7*8],
+ *(sal_uInt64 *)&stack[8*8],
+ *(sal_uInt64 *)&stack[9*8],
+ *(sal_uInt64 *)&stack[10*8],
+ *(sal_uInt64 *)&stack[11*8],
+ *(sal_uInt64 *)&stack[12*8],
+ *(sal_uInt64 *)&stack[13*8],
+ *(sal_uInt64 *)&stack[14*8],
+ *(sal_uInt64 *)&stack[15*8],
+ *(sal_uInt64 *)&stack[16*8],
+ *(sal_uInt64 *)&stack[17*8],
+ *(sal_uInt64 *)&stack[18*8],
+ *(sal_uInt64 *)&stack[19*8]);
+ break;
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ dRetVal =
+ proc_d(*(double *)&stack[0*8],
+ *(double *)&stack[1*8],
+ *(double *)&stack[2*8],
+ *(double *)&stack[3*8],
+ *(sal_uInt64 *)&stack[4*8],
+ *(sal_uInt64 *)&stack[5*8],
+ *(sal_uInt64 *)&stack[6*8],
+ *(sal_uInt64 *)&stack[7*8],
+ *(sal_uInt64 *)&stack[8*8],
+ *(sal_uInt64 *)&stack[9*8],
+ *(sal_uInt64 *)&stack[10*8],
+ *(sal_uInt64 *)&stack[11*8],
+ *(sal_uInt64 *)&stack[12*8],
+ *(sal_uInt64 *)&stack[13*8],
+ *(sal_uInt64 *)&stack[14*8],
+ *(sal_uInt64 *)&stack[15*8],
+ *(sal_uInt64 *)&stack[16*8],
+ *(sal_uInt64 *)&stack[17*8],
+ *(sal_uInt64 *)&stack[18*8],
+ *(sal_uInt64 *)&stack[19*8]);
+ }
+
+ 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:
+ {
+ char const * s1 = reinterpret_cast< char const * >(iRetVal);
+ rtl::OUString s2;
+ SbError e = convert(s1, rtl_str_getLength(s1), &s2);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ result.PutString(String(s2));
+ break;
+ }
+ case SbxOBJECT:
+ //TODO
+ break;
+ case SbxBOOL:
+ result.PutBool(static_cast< sal_Bool >(iRetVal));
+ break;
+ case SbxBYTE:
+ result.PutByte(static_cast< sal_uInt8 >(iRetVal));
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ for (int i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ arguments->Get(i)->ResetFlag(SBX_REFERENCE);
+ //TODO: skipped for errors?!?
+ }
+ for (std::vector< UnmarshalData >::iterator i(data.unmarshal.begin());
+ i != data.unmarshal.end(); ++i)
+ {
+ unmarshal(i->variable, i->buffer);
+ }
+ for (std::vector< StringData >::iterator i(data.unmarshalStrings.begin());
+ i != data.unmarshalStrings.end(); ++i)
+ {
+ SbError e = unmarshalString(*i, result);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+SbError getProcData(HMODULE handle, rtl::OUString const & name, ProcData * proc)
+{
+ OSL_ASSERT(proc != 0);
+ if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"???
+ sal_Int32 n = name.copy(1).toInt32(); //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 != 0) {
+ proc->name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("#")) +
+ rtl::OString::valueOf(n);
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ } else {
+ rtl::OString name8;
+ SbError e = convert(name, &name8);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ FARPROC p = GetProcAddress(handle, name8.getStr());
+ if (p != 0) {
+ 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 != 0) {
+ proc->name = name8;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ }
+ rtl::OString real(
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("_")) + name8);
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ real = name8 + rtl::OString(RTL_CONSTASCII_STRINGPARAM("A"));
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ }
+ return ERRCODE_BASIC_PROC_UNDEFINED;
+}
+
+struct Dll: public salhelper::SimpleReferenceObject {
+private:
+ typedef std::map< rtl::OUString, ProcData > Procs;
+
+ virtual ~Dll();
+
+public:
+ Dll(): handle(0) {}
+
+ SbError getProc(rtl::OUString const & name, ProcData * proc);
+
+ HMODULE handle;
+ Procs procs;
+};
+
+Dll::~Dll() {
+ if (handle != 0 && !FreeLibrary(handle)) {
+ OSL_TRACE("FreeLibrary(%p) failed with %u", handle, GetLastError());
+ }
+}
+
+SbError Dll::getProc(rtl::OUString const & name, ProcData * proc) {
+ Procs::iterator i(procs.find(name));
+ if (i != procs.end()) {
+ *proc = i->second;
+ return ERRCODE_NONE;
+ }
+ SbError e = getProcData(handle, name, proc);
+ if (e == ERRCODE_NONE) {
+ procs.insert(Procs::value_type(name, *proc));
+ }
+ return e;
+}
+
+rtl::OUString fullDllName(rtl::OUString const & name) {
+ rtl::OUString full(name);
+ if (full.indexOf('.') == -1) {
+ full += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".DLL"));
+ }
+ return full;
+}
+
+}
+
+struct SbiDllMgr::Impl: private boost::noncopyable {
+private:
+ typedef std::map< rtl::OUString, rtl::Reference< Dll > > Dlls;
+
+public:
+ Dll * getDll(rtl::OUString const & name);
+
+ Dlls dlls;
+};
+
+Dll * SbiDllMgr::Impl::getDll(rtl::OUString const & name) {
+ Dlls::iterator i(dlls.find(name));
+ if (i == dlls.end()) {
+ i = dlls.insert(Dlls::value_type(name, new Dll)).first;
+ HMODULE h = LoadLibraryW(reinterpret_cast<LPCWSTR>(name.getStr()));
+ if (h == 0) {
+ dlls.erase(i);
+ return 0;
+ }
+ i->second->handle = h;
+ }
+ return i->second.get();
+}
+
+SbError SbiDllMgr::Call(
+ rtl::OUString const & function, rtl::OUString const & library,
+ SbxArray * arguments, SbxVariable & result, bool cdeclConvention)
+{
+ if (cdeclConvention) {
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+ }
+ rtl::OUString dllName(fullDllName(library));
+ Dll * dll = impl_->getDll(dllName);
+ if (dll == 0) {
+ return ERRCODE_BASIC_BAD_DLL_LOAD;
+ }
+ ProcData proc;
+ SbError e = dll->getProc(function, &proc);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ return call(dllName, proc, arguments, result);
+}
+
+void SbiDllMgr::FreeDll(rtl::OUString const & library) {
+ impl_->dlls.erase(library);
+}
+
+SbiDllMgr::SbiDllMgr(): impl_(new Impl) {}
+
+SbiDllMgr::~SbiDllMgr() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/runtime/dllmgr-x86.cxx b/basic/source/runtime/dllmgr-x86.cxx
new file mode 100644
index 0000000..09aee07
--- /dev/null
+++ b/basic/source/runtime/dllmgr-x86.cxx
@@ -0,0 +1,722 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_basic.hxx"
+#include "sal/config.h"
+
+#include <algorithm>
+#include <cstddef>
+#include <list>
+#include <map>
+#include <vector>
+
+#include "basic/sbx.hxx"
+#include "basic/sbxvar.hxx"
+#include "osl/thread.h"
+#include "rtl/ref.hxx"
+#include "rtl/string.hxx"
+#include "rtl/ustring.hxx"
+#include "salhelper/simplereferenceobject.hxx"
+#include "tools/svwin.h"
+
+#undef max
+
+#include "dllmgr.hxx"
+
+/* Open issues:
+
+ Missing support for functions returning structs (see TODO in call()).
+
+ Missing support for additional data types (64 bit integers, Any, ...; would
+ trigger OSL_ASSERT(false) in various switches).
+
+ It is assumed that the variables passed into SbiDllMgr::Call to represent
+ the arguments and return value have types that exactly match the Declare
+ statement; it would be better if this code had access to the function
+ signature from the Declare statement, so that it could convert the passed
+ variables accordingly.
+*/
+
+extern "C" {
+
+int __stdcall DllMgr_call32(FARPROC, void const * stack, std::size_t size);
+double __stdcall DllMgr_callFp(FARPROC, void const * stack, std::size_t size);
+
+}
+
+namespace {
+
+char * address(std::vector< char > & blob) {
+ return blob.empty() ? 0 : &blob[0];
+}
+
+SbError convert(rtl::OUString const & source, rtl::OString * target) {
+ return
+ source.convertToString(
+ target, osl_getThreadTextEncoding(),
+ (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
+ RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+}
+
+SbError convert(char const * source, sal_Int32 length, rtl::OUString * target) {
+ return
+ rtl_convertStringToUString(
+ &target->pData, source, length, osl_getThreadTextEncoding(),
+ (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
+ RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
+ ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+}
+
+struct UnmarshalData {
+ UnmarshalData(SbxVariable * theVariable, void * theBuffer):
+ variable(theVariable), buffer(theBuffer) {}
+
+ SbxVariable * variable;
+ void * buffer;
+};
+
+struct StringData: public UnmarshalData {
+ StringData(SbxVariable * theVariable, void * theBuffer, bool theSpecial):
+ UnmarshalData(theVariable, theBuffer), special(theSpecial) {}
+
+ bool special;
+};
+
+class MarshalData: private boost::noncopyable {
+public:
+ std::vector< char > * newBlob() {
+ blobs_.push_front(std::vector< char >());
+ return &blobs_.front();
+ }
+
+ std::vector< UnmarshalData > unmarshal;
+
+ std::vector< StringData > unmarshalStrings;
+
+private:
+ std::list< std::vector< char > > blobs_;
+};
+
+std::size_t align(std::size_t address, std::size_t alignment) {
+ // alignment = 2^k for some k >= 0
+ return (address + (alignment - 1)) & ~(alignment - 1);
+}
+
+char * align(
+ std::vector< char > & blob, std::size_t alignment, std::size_t offset,
+ std::size_t add)
+{
+ std::vector< char >::size_type n = blob.size();
+ n = align(n - offset, alignment) + offset; //TODO: overflow in align()
+ blob.resize(n + add); //TODO: overflow
+ return address(blob) + n;
+}
+
+template< typename T > void add(
+ std::vector< char > & blob, T const & data, std::size_t alignment,
+ std::size_t offset)
+{
+ *reinterpret_cast< T * >(align(blob, alignment, offset, sizeof (T))) = data;
+}
+
+std::size_t alignment(SbxVariable * variable) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ return 2;
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxSTRING:
+ return 4;
+ case SbxDOUBLE:
+ return 8;
+ case SbxOBJECT:
+ {
+ std::size_t n = 1;
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ n = std::max(n, alignment(props->Get(i)));
+ }
+ return n;
+ }
+ case SbxBOOL:
+ case SbxBYTE:
+ return 1;
+ default:
+ OSL_ASSERT(false);
+ return 1;
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ for (int i = 0; i < dims; ++i) {
+ INT32 up;
+ arr->GetDim32(i + 1, low[i], up);
+ }
+ return alignment(arr->Get32(&low[0]));
+ }
+}
+
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data);
+
+SbError marshalString(
+ SbxVariable * variable, bool special, MarshalData & data, void ** buffer)
+{
+ OSL_ASSERT(variable != 0 && buffer != 0);
+ rtl::OString str;
+ SbError e = convert(variable->GetString(), &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ std::vector< char > * blob = data.newBlob();
+ blob->insert(blob->begin(), str.getStr(), str.getStr() + str.getLength());
+ *buffer = address(*blob);
+ data.unmarshalStrings.push_back(StringData(variable, *buffer, special));
+ return ERRCODE_NONE;
+}
+
+SbError marshalStruct(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ SbError e = marshal(false, props->Get(i), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+SbError marshalArray(
+ SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
+ MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ SbError e = marshal(
+ false, arr->Get32(&idx[0]), false, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ int 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"
+SbError marshal(
+ bool outer, SbxVariable * variable, bool special,
+ std::vector< char > & blob, std::size_t offset, MarshalData & data)
+{
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetFlags() & SBX_REFERENCE) == 0) {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ add(blob, variable->GetInteger(), outer ? 4 : 2, offset);
+ break;
+ case SbxLONG:
+ add(blob, variable->GetLong(), 4, offset);
+ break;
+ case SbxSINGLE:
+ add(blob, variable->GetSingle(), 4, offset);
+ break;
+ case SbxDOUBLE:
+ add(blob, variable->GetDouble(), outer ? 4 : 8, offset);
+ break;
+ case SbxSTRING:
+ {
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(blob, p, 4, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ align(blob, outer ? 4 : alignment(variable), offset, 0);
+ SbError e = marshalStruct(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ break;
+ }
+ case SbxBOOL:
+ add(blob, variable->GetBool(), outer ? 4 : 1, offset);
+ break;
+ case SbxBYTE:
+ add(blob, variable->GetByte(), outer ? 4 : 1, offset);
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ SbError e = marshalArray(variable, blob, offset, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ } else {
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ case SbxLONG:
+ case SbxSINGLE:
+ case SbxDOUBLE:
+ case SbxBOOL:
+ case SbxBYTE:
+ add(blob, variable->data(), 4, offset);
+ break;
+ case SbxSTRING:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ void * p;
+ SbError e = marshalString(variable, special, data, &p);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ add(*blob2, p, 4, 0);
+ add(blob, address(*blob2), 4, offset);
+ break;
+ }
+ case SbxOBJECT:
+ {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalStruct(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 4, offset);
+ break;
+ }
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ std::vector< char > * blob2 = data.newBlob();
+ SbError e = marshalArray(variable, *blob2, 0, data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ void * p = address(*blob2);
+ if (outer) {
+ data.unmarshal.push_back(UnmarshalData(variable, p));
+ }
+ add(blob, p, 4, offset);
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+template< typename T > T read(void const ** pointer) {
+ T const * p = static_cast< T const * >(*pointer);
+ *pointer = static_cast< void const * >(p + 1);
+ return *p;
+}
+
+void const * unmarshal(SbxVariable * variable, void const * data) {
+ OSL_ASSERT(variable != 0);
+ if ((variable->GetType() & SbxARRAY) == 0) {
+ switch (variable->GetType()) {
+ case SbxINTEGER:
+ variable->PutInteger(read< sal_Int16 >(&data));
+ break;
+ case SbxLONG:
+ variable->PutLong(read< sal_Int32 >(&data));
+ break;
+ case SbxSINGLE:
+ variable->PutSingle(read< float >(&data));
+ break;
+ case SbxDOUBLE:
+ variable->PutDouble(read< double >(&data));
+ break;
+ case SbxSTRING:
+ read< char * >(&data); // handled by unmarshalString
+ break;
+ case SbxOBJECT:
+ {
+ data = reinterpret_cast< void const * >(
+ align(
+ reinterpret_cast< sal_uIntPtr >(data),
+ alignment(variable)));
+ SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
+ GetProperties();
+ for (USHORT i = 0; i < props->Count(); ++i) {
+ data = unmarshal(props->Get(i), data);
+ }
+ break;
+ }
+ case SbxBOOL:
+ variable->PutBool(read< sal_Bool >(&data));
+ break;
+ case SbxBYTE:
+ variable->PutByte(read< sal_uInt8 >(&data));
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ } else {
+ SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
+ int dims = arr->GetDims();
+ std::vector< INT32 > low(dims);
+ std::vector< INT32 > up(dims);
+ for (int i = 0; i < dims; ++i) {
+ arr->GetDim32(i + 1, low[i], up[i]);
+ }
+ for (std::vector< INT32 > idx = low;;) {
+ data = unmarshal(arr->Get32(&idx[0]), data);
+ int i = dims - 1;
+ while (idx[i] == up[i]) {
+ idx[i] = low[i];
+ if (i == 0) {
+ goto done;
+ }
+ --i;
+ }
+ ++idx[i];
+ }
+ done:;
+ }
+ return data;
+}
+
+SbError unmarshalString(StringData const & data, SbxVariable & result) {
+ rtl::OUString str;
+ if (data.buffer != 0) {
+ char const * p = static_cast< char const * >(data.buffer);
+ sal_Int32 len;
+ if (data.special) {
+ len = static_cast< sal_Int32 >(result.GetULong());
+ if (len < 0) { // i.e., DWORD result >= 2^31
+ return ERRCODE_BASIC_BAD_ARGUMENT;
+ //TODO: more specific errcode?
+ }
+ } else {
+ len = rtl_str_getLength(p);
+ }
+ SbError e = convert(p, len, &str);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ data.variable->PutString(String(str));
+ return ERRCODE_NONE;
+}
+
+struct ProcData {
+ rtl::OString name;
+ FARPROC proc;
+};
+
+SbError call(
+ rtl::OUString const & dll, ProcData const & proc, SbxArray * arguments,
+ SbxVariable & result)
+{
+ std::vector< char > stack;
+ MarshalData data;
+ // 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 =
+ dll.equalsIgnoreAsciiCaseAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("KERNEL32.DLL")) &&
+ (proc.name ==
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("GetLogicalDriveStringsA")));
+ for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ SbError e = marshal(
+ true, arguments->Get(i), special && i == 2, stack, stack.size(),
+ data);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ align(stack, 4, 0, 0);
+ }
+ switch (result.GetType()) {
+ case SbxEMPTY:
+ DllMgr_call32(proc.proc, address(stack), stack.size());
+ break;
+ case SbxINTEGER:
+ result.PutInteger(
+ static_cast< sal_Int16 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxLONG:
+ result.PutLong(
+ static_cast< sal_Int32 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxSINGLE:
+ result.PutSingle(
+ static_cast< float >(
+ DllMgr_callFp(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxDOUBLE:
+ result.PutDouble(
+ DllMgr_callFp(proc.proc, address(stack), stack.size()));
+ break;
+ case SbxSTRING:
+ {
+ char const * s1 = reinterpret_cast< char const * >(
+ DllMgr_call32(proc.proc, address(stack), stack.size()));
+ rtl::OUString s2;
+ SbError e = convert(s1, rtl_str_getLength(s1), &s2);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ result.PutString(String(s2));
+ break;
+ }
+ case SbxOBJECT:
+ //TODO
+ DllMgr_call32(proc.proc, address(stack), stack.size());
+ break;
+ case SbxBOOL:
+ result.PutBool(
+ static_cast< sal_Bool >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ case SbxBYTE:
+ result.PutByte(
+ static_cast< sal_uInt8 >(
+ DllMgr_call32(proc.proc, address(stack), stack.size())));
+ break;
+ default:
+ OSL_ASSERT(false);
+ break;
+ }
+ for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
+ arguments->Get(i)->ResetFlag(SBX_REFERENCE);
+ //TODO: skipped for errors?!?
+ }
+ for (std::vector< UnmarshalData >::iterator i(data.unmarshal.begin());
+ i != data.unmarshal.end(); ++i)
+ {
+ unmarshal(i->variable, i->buffer);
+ }
+ for (std::vector< StringData >::iterator i(data.unmarshalStrings.begin());
+ i != data.unmarshalStrings.end(); ++i)
+ {
+ SbError e = unmarshalString(*i, result);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ }
+ return ERRCODE_NONE;
+}
+
+SbError getProcData(HMODULE handle, rtl::OUString const & name, ProcData * proc)
+{
+ OSL_ASSERT(proc != 0);
+ if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"???
+ sal_Int32 n = name.copy(1).toInt32(); //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 != 0) {
+ proc->name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("#")) +
+ rtl::OString::valueOf(n);
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ } else {
+ rtl::OString name8;
+ SbError e = convert(name, &name8);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ FARPROC p = GetProcAddress(handle, name8.getStr());
+ if (p != 0) {
+ 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 != 0) {
+ proc->name = name8;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ }
+ rtl::OString real(
+ rtl::OString(RTL_CONSTASCII_STRINGPARAM("_")) + name8);
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ real = name8 + rtl::OString(RTL_CONSTASCII_STRINGPARAM("A"));
+ p = GetProcAddress(handle, real.getStr());
+ if (p != 0) {
+ proc->name = real;
+ proc->proc = p;
+ return ERRCODE_NONE;
+ }
+ }
+ return ERRCODE_BASIC_PROC_UNDEFINED;
+}
+
+struct Dll: public salhelper::SimpleReferenceObject {
+private:
+ typedef std::map< rtl::OUString, ProcData > Procs;
+
+ virtual ~Dll();
+
+public:
+ Dll(): handle(0) {}
+
+ SbError getProc(rtl::OUString const & name, ProcData * proc);
+
+ HMODULE handle;
+ Procs procs;
+};
+
+Dll::~Dll() {
+ if (handle != 0 && !FreeLibrary(handle)) {
+ OSL_TRACE("FreeLibrary(%p) failed with %u", handle, GetLastError());
+ }
+}
+
+SbError Dll::getProc(rtl::OUString const & name, ProcData * proc) {
+ Procs::iterator i(procs.find(name));
+ if (i != procs.end()) {
+ *proc = i->second;
+ return ERRCODE_NONE;
+ }
+ SbError e = getProcData(handle, name, proc);
+ if (e == ERRCODE_NONE) {
+ procs.insert(Procs::value_type(name, *proc));
+ }
+ return e;
+}
+
+rtl::OUString fullDllName(rtl::OUString const & name) {
+ rtl::OUString full(name);
+ if (full.indexOf('.') == -1) {
+ full += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".DLL"));
+ }
+ return full;
+}
+
+}
+
+struct SbiDllMgr::Impl: private boost::noncopyable {
+private:
+ typedef std::map< rtl::OUString, rtl::Reference< Dll > > Dlls;
+
+public:
+ Dll * getDll(rtl::OUString const & name);
+
+ Dlls dlls;
+};
+
+Dll * SbiDllMgr::Impl::getDll(rtl::OUString const & name) {
+ Dlls::iterator i(dlls.find(name));
+ if (i == dlls.end()) {
+ i = dlls.insert(Dlls::value_type(name, new Dll)).first;
+ HMODULE h = LoadLibraryW(reinterpret_cast<LPCWSTR>(name.getStr()));
+ if (h == 0) {
+ dlls.erase(i);
+ return 0;
+ }
+ i->second->handle = h;
+ }
+ return i->second.get();
+}
+
+SbError SbiDllMgr::Call(
+ rtl::OUString const & function, rtl::OUString const & library,
+ SbxArray * arguments, SbxVariable & result, bool cdeclConvention)
+{
+ if (cdeclConvention) {
+ return ERRCODE_BASIC_NOT_IMPLEMENTED;
+ }
+ rtl::OUString dllName(fullDllName(library));
+ Dll * dll = impl_->getDll(dllName);
+ if (dll == 0) {
+ return ERRCODE_BASIC_BAD_DLL_LOAD;
+ }
+ ProcData proc;
+ SbError e = dll->getProc(function, &proc);
+ if (e != ERRCODE_NONE) {
+ return e;
+ }
+ return call(dllName, proc, arguments, result);
+}
+
+void SbiDllMgr::FreeDll(rtl::OUString const & library) {
+ impl_->dlls.erase(library);
+}
+
+SbiDllMgr::SbiDllMgr(): impl_(new Impl) {}
+
+SbiDllMgr::~SbiDllMgr() {}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/runtime/dllmgr.cxx b/basic/source/runtime/dllmgr.cxx
deleted file mode 100644
index 2afaa35..0000000
--- a/basic/source/runtime/dllmgr.cxx
+++ /dev/null
@@ -1,741 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*************************************************************************
- *
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * Copyright 2000, 2010 Oracle and/or its affiliates.
- *
- * OpenOffice.org - a multi-platform office productivity suite
- *
- * This file is part of OpenOffice.org.
- *
- * OpenOffice.org is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License version 3
- * only, as published by the Free Software Foundation.
- *
- * OpenOffice.org is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License version 3 for more details
- * (a copy is included in the LICENSE file that accompanied this code).
- *
- * You should have received a copy of the GNU Lesser General Public License
- * version 3 along with OpenOffice.org. If not, see
- * <http://www.openoffice.org/license.html>
- * for a copy of the LGPLv3 License.
- *
- ************************************************************************/
-
-#include "precompiled_basic.hxx"
-#include "sal/config.h"
-
-#include <algorithm>
-#include <cstddef>
-#include <list>
-#include <map>
-#include <vector>
-
-#include "basic/sbx.hxx"
-#include "basic/sbxvar.hxx"
-#include "osl/thread.h"
-#include "rtl/ref.hxx"
-#include "rtl/string.hxx"
-#include "rtl/ustring.hxx"
-#include "salhelper/simplereferenceobject.hxx"
-#include "tools/svwin.h"
-
-#undef max
-
-#include "dllmgr.hxx"
-
-/* Open issues:
-
- Only 32-bit Windows for now.
-
- Missing support for functions returning structs (see TODO in call()).
-
- Missing support for additional data types (64 bit integers, Any, ...; would
- trigger OSL_ASSERT(false) in various switches).
-
- It is assumed that the variables passed into SbiDllMgr::Call to represent
- the arguments and return value have types that exactly match the Declare
- statement; it would be better if this code had access to the function
- signature from the Declare statement, so that it could convert the passed
- variables accordingly.
-*/
-
-#if defined WNT // only 32-bit Windows, actually
-
-extern "C" {
-
-int __stdcall DllMgr_call32(FARPROC, void const * stack, std::size_t size);
-double __stdcall DllMgr_callFp(FARPROC, void const * stack, std::size_t size);
-
-}
-
-namespace {
-
-char * address(std::vector< char > & blob) {
- return blob.empty() ? 0 : &blob[0];
-}
-
-SbError convert(rtl::OUString const & source, rtl::OString * target) {
- return
- source.convertToString(
- target, osl_getThreadTextEncoding(),
- (RTL_UNICODETOTEXT_FLAGS_UNDEFINED_ERROR |
- RTL_UNICODETOTEXT_FLAGS_INVALID_ERROR))
- ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
- //TODO: more specific errcode?
-}
-
-SbError convert(char const * source, sal_Int32 length, rtl::OUString * target) {
- return
- rtl_convertStringToUString(
- &target->pData, source, length, osl_getThreadTextEncoding(),
- (RTL_TEXTTOUNICODE_FLAGS_UNDEFINED_ERROR |
- RTL_TEXTTOUNICODE_FLAGS_MBUNDEFINED_ERROR |
- RTL_TEXTTOUNICODE_FLAGS_INVALID_ERROR))
- ? ERRCODE_NONE : ERRCODE_BASIC_BAD_ARGUMENT;
- //TODO: more specific errcode?
-}
-
-struct UnmarshalData {
- UnmarshalData(SbxVariable * theVariable, void * theBuffer):
- variable(theVariable), buffer(theBuffer) {}
-
- SbxVariable * variable;
- void * buffer;
-};
-
-struct StringData: public UnmarshalData {
- StringData(SbxVariable * theVariable, void * theBuffer, bool theSpecial):
- UnmarshalData(theVariable, theBuffer), special(theSpecial) {}
-
- bool special;
-};
-
-class MarshalData: private boost::noncopyable {
-public:
- std::vector< char > * newBlob() {
- blobs_.push_front(std::vector< char >());
- return &blobs_.front();
- }
-
- std::vector< UnmarshalData > unmarshal;
-
- std::vector< StringData > unmarshalStrings;
-
-private:
- std::list< std::vector< char > > blobs_;
-};
-
-std::size_t align(std::size_t address, std::size_t alignment) {
- // alignment = 2^k for some k >= 0
- return (address + (alignment - 1)) & ~(alignment - 1);
-}
-
-char * align(
- std::vector< char > & blob, std::size_t alignment, std::size_t offset,
- std::size_t add)
-{
- std::vector< char >::size_type n = blob.size();
- n = align(n - offset, alignment) + offset; //TODO: overflow in align()
- blob.resize(n + add); //TODO: overflow
- return address(blob) + n;
-}
-
-template< typename T > void add(
- std::vector< char > & blob, T const & data, std::size_t alignment,
- std::size_t offset)
-{
- *reinterpret_cast< T * >(align(blob, alignment, offset, sizeof (T))) = data;
-}
-
-std::size_t alignment(SbxVariable * variable) {
- OSL_ASSERT(variable != 0);
- if ((variable->GetType() & SbxARRAY) == 0) {
- switch (variable->GetType()) {
- case SbxINTEGER:
- return 2;
- case SbxLONG:
- case SbxSINGLE:
- case SbxSTRING:
- return 4;
- case SbxDOUBLE:
- return 8;
- case SbxOBJECT:
- {
- std::size_t n = 1;
- SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
- GetProperties();
- for (USHORT i = 0; i < props->Count(); ++i) {
- n = std::max(n, alignment(props->Get(i)));
- }
- return n;
- }
- case SbxBOOL:
- case SbxBYTE:
- return 1;
- default:
- OSL_ASSERT(false);
- return 1;
- }
- } else {
- SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
- int dims = arr->GetDims();
- std::vector< INT32 > low(dims);
- for (int i = 0; i < dims; ++i) {
- INT32 up;
- arr->GetDim32(i + 1, low[i], up);
- }
- return alignment(arr->Get32(&low[0]));
- }
-}
-
-SbError marshal(
- bool outer, SbxVariable * variable, bool special,
- std::vector< char > & blob, std::size_t offset, MarshalData & data);
-
-SbError marshalString(
- SbxVariable * variable, bool special, MarshalData & data, void ** buffer)
-{
- OSL_ASSERT(variable != 0 && buffer != 0);
- rtl::OString str;
- SbError e = convert(variable->GetString(), &str);
- if (e != ERRCODE_NONE) {
- return e;
- }
- std::vector< char > * blob = data.newBlob();
- blob->insert(blob->begin(), str.getStr(), str.getStr() + str.getLength());
- *buffer = address(*blob);
- data.unmarshalStrings.push_back(StringData(variable, *buffer, special));
- return ERRCODE_NONE;
-}
-
-SbError marshalStruct(
- SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
- MarshalData & data)
-{
- OSL_ASSERT(variable != 0);
- SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
- GetProperties();
- for (USHORT i = 0; i < props->Count(); ++i) {
- SbError e = marshal(false, props->Get(i), false, blob, offset, data);
- if (e != ERRCODE_NONE) {
- return e;
- }
- }
- return ERRCODE_NONE;
-}
-
-SbError marshalArray(
- SbxVariable * variable, std::vector< char > & blob, std::size_t offset,
- MarshalData & data)
-{
- OSL_ASSERT(variable != 0);
- SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
- int dims = arr->GetDims();
- std::vector< INT32 > low(dims);
- std::vector< INT32 > up(dims);
- for (int i = 0; i < dims; ++i) {
- arr->GetDim32(i + 1, low[i], up[i]);
- }
- for (std::vector< INT32 > idx = low;;) {
- SbError e = marshal(
- false, arr->Get32(&idx[0]), false, blob, offset, data);
- if (e != ERRCODE_NONE) {
- return e;
- }
- int 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"
-SbError marshal(
- bool outer, SbxVariable * variable, bool special,
- std::vector< char > & blob, std::size_t offset, MarshalData & data)
-{
- OSL_ASSERT(variable != 0);
- if ((variable->GetFlags() & SBX_REFERENCE) == 0) {
- if ((variable->GetType() & SbxARRAY) == 0) {
- switch (variable->GetType()) {
- case SbxINTEGER:
- add(blob, variable->GetInteger(), outer ? 4 : 2, offset);
- break;
- case SbxLONG:
- add(blob, variable->GetLong(), 4, offset);
- break;
- case SbxSINGLE:
- add(blob, variable->GetSingle(), 4, offset);
- break;
- case SbxDOUBLE:
- add(blob, variable->GetDouble(), outer ? 4 : 8, offset);
- break;
- case SbxSTRING:
- {
- void * p;
- SbError e = marshalString(variable, special, data, &p);
- if (e != ERRCODE_NONE) {
- return e;
- }
- add(blob, p, 4, offset);
- break;
- }
- case SbxOBJECT:
- {
- align(blob, outer ? 4 : alignment(variable), offset, 0);
- SbError e = marshalStruct(variable, blob, offset, data);
- if (e != ERRCODE_NONE) {
- return e;
- }
- break;
- }
- case SbxBOOL:
- add(blob, variable->GetBool(), outer ? 4 : 1, offset);
- break;
- case SbxBYTE:
- add(blob, variable->GetByte(), outer ? 4 : 1, offset);
- break;
- default:
- OSL_ASSERT(false);
- break;
- }
- } else {
- SbError e = marshalArray(variable, blob, offset, data);
- if (e != ERRCODE_NONE) {
- return e;
- }
- }
- } else {
- if ((variable->GetType() & SbxARRAY) == 0) {
- switch (variable->GetType()) {
- case SbxINTEGER:
- case SbxLONG:
- case SbxSINGLE:
- case SbxDOUBLE:
- case SbxBOOL:
- case SbxBYTE:
- add(blob, variable->data(), 4, offset);
- break;
- case SbxSTRING:
- {
- std::vector< char > * blob2 = data.newBlob();
- void * p;
- SbError e = marshalString(variable, special, data, &p);
- if (e != ERRCODE_NONE) {
- return e;
- }
- add(*blob2, p, 4, 0);
- add(blob, address(*blob2), 4, offset);
- break;
- }
- case SbxOBJECT:
- {
- std::vector< char > * blob2 = data.newBlob();
- SbError e = marshalStruct(variable, *blob2, 0, data);
- if (e != ERRCODE_NONE) {
- return e;
- }
- void * p = address(*blob2);
- if (outer) {
- data.unmarshal.push_back(UnmarshalData(variable, p));
- }
- add(blob, p, 4, offset);
- break;
- }
- default:
- OSL_ASSERT(false);
- break;
- }
- } else {
- std::vector< char > * blob2 = data.newBlob();
- SbError e = marshalArray(variable, *blob2, 0, data);
- if (e != ERRCODE_NONE) {
- return e;
- }
- void * p = address(*blob2);
- if (outer) {
- data.unmarshal.push_back(UnmarshalData(variable, p));
- }
- add(blob, p, 4, offset);
- }
- }
- return ERRCODE_NONE;
-}
-
-template< typename T > T read(void const ** pointer) {
- T const * p = static_cast< T const * >(*pointer);
- *pointer = static_cast< void const * >(p + 1);
- return *p;
-}
-
-void const * unmarshal(SbxVariable * variable, void const * data) {
- OSL_ASSERT(variable != 0);
- if ((variable->GetType() & SbxARRAY) == 0) {
- switch (variable->GetType()) {
- case SbxINTEGER:
- variable->PutInteger(read< sal_Int16 >(&data));
- break;
- case SbxLONG:
- variable->PutLong(read< sal_Int32 >(&data));
- break;
- case SbxSINGLE:
- variable->PutSingle(read< float >(&data));
- break;
- case SbxDOUBLE:
- variable->PutDouble(read< double >(&data));
- break;
- case SbxSTRING:
- read< char * >(&data); // handled by unmarshalString
- break;
- case SbxOBJECT:
- {
- data = reinterpret_cast< void const * >(
- align(
- reinterpret_cast< sal_uIntPtr >(data),
- alignment(variable)));
- SbxArray * props = PTR_CAST(SbxObject, variable->GetObject())->
- GetProperties();
- for (USHORT i = 0; i < props->Count(); ++i) {
- data = unmarshal(props->Get(i), data);
- }
- break;
- }
- case SbxBOOL:
- variable->PutBool(read< sal_Bool >(&data));
- break;
- case SbxBYTE:
- variable->PutByte(read< sal_uInt8 >(&data));
- break;
- default:
- OSL_ASSERT(false);
- break;
- }
- } else {
- SbxDimArray * arr = PTR_CAST(SbxDimArray, variable->GetObject());
- int dims = arr->GetDims();
- std::vector< INT32 > low(dims);
- std::vector< INT32 > up(dims);
- for (int i = 0; i < dims; ++i) {
- arr->GetDim32(i + 1, low[i], up[i]);
- }
- for (std::vector< INT32 > idx = low;;) {
- data = unmarshal(arr->Get32(&idx[0]), data);
- int i = dims - 1;
- while (idx[i] == up[i]) {
- idx[i] = low[i];
- if (i == 0) {
- goto done;
- }
- --i;
- }
- ++idx[i];
- }
- done:;
- }
- return data;
-}
-
-SbError unmarshalString(StringData const & data, SbxVariable & result) {
- rtl::OUString str;
- if (data.buffer != 0) {
- char const * p = static_cast< char const * >(data.buffer);
- sal_Int32 len;
- if (data.special) {
- len = static_cast< sal_Int32 >(result.GetULong());
- if (len < 0) { // i.e., DWORD result >= 2^31
- return ERRCODE_BASIC_BAD_ARGUMENT;
- //TODO: more specific errcode?
- }
- } else {
- len = rtl_str_getLength(p);
- }
- SbError e = convert(p, len, &str);
- if (e != ERRCODE_NONE) {
- return e;
- }
- }
- data.variable->PutString(String(str));
- return ERRCODE_NONE;
-}
-
-struct ProcData {
- rtl::OString name;
- FARPROC proc;
-};
-
-SbError call(
- rtl::OUString const & dll, ProcData const & proc, SbxArray * arguments,
- SbxVariable & result)
-{
- std::vector< char > stack;
- MarshalData data;
- // 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 =
- dll.equalsIgnoreAsciiCaseAsciiL(
- RTL_CONSTASCII_STRINGPARAM("KERNEL32.DLL")) &&
- (proc.name ==
- rtl::OString(RTL_CONSTASCII_STRINGPARAM("GetLogicalDriveStringsA")));
- for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
- SbError e = marshal(
- true, arguments->Get(i), special && i == 2, stack, stack.size(),
- data);
- if (e != ERRCODE_NONE) {
- return e;
- }
- align(stack, 4, 0, 0);
- }
- switch (result.GetType()) {
- case SbxEMPTY:
- DllMgr_call32(proc.proc, address(stack), stack.size());
- break;
- case SbxINTEGER:
- result.PutInteger(
- static_cast< sal_Int16 >(
- DllMgr_call32(proc.proc, address(stack), stack.size())));
- break;
- case SbxLONG:
- result.PutLong(
- static_cast< sal_Int32 >(
- DllMgr_call32(proc.proc, address(stack), stack.size())));
- break;
- case SbxSINGLE:
- result.PutSingle(
- static_cast< float >(
- DllMgr_callFp(proc.proc, address(stack), stack.size())));
- break;
- case SbxDOUBLE:
- result.PutDouble(
- DllMgr_callFp(proc.proc, address(stack), stack.size()));
- break;
- case SbxSTRING:
- {
- char const * s1 = reinterpret_cast< char const * >(
- DllMgr_call32(proc.proc, address(stack), stack.size()));
- rtl::OUString s2;
- SbError e = convert(s1, rtl_str_getLength(s1), &s2);
- if (e != ERRCODE_NONE) {
- return e;
- }
- result.PutString(String(s2));
- break;
- }
- case SbxOBJECT:
- //TODO
- DllMgr_call32(proc.proc, address(stack), stack.size());
- break;
- case SbxBOOL:
- result.PutBool(
- static_cast< sal_Bool >(
- DllMgr_call32(proc.proc, address(stack), stack.size())));
- break;
- case SbxBYTE:
- result.PutByte(
- static_cast< sal_uInt8 >(
- DllMgr_call32(proc.proc, address(stack), stack.size())));
- break;
- default:
- OSL_ASSERT(false);
- break;
- }
- for (USHORT i = 1; i < (arguments == 0 ? 0 : arguments->Count()); ++i) {
- arguments->Get(i)->ResetFlag(SBX_REFERENCE);
- //TODO: skipped for errors?!?
- }
- for (std::vector< UnmarshalData >::iterator i(data.unmarshal.begin());
- i != data.unmarshal.end(); ++i)
- {
- unmarshal(i->variable, i->buffer);
- }
- for (std::vector< StringData >::iterator i(data.unmarshalStrings.begin());
- i != data.unmarshalStrings.end(); ++i)
- {
- SbError e = unmarshalString(*i, result);
- if (e != ERRCODE_NONE) {
- return e;
- }
- }
- return ERRCODE_NONE;
-}
-
-SbError getProcData(HMODULE handle, rtl::OUString const & name, ProcData * proc)
-{
- OSL_ASSERT(proc != 0);
- if (name.getLength() != 0 && name[0] == '@') { //TODO: "@" vs. "#"???
- sal_Int32 n = name.copy(1).toInt32(); //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 != 0) {
- proc->name = rtl::OString(RTL_CONSTASCII_STRINGPARAM("#")) +
- rtl::OString::valueOf(n);
- proc->proc = p;
- return ERRCODE_NONE;
- }
- } else {
- rtl::OString name8;
- SbError e = convert(name, &name8);
- if (e != ERRCODE_NONE) {
- return e;
- }
- FARPROC p = GetProcAddress(handle, name8.getStr());
- if (p != 0) {
- 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 != 0) {
- proc->name = name8;
- proc->proc = p;
- return ERRCODE_NONE;
- }
- }
- rtl::OString real(
- rtl::OString(RTL_CONSTASCII_STRINGPARAM("_")) + name8);
- p = GetProcAddress(handle, real.getStr());
- if (p != 0) {
- proc->name = real;
- proc->proc = p;
- return ERRCODE_NONE;
- }
- real = name8 + rtl::OString(RTL_CONSTASCII_STRINGPARAM("A"));
- p = GetProcAddress(handle, real.getStr());
- if (p != 0) {
- proc->name = real;
- proc->proc = p;
- return ERRCODE_NONE;
- }
- }
- return ERRCODE_BASIC_PROC_UNDEFINED;
-}
-
-struct Dll: public salhelper::SimpleReferenceObject {
-private:
- typedef std::map< rtl::OUString, ProcData > Procs;
-
- virtual ~Dll();
-
-public:
- Dll(): handle(0) {}
-
- SbError getProc(rtl::OUString const & name, ProcData * proc);
-
- HMODULE handle;
- Procs procs;
-};
-
-Dll::~Dll() {
- if (handle != 0 && !FreeLibrary(handle)) {
- OSL_TRACE("FreeLibrary(%p) failed with %u", handle, GetLastError());
- }
-}
-
-SbError Dll::getProc(rtl::OUString const & name, ProcData * proc) {
- Procs::iterator i(procs.find(name));
- if (i != procs.end()) {
- *proc = i->second;
- return ERRCODE_NONE;
- }
- SbError e = getProcData(handle, name, proc);
- if (e == ERRCODE_NONE) {
- procs.insert(Procs::value_type(name, *proc));
- }
- return e;
-}
-
-rtl::OUString fullDllName(rtl::OUString const & name) {
- rtl::OUString full(name);
- if (full.indexOf('.') == -1) {
- full += rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(".DLL"));
- }
- return full;
-}
-
-}
-
-struct SbiDllMgr::Impl: private boost::noncopyable {
-private:
- typedef std::map< rtl::OUString, rtl::Reference< Dll > > Dlls;
-
-public:
- Dll * getDll(rtl::OUString const & name);
-
- Dlls dlls;
-};
-
-Dll * SbiDllMgr::Impl::getDll(rtl::OUString const & name) {
- Dlls::iterator i(dlls.find(name));
- if (i == dlls.end()) {
- i = dlls.insert(Dlls::value_type(name, new Dll)).first;
- HMODULE h = LoadLibraryW(reinterpret_cast<LPCWSTR>(name.getStr()));
- if (h == 0) {
- dlls.erase(i);
- return 0;
- }
- i->second->handle = h;
- }
- return i->second.get();
-}
-
-SbError SbiDllMgr::Call(
- rtl::OUString const & function, rtl::OUString const & library,
- SbxArray * arguments, SbxVariable & result, bool cdeclConvention)
-{
- if (cdeclConvention) {
- return ERRCODE_BASIC_NOT_IMPLEMENTED;
- }
- rtl::OUString dllName(fullDllName(library));
- Dll * dll = impl_->getDll(dllName);
- if (dll == 0) {
- return ERRCODE_BASIC_BAD_DLL_LOAD;
- }
- ProcData proc;
- SbError e = dll->getProc(function, &proc);
- if (e != ERRCODE_NONE) {
- return e;
- }
- return call(dllName, proc, arguments, result);
-}
-
-void SbiDllMgr::FreeDll(rtl::OUString const & library) {
- impl_->dlls.erase(library);
-}
-
-#else
-
-struct SbiDllMgr::Impl {};
-
-SbError SbiDllMgr::Call(
- rtl::OUString const &, rtl::OUString const &, SbxArray *, SbxVariable &,
- bool)
-{
- return ERRCODE_BASIC_NOT_IMPLEMENTED;
-}
-
-void SbiDllMgr::FreeDll(rtl::OUString const &) {}
-
-#endif
-
-SbiDllMgr::SbiDllMgr(): impl_(new Impl) {}
-
-SbiDllMgr::~SbiDllMgr() {}
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/basic/source/runtime/makefile.mk b/basic/source/runtime/makefile.mk
index f2ed111..f8c8103 100644
--- a/basic/source/runtime/makefile.mk
+++ b/basic/source/runtime/makefile.mk
@@ -41,7 +41,7 @@ ENABLE_EXCEPTIONS = TRUE
SLOFILES= \
$(SLO)$/basrdll.obj \
- $(SLO)$/inputbox.obj \
+ $(SLO)$/inputbox.obj\
$(SLO)$/runtime.obj \
$(SLO)$/step0.obj \
$(SLO)$/step1.obj \
@@ -50,15 +50,25 @@ SLOFILES= \
$(SLO)$/stdobj.obj \
$(SLO)$/stdobj1.obj \
$(SLO)$/methods.obj \
- $(SLO)$/methods1.obj \
+ $(SLO)$/methods1.obj\
$(SLO)$/props.obj \
- $(SLO)$/ddectrl.obj \
- $(SLO)$/dllmgr.obj
+ $(SLO)$/ddectrl.obj
+.IF "$(GUI)$(CPU)" == "WNTI"
+SLOFILES+= \
+ $(SLO)$/dllmgr-x86.obj
+.ELIF "$(GUI)$(CPU)" == "WNTX"
+SLOFILES+= \
+ $(SLO)$/dllmgr-x64.obj
+.ELSE
+SLOFILES+= \
+ $(SLO)$/dllmgr-none.obj
+.ENDIF
.IF "$(GUI)$(COM)$(CPU)" == "WNTMSCI"
-SLOFILES+= $(SLO)$/wnt.obj
+ $(SLO)$/wnt-x86.obj
.ELIF "$(GUI)$(COM)$(CPU)" == "WNTGCCI"
-SLOFILES+= $(SLO)$/wnt-mingw.obj
+SLOFILES+= \
+ $(SLO)$/wnt-mingw.obj
.ENDIF
# --- Targets -------------------------------------------------------------
diff --git a/basic/source/runtime/wnt-x86.asm b/basic/source/runtime/wnt-x86.asm
new file mode 100644
index 0000000..2a8710e
--- /dev/null
+++ b/basic/source/runtime/wnt-x86.asm
@@ -0,0 +1,56 @@
+;*************************************************************************
+;
+; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+;
+; Copyright 2000, 2010 Oracle and/or its affiliates.
+;
+; OpenOffice.org - a multi-platform office productivity suite
+;
+; This file is part of OpenOffice.org.
+;
+; OpenOffice.org is free software: you can redistribute it and/or modify
+; it under the terms of the GNU Lesser General Public License version 3
+; only, as published by the Free Software Foundation.
+;
+; OpenOffice.org is distributed in the hope that it will be useful,
+; but WITHOUT ANY WARRANTY; without even the implied warranty of
+; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+; GNU Lesser General Public License version 3 for more details
+; (a copy is included in the LICENSE file that accompanied this code).
+;
+; You should have received a copy of the GNU Lesser General Public License
+; version 3 along with OpenOffice.org. If not, see
+; <http://www.openoffice.org/license.html>
+; for a copy of the LGPLv3 License.
+;
+;***********************************************************************/
+
+.386
+
+PUBLIC _DllMgr_call32 at 12
+PUBLIC _DllMgr_callFp at 12
+
+_TEXT SEGMENT
+_DllMgr_call32 at 12:
+_DllMgr_callFp at 12:
+ push ebp
+ mov ebp, esp
+ push esi
+ push edi
+ mov ecx, [ebp+16]
+ jecxz $1
+ sub esp, ecx
+ mov edi, esp
+ mov esi, [ebp+12]
+ shr ecx, 2
+ rep movsd
+$1: call DWORD PTR [ebp+8]
+ ; for extra safety, do not trust esp after call (in case the Basic Declare
+ ; signature is wrong):
+ mov edi, [ebp-8]
+ mov esi, [ebp-4]
+ mov esp, ebp
+ pop ebp
+ ret 12
+_TEXT ENDS
+END
diff --git a/basic/source/runtime/wnt.asm b/basic/source/runtime/wnt.asm
deleted file mode 100644
index 2a8710e..0000000
--- a/basic/source/runtime/wnt.asm
+++ /dev/null
@@ -1,56 +0,0 @@
-;*************************************************************************
-;
-; DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-;
-; Copyright 2000, 2010 Oracle and/or its affiliates.
-;
-; OpenOffice.org - a multi-platform office productivity suite
-;
-; This file is part of OpenOffice.org.
-;
-; OpenOffice.org is free software: you can redistribute it and/or modify
-; it under the terms of the GNU Lesser General Public License version 3
-; only, as published by the Free Software Foundation.
-;
-; OpenOffice.org is distributed in the hope that it will be useful,
-; but WITHOUT ANY WARRANTY; without even the implied warranty of
-; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-; GNU Lesser General Public License version 3 for more details
-; (a copy is included in the LICENSE file that accompanied this code).
-;
-; You should have received a copy of the GNU Lesser General Public License
-; version 3 along with OpenOffice.org. If not, see
-; <http://www.openoffice.org/license.html>
-; for a copy of the LGPLv3 License.
-;
-;***********************************************************************/
-
-.386
-
-PUBLIC _DllMgr_call32 at 12
-PUBLIC _DllMgr_callFp at 12
-
-_TEXT SEGMENT
-_DllMgr_call32 at 12:
-_DllMgr_callFp at 12:
- push ebp
- mov ebp, esp
- push esi
- push edi
- mov ecx, [ebp+16]
- jecxz $1
- sub esp, ecx
- mov edi, esp
- mov esi, [ebp+12]
- shr ecx, 2
- rep movsd
-$1: call DWORD PTR [ebp+8]
- ; for extra safety, do not trust esp after call (in case the Basic Declare
- ; signature is wrong):
- mov edi, [ebp-8]
- mov esi, [ebp-4]
- mov esp, ebp
- pop ebp
- ret 12
-_TEXT ENDS
-END
commit 6947ec9f4f7a2d6dee18e14f962bd8dedc05357a
Author: Tor Lillqvist <tlillqvist at novell.com>
Date: Mon Jan 24 20:49:24 2011 +0200
Make Get10ThSec declaration match the implementation
diff --git a/sfx2/source/bastyp/progress.cxx b/sfx2/source/bastyp/progress.cxx
index 9225093..9b27953 100644
--- a/sfx2/source/bastyp/progress.cxx
+++ b/sfx2/source/bastyp/progress.cxx
@@ -113,7 +113,7 @@ struct SfxProgress_Impl
#define aTypeLibInfo aProgressTypeLibImpl
//========================================================================
-extern ULONG Get10ThSec();
+extern sal_uInt32 Get10ThSec();
// -----------------------------------------------------------------------
commit e38dd82dc73245c652dd30bf0d5ec9f3a673befc
Author: Tor Lillqvist <tlillqvist at novell.com>
Date: Mon Jan 24 20:40:35 2011 +0200
Use correct LONG_PTR for parameters to IMediaEvent::GetEvent
diff --git a/avmedia/source/win/player.cxx b/avmedia/source/win/player.cxx
index 9b7e8f7..5f45b50 100644
--- a/avmedia/source/win/player.cxx
+++ b/avmedia/source/win/player.cxx
@@ -207,7 +207,8 @@ void Player::setDDrawParams( IDirectDraw* pDDraw, IDirectDrawSurface* pDDrawSurf
long Player::processEvent()
{
- long nCode, nParam1, nParam2;
+ long nCode;
+ LONG_PTR nParam1, nParam2;
if( mpME && SUCCEEDED( mpME->GetEvent( &nCode, &nParam1, &nParam2, 0 ) ) )
{
commit cf4f81cd71edbda8e79eb68acd79284a95d00236
Author: Tor Lillqvist <tlillqvist at novell.com>
Date: Mon Jan 24 13:55:50 2011 +0200
Include the wntmscx build directories
diff --git a/.gitignore b/.gitignore
index 2fc1892..25df106 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,7 +5,7 @@
# the build directories
/*/unxlng??
/*/unxlng??.pro
-/*/wntmsci??
-/*/wntmsci??.pro
+/*/wntmsc???
+/*/wntmsc???.pro
/*/unxmac??
/*/unxmac??.pro
More information about the Libreoffice-commits
mailing list