From f279e84e3074bf1b770340bababcb0bbf2380a61 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 21 Oct 2014 17:33:54 +0200 Subject: [PATCH 01/49] COM: Added Running Object Table bits. Added proxy and annotations to assist easy use of COM. Added java friendly version of some COM interfaces. Added Tests. --- contrib/platform/.project | 2 +- .../jna/platform/win32/COM/EnumMoniker.java | 71 ++++ .../jna/platform/win32/COM/IEnumMoniker.java | 94 +++++ .../sun/jna/platform/win32/COM/IMoniker.java | 94 +++++ .../sun/jna/platform/win32/COM/IPersist.java | 40 ++ .../platform/win32/COM/IPersistStream.java | 57 +++ .../win32/COM/IRunningObjectTable.java | 152 ++++++++ .../sun/jna/platform/win32/COM/IStream.java | 29 ++ .../sun/jna/platform/win32/COM/Moniker.java | 173 +++++++++ .../win32/COM/RunningObjectTable.java | 110 ++++++ .../jna/platform/win32/COM/proxy/Factory.java | 105 +++++ .../platform/win32/COM/proxy/ProxyObject.java | 358 ++++++++++++++++++ .../COM/proxy/annotation/ComInterface.java | 26 ++ .../win32/COM/proxy/annotation/ComObject.java | 27 ++ .../win32/COM/proxy/annotation/Method.java | 27 ++ .../win32/COM/proxy/annotation/Property.java | 27 ++ .../platform/win32/COM/util/EnumMoniker.java | 102 +++++ .../platform/win32/COM/util/IDispatch.java | 24 ++ .../win32/COM/util/IRunningObjectTable.java | 41 ++ .../jna/platform/win32/COM/util/IUnknown.java | 28 ++ .../win32/COM/util/RunningObjectTable.java | 63 +++ .../src/com/sun/jna/platform/win32/Ole32.java | 48 ++- .../platform/win32/COM/EnumMoniker_Test.java | 222 +++++++++++ .../win32/COM/RunningObjectTable_Test.java | 183 +++++++++ .../COM/util/RunningObjectTable_Test.java | 108 ++++++ 25 files changed, 2208 insertions(+), 3 deletions(-) create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/Factory.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/ProxyObject.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComInterface.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComObject.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Method.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Property.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java create mode 100644 contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java create mode 100644 contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java create mode 100644 contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java diff --git a/contrib/platform/.project b/contrib/platform/.project index eb21a1889c..2cad830e2f 100644 --- a/contrib/platform/.project +++ b/contrib/platform/.project @@ -1,6 +1,6 @@ - platform + com.sun.jna.platform diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java new file mode 100644 index 0000000000..6d17938428 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/EnumMoniker.java @@ -0,0 +1,71 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public class EnumMoniker extends Unknown implements IEnumMoniker { + + public EnumMoniker(Pointer pointer) { + super(pointer); + } + + // The magic number values for (vTableId) below, are worked out by + // counting the number of methods in the full interface (0 indexed), as this + // inherits IUnknown, which has 3 methods, we start here at 3. + + @Override + public HRESULT Next(ULONG celt, PointerByReference rgelt, ULONGByReference pceltFetched) { + final int vTableId = 3; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), celt, + rgelt, pceltFetched }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Skip(ULONG celt) { + final int vTableId = 4; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), celt }, + WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Reset() { + final int vTableId = 5; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), }, + WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Clone(PointerByReference ppenum) { + final int vTableId = 6; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, + new Object[] { this.getPointer(), ppenum }, WinNT.HRESULT.class); + + return hr; + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java new file mode 100644 index 0000000000..05a81c5aac --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IEnumMoniker.java @@ -0,0 +1,94 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.ptr.PointerByReference; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; + +/** + * Enumerates the components of a moniker or the monikers in a table of monikers. + * + * @see MSDN + * + */ +public interface IEnumMoniker extends IUnknown { + + public final static IID IID = new IID("{00000102-0000-0000-C000-000000000046}"); + + /** + * Creates a new enumerator that contains the same enumeration state as the + * current one. + * + * This method makes it possible to record a particular point in the + * enumeration sequence and then return to that point at a later time. The + * caller must release this new enumerator separately from the first + * enumerator. + * + * {@code + * HRESULT Clone( + * [out] IEnumMoniker **ppenum + * ); + * } + * + * @see MSDN + */ + HRESULT Clone(PointerByReference ppenum); + + /** + * Retrieves the specified number of items in the enumeration sequence. + * + * Note: The caller is responsible for calling Release through each pointer + * enumerated. + * + * {@code + * HRESULT Next( + * [in] ULONG celt, + * [out] IMoniker **rgelt, + * [in, out] ULONG *pceltFetched + * ); + * } + * + * @see MSDN + * + */ + HRESULT Next(ULONG celt, PointerByReference rgelt, ULONGByReference pceltFetched); + + /** + * Resets the enumeration sequence to the beginning. + * + * {@code + * HRESULT Reset(); + * } + * + * @see MSDN + * + */ + HRESULT Reset(); + + /** + * Skips over the specified number of items in the enumeration sequence. + * + * {@code + * HRESULT Skip( + * [in] ULONG celt + * ); + * } + * + * @see MSDN + * + */ + HRESULT Skip(ULONG celt); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java new file mode 100644 index 0000000000..4824a41f2b --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IMoniker.java @@ -0,0 +1,94 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WTypes.BSTRByReference; +import com.sun.jna.platform.win32.WTypes.LPSTR; +import com.sun.jna.platform.win32.WinNT.HRESULT; + + +/** + * Enables you to use a moniker object, which contains information that uniquely + * identifies a COM object. + * + * (Unimplemented, placeholder only at present) + * + * @see MSDN + * + */ +public interface IMoniker extends IPersistStream { + + /** + * Binds to the specified object. The binding process involves finding the + * object, putting it into the running state if necessary, and providing the + * caller with a pointer to a specified interface on the identified object. + * + * {@code + * HRESULT BindToObject( + * [in] IBindCtx *pbc, + * [in] IMoniker *pmkToLeft, + * [in] REFIID riidResult, + * [out] void **ppvResult + * ); + * } + * + * @see MSDN + */ + void BindToObject(); + + void BindToStorage(); + + void Reduce(); + + void ComposeWith(); + + void Enum(); + + void IsEqual(); + + void Hash(); + + void IsRunning(); + + void GetTimeOfLastChange(); + + void Inverse(); + + void CommonPrefixWith(); + + /** + * Retrieves the display name for the moniker. + * + * {@code + * HRESULT GetDisplayName( + * [in] IBindCtx *pbc, + * [in] IMoniker *pmkToLeft, + * [out] LPOLESTR *ppszDisplayName + * ); + * + * @see MSDN + * + * } + */ + HRESULT GetDisplayName(Pointer pbc, Pointer pmkToLeft, BSTRByReference ppszDisplayName); + + void ParseDisplayName(); + + void IsSystemMoniker(); + + void RelativePathTo(); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java new file mode 100644 index 0000000000..a5ea2b426a --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersist.java @@ -0,0 +1,40 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.platform.win32.Guid.CLSID; + +/** + * Provides the CLSID of an object that can be stored persistently in the + * system. Allows the object to specify which object handler to use in the + * client process, as it is used in the default implementation of marshaling. + * + * @see MSDN + * + */ +public interface IPersist extends IUnknown { + + /** + * Retrieves the class identifier (CLSID) of the object. + * + * {@code + * HRESULT GetClassID( + * [out] CLSID *pClassID + * ); + * } + * + * MSDN + */ + CLSID GetClassID(); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java new file mode 100644 index 0000000000..f2c6bf00e3 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IPersistStream.java @@ -0,0 +1,57 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + + +/** + * Enables the saving and loading of objects that use a simple serial stream for their storage needs. + * + * @see MSDN + * + */ +public interface IPersistStream extends IPersist { + + /** + * Determines whether an object has changed since it was last saved to its + * stream. + * + * (Unimplemented) + * + */ + boolean IsDirty(); + + /** + * Initializes an object from the stream where it was saved previously + * + * (Unimplemented) + * + */ + + void Load(IStream stm); + + /** + * Saves an object to the specified stream. + * + * (Unimplemented) + * + */ + void Save(IStream stm); + + /** + * Retrieves the size of the stream needed to save the object. + * + * (Unimplemented) + * + */ + void GetSizeMax(); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java new file mode 100644 index 0000000000..a33b5263fb --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IRunningObjectTable.java @@ -0,0 +1,152 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +/** + * Manages access to the running object table (ROT), a globally accessible + * look-up table on each workstation. + * + * @see MSDN + * + */ +public interface IRunningObjectTable extends IUnknown { + + public final static IID IID = new IID("{00000010-0000-0000-C000-000000000046}"); + + /** + * Creates and returns a pointer to an enumerator that can list the monikers + * of all the objects currently registered in the running object table + * (ROT). + * + * {@code + * HRESULT EnumRunning( + * [out] IEnumMoniker **ppenumMoniker + * ); + * } + * + * @see MSDN + * + */ + HRESULT EnumRunning(PointerByReference ppenumMoniker); + + /** + * + * Determines whether the object identified by the specified moniker is + * running, and if it is, retrieves a pointer to that object. + * + * {@code + * HRESULT GetObject( + * [in] IMoniker *pmkObjectName, + * [out] IUnknown **ppunkObject + * ); + * } + * + * @see MSDN + * + */ + HRESULT GetObject(Pointer pmkObjectName, PointerByReference ppunkObject); + + /** + * Retrieves the time that an object was last modified. + * + * {@code + * HRESULT GetTimeOfLastChange( + * [in] IMoniker *pmkObjectName, + * [out] FILETIME *pfiletime + * ); + * } + * + * @see MSDN + * + */ + HRESULT GetTimeOfLastChange(Pointer pmkObjectName, FILETIME.ByReference pfiletime); + + /** + * Determines whether the object identified by the specified moniker is + * currently running. + * + * {@code + * HRESULT IsRunning( + * [in] IMoniker *pmkObjectName + * ); + * } + * + * @see MSDN + * + */ + HRESULT IsRunning(Pointer pmkObjectName); + + /** + * Records the time that a running object was last modified. + * + * {@code + * HRESULT NoteChangeTime( + * [in] DWORD dwRegister, + * [in] FILETIME *pfiletime + * ); + * } + * + * @see MSDN + * + */ + HRESULT NoteChangeTime(DWORD dwRegister, FILETIME pfiletime); + + /** + * Registers an object and its identifying moniker in the running object + * table (ROT). + * + * {@code + * HRESULT Register( + * [in] DWORD grfFlags, + * [in] IUnknown *punkObject, + * [in] IMoniker *pmkObjectName, + * [out] DWORD *pdwRegister + * ); + * } + * + * @see MSDN + * + */ + HRESULT Register(DWORD grfFlags, Pointer punkObject, Pointer pmkObjectName, DWORDByReference pdwRegister); + + /** + * Removes an entry from the running object table (ROT) that was previously + * registered by a call to IRunningObjectTable.Register. + * + * {@code + * HRESULT Revoke( + * [in] DWORD dwRegister + * ); + * } + * + * @see MSDN + * + */ + HRESULT Revoke(DWORD dwRegister); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java new file mode 100644 index 0000000000..b81ae06b70 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/IStream.java @@ -0,0 +1,29 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +/** + * The IStream interface lets you read and write data to stream objects. Stream + * objects contain the data in a structured storage object, where storages + * provide the structure. Simple data can be written directly to a stream but, + * most frequently, streams are elements nested within a storage object. They + * are similar to standard files. + * + * (Place holder, incomplete) + * + * @see MSDN + * + */ +public interface IStream { + +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java new file mode 100644 index 0000000000..2df9158cd0 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/Moniker.java @@ -0,0 +1,173 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.WString; +import com.sun.jna.platform.win32.WTypes.BSTRByReference; +import com.sun.jna.platform.win32.WTypes.LPSTR; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.WinNT.HRESULT; + +public class Moniker extends Unknown implements IMoniker { + + public static class ByReference extends Moniker implements Structure.ByReference { + } + + public Moniker() { + } + + public Moniker(Pointer pointer) { + super(pointer); + } + + // There are 8 virtual methods in the ancestors of this class/interfaces + static final int vTableIdStart = 7; + + @Override + public void BindToObject() { + final int vTableId = vTableIdStart + 1; + + throw new UnsupportedOperationException(); + } + + @Override + public void BindToStorage() { + final int vTableId = vTableIdStart + 2; + + throw new UnsupportedOperationException(); + } + + @Override + public void Reduce() { + final int vTableId = vTableIdStart + 3; + + throw new UnsupportedOperationException(); + } + + @Override + public void ComposeWith() { + final int vTableId = vTableIdStart + 4; + + throw new UnsupportedOperationException(); + } + + @Override + public void Enum() { + final int vTableId = vTableIdStart + 5; + + throw new UnsupportedOperationException(); + } + + @Override + public void IsEqual() { + final int vTableId = vTableIdStart + 6; + + throw new UnsupportedOperationException(); + } + + @Override + public void Hash() { + final int vTableId = vTableIdStart + 7; + + throw new UnsupportedOperationException(); + } + + @Override + public void IsRunning() { + final int vTableId = vTableIdStart + 8; + + throw new UnsupportedOperationException(); + } + + @Override + public void GetTimeOfLastChange() { + final int vTableId = vTableIdStart + 9; + + throw new UnsupportedOperationException(); + } + + @Override + public void Inverse() { + final int vTableId = vTableIdStart + 10; + + throw new UnsupportedOperationException(); + } + + @Override + public void CommonPrefixWith() { + final int vTableId = vTableIdStart + 11; + + throw new UnsupportedOperationException(); + } + + @Override + public void RelativePathTo() { + final int vTableId = vTableIdStart + 12; + + throw new UnsupportedOperationException(); + } + + @Override + public HRESULT GetDisplayName(Pointer pbc, Pointer pmkToLeft, BSTRByReference ppszDisplayName) { + final int vTableId = vTableIdStart + 13; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), pbc, + pmkToLeft, ppszDisplayName }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public void ParseDisplayName() { + final int vTableId = vTableIdStart + 14; + + throw new UnsupportedOperationException(); + } + + @Override + public void IsSystemMoniker() { + final int vTableId = vTableIdStart + 15; + + throw new UnsupportedOperationException(); + } + + // ------------------------ IPersistStream ---------------------------- + @Override + public boolean IsDirty() { + throw new UnsupportedOperationException(); + } + + @Override + public void Load(IStream stm) { + throw new UnsupportedOperationException(); + } + + @Override + public void Save(IStream stm) { + throw new UnsupportedOperationException(); + } + + @Override + public void GetSizeMax() { + throw new UnsupportedOperationException(); + } + + @Override + public CLSID GetClassID() { + throw new UnsupportedOperationException(); + } + +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java new file mode 100644 index 0000000000..7ae90b5d73 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/RunningObjectTable.java @@ -0,0 +1,110 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import com.sun.jna.Pointer; +import com.sun.jna.Structure; +import com.sun.jna.platform.win32.WinBase.FILETIME; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.DWORDByReference; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public class RunningObjectTable extends Unknown implements IRunningObjectTable { + + public static class ByReference extends RunningObjectTable implements Structure.ByReference { + } + + public RunningObjectTable() { + } + + public RunningObjectTable(Pointer pointer) { + super(pointer); + } + + // The magic number values for (vTableId) below, are worked out by + // counting the number of methods in the full interface (0 indexed), as this + // inherits IUnknown, which has 3 methods, we start here at 3. + + @Override + public HRESULT Register(DWORD grfFlags, Pointer punkObject, Pointer pmkObjectName, DWORDByReference pdwRegister) { + final int vTableId = 3; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + grfFlags, punkObject, pmkObjectName, pdwRegister }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT Revoke(DWORD dwRegister) { + final int vTableId = 4; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + dwRegister }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT IsRunning(Pointer pmkObjectName) { + final int vTableId = 5; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + pmkObjectName }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT GetObject(Pointer pmkObjectName, PointerByReference ppunkObject) { + final int vTableId = 6; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + pmkObjectName, ppunkObject }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT NoteChangeTime(DWORD dwRegister, FILETIME pfiletime) { + final int vTableId = 7; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + dwRegister, pfiletime }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT GetTimeOfLastChange(Pointer pmkObjectName, FILETIME.ByReference pfiletime) { + final int vTableId = 8; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + pmkObjectName, pfiletime }, WinNT.HRESULT.class); + + return hr; + } + + @Override + public HRESULT EnumRunning(PointerByReference ppenumMoniker) { + final int vTableId = 9; + + WinNT.HRESULT hr = (WinNT.HRESULT) this._invokeNativeObject(vTableId, new Object[] { this.getPointer(), + ppenumMoniker }, WinNT.HRESULT.class); + + return hr; + } + +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/Factory.java new file mode 100644 index 0000000000..1a6c403343 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/Factory.java @@ -0,0 +1,105 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.proxy; + +import java.lang.reflect.Proxy; + +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Guid.GUID; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.IDispatch; +import com.sun.jna.platform.win32.COM.proxy.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.proxy.annotation.ComObject; +import com.sun.jna.ptr.PointerByReference; + +public class Factory { + + public static void initializeThreadForComAccess() { + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitialize(null); + COMUtils.checkRC(hr); + } + + public static void releaseThreadFromComAccess() { + Ole32.INSTANCE.CoUninitialize(); + } + + /** + * Creates a ProxyObject for the given interface and IDispatch pointer. + * + */ + public static T createProxy(Class comInterface, IDispatch dispatch) { + ProxyObject jop = new ProxyObject(dispatch); + Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[] { comInterface }, jop); + T result = comInterface.cast(proxy); + return result; + } + + /** + * Creates a new COM object (CoCreateInstance) for the given progId and returns a ProxyObject + * for the given interface. + */ + public static T createObject(Class comInterface) { + ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); + if (null==comObectAnnotation) { + throw new COMException("createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + } + GUID guid = Factory.discoverClsId(comObectAnnotation); + + PointerByReference ptrDisp = new PointerByReference(); + WinNT.HRESULT hr = Ole32.INSTANCE.CoCreateInstance(guid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp); + COMUtils.checkRC(hr); + + T t = Factory.createProxy(comInterface, new Dispatch(ptrDisp.getValue())); + return t; + } + + /** + * Gets and existing COM object (GetActiveObject) for the given progId and returns a ProxyObject + * for the given interface. + */ + public static T fetchObject(Class comInterface, String progId) { + ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); + if (null==comObectAnnotation) { + throw new COMException("createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + } + GUID guid = Factory.discoverClsId(comObectAnnotation); + + PointerByReference ptrDisp = new PointerByReference(); + WinNT.HRESULT hr = OleAuto.INSTANCE.GetActiveObject(guid, null, ptrDisp); + COMUtils.checkRC(hr); + + T t = Factory.createProxy(comInterface, new Dispatch(ptrDisp.getValue())); + return t; + } + + static GUID discoverClsId(ComObject annotation) { + String clsIdStr = annotation.clsId(); + String progIdStr = annotation.progId(); + if (null!=clsIdStr && !clsIdStr.isEmpty()) { + return new CLSID(clsIdStr); + } else if (null!=progIdStr && !progIdStr.isEmpty()) { + CLSID.ByReference rclsid = new CLSID.ByReference(); + WinNT.HRESULT hr = Ole32.INSTANCE.CLSIDFromProgID(progIdStr, rclsid); + COMUtils.checkRC(hr); + return rclsid; + } else { + throw new COMException("ComObject must define a value for either clsId or progId"); + } + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/ProxyObject.java new file mode 100644 index 0000000000..a9bf7b1a4f --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/ProxyObject.java @@ -0,0 +1,358 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.proxy; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Proxy; +import java.util.Date; + +import com.sun.jna.WString; +import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Kernel32; +import com.sun.jna.platform.win32.Kernel32Util; +import com.sun.jna.platform.win32.OaIdl; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.OaIdl.DISPID; +import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; +import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.OleAuto.DISPPARAMS; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.Variant.VARIANT; +import com.sun.jna.platform.win32.Variant.VariantArg; +import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinDef.LCID; +import com.sun.jna.platform.win32.WinDef.UINT; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.proxy.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.proxy.annotation.Method; +import com.sun.jna.platform.win32.COM.proxy.annotation.Property; +import com.sun.jna.platform.win32.COM.IDispatch; +import com.sun.jna.platform.win32.Guid.GUID; +import com.sun.jna.ptr.IntByReference; +import com.sun.jna.ptr.PointerByReference; + +/** + * Ole32.INSTANCE.CoInitialize must be called on the current thread before using this object + */ +public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win32.COM.util.IDispatch { + + public ProxyObject(IDispatch rawDispatch) { + this.rawDispatch = rawDispatch; + } + + com.sun.jna.platform.win32.COM.IDispatch rawDispatch; + + com.sun.jna.platform.win32.COM.IDispatch getIDispatch() { + return this.rawDispatch; + } + + //--------------------- InvocationHandler ----------------------------- + @Override + public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable { + Class dcls = method.getDeclaringClass(); + Class returnType = method.getReturnType(); + boolean isVoid = Void.TYPE.equals(returnType); + + Property prop = method.getAnnotation(Property.class); + if (null != prop) { + if (isVoid) { + String propName = this.getMutatorName(method, prop); + this.setProperty(propName, args[0]); + return null; + } else { + String propName = this.getAccessorName(method, prop); + return this.getProperty(returnType, propName); + } + } + + Method meth = method.getAnnotation(Method.class); + if (null != meth) { + String methName = this.getMethodName(method, meth); + Object res = this.invokeMethod(returnType, methName, args); + return res; + } + + return null; + } + + // --------------------- IDispatch ------------------------------ + @Override + public void setProperty(String name, T value) { + VARIANT v = this.toVariant(value); + WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYPUT, null, this.getIDispatch(), name, v); + COMUtils.checkRC(hr); + } + + @Override + public T getProperty(Class returnType, String name) { + Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); + WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getIDispatch(), name); + COMUtils.checkRC(hr); + Object jobj = this.getJavaObject(result); + if (jobj instanceof com.sun.jna.platform.win32.COM.IDispatch) { + return Factory.createProxy(returnType, (com.sun.jna.platform.win32.COM.IDispatch) jobj); + } + return (T)jobj; + } + + @Override + public T invokeMethod(Class returnType, String name, Object... args) { + VARIANT[] vargs; + if (null == args) { + vargs = new VARIANT[0]; + } else { + vargs = new VARIANT[args.length]; + } + for (int i = 0; i < vargs.length; ++i) { + vargs[i] = this.toVariant(args[i]); + } + Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); + WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_METHOD, result, this.getIDispatch(), name, vargs); + COMUtils.checkRC(hr); + + Object jobj = this.getJavaObject(result); + if (jobj instanceof IDispatch) { + return Factory.createProxy(returnType, (IDispatch) jobj); + } + return (T)jobj; + } + + @Override + public T queryInterface(Class comInterface) { + ComInterface comInterfaceAnnotation = comInterface.getAnnotation(ComInterface.class); + if (null==comInterfaceAnnotation) { + throw new COMException("createObject: Interface must define a value for either iid or progId via the ComInterface annotation"); + } + IID iid = this.getIID(comInterfaceAnnotation); + PointerByReference ppvObject = new PointerByReference(); + WinNT.HRESULT hr = this.getIDispatch().QueryInterface(iid, ppvObject); + if (WinNT.S_OK.equals(hr)) { + Dispatch dispatch = new Dispatch(ppvObject.getValue()); + return Factory.createProxy(comInterface, dispatch); + } else { + String formatMessageFromHR = Kernel32Util.formatMessage(hr); + throw new COMException("queryInterface: "+formatMessageFromHR); + } + } + + IID getIID(ComInterface annotation) { + String iidStr = annotation.iid(); + if (null!=iidStr && !iidStr.isEmpty()) { + return new IID(iidStr); + } else { + throw new COMException("ComInterface must define a value for either iid"); + } + } + + //--------------------- ProxyObject --------------------- + + private String getAccessorName(java.lang.reflect.Method method, Property prop) { + if (prop.name().isEmpty()) { + String methName = method.getName(); + if (methName.startsWith("get")) { + return methName.replaceFirst("get", ""); + } else { + throw new RuntimeException( + "Property Accessor name must start with 'get', or set the anotation 'name' value"); + } + } else { + return prop.name(); + } + } + + private String getMutatorName(java.lang.reflect.Method method, Property prop) { + if (prop.name().isEmpty()) { + String methName = method.getName(); + if (methName.startsWith("set")) { + return methName.replaceFirst("set", ""); + } else { + throw new RuntimeException( + "Property Mutator name must start with 'set', or set the anotation 'name' value"); + } + } else { + return prop.name(); + } + } + + private String getMethodName(java.lang.reflect.Method method, Method meth) { + if (meth.name().isEmpty()) { + String methName = method.getName(); + return methName; + } else { + return meth.name(); + } + } + + protected Object getJavaObject(VARIANT value) { + Object vobj = value.getValue(); + if (vobj instanceof WinDef.BOOL) { + return ((WinDef.BOOL) vobj).booleanValue(); + } else if (vobj instanceof WinDef.LONG) { + return ((WinDef.LONG) vobj).longValue(); + } else if (vobj instanceof WinDef.SHORT) { + return ((WinDef.SHORT) vobj).shortValue(); + } else if (vobj instanceof WinDef.UINT) { + return ((WinDef.UINT) vobj).intValue(); + } else if (vobj instanceof WinDef.WORD) { + return ((WinDef.WORD) vobj).intValue(); + } else if (vobj instanceof WTypes.BSTR) { + return ((WTypes.BSTR) vobj).getValue(); + } + return vobj; + } + + protected VARIANT toVariant(Object value) { + if (value instanceof Boolean) { + return new VARIANT((Boolean) value); + } else if (value instanceof Long) { + return new VARIANT(new WinDef.LONG((Long) value)); + } else if (value instanceof Integer) { + return new VARIANT((Integer) value); + } else if (value instanceof Short) { + return new VARIANT(new WinDef.SHORT((Short) value)); + } else if (value instanceof Float) { + return new VARIANT((Float) value); + } else if (value instanceof Double) { + return new VARIANT((Double) value); + } else if (value instanceof String) { + return new VARIANT((String) value); + } else if (value instanceof Date) { + return new VARIANT((Date) value); + } else if (value instanceof Proxy) { + InvocationHandler ih = Proxy.getInvocationHandler(value); + ProxyObject pobj = (ProxyObject) ih; + return new VARIANT(pobj.getIDispatch()); + } else { + throw new RuntimeException("Cannot convert to VARIANT - " + value); + } + } + + /** The Constant LOCALE_USER_DEFAULT. */ + public final static LCID LOCALE_USER_DEFAULT = Kernel32.INSTANCE.GetUserDefaultLCID(); + + /** The Constant LOCALE_SYSTEM_DEFAULT. */ + public final static LCID LOCALE_SYSTEM_DEFAULT = Kernel32.INSTANCE.GetSystemDefaultLCID(); + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name, VARIANT pArg) + throws COMException { + return this.oleMethod(nType, pvResult, pDisp, name, new VARIANT[] { pArg }); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId, VARIANT pArg) + throws COMException { + return this.oleMethod(nType, pvResult, pDisp, dispId, new VARIANT[] { pArg }); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name) + throws COMException { + return this.oleMethod(nType, pvResult, pDisp, name, (VARIANT[]) null); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId) + throws COMException { + + return this.oleMethod(nType, pvResult, pDisp, dispId, (VARIANT[]) null); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name, VARIANT[] pArgs) + throws COMException { + + if (pDisp == null) + throw new COMException("pDisp (IDispatch) parameter is null!"); + + // variable declaration + WString[] ptName = new WString[] { new WString(name) }; + DISPIDByReference pdispID = new DISPIDByReference(); + + // Get DISPID for name passed... + HRESULT hr = pDisp.GetIDsOfNames(Guid.IID_NULL, ptName, 1, LOCALE_USER_DEFAULT, pdispID); + + COMUtils.checkRC(hr); + + return this.oleMethod(nType, pvResult, pDisp, pdispID.getValue(), pArgs); + } + + /* + * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod + */ + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId, VARIANT[] pArgs) + throws COMException { + + if (pDisp == null) + throw new COMException("pDisp (IDispatch) parameter is null!"); + + // variable declaration + int _argsLen = 0; + VARIANT[] _args = null; + DISPPARAMS dp = new DISPPARAMS(); + EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); + IntByReference puArgErr = new IntByReference(); + + // make parameter reverse ordering as expected by COM runtime + if ((pArgs != null) && (pArgs.length > 0)) { + _argsLen = pArgs.length; + _args = new VARIANT[_argsLen]; + + int revCount = _argsLen; + for (int i = 0; i < _argsLen; i++) { + _args[i] = pArgs[--revCount]; + } + } + + // Handle special-case for property-puts! + if (nType == OleAuto.DISPATCH_PROPERTYPUT) { + dp.cNamedArgs = new UINT(_argsLen); + dp.rgdispidNamedArgs = new DISPIDByReference(OaIdl.DISPID_PROPERTYPUT); + } + + // Build DISPPARAMS + if (_argsLen > 0) { + dp.cArgs = new UINT(_args.length); + // make pointer of variant array + dp.rgvarg = new VariantArg.ByReference(_args); + + // write 'DISPPARAMS' structure to memory + dp.write(); + } + + // Make the call! + HRESULT hr = pDisp.Invoke(dispId, Guid.IID_NULL, LOCALE_SYSTEM_DEFAULT, new DISPID(nType), dp, pvResult, + pExcepInfo, puArgErr); + + COMUtils.checkRC(hr, pExcepInfo, puArgErr); + return hr; + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComInterface.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComInterface.java new file mode 100644 index 0000000000..8acc335b01 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComInterface.java @@ -0,0 +1,26 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.proxy.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Inherited +public @interface ComInterface { + String iid() default ""; +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComObject.java new file mode 100644 index 0000000000..ba3c777601 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComObject.java @@ -0,0 +1,27 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.proxy.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.TYPE }) +@Inherited +public @interface ComObject { + String clsId() default ""; + String progId() default ""; +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Method.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Method.java new file mode 100644 index 0000000000..7a2a038591 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Method.java @@ -0,0 +1,27 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.proxy.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +@Inherited +public @interface Method { + String iid() default ""; + String name() default ""; +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Property.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Property.java new file mode 100644 index 0000000000..5493245e5a --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Property.java @@ -0,0 +1,27 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.proxy.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target({ ElementType.METHOD }) +@Inherited +public @interface Property { + String iid() default ""; + String name() default ""; +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java new file mode 100644 index 0000000000..febcc80ecc --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java @@ -0,0 +1,102 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import java.util.Iterator; + +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.IEnumMoniker; +import com.sun.jna.platform.win32.COM.Moniker; +import com.sun.jna.platform.win32.COM.proxy.ProxyObject; +import com.sun.jna.ptr.PointerByReference; + +/** + * Enumerates the components of a moniker or the monikers in a table of monikers. + * + * @see MSDN + * + */ +public class EnumMoniker implements Iterable { + + protected EnumMoniker(IEnumMoniker raw, com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot) { + this.rawRot = rawRot; + this.raw = raw; + WinNT.HRESULT hr = this.raw.Reset(); + COMUtils.checkRC(hr); + + this.cacheNext(); + } + + com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot; + IEnumMoniker raw; + Moniker rawNext; + + protected void cacheNext() { + PointerByReference rgelt = new PointerByReference(); + WinDef.ULONGByReference pceltFetched = new WinDef.ULONGByReference(); + WinNT.HRESULT hr = this.raw.Next(new WinDef.ULONG(1), rgelt, pceltFetched); + + if (WinNT.S_OK.equals(hr) && pceltFetched.getValue().intValue() > 0) { + this.rawNext = new Moniker(rgelt.getValue()); + } else { + if (!WinNT.S_FALSE.equals(hr)) { + COMUtils.checkRC(hr); + } + this.rawNext = null; + } + } + + + @Override + public Iterator iterator() { + return new Iterator() { + + @Override + public boolean hasNext() { + return null!= EnumMoniker.this.rawNext; + } + + @Override + public IDispatch next() { + Moniker moniker = EnumMoniker.this.rawNext; + PointerByReference ppunkObject = new PointerByReference(); + WinNT.HRESULT hr = EnumMoniker.this.rawRot.GetObject(moniker.getPointer(),ppunkObject); + COMUtils.checkRC(hr); + + //To assist debug, can use the following code +// PointerByReference ppbc = new PointerByReference(); +// Ole32.INSTANCE.CreateBindCtx(new DWORD(), ppbc); +// +// BSTRByReference ppszDisplayName = new BSTRByReference(); +// hr = moniker.GetDisplayName(ppbc.getValue(), moniker.getPointer(), ppszDisplayName); +// COMUtils.checkRC(hr); +// String name = ppszDisplayName.getString(); +// Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0)); + + //TODO: Can we assume that the object is an IDispatch ? + //Unknown unk = new Unknown(ppunkObject.getValue()); + Dispatch dispatch = new Dispatch(ppunkObject.getValue()); + + EnumMoniker.this.cacheNext(); + + return new ProxyObject(dispatch); + } + + }; + } + + +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java new file mode 100644 index 0000000000..34c59be701 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IDispatch.java @@ -0,0 +1,24 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +/** + * Java friendly version of {@link com.sun.jna.platform.win32.COM.IDispatch}. + * + */ +public interface IDispatch extends IUnknown { + + void setProperty(String name, T value); + T getProperty(Class returnType, String name); + T invokeMethod(Class returnType, String name, Object... args); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java new file mode 100644 index 0000000000..33961d541c --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IRunningObjectTable.java @@ -0,0 +1,41 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import java.util.List; + +/** + * Java friendly version of + * {@link com.sun.jna.platform.win32.COM.IRunningObjectTable} + * + */ +public interface IRunningObjectTable { + + /** + * Creates and returns an enumerator of all the objects currently registered + * in the running object table (ROT). + * + */ + Iterable enumRunning(); + + /** + * Gets all the active (running) objects that support the give interface. + * + * Enumerates the running objects (via enumRunning), and returns a list of + * those for which queryInterface(iid) gives a valid result. + * + * @param iid + * @return + */ + List getActiveObjectsByInterface(Class comInterface); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java new file mode 100644 index 0000000000..5285f3cb6a --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/IUnknown.java @@ -0,0 +1,28 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +/** + * Java friendly version of the IUnknown interface. + * + * + */ +public interface IUnknown { + /** + * Returns a proxy object for the given interface. Assuming that the + * interface is annotated with a ComInterface annotation that provides a + * valid iid. + * + */ + T queryInterface(Class comInterface); +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java new file mode 100644 index 0000000000..dd20d83b96 --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java @@ -0,0 +1,63 @@ +package com.sun.jna.platform.win32.COM.util; + +import java.util.ArrayList; +import java.util.List; + +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.ptr.PointerByReference; + +public class RunningObjectTable implements IRunningObjectTable { + + /** + * CoInitialize must be called be fore this method. Either explicitly or + * implicitly via other methods. + * + * @return + */ + static public IRunningObjectTable getRunningObjectTable() { + PointerByReference rotPtr = new PointerByReference(); + WinNT.HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable( + new WinDef.DWORD(0), rotPtr); + COMUtils.checkRC(hr); + com.sun.jna.platform.win32.COM.RunningObjectTable raw = new com.sun.jna.platform.win32.COM.RunningObjectTable(rotPtr.getValue()); + IRunningObjectTable rot = new RunningObjectTable(raw); + return rot; + } + + protected RunningObjectTable(com.sun.jna.platform.win32.COM.RunningObjectTable raw) { + this.raw = raw; + } + + com.sun.jna.platform.win32.COM.RunningObjectTable raw; + + @Override + public Iterable enumRunning() { + PointerByReference ppenumMoniker = new PointerByReference(); + WinNT.HRESULT hr = this.raw.EnumRunning(ppenumMoniker); + COMUtils.checkRC(hr); + + com.sun.jna.platform.win32.COM.EnumMoniker raw = new com.sun.jna.platform.win32.COM.EnumMoniker(ppenumMoniker.getValue()); + return new EnumMoniker(raw, this.raw); + } + + @Override + public List getActiveObjectsByInterface(Class comInterface) { + List result = new ArrayList(); + + for(IDispatch obj: this.enumRunning()) { + try { + T dobj = obj.queryInterface(comInterface); + + result.add(dobj); + } catch(COMException ex) { + + } + } + + return result; + } +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java index aa6b32b220..e346d2f9a7 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java @@ -15,9 +15,9 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; import com.sun.jna.WString; -import com.sun.jna.platform.win32.BaseTSD.SIZE_T; import com.sun.jna.platform.win32.Guid.CLSID; import com.sun.jna.platform.win32.Guid.GUID; +import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.LPVOID; import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.ptr.PointerByReference; @@ -257,7 +257,7 @@ HRESULT CoCreateInstance(GUID rclsid, Pointer pUnkOuter, int dwClsContext, * @return If the function succeeds, it returns the reallocated memory block. Otherwise, it returns NULL. */ Pointer CoTaskMemRealloc(Pointer pv, long cb); - + /** * Frees a block of task memory previously allocated through a call to the {@link #CoTaskMemAlloc} or * {@link #CoTaskMemRealloc} function. The function uses the default OLE allocator. The number of bytes @@ -267,4 +267,48 @@ HRESULT CoCreateInstance(GUID rclsid, Pointer pUnkOuter, int dwClsContext, */ void CoTaskMemFree(Pointer pv); + /** + * Retrieves a pointer to the default OLE task memory allocator + * + * {@code + * HRESULT CoGetMalloc( + * [In] DWORD dwMemContext, + * [Out] LPMALLOC *ppMalloc + * ); + * + * @see MSDN + * + */ + HRESULT CoGetMalloc(DWORD dwMemContext, PointerByReference ppMalloc); + + /** + * Returns a pointer to the IRunningObjectTable interface on the local running object table (ROT). + * + * {@code + * HRESULT GetRunningObjectTable( + * [In] DWORD reserved, + * [Out] LPRUNNINGOBJECTTABLE *pprot + * ); + * } + * + * + * @see MSDN + */ + HRESULT GetRunningObjectTable(DWORD reserved, PointerByReference pprot); + + /** + * Returns a pointer to an implementation of IBindCtx (a bind context object). + * + * {@code + * HRESULT CreateBindCtx( + * [In] DWORD reserved, + * [Out] LPBC *ppbc + * ); + * } + * + * + * @see MSDN + */ + HRESULT CreateBindCtx(DWORD reserved, PointerByReference ppbc); + } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java new file mode 100644 index 0000000000..ed81b0deba --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java @@ -0,0 +1,222 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.jna.platform.win32.Guid.CLSID; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.platform.win32.COM.proxy.ProxyObject; +import com.sun.jna.ptr.PointerByReference; + +public class EnumMoniker_Test { + + ProxyObject ob1; + ProxyObject ob2; + + @Before + public void before() { + HRESULT hr = Ole32.INSTANCE.CoInitialize(null); + COMUtils.checkRC(hr); + + // Two COM objects are require to be running for these tests to work + CLSID.ByReference clsid = new CLSID.ByReference(); + hr = Ole32.INSTANCE.CLSIDFromProgID("Word.Application", clsid); + PointerByReference ptrDisp1 = new PointerByReference(); + Ole32.INSTANCE.CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp1); + this.ob1 = new ProxyObject(new Dispatch(ptrDisp1.getValue())); + + PointerByReference ptrDisp2 = new PointerByReference(); + Ole32.INSTANCE.CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp2); + this.ob2 = new ProxyObject(new Dispatch(ptrDisp2.getValue())); + + } + + @After + public void after() { + ob1.invokeMethod(Void.TYPE, "Quit"); + + ob2.invokeMethod(Void.TYPE, "Quit"); + + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + public void Reset() { + // GetRunningObjectTable + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + // EnumRunning + PointerByReference ppenumMoniker = new PointerByReference(); + hr = rot.EnumRunning(ppenumMoniker); + COMUtils.checkRC(hr); + IEnumMoniker iterator = new EnumMoniker(ppenumMoniker.getValue()); + + // Reset + hr = iterator.Reset(); + COMUtils.checkRC(hr); + + // Next + PointerByReference rgelt1 = new PointerByReference(); + ULONGByReference pceltFetched1 = new ULONGByReference(); + hr = iterator.Next(new ULONG(1), rgelt1, pceltFetched1); + COMUtils.checkRC(hr); + + // Reset + hr = iterator.Reset(); + COMUtils.checkRC(hr); + + // Next + PointerByReference rgelt2 = new PointerByReference(); + ULONGByReference pceltFetched2 = new ULONGByReference(); + hr = iterator.Next(new ULONG(1), rgelt2, pceltFetched2); + COMUtils.checkRC(hr); + + assertEquals(rgelt1.getValue(), rgelt2.getValue()); + } + + @Test + public void Next() { + // GetRunningObjectTable + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + // EnumRunning + PointerByReference ppenumMoniker = new PointerByReference(); + hr = rot.EnumRunning(ppenumMoniker); + COMUtils.checkRC(hr); + IEnumMoniker iterator = new EnumMoniker(ppenumMoniker.getValue()); + + // Reset + hr = iterator.Reset(); + COMUtils.checkRC(hr); + + // Next + PointerByReference rgelt1 = new PointerByReference(); + ULONGByReference pceltFetched1 = new ULONGByReference(); + hr = iterator.Next(new ULONG(1), rgelt1, pceltFetched1); + COMUtils.checkRC(hr); + + // Next + PointerByReference rgelt2 = new PointerByReference(); + ULONGByReference pceltFetched2 = new ULONGByReference(); + hr = iterator.Next(new ULONG(1), rgelt2, pceltFetched2); + COMUtils.checkRC(hr); + + assertNotEquals(rgelt1.getValue(), rgelt2.getValue()); + } + + @Test + public void Skip() { + // GetRunningObjectTable + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + // EnumRunning + PointerByReference ppenumMoniker = new PointerByReference(); + hr = rot.EnumRunning(ppenumMoniker); + COMUtils.checkRC(hr); + IEnumMoniker iterator = new EnumMoniker(ppenumMoniker.getValue()); + + // Reset + hr = iterator.Reset(); + COMUtils.checkRC(hr); + + // Next + PointerByReference rgelt1 = new PointerByReference(); + ULONGByReference pceltFetched1 = new ULONGByReference(); + hr = iterator.Next(new ULONG(1), rgelt1, pceltFetched1); + COMUtils.checkRC(hr); + + // Reset + hr = iterator.Reset(); + COMUtils.checkRC(hr); + + // Skip + hr = iterator.Skip(new ULONG(1)); + COMUtils.checkRC(hr); + + // Next + PointerByReference rgelt2 = new PointerByReference(); + ULONGByReference pceltFetched2 = new ULONGByReference(); + hr = iterator.Next(new ULONG(1), rgelt2, pceltFetched2); + COMUtils.checkRC(hr); + + assertNotEquals(rgelt1.getValue(), rgelt2.getValue()); + } + + @Test + public void Clone() { + // GetRunningObjectTable + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + // EnumRunning + PointerByReference ppenumMoniker = new PointerByReference(); + hr = rot.EnumRunning(ppenumMoniker); + COMUtils.checkRC(hr); + IEnumMoniker iterator1 = new EnumMoniker(ppenumMoniker.getValue()); + + // iterator1.Reset + hr = iterator1.Reset(); + COMUtils.checkRC(hr); + + // iterator1.Next + PointerByReference rgelt1 = new PointerByReference(); + ULONGByReference pceltFetched1 = new ULONGByReference(); + hr = iterator1.Next(new ULONG(1), rgelt1, pceltFetched1); + COMUtils.checkRC(hr); + + // iterator1.Clone + PointerByReference ppenum = new PointerByReference(); + hr = iterator1.Clone(ppenum); + COMUtils.checkRC(hr); + IEnumMoniker iterator2 = new EnumMoniker(ppenum.getValue()); + + // iterator2.Next + PointerByReference rgelt2 = new PointerByReference(); + ULONGByReference pceltFetched2 = new ULONGByReference(); + hr = iterator2.Next(new ULONG(1), rgelt2, pceltFetched2); + COMUtils.checkRC(hr); + + assertNotEquals(rgelt1.getValue(), rgelt2.getValue()); + + // iterator1.Next + rgelt1 = new PointerByReference(); + pceltFetched1 = new ULONGByReference(); + hr = iterator1.Next(new ULONG(1), rgelt1, pceltFetched1); + COMUtils.checkRC(hr); + + assertEquals(rgelt1.getValue(), rgelt2.getValue()); + } + +} diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java new file mode 100644 index 0000000000..50161e2bc8 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/RunningObjectTable_Test.java @@ -0,0 +1,183 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.WTypes.BSTRByReference; +import com.sun.jna.platform.win32.WinDef.DWORD; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.ptr.PointerByReference; + +public class RunningObjectTable_Test { + + @Before + public void before() { + HRESULT hr = Ole32.INSTANCE.CoInitialize(null); + COMUtils.checkRC(hr); + } + + @After + public void after() { + Ole32.INSTANCE.CoUninitialize(); + } + + @Test + public void GetRunningObjectTable() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + + assertNotNull(pprot.getValue()); + } + + @Test + public void Register() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + //Can't yet be tested as IMoniker is not fully implemented + //rot.Register(grfFlags, punkObject, pmkObjectName, pdwRegister); + + } + + @Test + public void Revoke() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + //Can't yet be tested as IMoniker is not fully implemented, + // so we can't register an object, and hence can't get a registration key to Revoke one + //rot.Revoke(dwRegister); + + } + + @Test + public void IsRunning() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + //Can't yet be tested as IMoniker is not fully implemented, + //rot.IsRunning(pmkObjectName); + + } + + @Test + public void GetObject() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + PointerByReference ppenumMoniker = new PointerByReference(); + hr = rot.EnumRunning(ppenumMoniker); + COMUtils.checkRC(hr); + IEnumMoniker iterator = new EnumMoniker(ppenumMoniker.getValue()); + + iterator.Reset(); + + PointerByReference rgelt = new PointerByReference(); + ULONGByReference pceltFetched = new ULONGByReference(); + hr = iterator.Next(new ULONG(1), rgelt, pceltFetched); + + while (WinNT.S_OK.equals(hr) && pceltFetched.getValue().intValue() > 0) { + Moniker moniker = new Moniker(rgelt.getValue()); + + PointerByReference ppbc = new PointerByReference(); + Ole32.INSTANCE.CreateBindCtx(new DWORD(), ppbc); + //IBindCtx pbc = new BindCtx(ppbc.getValue()); + + BSTRByReference ppszDisplayName = new BSTRByReference(); + hr = moniker.GetDisplayName(ppbc.getValue(), moniker.getPointer(), ppszDisplayName); + COMUtils.checkRC(hr); + String name = ppszDisplayName.getString(); + Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0)); + + PointerByReference ppunkObject = new PointerByReference(); + hr = rot.GetObject(moniker.getPointer(), ppunkObject); + COMUtils.checkRC(hr); + + + + IUnknown unk = new Unknown(ppunkObject.getValue()); + PointerByReference ppvObject = new PointerByReference(); + hr = unk.QueryInterface(IUnknown.IID_IUNKNOWN, ppvObject); + assertEquals(0, hr.intValue()); + assertNotNull(ppvObject.getValue()); + + moniker.Release(); + + hr = iterator.Next(new ULONG(1), rgelt, pceltFetched); + } + + } + + @Test + public void NoteChangeTime() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + //Can't yet be tested as IMoniker is not fully implemented, + // so we can't register an object, and hence can't get a registration key + //rot.NoteChangeTime(dwRegister, pfiletime); + + } + + @Test + public void GetTimeOfLastChange() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + //Can't yet be tested as IMoniker is not fully implemented, + // so we can't register an object, and hence can't get a registration key + //rot.GetTimeOfLastChange(pmkObjectName, pfiletime); + + } + + @Test + public void EnumRunning() { + PointerByReference pprot = new PointerByReference(); + HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable(new DWORD(0), pprot); + COMUtils.checkRC(hr); + IRunningObjectTable rot = new RunningObjectTable(pprot.getValue()); + + PointerByReference ppenumMoniker = new PointerByReference(); + hr = rot.EnumRunning(ppenumMoniker); + COMUtils.checkRC(hr); + + assertNotNull(ppenumMoniker.getValue()); + + } + + + +} diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java new file mode 100644 index 0000000000..6934016dd5 --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java @@ -0,0 +1,108 @@ +/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.util; + +import static org.junit.Assert.*; + +import java.util.List; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import com.sun.jna.platform.win32.COM.COMException; +import com.sun.jna.platform.win32.COM.COMUtils; +import com.sun.jna.platform.win32.COM.proxy.Factory; +import com.sun.jna.platform.win32.COM.proxy.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.proxy.annotation.ComObject; +import com.sun.jna.platform.win32.COM.proxy.annotation.Method; +import com.sun.jna.platform.win32.COM.proxy.annotation.Property; +import com.sun.jna.platform.win32.Guid.IID; +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.Ole32Util; +import com.sun.jna.platform.win32.OleAuto; +import com.sun.jna.platform.win32.Variant; +import com.sun.jna.platform.win32.WinDef; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.ptr.PointerByReference; + +public class RunningObjectTable_Test { + + @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") + interface Application { + @Property + boolean getVisible(); + + @Property + void setVisible(boolean value); + + @Method + void Quit(); + } + + @ComObject(progId="Word.Application") + interface MsWordApp extends Application { + } + + MsWordApp msWord; + + @Before + public void before() { + Factory.initializeThreadForComAccess(); + + this.msWord = Factory.createObject(MsWordApp.class); + msWord.setVisible(true); + } + + @After + public void after() { + this.msWord.Quit(); + + Factory.releaseThreadFromComAccess(); + } + + @Test + public void getRunningObjectTable() { + IRunningObjectTable rot = RunningObjectTable.getRunningObjectTable(); + + assertNotNull(rot); + } + + @Test + public void enumRunning() { + IRunningObjectTable rot = RunningObjectTable.getRunningObjectTable(); + + for(IUnknown obj: rot.enumRunning()) { + try { + Application msw = obj.queryInterface(Application.class); + } catch(COMException ex) { + int i= 0; + } + } + } + + @Test + public void getActiveObjectsByInterface() { + IRunningObjectTable rot = RunningObjectTable.getRunningObjectTable(); + + List objs = rot.getActiveObjectsByInterface(Application.class); + assertTrue(objs.size() > 0); + + for(Application dobj: objs) { + msWord.setVisible(true); + boolean v2 = dobj.getVisible(); + assertEquals(true, v2); + } + + } +} From c5c8da59ebda3d276cdee26ac845fb3ab84b8121 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 22 Oct 2014 14:00:56 +0200 Subject: [PATCH 02/49] Added pom files for building eclipse p2-repository, features and bundles --- eclipse/com.sun.jna.core/pom.xml | 337 ++++++++++++++++++ eclipse/com.sun.jna.feature/build.properties | 2 + eclipse/com.sun.jna.feature/pom.xml | 23 ++ .../src/main/resources/feature.xml | 203 +++++++++++ .../src/main/resources/license.txt | 177 +++++++++ eclipse/com.sun.jna.native-repo/pom.xml | 315 ++++++++++++++++ eclipse/com.sun.jna.p2.repository/pom.xml | 53 +++ .../src/main/resources/category.xml | 7 + eclipse/com.sun.jna.platform/pom.xml | 82 +++++ eclipse/pom.xml | 29 ++ 10 files changed, 1228 insertions(+) create mode 100644 eclipse/com.sun.jna.core/pom.xml create mode 100644 eclipse/com.sun.jna.feature/build.properties create mode 100644 eclipse/com.sun.jna.feature/pom.xml create mode 100644 eclipse/com.sun.jna.feature/src/main/resources/feature.xml create mode 100644 eclipse/com.sun.jna.feature/src/main/resources/license.txt create mode 100644 eclipse/com.sun.jna.native-repo/pom.xml create mode 100644 eclipse/com.sun.jna.p2.repository/pom.xml create mode 100644 eclipse/com.sun.jna.p2.repository/src/main/resources/category.xml create mode 100644 eclipse/com.sun.jna.platform/pom.xml create mode 100644 eclipse/pom.xml diff --git a/eclipse/com.sun.jna.core/pom.xml b/eclipse/com.sun.jna.core/pom.xml new file mode 100644 index 0000000000..0cf34110f2 --- /dev/null +++ b/eclipse/com.sun.jna.core/pom.xml @@ -0,0 +1,337 @@ + + 4.0.0 + + + com.sun.jna + com.sun.jna.parent + 4.1.1-SNAPSHOT + + + com.sun.jna.core + + bundle + + + + + ${project.basedir}/../com.sun.jna.native-repo/target/repo + com.sun.jna.native + ${parsedVersion.osgiVersion} + + + + + + project.local + project + file:${native-repo-dir} + + + + + ${project.basedir}/../../src + + + + + ${project.build.outputDirectory} + + **/*.dll + **/*.a + **/*.so + **/*.jnilib + + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.9.1 + + + parse-version + + parse-version + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.9 + + + unpack + process-resources + + unpack + + + ${native-repo-dir} + + + ${project.build.outputDirectory}/com/sun/jna/win32-x86 + jnidispatch.dll + win32-x86 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/win32-x86-64 + jnidispatch.dll + win32-x86-64 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/w32ce-arm + jnidispatch.dll + w32ce-arm + ${native-groupId} + ${project.version} + jar + true + + + + ${project.build.outputDirectory}/com/sun/jna/sunos-x86 + libjnidispatch.so + sunos-x86 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/sunos-x86-64 + libjnidispatch.so + sunos-x86-64 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/sunos-sparc + libjnidispatch.so + sunos-sparc + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/sunos-sparcv9 + libjnidispatch.so + sunos-sparcv9 + ${native-groupId} + ${project.version} + jar + true + + + + ${project.build.outputDirectory}/com/sun/jna/aix-ppc + libjnidispatch.a + aix-ppc + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/aix-ppc64 + libjnidispatch.a + aix-ppc64 + ${native-groupId} + ${project.version} + jar + true + + + + ${project.build.outputDirectory}/com/sun/jna/linux-ppc + libjnidispatch.so + linux-ppc + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/linux-ppc64 + libjnidispatch.so + linux-ppc64 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/linux-x86 + libjnidispatch.so + linux-x86 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/linux-x86-64 + libjnidispatch.so + linux-x86-64 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/linux-arm + libjnidispatch.so + linux-arm + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/linux-aarch64 + libjnidispatch.so + linux-aarch64 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/linux-ia64 + jnidispatch.dll + linux-ia64 + ${native-groupId} + ${project.version} + jar + true + + + + ${project.build.outputDirectory}/com/sun/jna/freebsd-x86 + libjnidispatch.so + freebsd-x86 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/freebsd-x86-64 + libjnidispatch.so + freebsd-x86-64 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/openbsd-x86 + libjnidispatch.so + openbsd-x86 + ${native-groupId} + ${project.version} + jar + true + + + ${project.build.outputDirectory}/com/sun/jna/openbsd-x86-64 + libjnidispatch.so + openbsd-x86-64 + ${native-groupId} + ${project.version} + jar + true + + + + ${project.build.outputDirectory}/com/sun/jna/darwin + libjnidispatch.jnilib + darwin + ${native-groupId} + ${project.version} + jar + true + + + + + + + + + + + org.apache.felix + maven-bundle-plugin + 2.5.3 + true + + + 1.0 + 2 + ${project.artifactId} + ${project.artifactId} + ${bundle-version} + JNA Development Team + J2SE-1.4 + lazy + com.sun.jna,com.sun.jna.ptr,com.sun.jna.win32 + +com/sun/jna/win32-x86/jnidispatch.dll;processor=x86;osname=win32, +com/sun/jna/win32-x86-64/jnidispatch.dll;processor=x86-64;osname=win32, +com/sun/jna/w32ce-arm/jnidispatch.dll;processor=arm;osname=wince, + +com/sun/jna/sunos-x86/libjnidispatch.so;processor=x86;osname=sunos, +com/sun/jna/sunos-x86-64/libjnidispatch.so;processor=x86-64;osname=sunos, +com/sun/jna/sunos-sparc/libjnidispatch.so;processor=sparc;osname=sunos, +com/sun/jna/sunos-sparcv9/libjnidispatch.so;processor=sparcv9;osname=sunos, + +com/sun/jna/aix-ppc/libjnidispatch.a;processor=ppc;osname=aix, + +com/sun/jna/linux-x86/libjnidispatch.so;processor=x86;osname=linux, +com/sun/jna/linux-x86-64/libjnidispatch.so;processor=x86-64;osname=linux, +com/sun/jna/linux-arm/libjnidispatch.so;processor=arm;osname=linux, +com/sun/jna/linux-aarch64/libjnidispatch.so;processor=aarch64;osname=linux, + + +com/sun/jna/freebsd-x86/libjnidispatch.so;processor=x86;osname=freebsd, +com/sun/jna/freebsd-x86-64/libjnidispatch.so;processor=x86-64;osname=freebsd, +com/sun/jna/openbsd-x86/libjnidispatch.so;processor=x86;osname=openbsd, +com/sun/jna/openbsd-x86-64/libjnidispatch.so;processor=x86-64;osname=openbsd, + +com/sun/jna/darwin/libjnidispatch.jnilib;osname=macosx;processor=x86;processor=x86-64;processor=ppc + + + + + + + + + diff --git a/eclipse/com.sun.jna.feature/build.properties b/eclipse/com.sun.jna.feature/build.properties new file mode 100644 index 0000000000..102d6a3475 --- /dev/null +++ b/eclipse/com.sun.jna.feature/build.properties @@ -0,0 +1,2 @@ +bin.includes = feature.xml,\ + LICENSE.txt diff --git a/eclipse/com.sun.jna.feature/pom.xml b/eclipse/com.sun.jna.feature/pom.xml new file mode 100644 index 0000000000..1d5be69da7 --- /dev/null +++ b/eclipse/com.sun.jna.feature/pom.xml @@ -0,0 +1,23 @@ + + + 4.0.0 + + + com.sun.jna + com.sun.jna.parent + 4.1.1-SNAPSHOT + + + feature + + jar + + + + + + diff --git a/eclipse/com.sun.jna.feature/src/main/resources/feature.xml b/eclipse/com.sun.jna.feature/src/main/resources/feature.xml new file mode 100644 index 0000000000..1031aee04d --- /dev/null +++ b/eclipse/com.sun.jna.feature/src/main/resources/feature.xml @@ -0,0 +1,203 @@ + + + + + The JNA library encapsulated in an Eclipse plugin. + + + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + + + + diff --git a/eclipse/com.sun.jna.feature/src/main/resources/license.txt b/eclipse/com.sun.jna.feature/src/main/resources/license.txt new file mode 100644 index 0000000000..ade750b16b --- /dev/null +++ b/eclipse/com.sun.jna.feature/src/main/resources/license.txt @@ -0,0 +1,177 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/eclipse/com.sun.jna.native-repo/pom.xml b/eclipse/com.sun.jna.native-repo/pom.xml new file mode 100644 index 0000000000..e20f79f536 --- /dev/null +++ b/eclipse/com.sun.jna.native-repo/pom.xml @@ -0,0 +1,315 @@ + + 4.0.0 + + + com.sun.jna + com.sun.jna.parent + 4.1.1-SNAPSHOT + + + com.sun.jna.native-repo + + pom + + + com.sun.jna.native + ${project.basedir}/../../lib/native + ${project.build.directory}/repo + + + + + + + + + org.apache.maven.plugins + maven-install-plugin + 2.4 + + + win32-x86 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/win32-x86.jar + ${native-groupId} + win32-x86 + ${project.version} + jar + + + + win32-x86-64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/win32-x86-64.jar + ${native-groupId} + win32-x86-64 + ${project.version} + jar + + + + w32ce-arm + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/w32ce-arm.jar + ${native-groupId} + w32ce-arm + ${project.version} + jar + + + + + sunos-x86 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/sunos-x86.jar + ${native-groupId} + sunos-x86 + ${project.version} + jar + + + + sunos-x86-64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/sunos-x86-64.jar + ${native-groupId} + sunos-x86-64 + ${project.version} + jar + + + + sunos-sparc + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/sunos-sparc.jar + ${native-groupId} + sunos-sparc + ${project.version} + jar + + + + sunos-sparcv9 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/sunos-sparcv9.jar + ${native-groupId} + sunos-sparcv9 + ${project.version} + jar + + + + + aix-ppc + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/aix-ppc.jar + ${native-groupId} + aix-ppc + ${project.version} + jar + + + + aix-ppc64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/aix-ppc64.jar + ${native-groupId} + aix-ppc64 + ${project.version} + jar + + + + + linux-ppc + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/linux-ppc.jar + ${native-groupId} + linux-ppc + ${project.version} + jar + + + + linux-ppc64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/linux-ppc64.jar + ${native-groupId} + linux-ppc64 + ${project.version} + jar + + + + linux-x86 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/linux-x86.jar + ${native-groupId} + linux-x86 + ${project.version} + jar + + + + linux-x86-64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/linux-x86-64.jar + ${native-groupId} + linux-x86-64 + ${project.version} + jar + + + + linux-arm + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/linux-arm.jar + ${native-groupId} + linux-arm + ${project.version} + jar + + + + linux-aarch64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/linux-aarch64.jar + ${native-groupId} + linux-aarch64 + ${project.version} + jar + + + + linux-ia64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/linux-ia64.jar + ${native-groupId} + linux-ia64 + ${project.version} + jar + + + + + freebsd-x86 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/freebsd-x86.jar + ${native-groupId} + freebsd-x86 + ${project.version} + jar + + + + freebsd-x86-64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/freebsd-x86-64.jar + ${native-groupId} + freebsd-x86-64 + ${project.version} + jar + + + + openbsd-x86 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/openbsd-x86.jar + ${native-groupId} + openbsd-x86 + ${project.version} + jar + + + + openbsd-x86-64 + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/openbsd-x86-64.jar + ${native-groupId} + openbsd-x86-64 + ${project.version} + jar + + + + + darwin + generate-resources + install-file + + ${native-repo-dir} + ${native-jars}/darwin.jar + ${native-groupId} + darwin + ${project.version} + jar + + + + + + + + + + diff --git a/eclipse/com.sun.jna.p2.repository/pom.xml b/eclipse/com.sun.jna.p2.repository/pom.xml new file mode 100644 index 0000000000..2fbadb8c44 --- /dev/null +++ b/eclipse/com.sun.jna.p2.repository/pom.xml @@ -0,0 +1,53 @@ + + + 4.0.0 + + + com.sun.jna + com.sun.jna.parent + 4.1.1-SNAPSHOT + + + com.sun.jna.p2.repository + + pom + + + + + org.reficio + p2-maven-plugin + 1.1.1-SNAPSHOT + + + default-cli + package + + site + + + ${project.basedir}/src/main/resources/category.xml + + + com.sun.jna:com.sun.jna.core:${project.version} + false + + + com.sun.jna:com.sun.jna.platform:${project.version} + false + + + + + com.sun.jna:feature:${project.version} + false + + + + + + + + + diff --git a/eclipse/com.sun.jna.p2.repository/src/main/resources/category.xml b/eclipse/com.sun.jna.p2.repository/src/main/resources/category.xml new file mode 100644 index 0000000000..e7bbc82692 --- /dev/null +++ b/eclipse/com.sun.jna.p2.repository/src/main/resources/category.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/eclipse/com.sun.jna.platform/pom.xml b/eclipse/com.sun.jna.platform/pom.xml new file mode 100644 index 0000000000..d23130a611 --- /dev/null +++ b/eclipse/com.sun.jna.platform/pom.xml @@ -0,0 +1,82 @@ + + 4.0.0 + + + com.sun.jna + com.sun.jna.parent + 4.1.1-SNAPSHOT + + + com.sun.jna.platform + + bundle + + + ${parsedVersion.osgiVersion} + + + + + com.sun.jna + com.sun.jna.core + ${project.version} + + + + + + ${project.basedir}/../../contrib/platform/src + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.9.1 + + + parse-version + + parse-version + + + + + + + + org.apache.felix + maven-bundle-plugin + 2.5.3 + true + + + 1.0 + 2 + ${project.artifactId} + ${project.artifactId} + ${bundle-version} + JNA Development Team + J2SE-1.4 + lazy + +com.sun.jna.platform, +com.sun.jna.platform.dnd, +com.sun.jna.platform.mac, +com.sun.jna.platform.unix, +com.sun.jna.platform.win32, +com.sun.jna.platform.win32.COM, +com.sun.jna.platform.win32.COM.proxy, +com.sun.jna.platform.win32.COM.proxy.annotation, +com.sun.jna.platform.win32.COM.tlb, +com.sun.jna.platform.win32.COM.tlb.imp, +com.sun.jna.platform.win32.COM.util, +com.sun.jna.platform.win32.COM.wince + + + + + + + + diff --git a/eclipse/pom.xml b/eclipse/pom.xml new file mode 100644 index 0000000000..ce35417165 --- /dev/null +++ b/eclipse/pom.xml @@ -0,0 +1,29 @@ + + 4.0.0 + + com.sun.jna + com.sun.jna.parent + 4.1.1-SNAPSHOT + + pom + + + + com.sun.jna.native-repo + + com.sun.jna.core + com.sun.jna.platform + com.sun.jna.feature + com.sun.jna.p2.repository + + + + + 0.20.0 + org.eclipse.tycho + kepler + UTF-8 + + + + From c153e9693a4d416824af84f8e24d6bf9e6a85d7c Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Mon, 27 Oct 2014 09:59:53 +0100 Subject: [PATCH 03/49] Added eclipse project files --- eclipse/.project | 17 ++++++++++++ eclipse/com.sun.jna.core/.classpath | 6 +++++ eclipse/com.sun.jna.core/.gitignore | 1 + eclipse/com.sun.jna.core/.project | 30 +++++++++++++++++++++ eclipse/com.sun.jna.feature/.classpath | 31 ++++++++++++++++++++++ eclipse/com.sun.jna.feature/.gitignore | 1 + eclipse/com.sun.jna.feature/.project | 29 ++++++++++++++++++++ eclipse/com.sun.jna.native-repo/.gitignore | 1 + eclipse/com.sun.jna.native-repo/.project | 17 ++++++++++++ eclipse/com.sun.jna.p2.repository/.project | 17 ++++++++++++ eclipse/com.sun.jna.platform/.classpath | 15 +++++++++++ eclipse/com.sun.jna.platform/.gitignore | 1 + eclipse/com.sun.jna.platform/.project | 31 ++++++++++++++++++++++ 13 files changed, 197 insertions(+) create mode 100644 eclipse/.project create mode 100644 eclipse/com.sun.jna.core/.classpath create mode 100644 eclipse/com.sun.jna.core/.gitignore create mode 100644 eclipse/com.sun.jna.core/.project create mode 100644 eclipse/com.sun.jna.feature/.classpath create mode 100644 eclipse/com.sun.jna.feature/.gitignore create mode 100644 eclipse/com.sun.jna.feature/.project create mode 100644 eclipse/com.sun.jna.native-repo/.gitignore create mode 100644 eclipse/com.sun.jna.native-repo/.project create mode 100644 eclipse/com.sun.jna.p2.repository/.project create mode 100644 eclipse/com.sun.jna.platform/.classpath create mode 100644 eclipse/com.sun.jna.platform/.gitignore create mode 100644 eclipse/com.sun.jna.platform/.project diff --git a/eclipse/.project b/eclipse/.project new file mode 100644 index 0000000000..8396c70a8d --- /dev/null +++ b/eclipse/.project @@ -0,0 +1,17 @@ + + + com.sun.jna.parent + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/eclipse/com.sun.jna.core/.classpath b/eclipse/com.sun.jna.core/.classpath new file mode 100644 index 0000000000..d171cd4c12 --- /dev/null +++ b/eclipse/com.sun.jna.core/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/eclipse/com.sun.jna.core/.gitignore b/eclipse/com.sun.jna.core/.gitignore new file mode 100644 index 0000000000..ea8c4bf7f3 --- /dev/null +++ b/eclipse/com.sun.jna.core/.gitignore @@ -0,0 +1 @@ +/target diff --git a/eclipse/com.sun.jna.core/.project b/eclipse/com.sun.jna.core/.project new file mode 100644 index 0000000000..49df77f80a --- /dev/null +++ b/eclipse/com.sun.jna.core/.project @@ -0,0 +1,30 @@ + + + com.sun.jna.core + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + + + src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/src + + + diff --git a/eclipse/com.sun.jna.feature/.classpath b/eclipse/com.sun.jna.feature/.classpath new file mode 100644 index 0000000000..885810809d --- /dev/null +++ b/eclipse/com.sun.jna.feature/.classpath @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/eclipse/com.sun.jna.feature/.gitignore b/eclipse/com.sun.jna.feature/.gitignore new file mode 100644 index 0000000000..ea8c4bf7f3 --- /dev/null +++ b/eclipse/com.sun.jna.feature/.gitignore @@ -0,0 +1 @@ +/target diff --git a/eclipse/com.sun.jna.feature/.project b/eclipse/com.sun.jna.feature/.project new file mode 100644 index 0000000000..39bf25bd31 --- /dev/null +++ b/eclipse/com.sun.jna.feature/.project @@ -0,0 +1,29 @@ + + + com.sun.jna.feature + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.FeatureBuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + org.eclipse.pde.FeatureNature + + diff --git a/eclipse/com.sun.jna.native-repo/.gitignore b/eclipse/com.sun.jna.native-repo/.gitignore new file mode 100644 index 0000000000..ea8c4bf7f3 --- /dev/null +++ b/eclipse/com.sun.jna.native-repo/.gitignore @@ -0,0 +1 @@ +/target diff --git a/eclipse/com.sun.jna.native-repo/.project b/eclipse/com.sun.jna.native-repo/.project new file mode 100644 index 0000000000..6b05cd0b9d --- /dev/null +++ b/eclipse/com.sun.jna.native-repo/.project @@ -0,0 +1,17 @@ + + + com.sun.jna.native-repo + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/eclipse/com.sun.jna.p2.repository/.project b/eclipse/com.sun.jna.p2.repository/.project new file mode 100644 index 0000000000..34f75d33b4 --- /dev/null +++ b/eclipse/com.sun.jna.p2.repository/.project @@ -0,0 +1,17 @@ + + + com.sun.jna.p2.repository + + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.m2e.core.maven2Nature + + diff --git a/eclipse/com.sun.jna.platform/.classpath b/eclipse/com.sun.jna.platform/.classpath new file mode 100644 index 0000000000..0088eca04c --- /dev/null +++ b/eclipse/com.sun.jna.platform/.classpath @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/eclipse/com.sun.jna.platform/.gitignore b/eclipse/com.sun.jna.platform/.gitignore new file mode 100644 index 0000000000..ea8c4bf7f3 --- /dev/null +++ b/eclipse/com.sun.jna.platform/.gitignore @@ -0,0 +1 @@ +/target diff --git a/eclipse/com.sun.jna.platform/.project b/eclipse/com.sun.jna.platform/.project new file mode 100644 index 0000000000..e26e5f2d04 --- /dev/null +++ b/eclipse/com.sun.jna.platform/.project @@ -0,0 +1,31 @@ + + + com.sun.jna.platform + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.m2e.core.maven2Builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + org.eclipse.m2e.core.maven2Nature + + + + src + 2 + $%7BPARENT-2-PROJECT_LOC%7D/contrib/platform/src + + + From fe0ed1ceaafd955e4265618a27ee486752516d8f Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 28 Oct 2014 09:15:31 +0100 Subject: [PATCH 04/49] renaming packages and interfaces in new COM bits --- .../platform/win32/COM/util/EnumMoniker.java | 1 - .../win32/COM/{proxy => util}/Factory.java | 8 +++--- .../COM/{proxy => util}/ProxyObject.java | 18 ++++++------- .../annotation/ComInterface.java | 2 +- .../annotation/ComMethod.java} | 4 +-- .../{proxy => util}/annotation/ComObject.java | 2 +- .../annotation/ComProperty.java} | 4 +-- .../platform/win32/COM/EnumMoniker_Test.java | 2 +- .../COM/util/RunningObjectTable_Test.java | 15 +++++------ eclipse/com.sun.jna.core/.classpath | 14 ++++++++-- eclipse/com.sun.jna.core/.project | 8 +++++- .../.settings/org.eclipse.pde.core.prefs | 2 ++ eclipse/com.sun.jna.core/pom.xml | 18 +++++++++++++ eclipse/com.sun.jna.feature/.classpath | 27 ------------------- eclipse/com.sun.jna.feature/.project | 12 +++++++++ eclipse/com.sun.jna.feature/build.properties | 2 +- eclipse/com.sun.jna.feature/pom.xml | 18 +++++++++++++ eclipse/com.sun.jna.platform/.classpath | 1 + eclipse/com.sun.jna.platform/.project | 5 ++++ eclipse/com.sun.jna.platform/pom.xml | 9 +++++++ 20 files changed, 112 insertions(+), 60 deletions(-) rename contrib/platform/src/com/sun/jna/platform/win32/COM/{proxy => util}/Factory.java (91%) rename contrib/platform/src/com/sun/jna/platform/win32/COM/{proxy => util}/ProxyObject.java (93%) rename contrib/platform/src/com/sun/jna/platform/win32/COM/{proxy => util}/annotation/ComInterface.java (91%) rename contrib/platform/src/com/sun/jna/platform/win32/COM/{proxy/annotation/Method.java => util/annotation/ComMethod.java} (89%) rename contrib/platform/src/com/sun/jna/platform/win32/COM/{proxy => util}/annotation/ComObject.java (91%) rename contrib/platform/src/com/sun/jna/platform/win32/COM/{proxy/annotation/Property.java => util/annotation/ComProperty.java} (91%) create mode 100644 eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java index febcc80ecc..c6833fec26 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java @@ -20,7 +20,6 @@ import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.IEnumMoniker; import com.sun.jna.platform.win32.COM.Moniker; -import com.sun.jna.platform.win32.COM.proxy.ProxyObject; import com.sun.jna.ptr.PointerByReference; /** diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java similarity index 91% rename from contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/Factory.java rename to contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 1a6c403343..c78085cbf4 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.proxy; +package com.sun.jna.platform.win32.COM.util; import java.lang.reflect.Proxy; @@ -24,8 +24,8 @@ import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.IDispatch; -import com.sun.jna.platform.win32.COM.proxy.annotation.ComInterface; -import com.sun.jna.platform.win32.COM.proxy.annotation.ComObject; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; import com.sun.jna.ptr.PointerByReference; public class Factory { @@ -73,7 +73,7 @@ public static T createObject(Class comInterface) { * Gets and existing COM object (GetActiveObject) for the given progId and returns a ProxyObject * for the given interface. */ - public static T fetchObject(Class comInterface, String progId) { + public static T fetchObject(Class comInterface) { ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); if (null==comObectAnnotation) { throw new COMException("createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java similarity index 93% rename from contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/ProxyObject.java rename to contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index a9bf7b1a4f..dd56a15a03 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.proxy; +package com.sun.jna.platform.win32.COM.util; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; @@ -41,9 +41,9 @@ import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.Dispatch; -import com.sun.jna.platform.win32.COM.proxy.annotation.ComInterface; -import com.sun.jna.platform.win32.COM.proxy.annotation.Method; -import com.sun.jna.platform.win32.COM.proxy.annotation.Property; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; import com.sun.jna.platform.win32.COM.IDispatch; import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.ptr.IntByReference; @@ -71,7 +71,7 @@ public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] arg Class returnType = method.getReturnType(); boolean isVoid = Void.TYPE.equals(returnType); - Property prop = method.getAnnotation(Property.class); + ComProperty prop = method.getAnnotation(ComProperty.class); if (null != prop) { if (isVoid) { String propName = this.getMutatorName(method, prop); @@ -83,7 +83,7 @@ public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] arg } } - Method meth = method.getAnnotation(Method.class); + ComMethod meth = method.getAnnotation(ComMethod.class); if (null != meth) { String methName = this.getMethodName(method, meth); Object res = this.invokeMethod(returnType, methName, args); @@ -164,7 +164,7 @@ IID getIID(ComInterface annotation) { //--------------------- ProxyObject --------------------- - private String getAccessorName(java.lang.reflect.Method method, Property prop) { + private String getAccessorName(java.lang.reflect.Method method, ComProperty prop) { if (prop.name().isEmpty()) { String methName = method.getName(); if (methName.startsWith("get")) { @@ -178,7 +178,7 @@ private String getAccessorName(java.lang.reflect.Method method, Property prop) { } } - private String getMutatorName(java.lang.reflect.Method method, Property prop) { + private String getMutatorName(java.lang.reflect.Method method, ComProperty prop) { if (prop.name().isEmpty()) { String methName = method.getName(); if (methName.startsWith("set")) { @@ -192,7 +192,7 @@ private String getMutatorName(java.lang.reflect.Method method, Property prop) { } } - private String getMethodName(java.lang.reflect.Method method, Method meth) { + private String getMethodName(java.lang.reflect.Method method, ComMethod meth) { if (meth.name().isEmpty()) { String methName = method.getName(); return methName; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComInterface.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java similarity index 91% rename from contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComInterface.java rename to contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java index 8acc335b01..b5a1081349 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComInterface.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.proxy.annotation; +package com.sun.jna.platform.win32.COM.util.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Method.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java similarity index 89% rename from contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Method.java rename to contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java index 7a2a038591..bed6eb519a 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Method.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.proxy.annotation; +package com.sun.jna.platform.win32.COM.util.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -21,7 +21,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) @Inherited -public @interface Method { +public @interface ComMethod { String iid() default ""; String name() default ""; } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java similarity index 91% rename from contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComObject.java rename to contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java index ba3c777601..3768b29aa1 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/ComObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.proxy.annotation; +package com.sun.jna.platform.win32.COM.util.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Property.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java similarity index 91% rename from contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Property.java rename to contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java index 5493245e5a..6be7082980 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/proxy/annotation/Property.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.proxy.annotation; +package com.sun.jna.platform.win32.COM.util.annotation; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; @@ -21,7 +21,7 @@ @Retention(RetentionPolicy.RUNTIME) @Target({ ElementType.METHOD }) @Inherited -public @interface Property { +public @interface ComProperty { String iid() default ""; String name() default ""; } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java index ed81b0deba..d3ff82142d 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java @@ -26,7 +26,7 @@ import com.sun.jna.platform.win32.WinDef.ULONG; import com.sun.jna.platform.win32.WinDef.ULONGByReference; import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.COM.proxy.ProxyObject; +import com.sun.jna.platform.win32.COM.util.ProxyObject; import com.sun.jna.ptr.PointerByReference; public class EnumMoniker_Test { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java index 6934016dd5..3f6b900bd2 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java @@ -22,11 +22,10 @@ import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMUtils; -import com.sun.jna.platform.win32.COM.proxy.Factory; -import com.sun.jna.platform.win32.COM.proxy.annotation.ComInterface; -import com.sun.jna.platform.win32.COM.proxy.annotation.ComObject; -import com.sun.jna.platform.win32.COM.proxy.annotation.Method; -import com.sun.jna.platform.win32.COM.proxy.annotation.Property; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; import com.sun.jna.platform.win32.Guid.IID; import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.Ole32Util; @@ -40,13 +39,13 @@ public class RunningObjectTable_Test { @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") interface Application { - @Property + @ComProperty boolean getVisible(); - @Property + @ComProperty void setVisible(boolean value); - @Method + @ComMethod void Quit(); } diff --git a/eclipse/com.sun.jna.core/.classpath b/eclipse/com.sun.jna.core/.classpath index d171cd4c12..94a4141d4f 100644 --- a/eclipse/com.sun.jna.core/.classpath +++ b/eclipse/com.sun.jna.core/.classpath @@ -1,6 +1,16 @@ - - + + + + + + + + + + + + diff --git a/eclipse/com.sun.jna.core/.project b/eclipse/com.sun.jna.core/.project index 49df77f80a..c2970d5b4e 100644 --- a/eclipse/com.sun.jna.core/.project +++ b/eclipse/com.sun.jna.core/.project @@ -17,7 +17,8 @@ - org.eclipse.jdt.core.javanature + org.eclipse.pde.PluginNature + org.eclipse.m2e.core.maven2Nature @@ -26,5 +27,10 @@ 2 $%7BPARENT-2-PROJECT_LOC%7D/src + + test + 2 + $%7BPARENT-2-PROJECT_LOC%7D/test + diff --git a/eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs b/eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000000..d1c84cae3b --- /dev/null +++ b/eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,2 @@ +BUNDLE_ROOT_PATH=src/main/resources +eclipse.preferences.version=1 \ No newline at end of file diff --git a/eclipse/com.sun.jna.core/pom.xml b/eclipse/com.sun.jna.core/pom.xml index 0cf34110f2..11332dbaeb 100644 --- a/eclipse/com.sun.jna.core/pom.xml +++ b/eclipse/com.sun.jna.core/pom.xml @@ -19,6 +19,24 @@ ${parsedVersion.osgiVersion} + + + + org.reflections + reflections + 0.9.8 + test + + + + junit + junit + 4.11 + test + + + + diff --git a/eclipse/com.sun.jna.feature/.classpath b/eclipse/com.sun.jna.feature/.classpath index 885810809d..019b3150a1 100644 --- a/eclipse/com.sun.jna.feature/.classpath +++ b/eclipse/com.sun.jna.feature/.classpath @@ -1,31 +1,4 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/eclipse/com.sun.jna.feature/.project b/eclipse/com.sun.jna.feature/.project index 39bf25bd31..8272d1e365 100644 --- a/eclipse/com.sun.jna.feature/.project +++ b/eclipse/com.sun.jna.feature/.project @@ -26,4 +26,16 @@ org.eclipse.m2e.core.maven2Nature org.eclipse.pde.FeatureNature + + + feature.xml + 1 + $%7BPROJECT_LOC%7D/src/main/resources/feature.xml + + + license.txt + 1 + $%7BPROJECT_LOC%7D/src/main/resources/license.txt + + diff --git a/eclipse/com.sun.jna.feature/build.properties b/eclipse/com.sun.jna.feature/build.properties index 102d6a3475..8ba7015cef 100644 --- a/eclipse/com.sun.jna.feature/build.properties +++ b/eclipse/com.sun.jna.feature/build.properties @@ -1,2 +1,2 @@ bin.includes = feature.xml,\ - LICENSE.txt + licence.txt diff --git a/eclipse/com.sun.jna.feature/pom.xml b/eclipse/com.sun.jna.feature/pom.xml index 1d5be69da7..3e98c458c2 100644 --- a/eclipse/com.sun.jna.feature/pom.xml +++ b/eclipse/com.sun.jna.feature/pom.xml @@ -16,8 +16,26 @@ jar + + + + com.sun.jna + com.sun.jna.core + 4.1.1-SNAPSHOT + + + + com.sun.jna + com.sun.jna.platform + 4.1.1-SNAPSHOT + + + + + + diff --git a/eclipse/com.sun.jna.platform/.classpath b/eclipse/com.sun.jna.platform/.classpath index 0088eca04c..94a4141d4f 100644 --- a/eclipse/com.sun.jna.platform/.classpath +++ b/eclipse/com.sun.jna.platform/.classpath @@ -1,6 +1,7 @@ + diff --git a/eclipse/com.sun.jna.platform/.project b/eclipse/com.sun.jna.platform/.project index e26e5f2d04..40f99139e2 100644 --- a/eclipse/com.sun.jna.platform/.project +++ b/eclipse/com.sun.jna.platform/.project @@ -27,5 +27,10 @@ 2 $%7BPARENT-2-PROJECT_LOC%7D/contrib/platform/src + + test + 2 + $%7BPARENT-2-PROJECT_LOC%7D/contrib/platform/test + diff --git a/eclipse/com.sun.jna.platform/pom.xml b/eclipse/com.sun.jna.platform/pom.xml index d23130a611..28383732dd 100644 --- a/eclipse/com.sun.jna.platform/pom.xml +++ b/eclipse/com.sun.jna.platform/pom.xml @@ -16,11 +16,20 @@ + com.sun.jna com.sun.jna.core ${project.version} + + + junit + junit + 4.11 + test + + From 0f399d56c0cf053a0f89628d0003587c441a0e43 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 28 Oct 2014 09:49:09 +0100 Subject: [PATCH 05/49] Added more eclipse files --- .../jna/platform/win32/COM/util/Factory.java | 19 +++++++++++++++++-- .../win32/COM/util/RunningObjectTable.java | 16 ---------------- .../org.eclipse.core.resources.prefs | 2 ++ eclipse/.settings/org.eclipse.m2e.core.prefs | 4 ++++ .../org.eclipse.core.resources.prefs | 2 ++ .../.settings/org.eclipse.m2e.core.prefs | 4 ++++ .../.settings/org.eclipse.pde.core.prefs | 4 ++-- .../.settings/org.eclipse.m2e.core.prefs | 4 ++++ .../.settings/org.eclipse.m2e.core.prefs | 4 ++++ .../org.eclipse.core.resources.prefs | 2 ++ .../.settings/org.eclipse.jdt.core.prefs | 2 ++ .../.settings/org.eclipse.m2e.core.prefs | 4 ++++ .../.settings/org.eclipse.pde.core.prefs | 2 ++ eclipse/com.sun.jna.platform/pom.xml | 3 +-- 14 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 eclipse/.settings/org.eclipse.core.resources.prefs create mode 100644 eclipse/.settings/org.eclipse.m2e.core.prefs create mode 100644 eclipse/com.sun.jna.core/.settings/org.eclipse.core.resources.prefs create mode 100644 eclipse/com.sun.jna.core/.settings/org.eclipse.m2e.core.prefs create mode 100644 eclipse/com.sun.jna.native-repo/.settings/org.eclipse.m2e.core.prefs create mode 100644 eclipse/com.sun.jna.p2.repository/.settings/org.eclipse.m2e.core.prefs create mode 100644 eclipse/com.sun.jna.platform/.settings/org.eclipse.core.resources.prefs create mode 100644 eclipse/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs create mode 100644 eclipse/com.sun.jna.platform/.settings/org.eclipse.m2e.core.prefs create mode 100644 eclipse/com.sun.jna.platform/.settings/org.eclipse.pde.core.prefs diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index c78085cbf4..13d6ef0d59 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -19,14 +19,13 @@ import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.OleAuto; import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.IDispatch; -import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComObject; -import com.sun.jna.ptr.PointerByReference; public class Factory { @@ -39,6 +38,22 @@ public static void releaseThreadFromComAccess() { Ole32.INSTANCE.CoUninitialize(); } + /** + * CoInitialize must be called be fore this method. Either explicitly or + * implicitly via other methods. + * + * @return + */ + static public IRunningObjectTable getRunningObjectTable() { + PointerByReference rotPtr = new PointerByReference(); + WinNT.HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable( + new WinDef.DWORD(0), rotPtr); + COMUtils.checkRC(hr); + com.sun.jna.platform.win32.COM.RunningObjectTable raw = new com.sun.jna.platform.win32.COM.RunningObjectTable(rotPtr.getValue()); + IRunningObjectTable rot = new RunningObjectTable(raw); + return rot; + } + /** * Creates a ProxyObject for the given interface and IDispatch pointer. * diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java index dd20d83b96..6002285f12 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java @@ -12,22 +12,6 @@ public class RunningObjectTable implements IRunningObjectTable { - /** - * CoInitialize must be called be fore this method. Either explicitly or - * implicitly via other methods. - * - * @return - */ - static public IRunningObjectTable getRunningObjectTable() { - PointerByReference rotPtr = new PointerByReference(); - WinNT.HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable( - new WinDef.DWORD(0), rotPtr); - COMUtils.checkRC(hr); - com.sun.jna.platform.win32.COM.RunningObjectTable raw = new com.sun.jna.platform.win32.COM.RunningObjectTable(rotPtr.getValue()); - IRunningObjectTable rot = new RunningObjectTable(raw); - return rot; - } - protected RunningObjectTable(com.sun.jna.platform.win32.COM.RunningObjectTable raw) { this.raw = raw; } diff --git a/eclipse/.settings/org.eclipse.core.resources.prefs b/eclipse/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..4824b80263 --- /dev/null +++ b/eclipse/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/eclipse/.settings/org.eclipse.m2e.core.prefs b/eclipse/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000..14b697b7bb --- /dev/null +++ b/eclipse/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/eclipse/com.sun.jna.core/.settings/org.eclipse.core.resources.prefs b/eclipse/com.sun.jna.core/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..4824b80263 --- /dev/null +++ b/eclipse/com.sun.jna.core/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/eclipse/com.sun.jna.core/.settings/org.eclipse.m2e.core.prefs b/eclipse/com.sun.jna.core/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000..14b697b7bb --- /dev/null +++ b/eclipse/com.sun.jna.core/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs b/eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs index d1c84cae3b..394603ceee 100644 --- a/eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs +++ b/eclipse/com.sun.jna.core/.settings/org.eclipse.pde.core.prefs @@ -1,2 +1,2 @@ -BUNDLE_ROOT_PATH=src/main/resources -eclipse.preferences.version=1 \ No newline at end of file +BUNDLE_ROOT_PATH=target/classes +eclipse.preferences.version=1 diff --git a/eclipse/com.sun.jna.native-repo/.settings/org.eclipse.m2e.core.prefs b/eclipse/com.sun.jna.native-repo/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000..14b697b7bb --- /dev/null +++ b/eclipse/com.sun.jna.native-repo/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/eclipse/com.sun.jna.p2.repository/.settings/org.eclipse.m2e.core.prefs b/eclipse/com.sun.jna.p2.repository/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000..14b697b7bb --- /dev/null +++ b/eclipse/com.sun.jna.p2.repository/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/eclipse/com.sun.jna.platform/.settings/org.eclipse.core.resources.prefs b/eclipse/com.sun.jna.platform/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000000..4824b80263 --- /dev/null +++ b/eclipse/com.sun.jna.platform/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/eclipse/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs b/eclipse/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..fd9afef6e9 --- /dev/null +++ b/eclipse/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning diff --git a/eclipse/com.sun.jna.platform/.settings/org.eclipse.m2e.core.prefs b/eclipse/com.sun.jna.platform/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000..14b697b7bb --- /dev/null +++ b/eclipse/com.sun.jna.platform/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/eclipse/com.sun.jna.platform/.settings/org.eclipse.pde.core.prefs b/eclipse/com.sun.jna.platform/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000000..394603ceee --- /dev/null +++ b/eclipse/com.sun.jna.platform/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,2 @@ +BUNDLE_ROOT_PATH=target/classes +eclipse.preferences.version=1 diff --git a/eclipse/com.sun.jna.platform/pom.xml b/eclipse/com.sun.jna.platform/pom.xml index 28383732dd..3760008864 100644 --- a/eclipse/com.sun.jna.platform/pom.xml +++ b/eclipse/com.sun.jna.platform/pom.xml @@ -75,11 +75,10 @@ com.sun.jna.platform.mac, com.sun.jna.platform.unix, com.sun.jna.platform.win32, com.sun.jna.platform.win32.COM, -com.sun.jna.platform.win32.COM.proxy, -com.sun.jna.platform.win32.COM.proxy.annotation, com.sun.jna.platform.win32.COM.tlb, com.sun.jna.platform.win32.COM.tlb.imp, com.sun.jna.platform.win32.COM.util, +com.sun.jna.platform.win32.COM.util.annotation, com.sun.jna.platform.win32.COM.wince From 06c884ae3180e69828ab9c848ed7b3a348b06a16 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 28 Oct 2014 09:49:49 +0100 Subject: [PATCH 06/49] Added .gitignore --- eclipse/com.sun.jna.p2.repository/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 eclipse/com.sun.jna.p2.repository/.gitignore diff --git a/eclipse/com.sun.jna.p2.repository/.gitignore b/eclipse/com.sun.jna.p2.repository/.gitignore new file mode 100644 index 0000000000..ea8c4bf7f3 --- /dev/null +++ b/eclipse/com.sun.jna.p2.repository/.gitignore @@ -0,0 +1 @@ +/target From cdff36081509d5017106cedcfbb74b96f7de41a6 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 28 Oct 2014 14:37:19 +0100 Subject: [PATCH 07/49] Calls to COM objects via ...utils should now all run on a single thread. --- .../platform/win32/COM/util/ComThread.java | 72 +++++++ .../platform/win32/COM/util/EnumMoniker.java | 141 +++++++++----- .../jna/platform/win32/COM/util/Factory.java | 179 ++++++++++++------ .../platform/win32/COM/util/ProxyObject.java | 165 ++++++++++------ .../win32/COM/util/RunningObjectTable.java | 47 +++-- .../platform/win32/COM/EnumMoniker_Test.java | 53 +++--- .../COM/util/RunningObjectTable_Test.java | 12 +- eclipse/com.sun.jna.core/.project | 2 +- eclipse/com.sun.jna.platform/.classpath | 1 + eclipse/com.sun.jna.platform/pom.xml | 1 + 10 files changed, 462 insertions(+), 211 deletions(-) create mode 100644 contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java new file mode 100644 index 0000000000..b3b98e7d0d --- /dev/null +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java @@ -0,0 +1,72 @@ +package com.sun.jna.platform.win32.COM.util; + +import java.lang.Thread.UncaughtExceptionHandler; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.ThreadFactory; + +import com.sun.jna.platform.win32.Ole32; +import com.sun.jna.platform.win32.WinNT; +import com.sun.jna.platform.win32.COM.COMUtils; + +public class ComThread { + + ExecutorService executor; + Runnable firstTask; + boolean requiresInitialisation; + + public ComThread(final String threadName) { + this.requiresInitialisation = true; + this.firstTask = new Runnable() { + @Override + public void run() { + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitialize(null); + COMUtils.checkRC(hr); + ComThread.this.requiresInitialisation = false; + } + }; + executor = Executors.newSingleThreadExecutor(new ThreadFactory() { + + @Override + public Thread newThread(Runnable r) { + if (!ComThread.this.requiresInitialisation) { + //something has gone wrong! + throw new RuntimeException("ComThread executor has a problem."); + } + Thread thread = new Thread(r, threadName); + + thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + ComThread.this.requiresInitialisation = true; + } + }); + + return thread; + } + }); + + } + + @Override + protected void finalize() throws Throwable { + executor.submit(new Runnable() { + @Override + public void run() { + Ole32.INSTANCE.CoUninitialize(); + } + }); + executor.shutdown(); + super.finalize(); + } + + public T execute(Callable task) throws InterruptedException, ExecutionException { + if (this.requiresInitialisation) { + executor.execute(firstTask); + } + return executor.submit(task).get(); + } + +} diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java index c6833fec26..8b7ccf67cd 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java @@ -13,6 +13,8 @@ package com.sun.jna.platform.win32.COM.util; import java.util.Iterator; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; @@ -23,79 +25,126 @@ import com.sun.jna.ptr.PointerByReference; /** - * Enumerates the components of a moniker or the monikers in a table of monikers. + * Enumerates the components of a moniker or the monikers in a table of + * monikers. + * + * @see MSDN * - * @see MSDN - * */ public class EnumMoniker implements Iterable { - protected EnumMoniker(IEnumMoniker raw, com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot) { + protected EnumMoniker(IEnumMoniker raw, com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot, + ComThread comThread) { this.rawRot = rawRot; this.raw = raw; - WinNT.HRESULT hr = this.raw.Reset(); - COMUtils.checkRC(hr); - + this.comThread = comThread; + + try { + WinNT.HRESULT hr = this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return EnumMoniker.this.raw.Reset(); + } + }); + COMUtils.checkRC(hr); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + this.cacheNext(); } - + + ComThread comThread; com.sun.jna.platform.win32.COM.IRunningObjectTable rawRot; IEnumMoniker raw; Moniker rawNext; - + protected void cacheNext() { - PointerByReference rgelt = new PointerByReference(); - WinDef.ULONGByReference pceltFetched = new WinDef.ULONGByReference(); - WinNT.HRESULT hr = this.raw.Next(new WinDef.ULONG(1), rgelt, pceltFetched); - - if (WinNT.S_OK.equals(hr) && pceltFetched.getValue().intValue() > 0) { - this.rawNext = new Moniker(rgelt.getValue()); - } else { - if (!WinNT.S_FALSE.equals(hr)) { - COMUtils.checkRC(hr); + try { + final PointerByReference rgelt = new PointerByReference(); + final WinDef.ULONGByReference pceltFetched = new WinDef.ULONGByReference(); + + WinNT.HRESULT hr = EnumMoniker.this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return EnumMoniker.this.raw.Next(new WinDef.ULONG(1), rgelt, pceltFetched); + } + }); + + if (WinNT.S_OK.equals(hr) && pceltFetched.getValue().intValue() > 0) { + this.rawNext = new Moniker(rgelt.getValue()); + } else { + if (!WinNT.S_FALSE.equals(hr)) { + COMUtils.checkRC(hr); + } + this.rawNext = null; } - this.rawNext = null; + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); } } - - + @Override public Iterator iterator() { return new Iterator() { @Override public boolean hasNext() { - return null!= EnumMoniker.this.rawNext; + return null != EnumMoniker.this.rawNext; } @Override public IDispatch next() { - Moniker moniker = EnumMoniker.this.rawNext; - PointerByReference ppunkObject = new PointerByReference(); - WinNT.HRESULT hr = EnumMoniker.this.rawRot.GetObject(moniker.getPointer(),ppunkObject); - COMUtils.checkRC(hr); - - //To assist debug, can use the following code -// PointerByReference ppbc = new PointerByReference(); -// Ole32.INSTANCE.CreateBindCtx(new DWORD(), ppbc); -// -// BSTRByReference ppszDisplayName = new BSTRByReference(); -// hr = moniker.GetDisplayName(ppbc.getValue(), moniker.getPointer(), ppszDisplayName); -// COMUtils.checkRC(hr); -// String name = ppszDisplayName.getString(); -// Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0)); - - //TODO: Can we assume that the object is an IDispatch ? - //Unknown unk = new Unknown(ppunkObject.getValue()); - Dispatch dispatch = new Dispatch(ppunkObject.getValue()); - - EnumMoniker.this.cacheNext(); - - return new ProxyObject(dispatch); + try { + + final Moniker moniker = EnumMoniker.this.rawNext; + final PointerByReference ppunkObject = new PointerByReference(); + WinNT.HRESULT hr = EnumMoniker.this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return EnumMoniker.this.rawRot.GetObject(moniker.getPointer(), ppunkObject); + } + }); + COMUtils.checkRC(hr); + + // To assist debug, can use the following code + // PointerByReference ppbc = new + // PointerByReference(); + // Ole32.INSTANCE.CreateBindCtx(new DWORD(), ppbc); + // + // BSTRByReference ppszDisplayName = new + // BSTRByReference(); + // hr = moniker.GetDisplayName(ppbc.getValue(), + // moniker.getPointer(), ppszDisplayName); + // COMUtils.checkRC(hr); + // String name = ppszDisplayName.getString(); + // Ole32.INSTANCE.CoTaskMemFree(ppszDisplayName.getPointer().getPointer(0)); + + // TODO: Can we assume that the object is an + // IDispatch ? + // Unknown unk = new + // Unknown(ppunkObject.getValue()); + + Dispatch dispatch = new Dispatch(ppunkObject.getValue()); + EnumMoniker.this.cacheNext(); + + return new ProxyObject(IUnknown.class, dispatch, EnumMoniker.this.comThread); + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } - + }; } - } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 13d6ef0d59..e271606d42 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -13,6 +13,8 @@ package com.sun.jna.platform.win32.COM.util; import java.lang.reflect.Proxy; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import com.sun.jna.platform.win32.Guid.CLSID; import com.sun.jna.platform.win32.Guid.GUID; @@ -26,95 +28,150 @@ import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.IDispatch; import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.ptr.PointerByReference; public class Factory { + + public static Factory INSTANCE = new Factory(); - public static void initializeThreadForComAccess() { - WinNT.HRESULT hr = Ole32.INSTANCE.CoInitialize(null); - COMUtils.checkRC(hr); - } - - public static void releaseThreadFromComAccess() { - Ole32.INSTANCE.CoUninitialize(); + public Factory() { + this.comThread = new ComThread("Factory COM Thread"); } - + + ComThread comThread; + /** * CoInitialize must be called be fore this method. Either explicitly or * implicitly via other methods. * * @return */ - static public IRunningObjectTable getRunningObjectTable() { - PointerByReference rotPtr = new PointerByReference(); - WinNT.HRESULT hr = Ole32.INSTANCE.GetRunningObjectTable( - new WinDef.DWORD(0), rotPtr); - COMUtils.checkRC(hr); - com.sun.jna.platform.win32.COM.RunningObjectTable raw = new com.sun.jna.platform.win32.COM.RunningObjectTable(rotPtr.getValue()); - IRunningObjectTable rot = new RunningObjectTable(raw); - return rot; + public IRunningObjectTable getRunningObjectTable() { + try { + + final PointerByReference rotPtr = new PointerByReference(); + + WinNT.HRESULT hr = this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return Ole32.INSTANCE.GetRunningObjectTable(new WinDef.DWORD(0), rotPtr); + } + }); + COMUtils.checkRC(hr); + com.sun.jna.platform.win32.COM.RunningObjectTable raw = new com.sun.jna.platform.win32.COM.RunningObjectTable( + rotPtr.getValue()); + IRunningObjectTable rot = new RunningObjectTable(raw, comThread); + return rot; + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } } - + /** * Creates a ProxyObject for the given interface and IDispatch pointer. * */ - public static T createProxy(Class comInterface, IDispatch dispatch) { - ProxyObject jop = new ProxyObject(dispatch); + public T createProxy(Class comInterface, IDispatch dispatch, ComThread comThread) { + ProxyObject jop = new ProxyObject(comInterface, dispatch, comThread); Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[] { comInterface }, jop); T result = comInterface.cast(proxy); return result; } /** - * Creates a new COM object (CoCreateInstance) for the given progId and returns a ProxyObject - * for the given interface. + * Creates a new COM object (CoCreateInstance) for the given progId and + * returns a ProxyObject for the given interface. */ - public static T createObject(Class comInterface) { - ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); - if (null==comObectAnnotation) { - throw new COMException("createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + public T createObject(Class comInterface) { + try { + + ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); + if (null == comObectAnnotation) { + throw new COMException( + "createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + } + final GUID guid = this.discoverClsId(comObectAnnotation); + + final PointerByReference ptrDisp = new PointerByReference(); + WinNT.HRESULT hr = this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return Ole32.INSTANCE.CoCreateInstance(guid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, + ptrDisp); + } + }); + COMUtils.checkRC(hr); + + T t = this.createProxy(comInterface, new Dispatch(ptrDisp.getValue()), this.comThread); + return t; + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); } - GUID guid = Factory.discoverClsId(comObectAnnotation); - - PointerByReference ptrDisp = new PointerByReference(); - WinNT.HRESULT hr = Ole32.INSTANCE.CoCreateInstance(guid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp); - COMUtils.checkRC(hr); - - T t = Factory.createProxy(comInterface, new Dispatch(ptrDisp.getValue())); - return t; } - + /** - * Gets and existing COM object (GetActiveObject) for the given progId and returns a ProxyObject - * for the given interface. + * Gets and existing COM object (GetActiveObject) for the given progId and + * returns a ProxyObject for the given interface. */ - public static T fetchObject(Class comInterface) { - ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); - if (null==comObectAnnotation) { - throw new COMException("createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + public T fetchObject(Class comInterface) { + try { + ComObject comObectAnnotation = comInterface.getAnnotation(ComObject.class); + if (null == comObectAnnotation) { + throw new COMException( + "createObject: Interface must define a value for either clsId or progId via the ComInterface annotation"); + } + final GUID guid = this.discoverClsId(comObectAnnotation); + + final PointerByReference ptrDisp = new PointerByReference(); + WinNT.HRESULT hr = this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return OleAuto.INSTANCE.GetActiveObject(guid, null, ptrDisp); + } + }); + COMUtils.checkRC(hr); + + T t = this.createProxy(comInterface, new Dispatch(ptrDisp.getValue()), this.comThread); + return t; + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); } - GUID guid = Factory.discoverClsId(comObectAnnotation); - - PointerByReference ptrDisp = new PointerByReference(); - WinNT.HRESULT hr = OleAuto.INSTANCE.GetActiveObject(guid, null, ptrDisp); - COMUtils.checkRC(hr); - - T t = Factory.createProxy(comInterface, new Dispatch(ptrDisp.getValue())); - return t; } - - static GUID discoverClsId(ComObject annotation) { - String clsIdStr = annotation.clsId(); - String progIdStr = annotation.progId(); - if (null!=clsIdStr && !clsIdStr.isEmpty()) { - return new CLSID(clsIdStr); - } else if (null!=progIdStr && !progIdStr.isEmpty()) { - CLSID.ByReference rclsid = new CLSID.ByReference(); - WinNT.HRESULT hr = Ole32.INSTANCE.CLSIDFromProgID(progIdStr, rclsid); - COMUtils.checkRC(hr); - return rclsid; - } else { - throw new COMException("ComObject must define a value for either clsId or progId"); + + GUID discoverClsId(ComObject annotation) { + try { + String clsIdStr = annotation.clsId(); + final String progIdStr = annotation.progId(); + if (null != clsIdStr && !clsIdStr.isEmpty()) { + return new CLSID(clsIdStr); + } else if (null != progIdStr && !progIdStr.isEmpty()) { + final CLSID.ByReference rclsid = new CLSID.ByReference(); + + WinNT.HRESULT hr = this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return Ole32.INSTANCE.CLSIDFromProgID(progIdStr, rclsid); + } + }); + + COMUtils.checkRC(hr); + return rclsid; + } else { + throw new COMException("ComObject must define a value for either clsId or progId"); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index dd56a15a03..d8441f3eac 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -15,15 +15,15 @@ import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.Date; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid; -import com.sun.jna.platform.win32.Guid.CLSID; import com.sun.jna.platform.win32.Guid.IID; import com.sun.jna.platform.win32.Kernel32; import com.sun.jna.platform.win32.Kernel32Util; import com.sun.jna.platform.win32.OaIdl; -import com.sun.jna.platform.win32.Ole32; import com.sun.jna.platform.win32.OaIdl.DISPID; import com.sun.jna.platform.win32.OaIdl.DISPIDByReference; import com.sun.jna.platform.win32.OaIdl.EXCEPINFO; @@ -41,33 +41,37 @@ import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.Dispatch; +import com.sun.jna.platform.win32.COM.IDispatch; import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; -import com.sun.jna.platform.win32.COM.IDispatch; -import com.sun.jna.platform.win32.Guid.GUID; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; /** - * Ole32.INSTANCE.CoInitialize must be called on the current thread before using this object + * Ole32.INSTANCE.CoInitialize must be called on the current thread before using + * this object */ public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win32.COM.util.IDispatch { - public ProxyObject(IDispatch rawDispatch) { + public ProxyObject(Class theInterface, IDispatch rawDispatch, ComThread comThread) { this.rawDispatch = rawDispatch; + this.comThread = comThread; + this.theInterface = theInterface; } + Class theInterface; + ComThread comThread; com.sun.jna.platform.win32.COM.IDispatch rawDispatch; com.sun.jna.platform.win32.COM.IDispatch getIDispatch() { return this.rawDispatch; } - //--------------------- InvocationHandler ----------------------------- + // --------------------- InvocationHandler ----------------------------- @Override - public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] args) throws Throwable { - Class dcls = method.getDeclaringClass(); + public Object invoke(final Object proxy, final java.lang.reflect.Method method, final Object[] args) + throws Throwable { Class returnType = method.getReturnType(); boolean isVoid = Void.TYPE.equals(returnType); @@ -90,6 +94,12 @@ public Object invoke(Object proxy, java.lang.reflect.Method method, Object[] arg return res; } + if (method.equals(Object.class.getMethod("toString"))) { + return this.theInterface.getName(); + } else if (method.equals(IUnknown.class.getMethod("queryInterface", Class.class))) { + return this.queryInterface((Class) args[0]); + } + return null; } @@ -108,11 +118,12 @@ public T getProperty(Class returnType, String name) { COMUtils.checkRC(hr); Object jobj = this.getJavaObject(result); if (jobj instanceof com.sun.jna.platform.win32.COM.IDispatch) { - return Factory.createProxy(returnType, (com.sun.jna.platform.win32.COM.IDispatch) jobj); + return Factory.INSTANCE.createProxy(returnType, (com.sun.jna.platform.win32.COM.IDispatch) jobj, + this.comThread); } - return (T)jobj; + return (T) jobj; } - + @Override public T invokeMethod(Class returnType, String name, Object... args) { VARIANT[] vargs; @@ -130,40 +141,54 @@ public T invokeMethod(Class returnType, String name, Object... args) { Object jobj = this.getJavaObject(result); if (jobj instanceof IDispatch) { - return Factory.createProxy(returnType, (IDispatch) jobj); + return Factory.INSTANCE.createProxy(returnType, (IDispatch) jobj, this.comThread); } - return (T)jobj; + return (T) jobj; } - + @Override public T queryInterface(Class comInterface) { - ComInterface comInterfaceAnnotation = comInterface.getAnnotation(ComInterface.class); - if (null==comInterfaceAnnotation) { - throw new COMException("createObject: Interface must define a value for either iid or progId via the ComInterface annotation"); - } - IID iid = this.getIID(comInterfaceAnnotation); - PointerByReference ppvObject = new PointerByReference(); - WinNT.HRESULT hr = this.getIDispatch().QueryInterface(iid, ppvObject); - if (WinNT.S_OK.equals(hr)) { - Dispatch dispatch = new Dispatch(ppvObject.getValue()); - return Factory.createProxy(comInterface, dispatch); - } else { - String formatMessageFromHR = Kernel32Util.formatMessage(hr); - throw new COMException("queryInterface: "+formatMessageFromHR); + try { + ComInterface comInterfaceAnnotation = comInterface.getAnnotation(ComInterface.class); + if (null == comInterfaceAnnotation) { + throw new COMException( + "createObject: Interface must define a value for either iid or progId via the ComInterface annotation"); + } + final IID iid = this.getIID(comInterfaceAnnotation); + final PointerByReference ppvObject = new PointerByReference(); + + HRESULT hr = this.comThread.execute(new Callable() { + @Override + public HRESULT call() throws Exception { + return ProxyObject.this.getIDispatch().QueryInterface(iid, ppvObject); + } + }); + + if (WinNT.S_OK.equals(hr)) { + Dispatch dispatch = new Dispatch(ppvObject.getValue()); + return Factory.INSTANCE.createProxy(comInterface, dispatch, this.comThread); + } else { + String formatMessageFromHR = Kernel32Util.formatMessage(hr); + throw new COMException("queryInterface: " + formatMessageFromHR); + } + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); } } - + IID getIID(ComInterface annotation) { String iidStr = annotation.iid(); - if (null!=iidStr && !iidStr.isEmpty()) { + if (null != iidStr && !iidStr.isEmpty()) { return new IID(iidStr); } else { throw new COMException("ComInterface must define a value for either iid"); } } - - //--------------------- ProxyObject --------------------- - + + // --------------------- ProxyObject --------------------- + private String getAccessorName(java.lang.reflect.Method method, ComProperty prop) { if (prop.name().isEmpty()) { String methName = method.getName(); @@ -287,29 +312,39 @@ protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch p /* * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod */ - protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, String name, VARIANT[] pArgs) - throws COMException { - - if (pDisp == null) - throw new COMException("pDisp (IDispatch) parameter is null!"); - - // variable declaration - WString[] ptName = new WString[] { new WString(name) }; - DISPIDByReference pdispID = new DISPIDByReference(); - - // Get DISPID for name passed... - HRESULT hr = pDisp.GetIDsOfNames(Guid.IID_NULL, ptName, 1, LOCALE_USER_DEFAULT, pdispID); - - COMUtils.checkRC(hr); - - return this.oleMethod(nType, pvResult, pDisp, pdispID.getValue(), pArgs); + protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, final IDispatch pDisp, String name, + VARIANT[] pArgs) throws COMException { + try { + if (pDisp == null) + throw new COMException("pDisp (IDispatch) parameter is null!"); + + // variable declaration + final WString[] ptName = new WString[] { new WString(name) }; + final DISPIDByReference pdispID = new DISPIDByReference(); + + // Get DISPID for name passed... + HRESULT hr = this.comThread.execute(new Callable() { + @Override + public HRESULT call() throws Exception { + HRESULT hr = pDisp.GetIDsOfNames(Guid.IID_NULL, ptName, 1, LOCALE_USER_DEFAULT, pdispID); + return hr; + } + }); + COMUtils.checkRC(hr); + + return this.oleMethod(nType, pvResult, pDisp, pdispID.getValue(), pArgs); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } } /* * @see com.sun.jna.platform.win32.COM.COMBindingBaseObject#oleMethod */ - protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch pDisp, DISPID dispId, VARIANT[] pArgs) - throws COMException { + protected HRESULT oleMethod(final int nType, final VARIANT.ByReference pvResult, final IDispatch pDisp, + final DISPID dispId, VARIANT[] pArgs) throws COMException { if (pDisp == null) throw new COMException("pDisp (IDispatch) parameter is null!"); @@ -317,9 +352,9 @@ protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch p // variable declaration int _argsLen = 0; VARIANT[] _args = null; - DISPPARAMS dp = new DISPPARAMS(); - EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); - IntByReference puArgErr = new IntByReference(); + final DISPPARAMS dp = new DISPPARAMS(); + final EXCEPINFO.ByReference pExcepInfo = new EXCEPINFO.ByReference(); + final IntByReference puArgErr = new IntByReference(); // make parameter reverse ordering as expected by COM runtime if ((pArgs != null) && (pArgs.length > 0)) { @@ -349,10 +384,22 @@ protected HRESULT oleMethod(int nType, VARIANT.ByReference pvResult, IDispatch p } // Make the call! - HRESULT hr = pDisp.Invoke(dispId, Guid.IID_NULL, LOCALE_SYSTEM_DEFAULT, new DISPID(nType), dp, pvResult, - pExcepInfo, puArgErr); - - COMUtils.checkRC(hr, pExcepInfo, puArgErr); - return hr; + try { + + HRESULT hr = this.comThread.execute(new Callable() { + @Override + public HRESULT call() throws Exception { + return pDisp.Invoke(dispId, Guid.IID_NULL, LOCALE_SYSTEM_DEFAULT, new DISPID(nType), dp, pvResult, + pExcepInfo, puArgErr); + } + }); + + COMUtils.checkRC(hr, pExcepInfo, puArgErr); + return hr; + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java index 6002285f12..c5da4aa413 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java @@ -2,9 +2,9 @@ import java.util.ArrayList; import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; -import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.COMUtils; @@ -12,33 +12,52 @@ public class RunningObjectTable implements IRunningObjectTable { - protected RunningObjectTable(com.sun.jna.platform.win32.COM.RunningObjectTable raw) { + protected RunningObjectTable(com.sun.jna.platform.win32.COM.RunningObjectTable raw, ComThread comThread) { this.raw = raw; + this.comThread = comThread; } + ComThread comThread; com.sun.jna.platform.win32.COM.RunningObjectTable raw; - + @Override public Iterable enumRunning() { - PointerByReference ppenumMoniker = new PointerByReference(); - WinNT.HRESULT hr = this.raw.EnumRunning(ppenumMoniker); - COMUtils.checkRC(hr); - - com.sun.jna.platform.win32.COM.EnumMoniker raw = new com.sun.jna.platform.win32.COM.EnumMoniker(ppenumMoniker.getValue()); - return new EnumMoniker(raw, this.raw); + + try { + + final PointerByReference ppenumMoniker = new PointerByReference(); + + WinNT.HRESULT hr = this.comThread.execute(new Callable() { + @Override + public WinNT.HRESULT call() throws Exception { + return RunningObjectTable.this.raw.EnumRunning(ppenumMoniker); + } + }); + COMUtils.checkRC(hr); + com.sun.jna.platform.win32.COM.EnumMoniker raw = new com.sun.jna.platform.win32.COM.EnumMoniker( + ppenumMoniker.getValue()); + + return new EnumMoniker(raw, this.raw, this.comThread); + + } catch (InterruptedException e) { + throw new RuntimeException(e); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } + } @Override public List getActiveObjectsByInterface(Class comInterface) { List result = new ArrayList(); - for(IDispatch obj: this.enumRunning()) { + for (IDispatch obj : this.enumRunning()) { try { T dobj = obj.queryInterface(comInterface); - + result.add(dobj); - } catch(COMException ex) { - + } catch (COMException ex) { + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java index d3ff82142d..8b57ceabcc 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/EnumMoniker_Test.java @@ -19,45 +19,54 @@ import org.junit.Before; import org.junit.Test; -import com.sun.jna.platform.win32.Guid.CLSID; import com.sun.jna.platform.win32.Ole32; -import com.sun.jna.platform.win32.WTypes; +import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.WinDef.DWORD; import com.sun.jna.platform.win32.WinDef.ULONG; import com.sun.jna.platform.win32.WinDef.ULONGByReference; import com.sun.jna.platform.win32.WinNT.HRESULT; -import com.sun.jna.platform.win32.COM.util.ProxyObject; +import com.sun.jna.platform.win32.COM.util.Factory; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; import com.sun.jna.ptr.PointerByReference; public class EnumMoniker_Test { - - ProxyObject ob1; - ProxyObject ob2; + + @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") + interface Application { + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComMethod + void Quit(); + } + + @ComObject(progId="Word.Application") + interface MsWordApp extends Application { + } + + MsWordApp ob1; + MsWordApp ob2; @Before public void before() { - HRESULT hr = Ole32.INSTANCE.CoInitialize(null); - COMUtils.checkRC(hr); - // Two COM objects are require to be running for these tests to work - CLSID.ByReference clsid = new CLSID.ByReference(); - hr = Ole32.INSTANCE.CLSIDFromProgID("Word.Application", clsid); - PointerByReference ptrDisp1 = new PointerByReference(); - Ole32.INSTANCE.CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp1); - this.ob1 = new ProxyObject(new Dispatch(ptrDisp1.getValue())); + this.ob1 = Factory.INSTANCE.createObject(MsWordApp.class); + this.ob2 = Factory.INSTANCE.createObject(MsWordApp.class); - PointerByReference ptrDisp2 = new PointerByReference(); - Ole32.INSTANCE.CoCreateInstance(clsid, null, WTypes.CLSCTX_SERVER, IDispatch.IID_IDISPATCH, ptrDisp2); - this.ob2 = new ProxyObject(new Dispatch(ptrDisp2.getValue())); - + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitialize(null); + COMUtils.checkRC(hr); } @After public void after() { - ob1.invokeMethod(Void.TYPE, "Quit"); - - ob2.invokeMethod(Void.TYPE, "Quit"); - + ob1.Quit(); + ob2.Quit(); Ole32.INSTANCE.CoUninitialize(); } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java index 3f6b900bd2..946044cd53 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java @@ -57,29 +57,25 @@ interface MsWordApp extends Application { @Before public void before() { - Factory.initializeThreadForComAccess(); - - this.msWord = Factory.createObject(MsWordApp.class); + this.msWord = Factory.INSTANCE.createObject(MsWordApp.class); msWord.setVisible(true); } @After public void after() { this.msWord.Quit(); - - Factory.releaseThreadFromComAccess(); } @Test public void getRunningObjectTable() { - IRunningObjectTable rot = RunningObjectTable.getRunningObjectTable(); + IRunningObjectTable rot = Factory.INSTANCE.getRunningObjectTable(); assertNotNull(rot); } @Test public void enumRunning() { - IRunningObjectTable rot = RunningObjectTable.getRunningObjectTable(); + IRunningObjectTable rot = Factory.INSTANCE.getRunningObjectTable(); for(IUnknown obj: rot.enumRunning()) { try { @@ -92,7 +88,7 @@ public void enumRunning() { @Test public void getActiveObjectsByInterface() { - IRunningObjectTable rot = RunningObjectTable.getRunningObjectTable(); + IRunningObjectTable rot = Factory.INSTANCE.getRunningObjectTable(); List objs = rot.getActiveObjectsByInterface(Application.class); assertTrue(objs.size() > 0); diff --git a/eclipse/com.sun.jna.core/.project b/eclipse/com.sun.jna.core/.project index c2970d5b4e..8dd6870f52 100644 --- a/eclipse/com.sun.jna.core/.project +++ b/eclipse/com.sun.jna.core/.project @@ -17,8 +17,8 @@ + org.eclipse.jdt.core.javanature org.eclipse.pde.PluginNature - org.eclipse.m2e.core.maven2Nature diff --git a/eclipse/com.sun.jna.platform/.classpath b/eclipse/com.sun.jna.platform/.classpath index 94a4141d4f..b7019feb04 100644 --- a/eclipse/com.sun.jna.platform/.classpath +++ b/eclipse/com.sun.jna.platform/.classpath @@ -12,5 +12,6 @@ + diff --git a/eclipse/com.sun.jna.platform/pom.xml b/eclipse/com.sun.jna.platform/pom.xml index 3760008864..99683a1fe4 100644 --- a/eclipse/com.sun.jna.platform/pom.xml +++ b/eclipse/com.sun.jna.platform/pom.xml @@ -35,6 +35,7 @@ ${project.basedir}/../../contrib/platform/src + ${project.basedir}/../../contrib/platform/test From 39e14d67919da2b3c3690870c77de6337355700b Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 29 Oct 2014 11:31:59 +0100 Subject: [PATCH 08/49] Improve COM.utils tests --- .../platform/win32/COM/util/ProxyObject.java | 2 +- .../COM/util/RunningObjectTable_Test.java | 34 +++++++++++++++++-- eclipse/com.sun.jna.core/pom.xml | 1 + 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index d8441f3eac..b462d27bd0 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -266,7 +266,7 @@ protected VARIANT toVariant(Object value) { ProxyObject pobj = (ProxyObject) ih; return new VARIANT(pobj.getIDispatch()); } else { - throw new RuntimeException("Cannot convert to VARIANT - " + value); + return null; } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java index 946044cd53..48c9c5991e 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java @@ -38,7 +38,7 @@ public class RunningObjectTable_Test { @ComInterface(iid="{00020970-0000-0000-C000-000000000046}") - interface Application { + interface Application extends IUnknown { @ComProperty boolean getVisible(); @@ -46,7 +46,7 @@ interface Application { void setVisible(boolean value); @ComMethod - void Quit(); + void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument); } @ComObject(progId="Word.Application") @@ -57,13 +57,41 @@ interface MsWordApp extends Application { @Before public void before() { + //ensure there is only one word application running. + while(true) { + try { + MsWordApp ao = Factory.INSTANCE.fetchObject(MsWordApp.class); + Application a = ao.queryInterface(Application.class); + try { + a.Quit(true, null, null); + try { + //wait for it to quit + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } catch (Exception e) { + e.printStackTrace();e.getCause().printStackTrace(); + } + } catch(Exception e) { + break; + } + } + + this.msWord = Factory.INSTANCE.createObject(MsWordApp.class); msWord.setVisible(true); } @After public void after() { - this.msWord.Quit(); + this.msWord.Quit(true, null, null); + try { + //wait for it to quit + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } } @Test diff --git a/eclipse/com.sun.jna.core/pom.xml b/eclipse/com.sun.jna.core/pom.xml index 11332dbaeb..dc17b972af 100644 --- a/eclipse/com.sun.jna.core/pom.xml +++ b/eclipse/com.sun.jna.core/pom.xml @@ -48,6 +48,7 @@ ${project.basedir}/../../src + ${project.basedir}/../../test + + jna-test + generate-resources + install-file + + ${native-repo-dir} + ${native-test-jars}/jna-test/win32-x86-64.jar + ${native-test-groupId} + win32-x86-64 + ${project.version} + jar + + + win32-x86 generate-resources diff --git a/maven/com.sun.jna.platform/pom.xml b/maven/com.sun.jna.platform/pom.xml index 99683a1fe4..6c4903b6df 100644 --- a/maven/com.sun.jna.platform/pom.xml +++ b/maven/com.sun.jna.platform/pom.xml @@ -36,7 +36,6 @@ ${project.basedir}/../../contrib/platform/src ${project.basedir}/../../contrib/platform/test - From b53fd3aadaa38b9b4257860e4bf870ee04c9d9da Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 12 Nov 2014 12:49:32 +0100 Subject: [PATCH 21/49] Iterator required 'remove' to be implemented for < Java 1.8 Added source artifacts --- .../platform/win32/COM/util/EnumMoniker.java | 5 +++++ maven/com.sun.jna.core/pom.xml | 17 +++++++++++++++++ maven/com.sun.jna.platform/pom.xml | 17 +++++++++++++++++ 3 files changed, 39 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java index 99d211306d..300020a8b7 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java @@ -146,6 +146,11 @@ public WinNT.HRESULT call() throws Exception { } + @Override + public void remove() { + throw new UnsupportedOperationException("remove"); + } + }; } diff --git a/maven/com.sun.jna.core/pom.xml b/maven/com.sun.jna.core/pom.xml index af3e36e016..f846d55d1a 100644 --- a/maven/com.sun.jna.core/pom.xml +++ b/maven/com.sun.jna.core/pom.xml @@ -357,6 +357,23 @@ com/sun/jna/linux-ia64/libjnidispatch.so;processor=ia64;osname=linux, + + + + org.apache.maven.plugins + maven-source-plugin + 2.4 + + + attach-sources + package + + jar-no-fork + + + + + diff --git a/maven/com.sun.jna.platform/pom.xml b/maven/com.sun.jna.platform/pom.xml index 6c4903b6df..13ccee6033 100644 --- a/maven/com.sun.jna.platform/pom.xml +++ b/maven/com.sun.jna.platform/pom.xml @@ -84,6 +84,23 @@ com.sun.jna.platform.win32.COM.wince + + + + org.apache.maven.plugins + maven-source-plugin + 2.4 + + + attach-sources + package + + jar-no-fork + + + + + From b5c542ba15b7d4c9da68af506b9b59b209dcd816 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 12 Nov 2014 13:52:52 +0100 Subject: [PATCH 22/49] comment out inclusion of testlib --- maven/com.sun.jna.native-repo/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/com.sun.jna.native-repo/pom.xml b/maven/com.sun.jna.native-repo/pom.xml index 5bf3e91f9c..74f81d4425 100644 --- a/maven/com.sun.jna.native-repo/pom.xml +++ b/maven/com.sun.jna.native-repo/pom.xml @@ -30,7 +30,7 @@ 2.4 + TODO: combine this with other platforms below as different test jat for each jna-test generate-resources @@ -43,7 +43,7 @@ ${project.version} jar - + --> win32-x86 From 81ffec85fe71c17e06ff86bce02f195446f8092d Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 12 Nov 2014 13:55:13 +0100 Subject: [PATCH 23/49] comment out dependency on missing testlib --- maven/com.sun.jna.core/pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/com.sun.jna.core/pom.xml b/maven/com.sun.jna.core/pom.xml index f846d55d1a..9c9fbc4418 100644 --- a/maven/com.sun.jna.core/pom.xml +++ b/maven/com.sun.jna.core/pom.xml @@ -27,14 +27,14 @@ 0.9.8 test - + junit junit From 4cd8d30b2ab576eab6fb5c8c831a957a1c1deef8 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 18 Nov 2014 10:45:04 +0100 Subject: [PATCH 24/49] COM.util: bug fix: arguments to callback events now converted where possible. Required a change to Variant, to enable size of array of VariantArg to be set. Might be a cleaner way to do this, but it could break the existing API of VariantArg. --- .../win32/COM/util/CallbackProxy.java | 45 ++++++++++--- .../jna/platform/win32/COM/util/Convert.java | 1 + .../platform/win32/COM/util/ProxyObject.java | 2 +- .../com/sun/jna/platform/win32/Variant.java | 7 ++ .../COM/util/ComEventCallbacks_Test.java | 65 +++++++++++++++++-- 5 files changed, 104 insertions(+), 16 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index fc2d4ee922..8a23766fdd 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -14,6 +14,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.lang.reflect.Parameter; import java.util.ArrayList; import java.util.HashMap; import java.util.List; @@ -43,6 +44,7 @@ import com.sun.jna.platform.win32.COM.COMException; import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.DispatchListener; +import com.sun.jna.platform.win32.COM.IDispatch; import com.sun.jna.platform.win32.COM.IDispatchCallback; import com.sun.jna.platform.win32.COM.Unknown; import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; @@ -52,7 +54,8 @@ public class CallbackProxy implements IDispatchCallback { - public CallbackProxy(Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) { + public CallbackProxy(Factory factory, Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) { + this.factory = factory; this.comEventCallbackInterface = comEventCallbackInterface; this.comEventCallbackListener = comEventCallbackListener; this.listenedToRiid = this.createRIID(comEventCallbackInterface); @@ -66,7 +69,7 @@ public Thread newThread(Runnable r) { } }); } - + Factory factory; Class comEventCallbackInterface; IComEventCallbackListener comEventCallbackListener; REFIID.ByValue listenedToRiid; @@ -116,22 +119,46 @@ void invokeOnThread(final DISPID dispIdMember, final REFIID.ByValue riid, LCID l public void run() { try { // decode argumentt - final List jargs = new ArrayList(); + List jargs = new ArrayList(); if (pDispParams.cArgs.intValue() > 0) { - VariantArg vargs = new VariantArg(pDispParams.getPointer()); + VariantArg vargs = pDispParams.rgvarg; + vargs.setArraySize(pDispParams.cArgs.intValue()); for (Variant.VARIANT varg : vargs.variantArg) { Object jarg = Convert.toJavaObject(varg); jargs.add(jarg); } } if (CallbackProxy.this.dsipIdMap.containsKey(dispIdMember)) { - final Method eventMethod = CallbackProxy.this.dsipIdMap.get(dispIdMember); + Method eventMethod = CallbackProxy.this.dsipIdMap.get(dispIdMember); String eventMethodName = eventMethod.getName(); - try { - eventMethod.invoke(comEventCallbackListener, jargs.toArray()); - } catch (Exception e) { + if (eventMethod.getParameterCount() != jargs.size()) { CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( - "Exception invoking method " + eventMethod, e); + "Trying to invoke method " + eventMethod +" with "+jargs.size()+" arguments", null); + } else { + try { + //need to convert arguments maybe + List margs = new ArrayList(); + Parameter[] params = eventMethod.getParameters(); + for(int i=0;i comEventCallbackInterface, final final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid); // create the dispatch listener - final IDispatchCallback rawListener = new CallbackProxy(comEventCallbackInterface, comEventCallbackListener); + final IDispatchCallback rawListener = new CallbackProxy(this.factory, comEventCallbackInterface, comEventCallbackListener); // store it the comEventCallback argument, so it is not garbage // collected. comEventCallbackListener.setDispatchCallbackListener(rawListener); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Variant.java b/contrib/platform/src/com/sun/jna/platform/win32/Variant.java index 469c68df73..1d3a897425 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Variant.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Variant.java @@ -707,5 +707,12 @@ public VariantArg(VARIANT[] variantArg) { protected List getFieldOrder() { return Arrays.asList(new String[] { "variantArg" }); } + + public void setArraySize(int size) { + this.variantArg = new VARIANT[size]; + this.read(); + } + + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java index 2eab0a38ea..b6ff8479f1 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java @@ -17,7 +17,8 @@ import org.junit.Before; import org.junit.Test; -import com.sun.jna.platform.win32.COM.util.RunningObjectTable_Test.Application; +import com.sun.jna.platform.win32.User32; +import com.sun.jna.platform.win32.WinDef.HWND; import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; @@ -53,12 +54,28 @@ interface ComIApplication extends IUnknown, IConnectionPoint { @ComMethod void Quit(boolean SaveChanges, Object OriginalFormat, Boolean RouteDocument); + + @ComProperty + ComIDocuments getDocuments(); + } + @ComInterface + interface ComIDocuments { + @ComMethod + ComIDocument Open(String fileName); + } + + @ComInterface + interface ComIDocument {} + + @ComInterface + interface ComIWindow {} + @ComInterface(iid="{00020A01-0000-0000-C000-000000000046}") interface ApplicationEvents4_Event { - @ComEventCallback - void WindowActive(); + @ComEventCallback(dispid=10) + void WindowActivate(ComIDocument doc, ComIWindow win); @ComEventCallback(dispid=2) void Quit(); @@ -66,9 +83,13 @@ interface ApplicationEvents4_Event { class ApplicationEvents4_EventListener extends AbstractComEventCallbackListener implements ApplicationEvents4_Event { Boolean Quit_called = null; + Boolean WindowActivate_called = null; @Override - public void WindowActive() { + public void WindowActivate(ComIDocument doc, ComIWindow win) { + if (null!=doc && null !=win) { + WindowActivate_called = true; + } } @Override @@ -85,7 +106,7 @@ public void errorReceivingCallbackEvent(String message, Exception exception) { } @Test - public void advise() { + public void advise_Quit() { // Create word object ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); @@ -107,7 +128,7 @@ public void advise() { } @Test - public void unadvise() { + public void unadvise_Quit() { // Create word object ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); @@ -129,4 +150,36 @@ public void unadvise() { Assert.assertNotNull(listener.Quit_called); Assert.assertFalse(listener.Quit_called); } + + @Test + public void WindowActivate() { + // Create word object + ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); + ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); + wordApp.setVisible(true); + ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); + wordApp.advise(ApplicationEvents4_Event.class, listener); + + wordApp.getDocuments().Open("C:\\temp\\test.doc"); + + //bring word doc to front + HWND h = User32.INSTANCE.FindWindow("OpusApp", null); + if (h == null) + h = User32.INSTANCE.FindWindow("NetUIHWND", null); + User32.INSTANCE.ShowWindow(h, User32.SW_RESTORE); + User32.INSTANCE.SetForegroundWindow(h); + + //Wait for event to happen + try { + Thread.sleep(200); + } catch (Exception e) { + e.printStackTrace(); + } + + Assert.assertNotNull(listener.WindowActivate_called); + Assert.assertTrue(listener.WindowActivate_called); + + wordApp.Quit(false, null, null); + + } } From 22915e0b2b90c1fa34052bd8bd6fbb2f3347b021 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 18 Nov 2014 14:40:10 +0100 Subject: [PATCH 25/49] ...COM.util: proxy must AddRef on COM handle and Release it updates to handling callback arguments --- .../win32/COM/util/CallbackProxy.java | 57 +++++++++----- .../platform/win32/COM/util/ProxyObject.java | 8 ++ .../COM/util/ComEventCallbacks_Test.java | 76 ++++++++++++++++--- 3 files changed, 110 insertions(+), 31 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index 8a23766fdd..034141a08d 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -16,9 +16,12 @@ import java.lang.reflect.Method; import java.lang.reflect.Parameter; import java.util.ArrayList; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; @@ -26,6 +29,7 @@ import com.sun.jna.Pointer; import com.sun.jna.WString; import com.sun.jna.platform.win32.Guid; +import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.Guid.IID; import com.sun.jna.platform.win32.Guid.REFIID; import com.sun.jna.platform.win32.OaIdl.DISPID; @@ -54,7 +58,8 @@ public class CallbackProxy implements IDispatchCallback { - public CallbackProxy(Factory factory, Class comEventCallbackInterface, IComEventCallbackListener comEventCallbackListener) { + public CallbackProxy(Factory factory, Class comEventCallbackInterface, + IComEventCallbackListener comEventCallbackListener) { this.factory = factory; this.comEventCallbackInterface = comEventCallbackInterface; this.comEventCallbackListener = comEventCallbackListener; @@ -69,6 +74,7 @@ public Thread newThread(Runnable r) { } }); } + Factory factory; Class comEventCallbackInterface; IComEventCallbackListener comEventCallbackListener; @@ -114,41 +120,54 @@ int fetchDispIdFromName(ComEventCallback annotation) { void invokeOnThread(final DISPID dispIdMember, final REFIID.ByValue riid, LCID lcid, WORD wFlags, final DISPPARAMS.ByReference pDispParams) { + List rjargs = new ArrayList(); + if (pDispParams.cArgs.intValue() > 0) { + VariantArg vargs = pDispParams.rgvarg; + vargs.setArraySize(pDispParams.cArgs.intValue()); + for (Variant.VARIANT varg : vargs.variantArg) { + Object jarg = Convert.toJavaObject(varg); + if (jarg instanceof IDispatch) { + IDispatch dispatch = (IDispatch) jarg; + IUnknown unk = CallbackProxy.this.factory.createProxy(IUnknown.class, dispatch); + rjargs.add(unk); + + } else { + rjargs.add(jarg); + } + } + } + final List jargs = new ArrayList(rjargs); Runnable invokation = new Runnable() { @Override public void run() { try { // decode argumentt - List jargs = new ArrayList(); - if (pDispParams.cArgs.intValue() > 0) { - VariantArg vargs = pDispParams.rgvarg; - vargs.setArraySize(pDispParams.cArgs.intValue()); - for (Variant.VARIANT varg : vargs.variantArg) { - Object jarg = Convert.toJavaObject(varg); - jargs.add(jarg); - } - } + + //Collections.reverse(jargs); if (CallbackProxy.this.dsipIdMap.containsKey(dispIdMember)) { Method eventMethod = CallbackProxy.this.dsipIdMap.get(dispIdMember); String eventMethodName = eventMethod.getName(); if (eventMethod.getParameterCount() != jargs.size()) { CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( - "Trying to invoke method " + eventMethod +" with "+jargs.size()+" arguments", null); + "Trying to invoke method " + eventMethod + " with " + jargs.size() + " arguments", + null); } else { try { - //need to convert arguments maybe + // need to convert arguments maybe List margs = new ArrayList(); Parameter[] params = eventMethod.getParameters(); - for(int i=0;i theInterface, IDispatch rawDispatch, Factory factory this.comThread = factory.getComThread(); this.theInterface = theInterface; this.factory = factory; + + //make sure dispatch object knows we have a reference to it + this.rawDispatch.AddRef(); } + @Override + protected void finalize() throws Throwable { + this.rawDispatch.Release(); + } + Class theInterface; Factory factory; ComThread comThread; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java index b6ff8479f1..1ec68f0321 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java @@ -60,18 +60,30 @@ interface ComIApplication extends IUnknown, IConnectionPoint { } - @ComInterface + @ComInterface(iid="{0002096C-0000-0000-C000-000000000046}") interface ComIDocuments { @ComMethod ComIDocument Open(String fileName); } - @ComInterface - interface ComIDocument {} + @ComInterface(iid="{0002096B-0000-0000-C000-000000000046}") + interface ComIDocument { + @ComProperty + String getFullName(); + + @ComMethod + void Select(); + } - @ComInterface + @ComInterface(iid="{00020962-0000-0000-C000-000000000046}") interface ComIWindow {} + @ComInterface(iid="{00020975-0000-0000-C000-000000000046}") + public interface ComISelection { + @ComProperty + String getText(); + } + @ComInterface(iid="{00020A01-0000-0000-C000-000000000046}") interface ApplicationEvents4_Event { @ComEventCallback(dispid=10) @@ -79,28 +91,40 @@ interface ApplicationEvents4_Event { @ComEventCallback(dispid=2) void Quit(); + + @ComEventCallback(dispid=12) + void WindowSelectionChange(ComISelection sel); } class ApplicationEvents4_EventListener extends AbstractComEventCallbackListener implements ApplicationEvents4_Event { - Boolean Quit_called = null; - Boolean WindowActivate_called = null; + + @Override + public void errorReceivingCallbackEvent(String message, Exception exception) { + + } + Boolean WindowActivate_called = null; @Override public void WindowActivate(ComIDocument doc, ComIWindow win) { - if (null!=doc && null !=win) { + if (null!=doc && null !=win) { + String docName = doc.getFullName(); WindowActivate_called = true; } } - + + Boolean Quit_called = null; @Override public void Quit() { Quit_called = true; } + Boolean WindowSelectionChange_called = null; @Override - public void errorReceivingCallbackEvent(String message, Exception exception) { - - + public void WindowSelectionChange(ComISelection sel) { + if (null!=sel) { + String t = sel.getText(); + WindowSelectionChange_called = true; + } } } @@ -171,7 +195,7 @@ public void WindowActivate() { //Wait for event to happen try { - Thread.sleep(200); + Thread.sleep(500); } catch (Exception e) { e.printStackTrace(); } @@ -182,4 +206,32 @@ public void WindowActivate() { wordApp.Quit(false, null, null); } + + @Test + public void WindowSelectionChanged() { + // Create word object + ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); + ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); + wordApp.setVisible(true); + ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); + wordApp.advise(ApplicationEvents4_Event.class, listener); + + ComIDocument doc = wordApp.getDocuments().Open("C:\\temp\\test.doc"); + + doc.Select(); + + //Wait for event to happen + try { + Thread.sleep(200); + } catch (Exception e) { + e.printStackTrace(); + } + + Assert.assertNotNull(listener.WindowSelectionChange_called); + Assert.assertTrue(listener.WindowSelectionChange_called); + + wordApp.Quit(false, null, null); + + } + } From 581cc006ca78a671230ab6a32eb1c38acb281116 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 18 Nov 2014 16:04:35 +0100 Subject: [PATCH 26/49] ..COM.utils: maven build pom update --- maven/com.sun.jna.p2.repository/pom.xml | 2 ++ maven/pom.xml | 25 ++++++++++++++++++------- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/maven/com.sun.jna.p2.repository/pom.xml b/maven/com.sun.jna.p2.repository/pom.xml index 2fbadb8c44..b8a6ed47b3 100644 --- a/maven/com.sun.jna.p2.repository/pom.xml +++ b/maven/com.sun.jna.p2.repository/pom.xml @@ -32,10 +32,12 @@ com.sun.jna:com.sun.jna.core:${project.version} false + true com.sun.jna:com.sun.jna.platform:${project.version} false + true diff --git a/maven/pom.xml b/maven/pom.xml index 8fe794119f..175ccf7d6e 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -24,12 +24,23 @@ kepler UTF-8 - - - - akehurst - https://projects.itemis.de/nexus/content/repositories/akehurst - - + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.2 + + 1.6 + 1.6 + + + + + + + From 669697ae69166cbc7ed9c1d6011ffd3e94472831 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 18 Nov 2014 16:24:03 +0100 Subject: [PATCH 27/49] added parameter to pom to allow commandline additional.pluginRepository --- maven/pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/maven/pom.xml b/maven/pom.xml index 175ccf7d6e..a07ef70910 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -23,6 +23,7 @@ org.eclipse.tycho kepler UTF-8 + @@ -43,4 +44,11 @@ + + + additional.pluginRepository + ${additional.pluginRepository} + + + From 58ea37122cd0a4260e9bcc8e3139bfb6b94bd914 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 18 Nov 2014 16:26:55 +0100 Subject: [PATCH 28/49] it needs a vaild default --- maven/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/maven/pom.xml b/maven/pom.xml index a07ef70910..80ea8eadae 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -23,7 +23,7 @@ org.eclipse.tycho kepler UTF-8 - + http://central From 88c9a5fe0bd2e4147960c56cf1142e22fe9112fc Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 18 Nov 2014 16:28:52 +0100 Subject: [PATCH 29/49] pom update --- maven/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/maven/pom.xml b/maven/pom.xml index 80ea8eadae..f953e88acf 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -48,6 +48,12 @@ additional.pluginRepository ${additional.pluginRepository} + + true + + + true + From 0cdd1cbd7a12a07d6fb175dad0b734b749fb3f65 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 19 Nov 2014 09:16:33 +0100 Subject: [PATCH 30/49] maven build: update --- maven/pom.xml | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/maven/pom.xml b/maven/pom.xml index f953e88acf..70bc83d247 100644 --- a/maven/pom.xml +++ b/maven/pom.xml @@ -19,11 +19,7 @@ - 0.20.0 - org.eclipse.tycho - kepler UTF-8 - http://central @@ -44,17 +40,6 @@ - - - additional.pluginRepository - ${additional.pluginRepository} - - true - - - true - - - + From d91d5cc36be1c578a6481992311757348b04d506 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 25 Nov 2014 12:40:39 +0100 Subject: [PATCH 31/49] ...COM.util: Added (I think) correct management of COM Refs via AddRef/Release --- .../win32/COM/util/CallbackProxy.java | 13 +- .../jna/platform/win32/COM/util/Factory.java | 80 +++++++++++- .../platform/win32/COM/util/IDispatch.java | 2 +- .../platform/win32/COM/util/ProxyObject.java | 121 ++++++++++++------ 4 files changed, 160 insertions(+), 56 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index 034141a08d..cfb95e57b6 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -120,6 +120,10 @@ int fetchDispIdFromName(ComEventCallback annotation) { void invokeOnThread(final DISPID dispIdMember, final REFIID.ByValue riid, LCID lcid, WORD wFlags, final DISPPARAMS.ByReference pDispParams) { + // decode arguments + // must decode them on this thread, and create a proxy for any COM objects (IDispatch) + // this will AddRef on the COM object so that it is not cleaned up before we can use it + // on the thread that does the java callback. List rjargs = new ArrayList(); if (pDispParams.cArgs.intValue() > 0) { VariantArg vargs = pDispParams.rgvarg; @@ -128,9 +132,9 @@ void invokeOnThread(final DISPID dispIdMember, final REFIID.ByValue riid, LCID l Object jarg = Convert.toJavaObject(varg); if (jarg instanceof IDispatch) { IDispatch dispatch = (IDispatch) jarg; + //Note: unlike in other places, there is currently no COM ref already added for this pointer IUnknown unk = CallbackProxy.this.factory.createProxy(IUnknown.class, dispatch); rjargs.add(unk); - } else { rjargs.add(jarg); } @@ -141,12 +145,8 @@ void invokeOnThread(final DISPID dispIdMember, final REFIID.ByValue riid, LCID l @Override public void run() { try { - // decode argumentt - - //Collections.reverse(jargs); if (CallbackProxy.this.dsipIdMap.containsKey(dispIdMember)) { Method eventMethod = CallbackProxy.this.dsipIdMap.get(dispIdMember); - String eventMethodName = eventMethod.getName(); if (eventMethod.getParameterCount() != jargs.size()) { CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( "Trying to invoke method " + eventMethod + " with " + jargs.size() + " arguments", @@ -162,8 +162,7 @@ public void run() { if (jobj != null && param.getType().getAnnotation(ComInterface.class) != null) { if (jobj instanceof IUnknown) { IUnknown unk = (IUnknown) jobj; - Object mobj = unk.queryInterface(param.getType());// CallbackProxy.this.factory.createProxy(param.getType(), - // dispatch); + Object mobj = unk.queryInterface(param.getType()); margs.add(mobj); } else { throw new RuntimeException("Cannot convert argument " + jobj.getClass() diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index b44d261d19..11a7abb5f9 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -12,7 +12,10 @@ */ package com.sun.jna.platform.win32.COM.util; +import java.lang.ref.WeakReference; import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.WeakHashMap; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -40,11 +43,21 @@ public class Factory { * */ public Factory() { - this.comThread = new ComThread("Factory COM Thread"); + this(new ComThread("Default Factory COM Thread")); } public Factory(ComThread comThread) { this.comThread = comThread; + this.registeredObjects = new WeakHashMap(); + } + + @Override + protected void finalize() throws Throwable { + try { + this.disposeAll(); + } finally { + super.finalize(); + } } ComThread comThread; @@ -116,8 +129,11 @@ public WinNT.HRESULT call() throws Exception { } }); COMUtils.checkRC(hr); - - T t = this.createProxy(comInterface, new Dispatch(ptrDisp.getValue())); + Dispatch d = new Dispatch(ptrDisp.getValue()); + T t = this.createProxy(comInterface,d); + //CoCreateInstance returns a pointer to COM object with a +1 reference count, so we must drop one + //Note: the createProxy adds one + int n = d.Release(); return t; } catch (InterruptedException e) { @@ -148,10 +164,13 @@ public WinNT.HRESULT call() throws Exception { } }); COMUtils.checkRC(hr); - - T t = this.createProxy(comInterface, new Dispatch(ptrDisp.getValue())); + Dispatch d = new Dispatch(ptrDisp.getValue()); + T t = this.createProxy(comInterface, d); + //GetActiveObject returns a pointer to COM object with a +1 reference count, so we must drop one + //Note: the createProxy adds one + d.Release(); + return t; - } catch (InterruptedException e) { throw new RuntimeException(e); } catch (ExecutionException e) { @@ -186,4 +205,53 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } } + + //factory needs to keep a register of all handles to COM objects so that it can clean them up properly + // (if java had an out of scope clean up destructor like C++, this wouldn't be needed) + WeakHashMap registeredObjects; + public void register(ProxyObject proxyObject) { + synchronized (this.registeredObjects) { + //make sure dispatch object knows we have a reference to it + // (for debug it is usefult to be able to see how many refs are present + int numRefs = proxyObject.rawDispatch.AddRef(); + if (this.registeredObjects.containsKey(proxyObject)) { + int r = this.registeredObjects.get(proxyObject); + this.registeredObjects.put(proxyObject, r+1); + } else { + this.registeredObjects.put(proxyObject, 1); + } + } + } + + public void dispose(ProxyObject proxyObject) { + synchronized (this.registeredObjects) { + if (this.registeredObjects.containsKey(proxyObject)) { + int r = this.registeredObjects.get(proxyObject); + if (r > 1) { + this.registeredObjects.put(proxyObject, r-1); + } else { + this.registeredObjects.remove(proxyObject); + } + int numRefs = proxyObject.rawDispatch.Release(); + int n=numRefs; + } else { + throw new RuntimeException("Tried to dispose a ProxyObject that is not registered"); + } + + } + } + + public void disposeAll() { + synchronized (this.registeredObjects) { + for(ProxyObject proxyObject : this.registeredObjects.keySet()) { + int r = this.registeredObjects.get(proxyObject); + for (int i=0; i void setProperty(String name, T value); - T getProperty(Class returnType, String name); + T getProperty(Class returnType, String name, Object... args); T invokeMethod(Class returnType, String name, Object... args); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index e48e14e363..4256594b44 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -65,16 +65,18 @@ public ProxyObject(Class theInterface, IDispatch rawDispatch, Factory factory this.comThread = factory.getComThread(); this.theInterface = theInterface; this.factory = factory; - - //make sure dispatch object knows we have a reference to it - this.rawDispatch.AddRef(); + factory.register(this); } @Override protected void finalize() throws Throwable { - this.rawDispatch.Release(); + this.dispose(); } - + + public void dispose() { + this.factory.dispose(this); + } + Class theInterface; Factory factory; ComThread comThread; @@ -85,45 +87,54 @@ public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { } // -------------------- Object ------------------------- - + /* - * The QueryInterface rule state that - * 'a call to QueryInterface with IID_IUnknown must always return the same physical pointer value.' + * The QueryInterface rule state that 'a call to QueryInterface with + * IID_IUnknown must always return the same physical pointer value.' * * [http://msdn.microsoft.com/en-us/library/ms686590%28VS.85%29.aspx] */ public boolean equals(Object arg) { - InvocationHandler handler = Proxy.getInvocationHandler(arg); - if (handler instanceof ProxyObject) { - ProxyObject other = (ProxyObject)handler; - - IUnknown unk1 = this.queryInterface(IUnknown.class); - IUnknown unk2 = other.queryInterface(IUnknown.class); - - InvocationHandler h1 = Proxy.getInvocationHandler(unk1); - InvocationHandler h2 = Proxy.getInvocationHandler(unk2); - - ProxyObject po1 = (ProxyObject)h1; - ProxyObject po2 = (ProxyObject)h2; - - IDispatch d1 = po1.getRawDispatch(); - IDispatch d2 = po2.getRawDispatch(); - - return d1.equals(d2); + if (arg instanceof ProxyObject) { + ProxyObject other = (ProxyObject) arg; + return this.getRawDispatch().equals(other.getRawDispatch()); + } else if (Proxy.isProxyClass(arg.getClass())) { + InvocationHandler handler = Proxy.getInvocationHandler(arg); + if (handler instanceof ProxyObject) { + ProxyObject other = (ProxyObject) handler; + + IUnknown unk1 = this.queryInterface(IUnknown.class); + IUnknown unk2 = other.queryInterface(IUnknown.class); + + InvocationHandler h1 = Proxy.getInvocationHandler(unk1); + InvocationHandler h2 = Proxy.getInvocationHandler(unk2); + + ProxyObject po1 = (ProxyObject) h1; + ProxyObject po2 = (ProxyObject) h2; + + IDispatch d1 = po1.getRawDispatch(); + IDispatch d2 = po2.getRawDispatch(); + + return d1.equals(d2); + } else { + return false; + } } else { return false; } }; + @Override public int hashCode() { // this returns the native pointer peer value return this.getRawDispatch().hashCode(); } + @Override public String toString() { - return this.theInterface.getName() + "{"+this.hashCode()+"}"; + return this.theInterface.getName() + "{" + this.hashCode() + "}"; } - + // --------------------- InvocationHandler ----------------------------- @Override public Object invoke(final Object proxy, final java.lang.reflect.Method method, final Object[] args) @@ -131,7 +142,7 @@ public Object invoke(final Object proxy, final java.lang.reflect.Method method, if (method.equals(Object.class.getMethod("toString"))) { return this.toString(); - } else if (method.equals(Object.class.getMethod("equals",Object.class))) { + } else if (method.equals(Object.class.getMethod("equals", Object.class))) { return this.equals(args[0]); } else if (method.equals(Object.class.getMethod("hashCode"))) { return this.hashCode(); @@ -139,10 +150,12 @@ public Object invoke(final Object proxy, final java.lang.reflect.Method method, return this.getRawDispatch(); } else if (method.equals(IUnknown.class.getMethod("queryInterface", Class.class))) { return this.queryInterface((Class) args[0]); - } else if (method.equals(IConnectionPoint.class.getMethod("advise", Class.class, IComEventCallbackListener.class))) { - return this.advise((Class)args[0], (IComEventCallbackListener) args[1]); - } else if (method.equals(IConnectionPoint.class.getMethod("unadvise", Class.class, IComEventCallbackCookie.class))) { - this.unadvise((Class)args[0], (IComEventCallbackCookie) args[1]); + } else if (method.equals(IConnectionPoint.class.getMethod("advise", Class.class, + IComEventCallbackListener.class))) { + return this.advise((Class) args[0], (IComEventCallbackListener) args[1]); + } else if (method.equals(IConnectionPoint.class.getMethod("unadvise", Class.class, + IComEventCallbackCookie.class))) { + this.unadvise((Class) args[0], (IComEventCallbackCookie) args[1]); return null; } @@ -157,7 +170,7 @@ public Object invoke(final Object proxy, final java.lang.reflect.Method method, return null; } else { String propName = this.getAccessorName(method, prop); - return this.getProperty(returnType, propName); + return this.getProperty(returnType, propName, args); } } @@ -192,7 +205,8 @@ public HRESULT call() throws Exception { return rawCp; } - public IComEventCallbackCookie advise(Class comEventCallbackInterface, final IComEventCallbackListener comEventCallbackListener) { + public IComEventCallbackCookie advise(Class comEventCallbackInterface, + final IComEventCallbackListener comEventCallbackListener) { try { ComInterface comInterfaceAnnotation = comEventCallbackInterface.getAnnotation(ComInterface.class); if (null == comInterfaceAnnotation) { @@ -204,7 +218,8 @@ public IComEventCallbackCookie advise(Class comEventCallbackInterface, final final ConnectionPoint rawCp = this.fetchRawConnectionPoint(iid); // create the dispatch listener - final IDispatchCallback rawListener = new CallbackProxy(this.factory, comEventCallbackInterface, comEventCallbackListener); + final IDispatchCallback rawListener = new CallbackProxy(this.factory, comEventCallbackInterface, + comEventCallbackListener); // store it the comEventCallback argument, so it is not garbage // collected. comEventCallbackListener.setDispatchCallbackListener(rawListener); @@ -223,7 +238,8 @@ public HRESULT call() throws Exception { return new ComEventCallbackCookie(pdwCookie.getValue()); } catch (Exception e) { - throw new COMException("Error occured in advise when trying to connect the listener " + comEventCallbackListener, e); + throw new COMException("Error occured in advise when trying to connect the listener " + + comEventCallbackListener, e); } } @@ -260,13 +276,26 @@ public void setProperty(String name, T value) { } @Override - public T getProperty(Class returnType, String name) { + public T getProperty(Class returnType, String name, Object... args) { + VARIANT[] vargs; + if (null == args) { + vargs = new VARIANT[0]; + } else { + vargs = new VARIANT[args.length]; + } + for (int i = 0; i < vargs.length; ++i) { + vargs[i] = Convert.toVariant(args[i]); + } Variant.VARIANT.ByReference result = new Variant.VARIANT.ByReference(); - WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getRawDispatch(), name); + WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getRawDispatch(), name, vargs); COMUtils.checkRC(hr); Object jobj = Convert.toJavaObject(result); - if (jobj instanceof com.sun.jna.platform.win32.COM.IDispatch) { - return this.factory.createProxy(returnType, (com.sun.jna.platform.win32.COM.IDispatch) jobj); + if (jobj instanceof IDispatch) { + IDispatch d = (IDispatch) jobj; + T t = this.factory.createProxy(returnType, d); + //must release a COM reference, createProxy adds one, as does the call + int n = d.Release(); + return t; } return (T) jobj; } @@ -288,7 +317,11 @@ public T invokeMethod(Class returnType, String name, Object... args) { Object jobj = Convert.toJavaObject(result); if (jobj instanceof IDispatch) { - return this.factory.createProxy(returnType, (IDispatch) jobj); + IDispatch d = (IDispatch) jobj; + T t = this.factory.createProxy(returnType, d); + //must release a COM reference, createProxy adds one, as does the call + int n = d.Release(); + return t; } return (T) jobj; } @@ -313,7 +346,11 @@ public HRESULT call() throws Exception { if (WinNT.S_OK.equals(hr)) { Dispatch dispatch = new Dispatch(ppvObject.getValue()); - return this.factory.createProxy(comInterface, dispatch); + T t = this.factory.createProxy(comInterface, dispatch); + // QueryInterface returns a COM object pointer with a +1 reference, we must drop one, + // Note: createProxy adds one; + int n = dispatch.Release(); + return t; } else { String formatMessageFromHR = Kernel32Util.formatMessage(hr); throw new COMException("queryInterface: " + formatMessageFromHR); From 421a2dce2ab4ab12eddd23564bda43b326dc6657 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 25 Nov 2014 12:41:54 +0100 Subject: [PATCH 32/49] msoffice Demo: added ..COM.util version for Excel --- .../win32/COM/office/MSOfficeDemo.java | 4 +- .../COM/util/office/MSOfficeExcelDemo.java | 75 ++++++++++++ ...SOfficeDemo.java => MSOfficeWordDemo.java} | 40 ++----- .../office/excel/ComExcel_Application.java | 10 ++ .../util/office/excel/ComIApplication.java | 32 +++++ .../COM/util/office/excel/ComIRange.java | 22 ++++ .../COM/util/office/excel/ComIWorkbook.java | 13 +++ .../COM/util/office/excel/ComIWorkbooks.java | 19 +++ .../COM/util/office/excel/ComIWorksheet.java | 19 +++ .../office/{ => word}/ComIApplication.java | 2 +- .../util/office/{ => word}/ComIDocument.java | 2 +- .../util/office/{ => word}/ComIDocuments.java | 2 +- .../util/office/{ => word}/ComISelection.java | 2 +- .../{ => word}/ComWord_Application.java | 2 +- .../office/{ => word}/WdOriginalFormat.java | 2 +- .../util/office/{ => word}/WdSaveFormat.java | 2 +- maven/com.sun.jna.p2.repository/pom.xml | 110 +++++++++--------- 17 files changed, 261 insertions(+), 97 deletions(-) create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{MSOfficeDemo.java => MSOfficeWordDemo.java} (79%) create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{ => word}/ComIApplication.java (92%) rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{ => word}/ComIDocument.java (90%) rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{ => word}/ComIDocuments.java (91%) rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{ => word}/ComISelection.java (91%) rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{ => word}/ComWord_Application.java (91%) rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{ => word}/WdOriginalFormat.java (92%) rename contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/{ => word}/WdSaveFormat.java (96%) diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java index 49967d4374..f4d6658cbd 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/office/MSOfficeDemo.java @@ -18,8 +18,8 @@ public static void main(String[] args) { + File.separator; public MSOfficeDemo() { - this.testMSWord(); - // this.testMSExcel(); + //this.testMSWord(); + this.testMSExcel(); } public void testMSWord() { diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java new file mode 100644 index 0000000000..d9c9ac9948 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java @@ -0,0 +1,75 @@ +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 for more details. + */ +package com.sun.jna.platform.win32.COM.util.office; + +import java.io.File; + +import com.sun.jna.platform.win32.COM.office.MSExcel; +import com.sun.jna.platform.win32.COM.util.Factory; +import com.sun.jna.platform.win32.COM.util.office.excel.ComExcel_Application; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIApplication; +import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application; + +public class MSOfficeExcelDemo { + + /** + * @param args + */ + public static void main(String[] args) { + new MSOfficeExcelDemo(); + } + + private String currentWorkingDir = new File("").getAbsolutePath() + File.separator; + + public MSOfficeExcelDemo() { + this.testMSExcel(); + } + + public void testMSExcel() { + ComExcel_Application excelObject = null; + ComIApplication msExcel = null; + Factory factory = null; + try { + factory = new Factory(); + excelObject = factory.createObject(ComExcel_Application.class); + msExcel = excelObject.queryInterface(ComIApplication.class); + System.out.println("MSExcel version: " + msExcel.getVersion()); + msExcel.setVisible(true); + // msExcel.newExcelBook(); + msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls"); + msExcel.getActiveSheet().getRange("A1").setValue("Hello from JNA!"); + // wait 10sec. before closing + Thread.currentThread().sleep(1000); + // close and save the active sheet + msExcel.getActiveWorkbook().Close(true); + msExcel.setVisible(true); + // msExcel.newExcelBook(); + msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls"); + msExcel.getActiveSheet().getRange("A2").setValue("Hello again from JNA!"); + // close and save the active sheet + msExcel.getActiveWorkbook().Close(true); + + msExcel.Quit(); + msExcel = null; + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (null != msExcel) { + msExcel.Quit(); + } + if (null != factory) { + factory.disposeAll(); + } + } + } +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeDemo.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java similarity index 79% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeDemo.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java index f2eda77b29..c3704d2111 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeDemo.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java @@ -15,23 +15,25 @@ import java.io.File; import com.sun.jna.platform.win32.COM.COMException; -import com.sun.jna.platform.win32.COM.office.MSExcel; import com.sun.jna.platform.win32.COM.util.Factory; +import com.sun.jna.platform.win32.COM.util.office.word.ComIApplication; +import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application; +import com.sun.jna.platform.win32.COM.util.office.word.WdOriginalFormat; +import com.sun.jna.platform.win32.COM.util.office.word.WdSaveFormat; -public class MSOfficeDemo { +public class MSOfficeWordDemo { /** * @param args */ public static void main(String[] args) { - new MSOfficeDemo(); + new MSOfficeWordDemo(); } private String currentWorkingDir = new File("").getAbsolutePath() + File.separator; - public MSOfficeDemo() { + public MSOfficeWordDemo() { this.testMSWord(); - // this.testMSExcel(); } public void testMSWord() { @@ -101,32 +103,4 @@ public void testMSWord() { } } } - - public void testMSExcel() { - MSExcel msExcel = null; - - try { - msExcel = new MSExcel(); - System.out.println("MSExcel version: " + msExcel.getVersion()); - msExcel.setVisible(true); - // msExcel.newExcelBook(); - msExcel.openExcelBook(currentWorkingDir + "jnatest.xls", true); - msExcel.insertValue("A1", "Hello from JNA!"); - // wait 10sec. before closing - Thread.currentThread().sleep(10000); - // close and save the active sheet - msExcel.closeActiveWorkbook(true); - msExcel.setVisible(true); - // msExcel.newExcelBook(); - msExcel.openExcelBook(currentWorkingDir + "jnatest.xls", true); - msExcel.insertValue("A1", "Hello from JNA!"); - // close and save the active sheet - msExcel.closeActiveWorkbook(true); - } catch (Exception e) { - e.printStackTrace(); - - if (msExcel != null) - msExcel.quit(); - } - } } diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java new file mode 100644 index 0000000000..07cc479b48 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComExcel_Application.java @@ -0,0 +1,10 @@ +package com.sun.jna.platform.win32.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.IUnknown; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComObject; + +@ComObject(progId="Excel.Application") +public interface ComExcel_Application extends IUnknown { + +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java new file mode 100644 index 0000000000..11f7cec543 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIApplication.java @@ -0,0 +1,32 @@ +package com.sun.jna.platform.win32.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.IConnectionPoint; +import com.sun.jna.platform.win32.COM.util.IUnknown; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface(iid="{000208D5-0000-0000-C000-000000000046}") +public interface ComIApplication extends IUnknown, IConnectionPoint { + + @ComProperty + String getVersion(); + + @ComProperty + boolean getVisible(); + + @ComProperty + void setVisible(boolean value); + + @ComProperty + ComIWorkbooks getWorkbooks(); + + @ComProperty + ComIWorksheet getActiveSheet(); + + @ComProperty + ComIWorkbook getActiveWorkbook(); + + @ComMethod + void Quit(); +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java new file mode 100644 index 0000000000..4dfd617056 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java @@ -0,0 +1,22 @@ +package com.sun.jna.platform.win32.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface(iid = "{00020846-0000-0000-C000-000000000046}") +public interface ComIRange { + + @ComProperty + ComIApplication getApplication(); + + @ComProperty + String getText(); + + @ComMethod + void Select(); + + @ComProperty + void setValue(String value); + +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java new file mode 100644 index 0000000000..375a684510 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbook.java @@ -0,0 +1,13 @@ +package com.sun.jna.platform.win32.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; + +@ComInterface(iid="{0002096B-0000-0000-C000-000000000046}") +public interface ComIWorkbook { + + @ComMethod + void Close(boolean saveChanges); + + +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java new file mode 100644 index 0000000000..c9174c23c2 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorkbooks.java @@ -0,0 +1,19 @@ +package com.sun.jna.platform.win32.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface(iid = "{000208DB-0000-0000-C000-000000000046}") +public interface ComIWorkbooks { + + @ComProperty + long getCount(); + + @ComMethod + ComIWorkbook Item(long index); + + @ComMethod + ComIWorkbook Open(Object FileName); + +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java new file mode 100644 index 0000000000..2687f80d27 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIWorksheet.java @@ -0,0 +1,19 @@ +package com.sun.jna.platform.win32.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; +import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; +import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; + +@ComInterface(iid="{000208D8-0000-0000-C000-000000000046}") +public interface ComIWorksheet { + + @ComProperty + String getName(); + + @ComProperty + ComIRange getRange(String cell1); + + @ComProperty + ComIApplication getApplication(); + +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIApplication.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIApplication.java similarity index 92% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIApplication.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIApplication.java index 805dd1d8d3..10a18b21e8 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIApplication.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIApplication.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.util.office; +package com.sun.jna.platform.win32.COM.util.office.word; import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIDocument.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocument.java similarity index 90% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIDocument.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocument.java index d09d95a812..e370130b8e 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIDocument.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocument.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.util.office; +package com.sun.jna.platform.win32.COM.util.office.word; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIDocuments.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocuments.java similarity index 91% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIDocuments.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocuments.java index 56019c70c2..2096de5af5 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComIDocuments.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComIDocuments.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.util.office; +package com.sun.jna.platform.win32.COM.util.office.word; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComISelection.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComISelection.java similarity index 91% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComISelection.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComISelection.java index 2a4ec90df6..53d59b4f90 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComISelection.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComISelection.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.util.office; +package com.sun.jna.platform.win32.COM.util.office.word; import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComWord_Application.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComWord_Application.java similarity index 91% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComWord_Application.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComWord_Application.java index 875b3ccf26..af7a26e2d9 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/ComWord_Application.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/ComWord_Application.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.util.office; +package com.sun.jna.platform.win32.COM.util.office.word; import com.sun.jna.platform.win32.COM.util.IUnknown; import com.sun.jna.platform.win32.COM.util.annotation.ComObject; diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/WdOriginalFormat.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdOriginalFormat.java similarity index 92% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/WdOriginalFormat.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdOriginalFormat.java index e16ffb3c0b..b7f4bbee46 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/WdOriginalFormat.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdOriginalFormat.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.util.office; +package com.sun.jna.platform.win32.COM.util.office.word; import com.sun.jna.platform.win32.COM.util.IComEnum; diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/WdSaveFormat.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveFormat.java similarity index 96% rename from contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/WdSaveFormat.java rename to contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveFormat.java index 1419573972..7b7fce9fb1 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/WdSaveFormat.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/word/WdSaveFormat.java @@ -10,7 +10,7 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ -package com.sun.jna.platform.win32.COM.util.office; +package com.sun.jna.platform.win32.COM.util.office.word; import com.sun.jna.platform.win32.COM.util.IComEnum; diff --git a/maven/com.sun.jna.p2.repository/pom.xml b/maven/com.sun.jna.p2.repository/pom.xml index b8a6ed47b3..32735c6118 100644 --- a/maven/com.sun.jna.p2.repository/pom.xml +++ b/maven/com.sun.jna.p2.repository/pom.xml @@ -1,55 +1,55 @@ - - - 4.0.0 - - - com.sun.jna - com.sun.jna.parent - 4.1.1-SNAPSHOT - - - com.sun.jna.p2.repository - - pom - - - - - org.reficio - p2-maven-plugin - 1.1.1-SNAPSHOT - - - default-cli - package - - site - - - ${project.basedir}/src/main/resources/category.xml - - - com.sun.jna:com.sun.jna.core:${project.version} - false - true - - - com.sun.jna:com.sun.jna.platform:${project.version} - false - true - - - - - com.sun.jna:feature:${project.version} - false - - - - - - - - - + + + 4.0.0 + + + com.sun.jna + com.sun.jna.parent + 4.1.1-SNAPSHOT + + + com.sun.jna.p2.repository + + pom + + + + + org.reficio + p2-maven-plugin + 1.1.1 + + + default-cli + package + + site + + + ${project.basedir}/src/main/resources/category.xml + + + com.sun.jna:com.sun.jna.core:${project.version} + false + true + + + com.sun.jna:com.sun.jna.platform:${project.version} + false + true + + + + + com.sun.jna:feature:${project.version} + false + + + + + + + + + From 1ebbff4bf50163fe0a57d99e6f322b6ceff08e6c Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 25 Nov 2014 15:31:05 +0100 Subject: [PATCH 33/49] Update Excel Test, Added another Release on COM reference --- .../COM/util/office/MSOfficeExcelDemo.java | 41 +++++++++++++++---- .../COM/util/office/excel/ComIAppEvents.java | 12 ++++++ .../COM/util/office/excel/ComIRange.java | 3 ++ .../platform/win32/COM/util/EnumMoniker.java | 6 ++- .../platform/win32/COM/util/ProxyObject.java | 7 +++- .../COM/util/ComEventCallbacks_Test.java | 1 + 6 files changed, 59 insertions(+), 11 deletions(-) create mode 100644 contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java index d9c9ac9948..a7a49b7d06 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeExcelDemo.java @@ -15,9 +15,13 @@ import java.io.File; import com.sun.jna.platform.win32.COM.office.MSExcel; +import com.sun.jna.platform.win32.COM.util.AbstractComEventCallbackListener; import com.sun.jna.platform.win32.COM.util.Factory; import com.sun.jna.platform.win32.COM.util.office.excel.ComExcel_Application; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIAppEvents; import com.sun.jna.platform.win32.COM.util.office.excel.ComIApplication; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIRange; +import com.sun.jna.platform.win32.COM.util.office.excel.ComIWorksheet; import com.sun.jna.platform.win32.COM.util.office.word.ComWord_Application; public class MSOfficeExcelDemo { @@ -48,17 +52,38 @@ public void testMSExcel() { // msExcel.newExcelBook(); msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls"); msExcel.getActiveSheet().getRange("A1").setValue("Hello from JNA!"); - // wait 10sec. before closing + // wait 1sec. before closing Thread.currentThread().sleep(1000); +// // close and save the active sheet +// msExcel.getActiveWorkbook().Close(true); +// msExcel.setVisible(true); +// // msExcel.newExcelBook(); +// msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls"); +// msExcel.getActiveSheet().getRange("A2").setValue("Hello again from JNA!"); + + class Listener extends AbstractComEventCallbackListener implements ComIAppEvents { + boolean SheetSelectionChange_called; + + @Override + public void errorReceivingCallbackEvent(String message, Exception exception) { + } + + @Override + public void SheetSelectionChange(ComIWorksheet sheet, ComIRange target) { + SheetSelectionChange_called = true; + } + + }; + Listener listener = new Listener(); + msExcel.advise(ComIAppEvents.class, listener); +// +// msExcel.getActiveSheet().getRange("A5").Activate(); +// +// Thread.currentThread().sleep(500); + // close and save the active sheet msExcel.getActiveWorkbook().Close(true); - msExcel.setVisible(true); - // msExcel.newExcelBook(); - msExcel.getWorkbooks().Open(currentWorkingDir + "jnatest.xls"); - msExcel.getActiveSheet().getRange("A2").setValue("Hello again from JNA!"); - // close and save the active sheet - msExcel.getActiveWorkbook().Close(true); - + msExcel.Quit(); msExcel = null; } catch (Exception e) { diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java new file mode 100644 index 0000000000..381abef705 --- /dev/null +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIAppEvents.java @@ -0,0 +1,12 @@ +package com.sun.jna.platform.win32.COM.util.office.excel; + +import com.sun.jna.platform.win32.COM.util.annotation.ComEventCallback; +import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; + +@ComInterface(iid="{00024413-0000-0000-C000-000000000046}") +public interface ComIAppEvents { + + @ComEventCallback(dispid=1558) + public void SheetSelectionChange(ComIWorksheet sheet, ComIRange target); + +} diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java index 4dfd617056..4d79f20f44 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/excel/ComIRange.java @@ -19,4 +19,7 @@ public interface ComIRange { @ComProperty void setValue(String value); + @ComMethod + void Activate(); + } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java index 300020a8b7..e57bdc7a31 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java @@ -135,8 +135,10 @@ public WinNT.HRESULT call() throws Exception { Dispatch dispatch = new Dispatch(ppunkObject.getValue()); EnumMoniker.this.cacheNext(); - - return new ProxyObject(IUnknown.class, dispatch, EnumMoniker.this.factory); + IDispatch d = EnumMoniker.this.factory.createProxy(IDispatch.class, dispatch); + //must release a COM Ref, GetObject returns a pointer with +1 + int n = dispatch.Release(); + return d; } catch (InterruptedException e) { throw new RuntimeException(e); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index 4256594b44..3bfb647202 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -95,7 +95,9 @@ public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { * [http://msdn.microsoft.com/en-us/library/ms686590%28VS.85%29.aspx] */ public boolean equals(Object arg) { - if (arg instanceof ProxyObject) { + if (null==arg) { + return false; + } else if (arg instanceof ProxyObject) { ProxyObject other = (ProxyObject) arg; return this.getRawDispatch().equals(other.getRawDispatch()); } else if (Proxy.isProxyClass(arg.getClass())) { @@ -232,6 +234,7 @@ public HRESULT call() throws Exception { return rawCp.Advise(rawListener, pdwCookie); } }); + int n = rawCp.Release(); //release before check in case check throws exception COMUtils.checkRC(hr); // return the cookie so that a call to stop listening can be made @@ -260,6 +263,8 @@ public HRESULT call() throws Exception { return rawCp.Unadvise(((ComEventCallbackCookie) cookie).getValue()); } }); + + rawCp.Release(); COMUtils.checkRC(hr); } catch (Exception e) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java index 1ec68f0321..cf52440414 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java @@ -36,6 +36,7 @@ public void before() { @After public void after() { + this.factory.disposeAll(); this.factory.getComThread().terminate(100); } From f11024639789a3e14014e8a74fae371656af20b6 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 26 Nov 2014 15:09:02 +0100 Subject: [PATCH 34/49] Using new version of p2 generator --- maven/com.sun.jna.feature/build.properties | 2 +- maven/com.sun.jna.p2.repository/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/maven/com.sun.jna.feature/build.properties b/maven/com.sun.jna.feature/build.properties index 8ba7015cef..cf058056a8 100644 --- a/maven/com.sun.jna.feature/build.properties +++ b/maven/com.sun.jna.feature/build.properties @@ -1,2 +1,2 @@ bin.includes = feature.xml,\ - licence.txt + license.txt diff --git a/maven/com.sun.jna.p2.repository/pom.xml b/maven/com.sun.jna.p2.repository/pom.xml index 32735c6118..7f7ff4d1e9 100644 --- a/maven/com.sun.jna.p2.repository/pom.xml +++ b/maven/com.sun.jna.p2.repository/pom.xml @@ -18,7 +18,7 @@ org.reficio p2-maven-plugin - 1.1.1 + 1.1.2-SNAPSHOT default-cli From 4b9362f6acfdf7b4ef308a964f80990022b0b13d Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Thu, 27 Nov 2014 10:01:27 +0100 Subject: [PATCH 35/49] ..COM.util: reorganise disposing --- .../win32/COM/util/CallbackProxy.java | 1 + .../jna/platform/win32/COM/util/Factory.java | 23 ++++++++----------- .../platform/win32/COM/util/ProxyObject.java | 20 +++++++++++++--- .../win32/COM/util/ProxyObject_Test.java | 1 + 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index cfb95e57b6..760b9bd03a 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -70,6 +70,7 @@ public CallbackProxy(Factory factory, Class comEventCallbackInterface, @Override public Thread newThread(Runnable r) { Thread t = new Thread(r, "COM Event Callback executor"); + t.setDaemon(true); return t; } }); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 11a7abb5f9..8ee742af36 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -15,6 +15,8 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Proxy; import java.util.ArrayList; +import java.util.HashSet; +import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; @@ -211,9 +213,9 @@ public WinNT.HRESULT call() throws Exception { WeakHashMap registeredObjects; public void register(ProxyObject proxyObject) { synchronized (this.registeredObjects) { - //make sure dispatch object knows we have a reference to it - // (for debug it is usefult to be able to see how many refs are present - int numRefs = proxyObject.rawDispatch.AddRef(); + //ProxyObject identity resolves to the underlying native pointer value + // different java ProxyObjects will resolve to the same pointer + // thus we need to count the number of references. if (this.registeredObjects.containsKey(proxyObject)) { int r = this.registeredObjects.get(proxyObject); this.registeredObjects.put(proxyObject, r+1); @@ -223,17 +225,15 @@ public void register(ProxyObject proxyObject) { } } - public void dispose(ProxyObject proxyObject) { + public void unregister(ProxyObject proxyObject, int d) { synchronized (this.registeredObjects) { if (this.registeredObjects.containsKey(proxyObject)) { int r = this.registeredObjects.get(proxyObject); if (r > 1) { - this.registeredObjects.put(proxyObject, r-1); + this.registeredObjects.put(proxyObject, r-d); } else { this.registeredObjects.remove(proxyObject); } - int numRefs = proxyObject.rawDispatch.Release(); - int n=numRefs; } else { throw new RuntimeException("Tried to dispose a ProxyObject that is not registered"); } @@ -243,13 +243,10 @@ public void dispose(ProxyObject proxyObject) { public void disposeAll() { synchronized (this.registeredObjects) { - for(ProxyObject proxyObject : this.registeredObjects.keySet()) { + Set s = new HashSet(this.registeredObjects.keySet()); + for(ProxyObject proxyObject : s) { int r = this.registeredObjects.get(proxyObject); - for (int i=0; i theInterface, IDispatch rawDispatch, Factory factory this.comThread = factory.getComThread(); this.theInterface = theInterface; this.factory = factory; + //make sure dispatch object knows we have a reference to it + // (for debug it is usefult to be able to see how many refs are present + int n = this.rawDispatch.AddRef(); factory.register(this); } @Override protected void finalize() throws Throwable { - this.dispose(); + this.dispose(1); } - public void dispose() { - this.factory.dispose(this); + public void dispose(int r) { + if (((Dispatch)this.rawDispatch).getPointer().equals(Pointer.NULL)) { + //do nothing, already disposed + } else { + for (int i=0; i theInterface; diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java index 7a9b61959e..28374702bf 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java @@ -102,5 +102,6 @@ public void equals() { assertTrue(res); + comObj1.Quit(false, null,null); } } From ed27da3077feea3c3dce1ebb9ebe50b6c9db4994 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Fri, 28 Nov 2014 16:00:45 +0100 Subject: [PATCH 36/49] Enable COM calls to timeout and throw exception --- .../platform/win32/COM/util/ComThread.java | 14 ++--- .../platform/win32/COM/util/EnumMoniker.java | 7 +++ .../jna/platform/win32/COM/util/Factory.java | 13 ++++- .../platform/win32/COM/util/ProxyObject.java | 54 ++++++++++++------- .../win32/COM/util/RunningObjectTable.java | 3 ++ 5 files changed, 63 insertions(+), 28 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java index 9d7cf61154..7078b47eec 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java @@ -30,13 +30,15 @@ public class ComThread { ExecutorService executor; Runnable firstTask; boolean requiresInitialisation; - - public ComThread(final String threadName) { - this(threadName, Ole32.COINIT_MULTITHREADED); + long timeoutMilliseconds; + + public ComThread(final String threadName, long timeoutMilliseconds) { + this(threadName, timeoutMilliseconds, Ole32.COINIT_MULTITHREADED); } - public ComThread(final String threadName, final int coinitialiseExFlag) { + public ComThread(final String threadName, long timeoutMilliseconds, final int coinitialiseExFlag) { this.requiresInitialisation = true; + this.timeoutMilliseconds = timeoutMilliseconds; this.firstTask = new Runnable() { @Override public void run() { @@ -110,11 +112,11 @@ protected void finalize() throws Throwable { } } - public T execute(Callable task) throws InterruptedException, ExecutionException { + public T execute(Callable task) throws TimeoutException, InterruptedException, ExecutionException { if (this.requiresInitialisation) { executor.execute(firstTask); } - return executor.submit(task).get(); + return executor.submit(task).get(this.timeoutMilliseconds, TimeUnit.MILLISECONDS); } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java index e57bdc7a31..f12bf8d2d1 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/EnumMoniker.java @@ -15,6 +15,7 @@ import java.util.Iterator; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; import com.sun.jna.platform.win32.WinDef; import com.sun.jna.platform.win32.WinNT; @@ -53,6 +54,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } this.cacheNext(); @@ -89,6 +92,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } } @@ -144,6 +149,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 8ee742af36..f2f756e349 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -20,6 +20,7 @@ import java.util.WeakHashMap; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; import com.sun.jna.platform.win32.Guid.CLSID; import com.sun.jna.platform.win32.Guid.GUID; @@ -40,12 +41,12 @@ public class Factory { //public static Factory INSTANCE = new Factory(); /** - * Creates a utility COM Factory and a ComThreadon which all COM calls are executed. + * Creates a utility COM Factory and a ComThread on which all COM calls are executed. * NOTE: Remember to call factory.getComThread().terminate() at some appropriate point. * */ public Factory() { - this(new ComThread("Default Factory COM Thread")); + this(new ComThread("Default Factory COM Thread", 5000)); } public Factory(ComThread comThread) { @@ -94,6 +95,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } } @@ -142,6 +145,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } } @@ -177,6 +182,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } } @@ -205,6 +212,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index 8c777d5c37..a07107a7ec 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -17,6 +17,7 @@ import java.util.Date; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; import com.sun.jna.Pointer; import com.sun.jna.WString; @@ -107,6 +108,9 @@ public com.sun.jna.platform.win32.COM.IDispatch getRawDispatch() { * IID_IUnknown must always return the same physical pointer value.' * * [http://msdn.microsoft.com/en-us/library/ms686590%28VS.85%29.aspx] + * + * therefore we can compare the pointers + * */ public boolean equals(Object arg) { if (null==arg) { @@ -117,21 +121,27 @@ public boolean equals(Object arg) { } else if (Proxy.isProxyClass(arg.getClass())) { InvocationHandler handler = Proxy.getInvocationHandler(arg); if (handler instanceof ProxyObject) { - ProxyObject other = (ProxyObject) handler; - - IUnknown unk1 = this.queryInterface(IUnknown.class); - IUnknown unk2 = other.queryInterface(IUnknown.class); - - InvocationHandler h1 = Proxy.getInvocationHandler(unk1); - InvocationHandler h2 = Proxy.getInvocationHandler(unk2); - - ProxyObject po1 = (ProxyObject) h1; - ProxyObject po2 = (ProxyObject) h2; - - IDispatch d1 = po1.getRawDispatch(); - IDispatch d2 = po2.getRawDispatch(); - - return d1.equals(d2); + try { + ProxyObject other = (ProxyObject) handler; + + IUnknown unk1 = this.queryInterface(IUnknown.class); + IUnknown unk2 = other.queryInterface(IUnknown.class); + + InvocationHandler h1 = Proxy.getInvocationHandler(unk1); + InvocationHandler h2 = Proxy.getInvocationHandler(unk2); + + ProxyObject po1 = (ProxyObject) h1; + ProxyObject po2 = (ProxyObject) h2; + + IDispatch d1 = po1.getRawDispatch(); + IDispatch d2 = po2.getRawDispatch(); + + return d1.equals(d2); + } catch (Exception e) { + //if can't do this comparison, return false + // (queryInterface may throw if COM objects become invalid) + return false; + } } else { return false; } @@ -201,7 +211,7 @@ public Object invoke(final Object proxy, final java.lang.reflect.Method method, } // ---------------------- IConnectionPoint ---------------------- - ConnectionPoint fetchRawConnectionPoint(IID iid) throws InterruptedException, ExecutionException { + ConnectionPoint fetchRawConnectionPoint(IID iid) throws InterruptedException, ExecutionException, TimeoutException { // query for ConnectionPointContainer IConnectionPointContainer cpc = this.queryInterface(IConnectionPointContainer.class); Dispatch rawCpcDispatch = (Dispatch) cpc.getRawDispatch(); @@ -492,9 +502,11 @@ public HRESULT call() throws Exception { return this.oleMethod(nType, pvResult, pDisp, pdispID.getValue(), pArgs); } catch (InterruptedException e) { - throw new RuntimeException(e); + throw new COMException(e); } catch (ExecutionException e) { - throw new RuntimeException(e); + throw new COMException(e); + } catch (TimeoutException e) { + throw new COMException(e); } } @@ -555,9 +567,11 @@ public HRESULT call() throws Exception { COMUtils.checkRC(hr, pExcepInfo, puArgErr); return hr; } catch (InterruptedException e) { - throw new RuntimeException(e); + throw new COMException(e); } catch (ExecutionException e) { - throw new RuntimeException(e); + throw new COMException(e); + } catch (TimeoutException e) { + throw new COMException(e); } } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java index 1d7bd41ea0..874461378e 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/RunningObjectTable.java @@ -16,6 +16,7 @@ import java.util.List; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeoutException; import com.sun.jna.platform.win32.WinNT; import com.sun.jna.platform.win32.COM.COMException; @@ -57,6 +58,8 @@ public WinNT.HRESULT call() throws Exception { throw new RuntimeException(e); } catch (ExecutionException e) { throw new RuntimeException(e); + } catch (TimeoutException e) { + throw new RuntimeException(e); } } From 201139ca0593c35029ff17c258a1d436185e217b Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Fri, 5 Dec 2014 17:28:27 +0100 Subject: [PATCH 37/49] COM.util bug fix --- contrib/msoffice/jnatest.xls | Bin 22016 -> 28160 bytes contrib/platform/.classpath | 2 +- .../win32/COM/util/CallbackProxy.java | 16 ++++++++-------- maven/com.sun.jna.core/pom.xml | 1 + pom-jna-platform.xml | 4 ++-- pom-jna.xml | 2 +- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/contrib/msoffice/jnatest.xls b/contrib/msoffice/jnatest.xls index 8da722704c14a3e3a60a75eb526105a1a8e2576b..6077e40a432103a9a651ea187b16e50078424fd0 100644 GIT binary patch delta 4175 zcmbVQdu&tJ8UK!bV_!dFC$?kf;W&=%B+kQ$UpSC7BoHX1O-W!-rV^T#-OX2DT` zi6(U2{#-MEUD*oVLt~?KbcJSG$_9c;Y|}L8kTwYf6j;?wn?^_3pCa;%hc- z>W%I__n!0pe&6#voVk;1?k1b}J6AyFDgt$n8H-4b=|H}qDj4Z~TkL;=z#zOT_p16I8PY%tHHA&@YyWiS>)6JxM4 z7iTdD@~(bOb%q9Db(V%}u<8NAvJO1EWJ_n3laZtaABu%;re@s`g-O^2(=bMF0dT-g zU=)pv-CWj+Z)$Y28QBSvOG`ThI~0%`;PSZKO>Vb;u)cl3oBbH5cL>#>0=sN{$ClXe zPPvc^)KIxB)a;k@&^M>5nf19NE}x4G zAM|z&lA30yr$2(`;u@R;n&lo!s0ODD(g{t_CfAnsL9S4;Ek|c(=d#uaG*aZ3wPx{> zVy>4u%9eHKLPKy2Kh{K)-vc||)0Ex6n_oI)DojlMyG) zHfH4VWi;J0+KP)0>kjKccw3Sw#@9*4gg-O2n9VsdX^URPd!|Y}YSv)PU}PnD&}1`P zvr>Pj7wNiyMoWoM{L}EY1+V3R3RjmDF)u0{KEc-vehgQ%yhpYagAJye{KjhnJ#Q?MV~%dL)$&3gI_Bxh%Qn zUg}-E^+$=NLe6q8!%|)&u{>RqHC*~USCbpr+++kp*I#`F@7Gz1OtedoVUZ=nxIb;R z>3Hln(eV zKSA-Hp=XpP*%-uO3UAk!;a3{E+l;hf(jwhG8XFpScE=_rlHzP0i7llil2MwYLoiP1 z>!!B}n805Lo|#330F86XR8n-xQ3c9W0ZGQ`fH6sG`Nd_M=2Rr>&68E7G&!{69`kAhY?aD`A%L<(;r_xhG72^q{QoP0~cEdTfde~p9)I%%YYTEKNrD+bRJX~@#gOmz3QI4jiik-+5lZFoDgxC~M z#FFAJIYgnQ#BxXiVz|TiWU~%d(YY7;W)hND&*zDkkcK|)QO2*^^#e))+VF(0q9aCn zvx_2EjS4Na^9XGnOH7dJfSgNdqzG*#UlUZBF?_wblp^|=Bp**iX%;_~CtoJXb5m(K zzz2=tNHKKKP7B+k(^I?(x5oBSB0A+Tg^uRTc7jY(GNeMJ!gpeQaHK)w=VpqqHM)zI zjacAIG;@xxll298-&2p{nc!L_1GexmIL{hrT5`3pk=kBrU#1qRy-Mv3YO7iR+zeoM z3%(m3tG4hWlyj+afNr>KpVc zY*L5M_XHerI(}eWzRs-2pZ9!HECQ#XD@{SxEk4oz|8fj&_}?6ddn3uscC`0f*f9+B zyUQj>8Q1s{-L$#FJl*`9dK4%7tBiak`}>q$@o;~G_<5JvslCFK3#YgAv4sm;x<17N zuk?D7oBiw#1~!k;3Hr$90SnDA*dCuA-#Z$MCHC^22tKurE4{TWxk-E`1;YN-Zj2?knBf&VO$PK5k?#K-@&@Et`9OA6hL;X1*|kLc3X u|M7=E_E0d={{X-P!V`G0z>j`GQ2cEJJ`fJ5JY22_4-_2GH%YG&4*m_d4T|#s delta 4064 zcmai1eQZ)CN)$N6%c5WjplpLXIe0!g8SB!Ea$$VMq8g%uK>6BEY)$64D* zl>D)(leUiFv#wQIp|Vdt+Ip`|O`rfE}Kwn-by@Xmd996v+U zXWjSiJNKO5`JHp`J-%<|I-7Zo&3YvU>B|aGPhI|gHihuEypD}&%eS(}~*5P`Mygz?+e;Yfx$D4@sFu>l3RN6JxduOih65GT6bMns}mskU-ofmLA(r4CE zmkgB)ulCjH1wOVB??k528qf+?0H?>NALMGqX?8}D*y(j}+Ii9N4pG$8;Kv}q&$Yj! zJHQ{Q?Scbf0Ej<15efOcxL(+S1A+x#5~`RL-w^f_u`bPu``+hBejB^ArFcn`N4)`E zwQ{$cf^d%G3!n@qbg5ChNz9gWWimDc6v8ZLoK`2n8kGP)SKzy}#okfIV08w>zKUP7v9twGfsnQ9~Tx$I*mE_5yDP+sL}>NhvSBJjUFm- z!eGbW8tQchSOE;Jref?8MSRXsfO|xnVKazOlaU8C&CrfFjl~J07LSO7nkEROULVuA z;X&$Fk+mKV8^6X{@I&J>?1#A9RKb3PPn#t6W1KTpv!CEOQ$0I@pO{v&lUSM8#!g{> zUKcz4gXi~+TnSezDqV#7ZYcDY^DQT6-@qeS^&{u>)URVR3s}!AtW{3>q$` z=79&`3A!H=dCOQ)rxm|n?qzNGZh0^B;_ZrF=EGH$omy^%Q{?-o!+~q;bvh0w;5CQ0 zm>m+==b)^_-Htk3<1nVx<|-;NwuF~8h{H!HW>P_TiO6u|FwNgiqa*fa`NjhZo-Mpj#- zlS3bT`UQUMEXBvG%mNLDs~Rh45M+o#9Q*{Tp*ms)1F7D=ahlZf^^d_f*e!RLAA9mWZJOr224RYwyn}1W(XH)9OoQ>s6WL7Szio_c~a@KLi6E&q+ zA=#9Wyiz9@MWjrGcuH#EqIc7xyHcs}>t88O+|>%FD^;a9P@T;wJA@1U@83G7L|x9K z4ra1=ygKFMLbc-Z7^SePCL1N2?uGte-uR1xQlUnfs7ayB)hHdvjb7|65zY6G2npaVPVkoi>UKB-$Dh ztcRs6XHSSfaOU{iX)lu63y=4kb<4%;58%Zcir07Q6t8@eK2xc;FU_XWAGmXVmefnd z8vfVB7ip)fa&eJj#8u6iA4!XT>IznmP0P`EAVJ$Pk+rFr)|E7*qCri4kQ;T>r*Ixi zy?!VC`g(mDqy1hCUj{>HaQn>AsBoH^9N9Z0C&Z`K9)%J`dkQ9Dglg>&$oM_au1*Uy zfeD~nj>*HL(W&T2LOh&fSei6JH|?_+wP6^g{We8y1kX0?I;@4}8BH=F)~RiD8gkZ4 z`qT6eHBRm#ltijlf)-k4^rY|3(bp&Qa`Yv5oF;yE+RhAa9^8g-R23YRZ{=b_F*)2o z&WKn#y7`t}!F*aZl=cm=5qT&Yo=k|_)P6PPNs-KAWF%8cq69FBv#r7I5@@ArM22IL zTQNDhPmW2C$WO%+;wCkKurg^?0LCc9TS|(eu#YDT&oGshI7CF&s;xB^S`yd! zIwiYFg%CeVg(!CZPr@k}D7DVbhj6Av*Uk9<$4b8Svp^+ZLfo1IYo(HMUs&AU+}vZM za+8DMzZau$ISeXMe%#qyxjDJ+#Q6^?Pn^}NTtq4dxvXrT0Bi-wV*Z4xpw7 zFK&DdKk@g{xwJ-;*HEW&3t`l{5{l!L76OfOk|P8OFo4ScC`_ePa+)BLr*E|%DD zUctW^sbYbi8kJ~XU6k)l`d5Lw{A2Uzp2kFHtE%=q%)F1v+v*T;tBaC~woaw{H}W6D{Y z>-t6*QP20{K!cMedP`t8|e9PcsMpOIT4CWTSKAnuqCU+vq;EDU<6&W_Vg*-Fc0KPNz^9U=2g%t?^2 WPG=;LN$Ndh=Ay-m1o1Bwc>fRCu)Dkf diff --git a/contrib/platform/.classpath b/contrib/platform/.classpath index 91a28a2ee6..18570b05fd 100644 --- a/contrib/platform/.classpath +++ b/contrib/platform/.classpath @@ -2,9 +2,9 @@ - + diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index 760b9bd03a..9a2c967522 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -14,7 +14,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Parameter; + import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -148,7 +148,7 @@ public void run() { try { if (CallbackProxy.this.dsipIdMap.containsKey(dispIdMember)) { Method eventMethod = CallbackProxy.this.dsipIdMap.get(dispIdMember); - if (eventMethod.getParameterCount() != jargs.size()) { + if (eventMethod.getParameterTypes().length != jargs.size()) { CallbackProxy.this.comEventCallbackListener.errorReceivingCallbackEvent( "Trying to invoke method " + eventMethod + " with " + jargs.size() + " arguments", null); @@ -156,18 +156,18 @@ public void run() { try { // need to convert arguments maybe List margs = new ArrayList(); - Parameter[] params = eventMethod.getParameters(); - for (int i = 0; i < eventMethod.getParameterCount(); ++i) { - Parameter param = params[i]; + Class[] params = eventMethod.getParameterTypes(); + for (int i = 0; i < eventMethod.getParameterTypes().length; ++i) { + Class paramType = params[i]; Object jobj = jargs.get(i); - if (jobj != null && param.getType().getAnnotation(ComInterface.class) != null) { + if (jobj != null && paramType.getAnnotation(ComInterface.class) != null) { if (jobj instanceof IUnknown) { IUnknown unk = (IUnknown) jobj; - Object mobj = unk.queryInterface(param.getType()); + Object mobj = unk.queryInterface(paramType); margs.add(mobj); } else { throw new RuntimeException("Cannot convert argument " + jobj.getClass() - + " to ComInterface " + param.getType()); + + " to ComInterface " + paramType); } } else { margs.add(jobj); diff --git a/maven/com.sun.jna.core/pom.xml b/maven/com.sun.jna.core/pom.xml index 9c9fbc4418..86a153f07a 100644 --- a/maven/com.sun.jna.core/pom.xml +++ b/maven/com.sun.jna.core/pom.xml @@ -72,6 +72,7 @@ + org.codehaus.mojo build-helper-maven-plugin diff --git a/pom-jna-platform.xml b/pom-jna-platform.xml index 878fa63fb1..c5e12252c5 100644 --- a/pom-jna-platform.xml +++ b/pom-jna-platform.xml @@ -6,7 +6,7 @@ net.java.dev.jna jna-platform - 4.1.0 + 4.1.1-SNAPSHOT jar Java Native Access Platform @@ -46,7 +46,7 @@ net.java.dev.jna jna - 4.1.0 + 4.1.1-SNAPSHOT diff --git a/pom-jna.xml b/pom-jna.xml index 539400b6af..736e7b6241 100644 --- a/pom-jna.xml +++ b/pom-jna.xml @@ -6,7 +6,7 @@ net.java.dev.jna jna - 4.1.0 + 4.1.1-SNAPSHOT jar Java Native Access From 57abe602d07f4f2f91808103e6bb682bebc5ba11 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 9 Dec 2014 10:28:04 +0100 Subject: [PATCH 38/49] ..COM.util: Catch exceptions in ComThread-firstTask forward uncaught exceptions --- .../platform/win32/COM/util/ComThread.java | 27 ++++++++++++------- .../jna/platform/win32/COM/util/Factory.java | 9 ++++--- .../COM/util/ComEventCallbacks_Test.java | 7 ++--- 3 files changed, 27 insertions(+), 16 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java index 7078b47eec..3ac5c13407 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ComThread.java @@ -31,24 +31,30 @@ public class ComThread { Runnable firstTask; boolean requiresInitialisation; long timeoutMilliseconds; + UncaughtExceptionHandler uncaughtExceptionHandler; - public ComThread(final String threadName, long timeoutMilliseconds) { - this(threadName, timeoutMilliseconds, Ole32.COINIT_MULTITHREADED); + public ComThread(final String threadName, long timeoutMilliseconds, UncaughtExceptionHandler uncaughtExceptionHandler) { + this(threadName, timeoutMilliseconds, uncaughtExceptionHandler, Ole32.COINIT_MULTITHREADED); } - public ComThread(final String threadName, long timeoutMilliseconds, final int coinitialiseExFlag) { + public ComThread(final String threadName, long timeoutMilliseconds, UncaughtExceptionHandler uncaughtExceptionHandler, final int coinitialiseExFlag) { this.requiresInitialisation = true; this.timeoutMilliseconds = timeoutMilliseconds; + this.uncaughtExceptionHandler = uncaughtExceptionHandler; this.firstTask = new Runnable() { @Override public void run() { - //If we do not use COINIT_MULTITHREADED, it is necessary to have - // a message loop see - - // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5529/Understanding-COM-Apartments-Part-I.htm] - // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/Understanding-COM-Apartments-Part-II.htm] - WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, coinitialiseExFlag); - COMUtils.checkRC(hr); - ComThread.this.requiresInitialisation = false; + try { + //If we do not use COINIT_MULTITHREADED, it is necessary to have + // a message loop see - + // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5529/Understanding-COM-Apartments-Part-I.htm] + // [http://www.codeguru.com/cpp/com-tech/activex/apts/article.php/c5533/Understanding-COM-Apartments-Part-II.htm] + WinNT.HRESULT hr = Ole32.INSTANCE.CoInitializeEx(null, coinitialiseExFlag); + COMUtils.checkRC(hr); + ComThread.this.requiresInitialisation = false; + } catch (Throwable t) { + ComThread.this.uncaughtExceptionHandler.uncaughtException(Thread.currentThread(), t); + } } }; executor = Executors.newSingleThreadExecutor(new ThreadFactory() { @@ -68,6 +74,7 @@ public Thread newThread(Runnable r) { @Override public void uncaughtException(Thread t, Throwable e) { ComThread.this.requiresInitialisation = true; + ComThread.this.uncaughtExceptionHandler.uncaughtException(t, e); } }); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index f2f756e349..07edeece92 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -12,9 +12,7 @@ */ package com.sun.jna.platform.win32.COM.util; -import java.lang.ref.WeakReference; import java.lang.reflect.Proxy; -import java.util.ArrayList; import java.util.HashSet; import java.util.Set; import java.util.WeakHashMap; @@ -46,7 +44,12 @@ public class Factory { * */ public Factory() { - this(new ComThread("Default Factory COM Thread", 5000)); + this(new ComThread("Default Factory COM Thread", 5000, new Thread.UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + //ignore + } + })); } public Factory(ComThread comThread) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java index cf52440414..8a585af44f 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java @@ -65,6 +65,8 @@ interface ComIApplication extends IUnknown, IConnectionPoint { interface ComIDocuments { @ComMethod ComIDocument Open(String fileName); + @ComMethod + ComIDocument Add(); } @ComInterface(iid="{0002096B-0000-0000-C000-000000000046}") @@ -184,8 +186,7 @@ public void WindowActivate() { wordApp.setVisible(true); ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); wordApp.advise(ApplicationEvents4_Event.class, listener); - - wordApp.getDocuments().Open("C:\\temp\\test.doc"); + wordApp.getDocuments().Add(); //bring word doc to front HWND h = User32.INSTANCE.FindWindow("OpusApp", null); @@ -217,7 +218,7 @@ public void WindowSelectionChanged() { ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); wordApp.advise(ApplicationEvents4_Event.class, listener); - ComIDocument doc = wordApp.getDocuments().Open("C:\\temp\\test.doc"); + ComIDocument doc = wordApp.getDocuments().Add(); doc.Select(); From 280f1e348e48ed679843a30ba92c2f619d2a5acf Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Thu, 18 Dec 2014 10:42:25 +0100 Subject: [PATCH 39/49] ...COM.utild: add capability to return from methods and properties --- .../jna/platform/win32/COM/util/Convert.java | 19 +++++++++++++++++++ .../platform/win32/COM/util/ProxyObject.java | 6 ++++++ 2 files changed, 25 insertions(+) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java index 9dd5180f60..4b0f03a55c 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Convert.java @@ -13,6 +13,8 @@ package com.sun.jna.platform.win32.COM.util; import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Date; @@ -70,4 +72,21 @@ public static Object toJavaObject(VARIANT value) { } return vobj; } + + public static T toComEnum(Class enumType, Object value) { + try { + Method m = enumType.getMethod("values"); + T[] values = (T[])m.invoke(null); + for(T t: values) { + if (value.equals(t.getValue())) { + return t; + } + } + } catch (NoSuchMethodException e) { + } catch (IllegalAccessException e) { + } catch (IllegalArgumentException e) { + } catch (InvocationTargetException e) { + } + return null; + } } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index a07107a7ec..660ddcd9f8 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -319,6 +319,9 @@ public T getProperty(Class returnType, String name, Object... args) { WinNT.HRESULT hr = this.oleMethod(OleAuto.DISPATCH_PROPERTYGET, result, this.getRawDispatch(), name, vargs); COMUtils.checkRC(hr); Object jobj = Convert.toJavaObject(result); + if (IComEnum.class.isAssignableFrom(returnType)) { + return (T)Convert.toComEnum((Class)returnType, jobj); + } if (jobj instanceof IDispatch) { IDispatch d = (IDispatch) jobj; T t = this.factory.createProxy(returnType, d); @@ -345,6 +348,9 @@ public T invokeMethod(Class returnType, String name, Object... args) { COMUtils.checkRC(hr); Object jobj = Convert.toJavaObject(result); + if (IComEnum.class.isAssignableFrom(returnType)) { + return (T)Convert.toComEnum((Class)returnType, jobj); + } if (jobj instanceof IDispatch) { IDispatch d = (IDispatch) jobj; T t = this.factory.createProxy(returnType, d); From 04fa5365bf5ab70eb25731c2a3cb3b9b8d3b9a33 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Mon, 19 Jan 2015 11:02:25 +0100 Subject: [PATCH 40/49] fix null pointer issue in COMException --- .../src/com/sun/jna/platform/win32/COM/COMException.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java index eefc7d6c26..8431a63733 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/COMException.java @@ -72,7 +72,7 @@ public COMException(String message) { */ public COMException(String message, EXCEPINFO pExcepInfo, IntByReference puArgErr) { - super(message + " (puArgErr=" + puArgErr.getValue() + ")"); + super(message + " (puArgErr=" + (null==puArgErr?"":puArgErr.getValue()) + ")"); this.pExcepInfo = pExcepInfo; this.puArgErr = puArgErr; } From 25f1b082f9989a49ac384496341f45a3e895c78a Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Mon, 19 Jan 2015 14:58:59 +0100 Subject: [PATCH 41/49] Improve thread safety --- .../win32/COM/util/CallbackProxy.java | 16 ++++++---- .../platform/win32/COM/util/ProxyObject.java | 13 +++++++-- .../COM/util/ComEventCallbacks_Test.java | 29 +++++++++++++++++++ .../win32/COM/util/ProxyObject_Test.java | 11 +++++++ 4 files changed, 61 insertions(+), 8 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index 9a2c967522..dad5155e5d 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -12,9 +12,9 @@ */ package com.sun.jna.platform.win32.COM.util; +import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; - import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -66,12 +66,18 @@ public CallbackProxy(Factory factory, Class comEventCallbackInterface, this.listenedToRiid = this.createRIID(comEventCallbackInterface); this.dsipIdMap = this.createDispIdMap(comEventCallbackInterface); this.dispatchListener = new DispatchListener(this); - this.executorService = Executors.newCachedThreadPool(new ThreadFactory() { + this.executorService = Executors.newSingleThreadExecutor(new ThreadFactory() { @Override public Thread newThread(Runnable r) { - Thread t = new Thread(r, "COM Event Callback executor"); - t.setDaemon(true); - return t; + Thread thread = new Thread(r, "COM Event Callback executor"); + thread.setDaemon(true); + thread.setUncaughtExceptionHandler(new UncaughtExceptionHandler() { + @Override + public void uncaughtException(Thread t, Throwable e) { + CallbackProxy.this.factory.comThread.uncaughtExceptionHandler.uncaughtException(t, e); + } + }); + return thread; } }); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index 660ddcd9f8..8d7aecb8ff 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -163,9 +163,16 @@ public String toString() { // --------------------- InvocationHandler ----------------------------- @Override - public Object invoke(final Object proxy, final java.lang.reflect.Method method, final Object[] args) - throws Throwable { - + public Object invoke(final Object proxy, final java.lang.reflect.Method method, final Object[] args) throws Throwable { + return this.invokeSynchronised(proxy, method, args); + } + + /* + * may not necessary for this method to be synchronised as all calls to COM are on their + * own , single, thread. However, might be best not to overlap calls to COM object + * with advise,unadvise,queryInterface, etc. + */ + synchronized Object invokeSynchronised(final Object proxy, final java.lang.reflect.Method method, final Object[] args) throws Throwable { if (method.equals(Object.class.getMethod("toString"))) { return this.toString(); } else if (method.equals(Object.class.getMethod("equals", Object.class))) { diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java index 8a585af44f..cc099a13d1 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ComEventCallbacks_Test.java @@ -236,4 +236,33 @@ public void WindowSelectionChanged() { } +// @Test +// public void WindowSelectionChanged_jvmCrash() { +// // Create word object +// ComIMsWordApp wordObj = factory.createObject(ComIMsWordApp.class); +// ComIApplication wordApp = wordObj.queryInterface(ComIApplication.class); +// wordApp.setVisible(true); +// ApplicationEvents4_EventListener listener = new ApplicationEvents4_EventListener(); +// wordApp.advise(ApplicationEvents4_Event.class, listener); +// +// +// +// ComIDocument doc = wordApp.getDocuments().Add(); +// +// doc.Select(); +// +// //Wait for event to happen +// try { +// Thread.sleep(2000000); +// } catch (Exception e) { +// e.printStackTrace(); +// } +// +// Assert.assertNotNull(listener.WindowSelectionChange_called); +// Assert.assertTrue(listener.WindowSelectionChange_called); +// +// wordApp.Quit(false, null, null); +// +// } + } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java index 28374702bf..b402acc11b 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java @@ -104,4 +104,15 @@ public void equals() { comObj1.Quit(false, null,null); } + + @Test + public void accessWhilstDisposing() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + + //TODO: how to test this? + + this.factory.disposeAll(); + + } + } From 756685e633a1f880e569c8ecf403b210b2e8fa88 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Mon, 19 Jan 2015 15:14:03 +0100 Subject: [PATCH 42/49] added use java 1.6 to pom.xml files --- maven/com.sun.jna.core/pom.xml | 12 ++++++++++++ maven/com.sun.jna.platform/.classpath | 18 +++++++++++++++--- .../.settings/org.eclipse.jdt.core.prefs | 3 +++ maven/com.sun.jna.platform/pom.xml | 14 +++++++++++++- 4 files changed, 43 insertions(+), 4 deletions(-) diff --git a/maven/com.sun.jna.core/pom.xml b/maven/com.sun.jna.core/pom.xml index 86a153f07a..10e0c2ef50 100644 --- a/maven/com.sun.jna.core/pom.xml +++ b/maven/com.sun.jna.core/pom.xml @@ -375,6 +375,18 @@ com/sun/jna/linux-ia64/libjnidispatch.so;processor=ia64;osname=linux, + + org.apache.maven.plugins + maven-compiler-plugin + 3.0 + + 1.6 + 1.6 + 1.6 + 1.6 + + + diff --git a/maven/com.sun.jna.platform/.classpath b/maven/com.sun.jna.platform/.classpath index b7019feb04..b089109d64 100644 --- a/maven/com.sun.jna.platform/.classpath +++ b/maven/com.sun.jna.platform/.classpath @@ -2,16 +2,28 @@ - + - + + + + + + + + + + + + + + - diff --git a/maven/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs b/maven/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs index fd9afef6e9..14f521d2ad 100644 --- a/maven/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs +++ b/maven/com.sun.jna.platform/.settings/org.eclipse.jdt.core.prefs @@ -1,2 +1,5 @@ eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/maven/com.sun.jna.platform/pom.xml b/maven/com.sun.jna.platform/pom.xml index 13ccee6033..c2a8515e48 100644 --- a/maven/com.sun.jna.platform/pom.xml +++ b/maven/com.sun.jna.platform/pom.xml @@ -100,7 +100,19 @@ com.sun.jna.platform.win32.COM.wince - + + + org.apache.maven.plugins + maven-compiler-plugin + 3.0 + + 1.6 + 1.6 + 1.6 + 1.6 + + + From d60291b4cab2c69bdb2b91665338401f5b849500 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 20 Jan 2015 17:33:14 +0100 Subject: [PATCH 43/49] ...COM.util: improve equals and hashCode for ProxyObject --- contrib/platform/.classpath | 3 +- .../.settings/org.eclipse.jdt.core.prefs | 11 +++ .../platform/win32/COM/util/ProxyObject.java | 71 ++++++++++++++----- 3 files changed, 66 insertions(+), 19 deletions(-) create mode 100644 contrib/platform/.settings/org.eclipse.jdt.core.prefs diff --git a/contrib/platform/.classpath b/contrib/platform/.classpath index 18570b05fd..77917d7b3f 100644 --- a/contrib/platform/.classpath +++ b/contrib/platform/.classpath @@ -2,9 +2,8 @@ - - + diff --git a/contrib/platform/.settings/org.eclipse.jdt.core.prefs b/contrib/platform/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..54e493c07c --- /dev/null +++ b/contrib/platform/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index 8d7aecb8ff..12551bd5ef 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -63,6 +63,7 @@ public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win3 IRawDispatchHandle { public ProxyObject(Class theInterface, IDispatch rawDispatch, Factory factory) { + this.unknownId = -1; this.rawDispatch = rawDispatch; this.comThread = factory.getComThread(); this.theInterface = theInterface; @@ -70,8 +71,43 @@ public ProxyObject(Class theInterface, IDispatch rawDispatch, Factory factory //make sure dispatch object knows we have a reference to it // (for debug it is usefult to be able to see how many refs are present int n = this.rawDispatch.AddRef(); + this.getUnknownId(); //pre cache it factory.register(this); } + + //cached value of the IUnknown interface pointer + // Rules of COM state that querying for the IUnknown interface must return an identical pointer value + long unknownId; + long getUnknownId() { + if (-1 == this.unknownId) { + try { + + final PointerByReference ppvObject = new PointerByReference(); + +// HRESULT hr = this.comThread.execute(new Callable() { +// @Override +// public HRESULT call() throws Exception { + IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; + HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID.ByValue(iid), ppvObject); +// } +// }); + + if (WinNT.S_OK.equals(hr)) { + Dispatch dispatch = new Dispatch(ppvObject.getValue()); + this.unknownId = Pointer.nativeValue(dispatch.getPointer()); + // QueryInterface returns a COM object pointer with a +1 reference, we must drop one, + // Note: createProxy adds one; + int n = dispatch.Release(); + } else { + String formatMessageFromHR = Kernel32Util.formatMessage(hr); + throw new COMException("getUnknownId: " + formatMessageFromHR); + } + } catch (Exception e) { + throw new COMException("Error occured when trying get Unknown Id ", e); + } + } + return this.unknownId; + } @Override protected void finalize() throws Throwable { @@ -117,26 +153,26 @@ public boolean equals(Object arg) { return false; } else if (arg instanceof ProxyObject) { ProxyObject other = (ProxyObject) arg; - return this.getRawDispatch().equals(other.getRawDispatch()); + return this.getUnknownId() == other.getUnknownId();//this.getRawDispatch().equals(other.getRawDispatch()); } else if (Proxy.isProxyClass(arg.getClass())) { InvocationHandler handler = Proxy.getInvocationHandler(arg); if (handler instanceof ProxyObject) { try { ProxyObject other = (ProxyObject) handler; - - IUnknown unk1 = this.queryInterface(IUnknown.class); - IUnknown unk2 = other.queryInterface(IUnknown.class); - - InvocationHandler h1 = Proxy.getInvocationHandler(unk1); - InvocationHandler h2 = Proxy.getInvocationHandler(unk2); - - ProxyObject po1 = (ProxyObject) h1; - ProxyObject po2 = (ProxyObject) h2; - - IDispatch d1 = po1.getRawDispatch(); - IDispatch d2 = po2.getRawDispatch(); - - return d1.equals(d2); + return this.getUnknownId() == other.getUnknownId(); +// IUnknown unk1 = this.queryInterface(IUnknown.class); +// IUnknown unk2 = other.queryInterface(IUnknown.class); +// +// InvocationHandler h1 = Proxy.getInvocationHandler(unk1); +// InvocationHandler h2 = Proxy.getInvocationHandler(unk2); +// +// ProxyObject po1 = (ProxyObject) h1; +// ProxyObject po2 = (ProxyObject) h2; +// +// IDispatch d1 = po1.getRawDispatch(); +// IDispatch d2 = po2.getRawDispatch(); +// +// return d1.equals(d2); } catch (Exception e) { //if can't do this comparison, return false // (queryInterface may throw if COM objects become invalid) @@ -152,13 +188,14 @@ public boolean equals(Object arg) { @Override public int hashCode() { + return Long.valueOf(this.getUnknownId()).intValue(); // this returns the native pointer peer value - return this.getRawDispatch().hashCode(); + //return this.getRawDispatch().hashCode(); } @Override public String toString() { - return this.theInterface.getName() + "{" + this.hashCode() + "}"; + return this.theInterface.getName() + "{unk=" + this.hashCode() + "}"; } // --------------------- InvocationHandler ----------------------------- From 4e0aa5ed9fb181154d038ac9b8868503d0198609 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Mon, 9 Feb 2015 13:46:40 +0100 Subject: [PATCH 44/49] test update --- .../platform/win32/COM/util/ProxyObject_Test.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java index b402acc11b..1b9994267a 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java @@ -105,6 +105,18 @@ public void equals() { comObj1.Quit(false, null,null); } + @Test + public void notEquals() { + MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); + MsWordApp comObj2 = this.factory.createObject(MsWordApp.class); + + boolean res = comObj1.equals(comObj2); + + assertFalse(res); + + comObj1.Quit(false, null,null); + } + @Test public void accessWhilstDisposing() { MsWordApp comObj1 = this.factory.createObject(MsWordApp.class); From c171c2fbfc1387d77c2a8c688912428fa07f33d8 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Mon, 9 Feb 2015 13:48:16 +0100 Subject: [PATCH 45/49] added a file --- .../.settings/org.eclipse.jdt.core.prefs | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 maven/com.sun.jna.core/.settings/org.eclipse.jdt.core.prefs diff --git a/maven/com.sun.jna.core/.settings/org.eclipse.jdt.core.prefs b/maven/com.sun.jna.core/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..54e493c07c --- /dev/null +++ b/maven/com.sun.jna.core/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 From af5db876df1e15f2abfd127fa2c756d33a0e5b3a Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Mon, 9 Feb 2015 13:53:04 +0100 Subject: [PATCH 46/49] header comment modification --- .../platform/win32/COM/util/annotation/ComEventCallback.java | 2 +- .../jna/platform/win32/COM/util/annotation/ComInterface.java | 2 +- .../sun/jna/platform/win32/COM/util/annotation/ComMethod.java | 2 +- .../sun/jna/platform/win32/COM/util/annotation/ComObject.java | 2 +- .../sun/jna/platform/win32/COM/util/annotation/ComProperty.java | 2 +- .../com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java | 2 +- .../jna/platform/win32/COM/util/RunningObjectTable_Test.java | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java index 2a938219e2..ad72ce7ccc 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComEventCallback.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java index b5a1081349..ff4f898c71 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComInterface.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java index 4b8739b710..ce8e4e8c20 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComMethod.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java index 3768b29aa1..fea5158b75 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComObject.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java index 7f447cb712..6104c1dbaa 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/annotation/ComProperty.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java index 1b9994267a..30a55dc892 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/ProxyObject_Test.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java index 9beff858c4..544bec0365 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/COM/util/RunningObjectTable_Test.java @@ -1,4 +1,4 @@ -/* Copyright (c) 2014 Dr David H. Akehurst, All Rights Reserved +/* Copyright (c) 2014 Dr David H. Akehurst (itemis), All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public From ce7a46348454b34b78ac52512dff6dc1225669c0 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Tue, 10 Feb 2015 10:17:30 +0100 Subject: [PATCH 47/49] minor modifications --- .../COM/util/office/MSOfficeWordDemo.java | 23 ++++++++------ .../jna/platform/win32/COM/util/Factory.java | 2 -- .../platform/win32/COM/util/ProxyObject.java | 31 +++++-------------- .../src/com/sun/jna/platform/win32/Ole32.java | 2 +- .../com/sun/jna/platform/win32/GuidTest.java | 14 +++++++++ 5 files changed, 35 insertions(+), 37 deletions(-) diff --git a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java index c3704d2111..f03467993f 100644 --- a/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java +++ b/contrib/msoffice/src/com/sun/jna/platform/win32/COM/util/office/MSOfficeWordDemo.java @@ -41,6 +41,9 @@ public void testMSWord() { ComIApplication msWord = null; Factory factory = null; try { + String tempDir = System.getProperty("java.io.tmpdir"); + System.out.println("Files in temp dir: "+tempDir); + factory = new Factory(); msWordObject = factory.createObject(ComWord_Application.class); msWord = msWordObject.queryInterface(ComIApplication.class); @@ -55,10 +58,10 @@ public void testMSWord() { Thread.sleep(1000); // save in different formats // pdf format is only supported in MSWord 2007 and above - msWord.getActiveDocument().SaveAs("C:\\TEMP\\jnatestSaveAs.doc", WdSaveFormat.wdFormatDocument); - msWord.getActiveDocument().SaveAs("C:\\TEMP\\jnatestSaveAs.pdf", WdSaveFormat.wdFormatPDF); - msWord.getActiveDocument().SaveAs("C:\\TEMP\\jnatestSaveAs.rtf", WdSaveFormat.wdFormatRTF); - msWord.getActiveDocument().SaveAs("C:\\TEMP\\jnatestSaveAs.html", WdSaveFormat.wdFormatHTML); + msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.doc", WdSaveFormat.wdFormatDocument); + msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.pdf", WdSaveFormat.wdFormatPDF); + msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.rtf", WdSaveFormat.wdFormatRTF); + msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestSaveAs.html", WdSaveFormat.wdFormatHTML); // close and save the document msWord.getActiveDocument().Close(false); msWord.getDocuments().Add(); @@ -67,17 +70,17 @@ public void testMSWord() { .TypeText( "Hello from JNA! \n Please notice that JNA can control MS Word via the new COM interface! \nHere we are creating a new word document and we save it to the 'TEMP' directory!"); // save with no user prompt - msWord.getActiveDocument().SaveAs("C:\\TEMP\\jnatestNewDoc1.docx", WdSaveFormat.wdFormatDocumentDefault); - msWord.getActiveDocument().SaveAs("C:\\TEMP\\jnatestNewDoc2.docx", WdSaveFormat.wdFormatDocumentDefault); - msWord.getActiveDocument().SaveAs("C:\\TEMP\\jnatestNewDoc3.docx", WdSaveFormat.wdFormatDocumentDefault); + msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc1.docx", WdSaveFormat.wdFormatDocumentDefault); + msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc2.docx", WdSaveFormat.wdFormatDocumentDefault); + msWord.getActiveDocument().SaveAs(tempDir+"\\jnatestNewDoc3.docx", WdSaveFormat.wdFormatDocumentDefault); // close and save the document msWord.getActiveDocument().Close(false); // open 3 documents - msWord.getDocuments().Open("C:\\TEMP\\jnatestNewDoc1.docx"); + msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc1.docx"); msWord.getSelection().TypeText("Hello some changes from JNA!\n"); - msWord.getDocuments().Open("C:\\TEMP\\jnatestNewDoc2.docx"); + msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc2.docx"); msWord.getSelection().TypeText("Hello some changes from JNA!\n"); - msWord.getDocuments().Open("C:\\TEMP\\jnatestNewDoc3.docx"); + msWord.getDocuments().Open(tempDir+"\\jnatestNewDoc3.docx"); msWord.getSelection().TypeText("Hello some changes from JNA!\n"); // save the document and prompt the user msWord.getDocuments().Save(false, WdOriginalFormat.wdPromptUser); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 07edeece92..46be984b48 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -36,8 +36,6 @@ public class Factory { - //public static Factory INSTANCE = new Factory(); - /** * Creates a utility COM Factory and a ComThread on which all COM calls are executed. * NOTE: Remember to call factory.getComThread().terminate() at some appropriate point. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index 12551bd5ef..b12fc5e18f 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -56,8 +56,9 @@ import com.sun.jna.ptr.PointerByReference; /** - * Ole32.INSTANCE.CoInitialize must be called on the current thread before using - * this object + * This object acts as the invocation handler for interfaces annotated with ComInterface. + * It wraps all (necessary) low level COM calls and executes them on a 'ComThread' held by + * the Factory object. */ public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win32.COM.util.IDispatch, IRawDispatchHandle { @@ -84,13 +85,8 @@ long getUnknownId() { final PointerByReference ppvObject = new PointerByReference(); -// HRESULT hr = this.comThread.execute(new Callable() { -// @Override -// public HRESULT call() throws Exception { - IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; - HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID.ByValue(iid), ppvObject); -// } -// }); + IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; + HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID.ByValue(iid), ppvObject); if (WinNT.S_OK.equals(hr)) { Dispatch dispatch = new Dispatch(ppvObject.getValue()); @@ -153,26 +149,13 @@ public boolean equals(Object arg) { return false; } else if (arg instanceof ProxyObject) { ProxyObject other = (ProxyObject) arg; - return this.getUnknownId() == other.getUnknownId();//this.getRawDispatch().equals(other.getRawDispatch()); + return this.getUnknownId() == other.getUnknownId(); } else if (Proxy.isProxyClass(arg.getClass())) { InvocationHandler handler = Proxy.getInvocationHandler(arg); if (handler instanceof ProxyObject) { try { ProxyObject other = (ProxyObject) handler; return this.getUnknownId() == other.getUnknownId(); -// IUnknown unk1 = this.queryInterface(IUnknown.class); -// IUnknown unk2 = other.queryInterface(IUnknown.class); -// -// InvocationHandler h1 = Proxy.getInvocationHandler(unk1); -// InvocationHandler h2 = Proxy.getInvocationHandler(unk2); -// -// ProxyObject po1 = (ProxyObject) h1; -// ProxyObject po2 = (ProxyObject) h2; -// -// IDispatch d1 = po1.getRawDispatch(); -// IDispatch d2 = po2.getRawDispatch(); -// -// return d1.equals(d2); } catch (Exception e) { //if can't do this comparison, return false // (queryInterface may throw if COM objects become invalid) @@ -207,7 +190,7 @@ public Object invoke(final Object proxy, final java.lang.reflect.Method method, /* * may not necessary for this method to be synchronised as all calls to COM are on their * own , single, thread. However, might be best not to overlap calls to COM object - * with advise,unadvise,queryInterface, etc. + * with advise, unadvise, queryInterface, etc. */ synchronized Object invokeSynchronised(final Object proxy, final java.lang.reflect.Method method, final Object[] args) throws Throwable { if (method.equals(Object.class.getMethod("toString"))) { diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java index 4000a1b38d..e344d394c3 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Ole32.java @@ -268,7 +268,7 @@ HRESULT CoCreateInstance(GUID rclsid, Pointer pUnkOuter, int dwClsContext, void CoTaskMemFree(Pointer pv); /** - * Retrieves a pointer to the default OLE task memory allocator + * Retrieves a pointer to the default OLE task memory allocator. * * {@code * HRESULT CoGetMalloc( diff --git a/contrib/platform/test/com/sun/jna/platform/win32/GuidTest.java b/contrib/platform/test/com/sun/jna/platform/win32/GuidTest.java index b5bb00b3b3..c474981348 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/GuidTest.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/GuidTest.java @@ -126,4 +126,18 @@ public void testNewGuid() { assertEquals(guidFromString.toGuidString(), guidString); } + + /** + * Tests the GUID.ByValue. + */ + public void testGuidByValue() { + GUID newGuid = GUID.newGuid(); + String guidString = newGuid.toGuidString(); + + GUID.ByValue bv = new GUID.ByValue(newGuid); + + String guidBV = bv.toGuidString(); + + assertEquals(guidBV, guidString); + } } From 293a62e0589fc8ada3d0d5038dabd9ba54e20b7a Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Fri, 20 Feb 2015 09:01:49 +0100 Subject: [PATCH 48/49] ...COM.util: added changes to CHANGES.md (fixed a bug in ProxyObject) --- CHANGES.md | 4 + .../win32/COM/util/CallbackProxy.java | 9 +- .../jna/platform/win32/COM/util/Factory.java | 14 +++ .../platform/win32/COM/util/ProxyObject.java | 108 ++++++++++++------ 4 files changed, 99 insertions(+), 36 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 514c259fc0..b51f00ed9b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,10 @@ Release 4.2 Features -------- +* Significant enhancements to COM support under com.sun.jna.platform.win32.COM.util, - [@dhakehurst](https://github.com/dhakehurst) + * Use of interfaces and annotations to provide easier implementation of COM interfaces (uses InvocationHandler). - [@dhakehurst](https://github.com/dhakehurst) + * Support for COM event callbacks (this was particularly tricky, very happy I got it to work). - [@dhakehurst](https://github.com/dhakehurst) + * Support for COM interface discovery by iteration over the RunningObjectTable. - [@dhakehurst](https://github.com/dhakehurst) * Updated AIX natives and build - [@twall](https://github.com/twall). * [#290](https://github.com/twall/jna/pull/290): Improved the stacktrace for the exceptions thrown by `com.sun.jna.Structure` - [@ebourg](https://github.com/ebourg). * [#332](https://github.com/twall/jna/pull/332): Added Win32 Monitor Configuration API in `com.sun.jna.platform.win32.Dxva2` - [@msteiger](https://github.com/msteiger). diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java index dad5155e5d..7a8ccc31ee 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/CallbackProxy.java @@ -139,8 +139,15 @@ void invokeOnThread(final DISPID dispIdMember, final REFIID.ByValue riid, LCID l Object jarg = Convert.toJavaObject(varg); if (jarg instanceof IDispatch) { IDispatch dispatch = (IDispatch) jarg; + //get raw IUnknown interface + PointerByReference ppvObject = new PointerByReference(); + IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; + dispatch.QueryInterface(new REFIID.ByValue(iid), ppvObject); + Unknown rawUnk = new Unknown(ppvObject.getValue()); + long unknownId = Pointer.nativeValue( rawUnk.getPointer() ); + int n = rawUnk.Release(); //Note: unlike in other places, there is currently no COM ref already added for this pointer - IUnknown unk = CallbackProxy.this.factory.createProxy(IUnknown.class, dispatch); + IUnknown unk = CallbackProxy.this.factory.createProxy(IUnknown.class, unknownId, dispatch); rjargs.add(unk); } else { rjargs.add(jarg); diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java index 46be984b48..e14a88624b 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/Factory.java @@ -112,6 +112,20 @@ public T createProxy(Class comInterface, IDispatch dispatch) { return result; } + /** only for use when creating ProxyObjects from Callbacks + * + * @param comInterface + * @param unk + * @param dispatch + * @return + */ + T createProxy(Class comInterface, long unknownId, IDispatch dispatch) { + ProxyObject jop = new ProxyObject(comInterface, unknownId, dispatch, this); + Object proxy = Proxy.newProxyInstance(comInterface.getClassLoader(), new Class[] { comInterface }, jop); + T result = comInterface.cast(proxy); + return result; + } + /** * Creates a new COM object (CoCreateInstance) for the given progId and * returns a ProxyObject for the given interface. diff --git a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java index b12fc5e18f..1aca3177ae 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/COM/util/ProxyObject.java @@ -49,6 +49,7 @@ import com.sun.jna.platform.win32.COM.Dispatch; import com.sun.jna.platform.win32.COM.IDispatch; import com.sun.jna.platform.win32.COM.IDispatchCallback; +import com.sun.jna.platform.win32.COM.Unknown; import com.sun.jna.platform.win32.COM.util.annotation.ComInterface; import com.sun.jna.platform.win32.COM.util.annotation.ComMethod; import com.sun.jna.platform.win32.COM.util.annotation.ComProperty; @@ -56,9 +57,9 @@ import com.sun.jna.ptr.PointerByReference; /** - * This object acts as the invocation handler for interfaces annotated with ComInterface. - * It wraps all (necessary) low level COM calls and executes them on a 'ComThread' held by - * the Factory object. + * This object acts as the invocation handler for interfaces annotated with + * ComInterface. It wraps all (necessary) low level COM calls and executes them + * on a 'ComThread' held by the Factory object. */ public class ProxyObject implements InvocationHandler, com.sun.jna.platform.win32.COM.util.IDispatch, IRawDispatchHandle { @@ -69,29 +70,61 @@ public ProxyObject(Class theInterface, IDispatch rawDispatch, Factory factory this.comThread = factory.getComThread(); this.theInterface = theInterface; this.factory = factory; - //make sure dispatch object knows we have a reference to it + // make sure dispatch object knows we have a reference to it + // (for debug it is usefult to be able to see how many refs are present + int n = this.rawDispatch.AddRef(); + this.getUnknownId(); // pre cache/calculate it + factory.register(this); + } + + /** when proxy is created for arguments on a call back, they are already on the + * com thread, and hence calling 'getUnknownId' will not work as it uses the ComThread + * however, the unknown pointer value is passed in; + * + * @param theInterface + * @param rawUnk + * @param rawDispatch + * @param factory + */ + ProxyObject(Class theInterface, long unknownId, IDispatch rawDispatch, Factory factory) { + this.unknownId = unknownId; + this.rawDispatch = rawDispatch; + this.comThread = factory.getComThread(); + this.theInterface = theInterface; + this.factory = factory; + // make sure dispatch object knows we have a reference to it // (for debug it is usefult to be able to see how many refs are present int n = this.rawDispatch.AddRef(); - this.getUnknownId(); //pre cache it factory.register(this); } - //cached value of the IUnknown interface pointer - // Rules of COM state that querying for the IUnknown interface must return an identical pointer value + // cached value of the IUnknown interface pointer + // Rules of COM state that querying for the IUnknown interface must return + // an identical pointer value long unknownId; + long getUnknownId() { if (-1 == this.unknownId) { try { - + final PointerByReference ppvObject = new PointerByReference(); - - IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; - HRESULT hr = ProxyObject.this.getRawDispatch().QueryInterface(new REFIID.ByValue(iid), ppvObject); - + + Thread current = Thread.currentThread(); + String tn = current.getName(); + + HRESULT hr = this.comThread.execute(new Callable() { + @Override + public HRESULT call() throws Exception { + IID iid = com.sun.jna.platform.win32.COM.IUnknown.IID_IUNKNOWN; + return ProxyObject.this.getRawDispatch().QueryInterface(new REFIID.ByValue(iid), ppvObject); + } + }); + if (WinNT.S_OK.equals(hr)) { Dispatch dispatch = new Dispatch(ppvObject.getValue()); this.unknownId = Pointer.nativeValue(dispatch.getPointer()); - // QueryInterface returns a COM object pointer with a +1 reference, we must drop one, + // QueryInterface returns a COM object pointer with a +1 + // reference, we must drop one, // Note: createProxy adds one; int n = dispatch.Release(); } else { @@ -111,16 +144,16 @@ protected void finalize() throws Throwable { } public void dispose(int r) { - if (((Dispatch)this.rawDispatch).getPointer().equals(Pointer.NULL)) { - //do nothing, already disposed + if (((Dispatch) this.rawDispatch).getPointer().equals(Pointer.NULL)) { + // do nothing, already disposed } else { - for (int i=0; i T getProperty(Class returnType, String name, Object... args) { COMUtils.checkRC(hr); Object jobj = Convert.toJavaObject(result); if (IComEnum.class.isAssignableFrom(returnType)) { - return (T)Convert.toComEnum((Class)returnType, jobj); + return (T) Convert.toComEnum((Class) returnType, jobj); } if (jobj instanceof IDispatch) { IDispatch d = (IDispatch) jobj; T t = this.factory.createProxy(returnType, d); - //must release a COM reference, createProxy adds one, as does the call + // must release a COM reference, createProxy adds one, as does the + // call int n = d.Release(); return t; } @@ -376,12 +412,13 @@ public T invokeMethod(Class returnType, String name, Object... args) { Object jobj = Convert.toJavaObject(result); if (IComEnum.class.isAssignableFrom(returnType)) { - return (T)Convert.toComEnum((Class)returnType, jobj); + return (T) Convert.toComEnum((Class) returnType, jobj); } if (jobj instanceof IDispatch) { IDispatch d = (IDispatch) jobj; T t = this.factory.createProxy(returnType, d); - //must release a COM reference, createProxy adds one, as does the call + // must release a COM reference, createProxy adds one, as does the + // call int n = d.Release(); return t; } @@ -409,7 +446,8 @@ public HRESULT call() throws Exception { if (WinNT.S_OK.equals(hr)) { Dispatch dispatch = new Dispatch(ppvObject.getValue()); T t = this.factory.createProxy(comInterface, dispatch); - // QueryInterface returns a COM object pointer with a +1 reference, we must drop one, + // QueryInterface returns a COM object pointer with a +1 + // reference, we must drop one, // Note: createProxy adds one; int n = dispatch.Release(); return t; From 57aeb2f3c561a2eccd60df745b948a6b160402f6 Mon Sep 17 00:00:00 2001 From: "Dr. David H. Akehurst" Date: Wed, 4 Mar 2015 10:38:44 +0100 Subject: [PATCH 49/49] updated full stops --- CHANGES.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGES.md b/CHANGES.md index 2575333c47..c36e1a1164 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,10 +7,10 @@ Release 4.2 Features -------- -* Significant enhancements to COM support under com.sun.jna.platform.win32.COM.util, - [@dhakehurst](https://github.com/dhakehurst) - * Use of interfaces and annotations to provide easier implementation of COM interfaces (uses InvocationHandler). - [@dhakehurst](https://github.com/dhakehurst) - * Support for COM event callbacks (this was particularly tricky, very happy I got it to work). - [@dhakehurst](https://github.com/dhakehurst) - * Support for COM interface discovery by iteration over the RunningObjectTable. - [@dhakehurst](https://github.com/dhakehurst) +* Significant enhancements to COM support under com.sun.jna.platform.win32.COM.util - [@dhakehurst](https://github.com/dhakehurst). + * Use of interfaces and annotations to provide easier implementation of COM interfaces (uses InvocationHandler) - [@dhakehurst](https://github.com/dhakehurst). + * Support for COM event callbacks (this was particularly tricky, very happy I got it to work) - [@dhakehurst](https://github.com/dhakehurst). + * Support for COM interface discovery by iteration over the RunningObjectTable - [@dhakehurst](https://github.com/dhakehurst). * Updated AIX natives and build - [@twall](https://github.com/twall). * [#290](https://github.com/twall/jna/pull/290): Improved the stacktrace for the exceptions thrown by `com.sun.jna.Structure` - [@ebourg](https://github.com/ebourg). * [#332](https://github.com/twall/jna/pull/332): Added Win32 Monitor Configuration API in `com.sun.jna.platform.win32.Dxva2` - [@msteiger](https://github.com/msteiger).