1 /*
2  * The contents of this file is dual-licensed under 2
3  * alternative Open Source/Free licenses: LGPL 2.1 or later and
4  * Apache License 2.0. (starting with JNA version 4.0.0).
5  *
6  * You can freely decide which license you want to apply to
7  * the project.
8  *
9  * You may obtain a copy of the LGPL License at:
10  *
11  * http://www.gnu.org/licenses/licenses.html
12  *
13  * A copy is also included in the downloadable source code package
14  * containing JNA, in file "LGPL2.1".
15  *
16  * You may obtain a copy of the Apache License at:
17  *
18  * http://www.apache.org/licenses/
19  *
20  * A copy is also included in the downloadable source code package
21  * containing JNA, in file "AL2.0".
22  */
23 package com.sun.jna.platform.win32;
24 
25 import java.util.List;
26 
27 import com.sun.jna.IntegerType;
28 import com.sun.jna.Memory;
29 import com.sun.jna.NativeLong;
30 import com.sun.jna.Pointer;
31 import com.sun.jna.Structure;
32 import com.sun.jna.Structure.FieldOrder;
33 import com.sun.jna.Union;
34 import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR;
35 import com.sun.jna.platform.win32.COM.COMUtils;
36 import com.sun.jna.platform.win32.COM.Dispatch;
37 import com.sun.jna.platform.win32.Guid.GUID;
38 import com.sun.jna.platform.win32.Variant.VARIANT;
39 import com.sun.jna.platform.win32.Variant.VariantArg;
40 import com.sun.jna.platform.win32.WTypes.BSTR;
41 import com.sun.jna.platform.win32.WTypes.LPOLESTR;
42 import com.sun.jna.platform.win32.WTypes.VARTYPE;
43 import com.sun.jna.platform.win32.WinDef.BYTE;
44 import com.sun.jna.platform.win32.WinDef.DWORD;
45 import com.sun.jna.platform.win32.WinDef.DWORDByReference;
46 import com.sun.jna.platform.win32.WinDef.LCID;
47 import com.sun.jna.platform.win32.WinDef.LONG;
48 import com.sun.jna.platform.win32.WinDef.LONGLONG;
49 import com.sun.jna.platform.win32.WinDef.PVOID;
50 import com.sun.jna.platform.win32.WinDef.SCODE;
51 import com.sun.jna.platform.win32.WinDef.SHORT;
52 import com.sun.jna.platform.win32.WinDef.ULONG;
53 import com.sun.jna.platform.win32.WinDef.ULONGLONG;
54 import com.sun.jna.platform.win32.WinDef.USHORT;
55 import com.sun.jna.platform.win32.WinDef.WORD;
56 import com.sun.jna.platform.win32.COM.TypeComp;
57 import com.sun.jna.platform.win32.COM.Unknown;
58 import static com.sun.jna.platform.win32.Variant.VT_BOOL;
59 import static com.sun.jna.platform.win32.Variant.VT_BSTR;
60 import static com.sun.jna.platform.win32.Variant.VT_CY;
61 import static com.sun.jna.platform.win32.Variant.VT_DATE;
62 import static com.sun.jna.platform.win32.Variant.VT_DECIMAL;
63 import static com.sun.jna.platform.win32.Variant.VT_DISPATCH;
64 import static com.sun.jna.platform.win32.Variant.VT_ERROR;
65 import static com.sun.jna.platform.win32.Variant.VT_I1;
66 import static com.sun.jna.platform.win32.Variant.VT_I2;
67 import static com.sun.jna.platform.win32.Variant.VT_I4;
68 import static com.sun.jna.platform.win32.Variant.VT_INT;
69 import static com.sun.jna.platform.win32.Variant.VT_R4;
70 import static com.sun.jna.platform.win32.Variant.VT_R8;
71 import static com.sun.jna.platform.win32.Variant.VT_RECORD;
72 import static com.sun.jna.platform.win32.Variant.VT_UI1;
73 import static com.sun.jna.platform.win32.Variant.VT_UI2;
74 import static com.sun.jna.platform.win32.Variant.VT_UI4;
75 import static com.sun.jna.platform.win32.Variant.VT_UINT;
76 import static com.sun.jna.platform.win32.Variant.VT_UNKNOWN;
77 import static com.sun.jna.platform.win32.Variant.VT_VARIANT;
78 import com.sun.jna.ptr.ByReference;
79 import com.sun.jna.ptr.PointerByReference;
80 import java.io.Closeable;
81 import java.util.Date;
82 
83 /**
84  * The Interface OaIdl.
85  */
86 public interface OaIdl {
87 
88     // The DATE Type is defined in localtime and the java Date type always contains
89     // a a timezone offset, so the difference has to be calculated and can't be
90     // predetermined
91     public static final long DATE_OFFSET = new Date(1899 - 1900, 12 - 1, 30, 0, 0, 0).getTime();
92 
93     /**
94      * The Class EXCEPINFO.
95      */
96     @FieldOrder({"wCode", "wReserved", "bstrSource", "bstrDescription",
97         "bstrHelpFile", "dwHelpContext", "pvReserved", "pfnDeferredFillIn",
98         "scode"})
99     public static class EXCEPINFO extends Structure {
100 
101         /**
102          * The Class ByReference.
103          */
104         public static class ByReference extends EXCEPINFO implements
105                 Structure.ByReference {
106         }
107 
108         /** The w code. */
109         public WORD wCode;
110 
111         /** The w reserved. */
112         public WORD wReserved;
113 
114         /** The bstr source. */
115         public BSTR bstrSource;
116 
117         /** The bstr description. */
118         public BSTR bstrDescription;
119 
120         /** The bstr help file. */
121         public BSTR bstrHelpFile;
122 
123         /** The dw help context. */
124         public DWORD dwHelpContext;
125 
126         /** The pv reserved. */
127         public PVOID pvReserved;
128 
129         /** The pfn deferred fill in. */
130         public EXCEPINFO.ByReference pfnDeferredFillIn;
131 
132         /** The scode. */
133         public SCODE scode;
134 
135         /**
136          * Instantiates a new excepinfo.
137          */
EXCEPINFO()138         public EXCEPINFO() {
139             super();
140         }
141 
142         /**
143          * Instantiates a new excepinfo.
144          *
145          * @param p
146          *            the p
147          */
EXCEPINFO(Pointer p)148         public EXCEPINFO(Pointer p) {
149             super(p);
150         }
151     }
152 
153     public static class VARIANT_BOOL extends IntegerType {
154         private static final long serialVersionUID = 1L;
155         public static final int SIZE = 2;
156 
VARIANT_BOOL()157         public VARIANT_BOOL() {
158             this(0);
159         }
160 
VARIANT_BOOL(long value)161         public VARIANT_BOOL(long value) {
162             super(2, value);
163         }
164 
VARIANT_BOOL(boolean value)165         public VARIANT_BOOL(boolean value) {
166             this(value ? 0xFFFF : 0x0000);
167         }
168 
booleanValue()169         public boolean booleanValue() {
170             return shortValue() != 0x0000;
171         }
172     }
173 
174     public static class _VARIANT_BOOL extends VARIANT_BOOL {
175         private static final long serialVersionUID = 1L;
176 
_VARIANT_BOOL()177         public _VARIANT_BOOL() {
178             this(0);
179         }
180 
_VARIANT_BOOL(long value)181         public _VARIANT_BOOL(long value) {
182             super(value);
183         }
184     }
185 
186     public static class VARIANT_BOOLByReference extends ByReference {
VARIANT_BOOLByReference()187         public VARIANT_BOOLByReference() {
188             this(new VARIANT_BOOL(0));
189         }
190 
VARIANT_BOOLByReference(VARIANT_BOOL value)191         public VARIANT_BOOLByReference(VARIANT_BOOL value) {
192             super(VARIANT_BOOL.SIZE);
193             setValue(value);
194         }
195 
setValue(VARIANT_BOOL value)196         public void setValue(VARIANT_BOOL value) {
197             getPointer().setShort(0, value.shortValue());
198         }
199 
getValue()200         public VARIANT_BOOL getValue() {
201             return new VARIANT_BOOL(getPointer().getShort(0));
202         }
203     }
204 
205     public static class _VARIANT_BOOLByReference extends ByReference {
_VARIANT_BOOLByReference()206         public _VARIANT_BOOLByReference() {
207             this(new VARIANT_BOOL(0));
208         }
209 
_VARIANT_BOOLByReference(VARIANT_BOOL value)210         public _VARIANT_BOOLByReference(VARIANT_BOOL value) {
211             super(VARIANT_BOOL.SIZE);
212             setValue(value);
213         }
214 
setValue(VARIANT_BOOL value)215         public void setValue(VARIANT_BOOL value) {
216             getPointer().setShort(0, value.shortValue());
217         }
218 
getValue()219         public VARIANT_BOOL getValue() {
220             return new VARIANT_BOOL(getPointer().getShort(0));
221         }
222     }
223 
224     @FieldOrder({"date"})
225     public static class DATE extends Structure {
226         private final static long MICRO_SECONDS_PER_DAY = 24L * 60L * 60L * 1000L;
227 
228         public static class ByReference extends DATE implements
229                 Structure.ByReference {
230         }
231 
232         public double date;
233 
DATE()234         public DATE() {
235             super();
236         }
237 
DATE(double date)238         public DATE(double date) {
239             this.date = date;
240         }
241 
DATE(Date javaDate)242         public DATE(Date javaDate) {
243             setFromJavaDate(javaDate);
244         }
245 
getAsJavaDate()246         public Date getAsJavaDate() {
247             long days = (((long) this.date) * MICRO_SECONDS_PER_DAY) + DATE_OFFSET;
248             double timePart = 24 * Math.abs(this.date - ((long) this.date));
249             int hours = (int) timePart;
250             timePart = 60 * (timePart - ((int) timePart));
251             int minutes = (int) timePart;
252             timePart = 60 * (timePart - ((int) timePart));
253             int seconds = (int) timePart;
254             timePart = 1000 * (timePart - ((int) timePart));
255             int milliseconds = (int) timePart;
256 
257             Date baseDate = new Date(days);
258             baseDate.setHours(hours);
259             baseDate.setMinutes(minutes);
260             baseDate.setSeconds(seconds);
261             baseDate.setTime(baseDate.getTime() + milliseconds);
262             return baseDate;
263         }
264 
setFromJavaDate(Date javaDate)265         public void setFromJavaDate(Date javaDate) {
266             double msSinceOrigin = javaDate.getTime() - DATE_OFFSET;
267             double daysAsFract = msSinceOrigin / MICRO_SECONDS_PER_DAY;
268 
269             Date dayDate = new Date(javaDate.getTime());
270             dayDate.setHours(0);
271             dayDate.setMinutes(0);
272             dayDate.setSeconds(0);
273             dayDate.setTime(dayDate.getTime() / 1000 * 1000); // Clear milliseconds
274 
275             double integralPart = Math.floor(daysAsFract);
276             double fractionalPart = Math.signum(daysAsFract) * ((javaDate.getTime() - dayDate.getTime()) / (24d * 60 * 60 * 1000));
277 
278             this.date = integralPart + fractionalPart;
279         }
280     }
281 
282     /**
283      * The Class DISPID.
284      */
285     public static class DISPID extends LONG {
286         private static final long serialVersionUID = 1L;
287 
DISPID()288         public DISPID() {
289             this(0);
290         }
291 
DISPID(int value)292         public DISPID(int value) {
293             super(value);
294         }
295     }
296 
297     public static class DISPIDByReference extends ByReference {
DISPIDByReference()298         public DISPIDByReference() {
299             this(new DISPID(0));
300         }
301 
DISPIDByReference(DISPID value)302         public DISPIDByReference(DISPID value) {
303             super(DISPID.SIZE);
304             setValue(value);
305         }
306 
setValue(DISPID value)307         public void setValue(DISPID value) {
308             getPointer().setInt(0, value.intValue());
309         }
310 
getValue()311         public DISPID getValue() {
312             return new DISPID(getPointer().getInt(0));
313         }
314     }
315 
316     public static class MEMBERID extends DISPID {
317         private static final long serialVersionUID = 1L;
318 
MEMBERID()319         public MEMBERID() {
320             this(0);
321         }
322 
MEMBERID(int value)323         public MEMBERID(int value) {
324             super(value);
325         }
326     }
327 
328     public static class MEMBERIDByReference extends ByReference {
MEMBERIDByReference()329         public MEMBERIDByReference() {
330             this(new MEMBERID(0));
331         }
332 
MEMBERIDByReference(MEMBERID value)333         public MEMBERIDByReference(MEMBERID value) {
334             super(MEMBERID.SIZE);
335             setValue(value);
336         }
337 
setValue(MEMBERID value)338         public void setValue(MEMBERID value) {
339             getPointer().setInt(0, value.intValue());
340         }
341 
getValue()342         public MEMBERID getValue() {
343             return new MEMBERID(getPointer().getInt(0));
344         }
345     }
346 
347     // The Collect property. You use this property if the method you are calling
348     // through Invoke is an accessor function.
349     /** The Constant DISPID_COLLECT. */
350     public final static DISPID DISPID_COLLECT = new DISPID(-8);
351 
352     // The C++ constructor function for the object.
353     /** The Constant DISPID_CONSTRUCTOR. */
354     public final static DISPID DISPID_CONSTRUCTOR = new DISPID(-6);
355 
356     // The C++ destructor function for the object.
357     /** The Constant DISPID_DESTRUCTOR. */
358     public final static DISPID DISPID_DESTRUCTOR = new DISPID(-7);
359 
360     // The Evaluate method. This method is implicitly invoked when the ActiveX
361     // client encloses the arguments in square brackets. For example, the
362     // following two lines are equivalent:
363     /** The Constant DISPID_EVALUATE. */
364     public final static DISPID DISPID_EVALUATE = new DISPID(-5);
365 
366     // The _NewEnum property. This special, restricted property is required for
367     // collection objects. It returns an enumerator object that supports
368     // IEnumVARIANT, and should have the restricted attribute specified.
369     /** The Constant DISPID_NEWENUM. */
370     public final static DISPID DISPID_NEWENUM = new DISPID(-4);
371 
372     // The parameter that receives the value of an assignment in a PROPERTYPUT.
373     /** The Constant DISPID_PROPERTYPUT. */
374     public final static DISPID DISPID_PROPERTYPUT = new DISPID(-3);
375 
376     // The value returned by IDispatch::GetIDsOfNames to indicate that a member
377     // or parameter name was not found.
378     /** The Constant DISPID_UNKNOWN. */
379     public final static DISPID DISPID_UNKNOWN = new DISPID(-1);
380 
381     // The default member for the object. This property or method is invoked
382     // when an ActiveX client specifies the object name without a property or
383     // method.
384     /** The Constant DISPID_VALUE. */
385     public final static DISPID DISPID_VALUE = new DISPID(0);
386 
387     public final static MEMBERID MEMBERID_NIL = new MEMBERID(
388             DISPID_UNKNOWN.intValue());
389 
390     /** An array that is allocated on the stack. */
391     public final static int FADF_AUTO = 0x0001;
392 
393     /** An array that is statically allocated. */
394     public final static int FADF_STATIC = 0x0002;
395 
396     /** An array that is embedded in a structure. */
397     public final static int FADF_EMBEDDED = 0x0004;
398 
399     /** An array that may not be resized or reallocated. */
400     public final static int FADF_FIXEDSIZE = 0x0010;
401 
402     /**
403      * An array that contains records. When set, there will be a pointer to the
404      * IRecordInfo interface at negative offset 4 in the array descriptor.
405      */
406     public final static int FADF_RECORD = 0x0020;
407 
408     /**
409      * An array that has an IID identifying interface. When set, there will be a
410      * GUID at negative offset 16 in the safe array descriptor. Flag is set only
411      * when FADF_DISPATCH or FADF_UNKNOWN is also set.
412      */
413     public final static int FADF_HAVEIID = 0x0040;
414 
415     /**
416      * An array that has a variant type. The variant type can be retrieved with
417      * SafeArrayGetVartype.
418      */
419     public final static int FADF_HAVEVARTYPE = 0x0080;
420 
421     /** An array of BSTRs. */
422     public final static int FADF_BSTR = 0x0100;
423 
424     /** An array of IUnknown*. */
425     public final static int FADF_UNKNOWN = 0x0200;
426 
427     /** An array of IDispatch*. */
428     public final static int FADF_DISPATCH = 0x0400;
429 
430     /** An array of VARIANTs. */
431     public final static int FADF_VARIANT = 0x0800;
432 
433     /** Bits reserved for future use. */
434     public final static int FADF_RESERVED = 0xF008;
435 
436     @FieldOrder({"value"})
437     public static class TYPEKIND extends Structure {
438         public static class ByReference extends TYPEKIND implements
439                 Structure.ByReference {
ByReference()440             public ByReference() {
441 
442             }
443 
ByReference(int value)444             public ByReference(int value) {
445                 super(value);
446             }
447 
ByReference(TYPEKIND typekind)448             public ByReference(TYPEKIND typekind) {
449                 super(typekind.getPointer());
450                 value = typekind.value;
451             }
452         }
453 
454         public int value;
455 
TYPEKIND()456         public TYPEKIND() {
457             super();
458         }
459 
TYPEKIND(int value)460         public TYPEKIND(int value) {
461             this.value = value;
462         }
463 
TYPEKIND(Pointer pointer)464         public TYPEKIND(Pointer pointer) {
465             super(pointer);
466             this.read();
467         }
468 
469         // / <i>native declaration : line 4</i>
470         public static final int TKIND_ENUM = 0;
471         // / <i>native declaration : line 5</i>
472         public static final int TKIND_RECORD = TYPEKIND.TKIND_ENUM + 1;
473         // / <i>native declaration : line 6</i>
474         public static final int TKIND_MODULE = TYPEKIND.TKIND_RECORD + 1;
475         // / <i>native declaration : line 7</i>
476         public static final int TKIND_INTERFACE = TYPEKIND.TKIND_MODULE + 1;
477         // / <i>native declaration : line 8</i>
478         public static final int TKIND_DISPATCH = TYPEKIND.TKIND_INTERFACE + 1;
479         // / <i>native declaration : line 9</i>
480         public static final int TKIND_COCLASS = TYPEKIND.TKIND_DISPATCH + 1;
481         // / <i>native declaration : line 10</i>
482         public static final int TKIND_ALIAS = TYPEKIND.TKIND_COCLASS + 1;
483         // / <i>native declaration : line 11</i>
484         public static final int TKIND_UNION = TYPEKIND.TKIND_ALIAS + 1;
485         // / <i>native declaration : line 12</i>
486         public static final int TKIND_MAX = TYPEKIND.TKIND_UNION + 1;
487     }
488 
489     @FieldOrder({"value"})
490     public static class DESCKIND extends Structure {
491         public static class ByReference extends DESCKIND implements
492                 Structure.ByReference {
493         }
494 
495         public int value;
496 
DESCKIND()497         public DESCKIND() {
498             super();
499         }
500 
DESCKIND(int value)501         public DESCKIND(int value) {
502             this.value = value;
503         }
504 
DESCKIND(Pointer pointer)505         public DESCKIND(Pointer pointer) {
506             super(pointer);
507             this.read();
508         }
509 
510         // / <i>native declaration : line 4</i>
511         public static final int DESCKIND_NONE = 0;
512         // / <i>native declaration : line 5</i>
513         public static final int DESCKIND_FUNCDESC = DESCKIND.DESCKIND_NONE + 1;
514         // / <i>native declaration : line 6</i>
515         public static final int DESCKIND_VARDESC = DESCKIND.DESCKIND_FUNCDESC + 1;
516         // / <i>native declaration : line 7</i>
517         public static final int DESCKIND_TYPECOMP = DESCKIND.DESCKIND_VARDESC + 1;
518         // / <i>native declaration : line 8</i>
519         public static final int DESCKIND_IMPLICITAPPOBJ = DESCKIND.DESCKIND_TYPECOMP + 1;
520         // / <i>native declaration : line 9</i>
521         public static final int DESCKIND_MAX = DESCKIND.DESCKIND_IMPLICITAPPOBJ + 1;
522     }
523 
524     /**
525      * Implementation of SAFEARRAY. Implements Closable, which in this case
526      * delegates to destroy, to free native memory on close.
527      *
528      * <p>VARTYPE for the SAFEARRAY can be:</p>
529      *
530      * <ul>
531      * <li>VT_BOOL</li>
532      * <li>VT_BSTR</li>
533      * <li>VT_CY</li>
534      * <li>VT_DATE</li>
535      * <li>VT_DECIMAL</li>
536      * <li>VT_DISPATCH</li>
537      * <li>VT_ERROR</li>
538      * <li>VT_I1</li>
539      * <li>VT_I2</li>
540      * <li>VT_I4</li>
541      * <li>VT_INT</li>
542      * <li>VT_R4</li>
543      * <li>VT_R8</li>
544      * <li>VT_RECORD</li>
545      * <li>VT_UI1</li>
546      * <li>VT_UI2</li>
547      * <li>VT_UI4</li>
548      * <li>VT_UINT</li>
549      * <li>VT_UNKNOWN</li>
550      * <li>VT_VARIANT</li>
551      * </ul>
552      *
553      * <p>General comment: All indices in the helper methods use java int.</p>
554      *
555      * <p>The native type for the indices is LONG, which is defined as:</p>
556      *
557      * <blockquote>A 32-bit signed integer. The range is �2147483648 through 2147483647 decimal.</blockquote>
558      */
559     @FieldOrder({"cDims", "fFeatures", "cbElements", "cLocks", "pvData", "rgsabound"})
560     public static class SAFEARRAY extends Structure implements Closeable {
561 
562         public static class ByReference extends SAFEARRAY implements
563                 Structure.ByReference {
564         }
565 
566         public USHORT cDims;
567         public USHORT fFeatures;
568         public ULONG cbElements;
569         public ULONG cLocks;
570         public PVOID pvData;
571 
572         /** The rgsabound. */
573         public SAFEARRAYBOUND[] rgsabound = { new SAFEARRAYBOUND() };
574 
SAFEARRAY()575         public SAFEARRAY() {
576             super();
577         }
578 
SAFEARRAY(Pointer pointer)579         public SAFEARRAY(Pointer pointer) {
580             super(pointer);
581             this.read();
582         }
583 
584         @Override
read()585         public void read() {
586             super.read();
587             if(cDims.intValue() > 0) {
588                 rgsabound = (SAFEARRAYBOUND[]) rgsabound[0].toArray(cDims.intValue());
589             } else {
590                 rgsabound = new SAFEARRAYBOUND[]{ new SAFEARRAYBOUND() };
591             }
592         }
593 
594         /**
595          * Create a SAFEARRAY with supplied VARIANT as element type.
596          *
597          * <p>
598          * This helper creates a basic SAFEARRAY with a base type of VT_VARIANT.
599          * The array will have as many dimensions as parameters are passed in.
600          * The lowerbound for each dimension is set to zero, the count to the
601          * parameter value.</p>
602          *
603          * @param size array of dimension size
604          * @return SAFEARRAYWrapper or {@code NULL} if creation fails.
605          */
createSafeArray(int... size)606         public static SAFEARRAY.ByReference createSafeArray(int... size) {
607             return createSafeArray(new WTypes.VARTYPE(Variant.VT_VARIANT), size);
608         }
609 
610         /**
611          * Create a SAFEARRAY with supplied element type.
612          *
613          * <p>
614          * The array will have as many dimensions as parameters are passed in.
615          * The lowerbound for each dimension is set to zero, the count to the
616          * parameter value.</p>
617          *
618          * @param vartype type of array contents (see Variant.VT_* constants)
619          * @param size array of dimension size
620          * @return SAFEARRAYWrapper or {@code NULL} if creation fails.
621          */
createSafeArray(VARTYPE vartype, int... size)622         public static SAFEARRAY.ByReference createSafeArray(VARTYPE vartype, int... size) {
623             OaIdl.SAFEARRAYBOUND[] rgsabound = (OaIdl.SAFEARRAYBOUND[]) new OaIdl.SAFEARRAYBOUND().toArray(size.length);
624             for (int i = 0; i < size.length; i++) {
625                 rgsabound[i].lLbound = new WinDef.LONG(0);
626                 rgsabound[i].cElements = new WinDef.ULONG(size[size.length - i - 1]);
627             }
628             SAFEARRAY.ByReference data = OleAuto.INSTANCE.SafeArrayCreate(vartype, new WinDef.UINT(size.length), rgsabound);
629             return data;
630         }
631 
632         /**
633          * Set value at {@code indices} in {@code array} to arg.
634          *
635          * <p>
636          * The supplied argument is copied into the array. If the value is no
637          * longer needed, it needs to be freed if not handled automatically.</p>
638          *
639          * @param indices the index, order follows java/C convention
640          * @param arg the arg
641          */
putElement(Object arg, int... indices)642         public void putElement(Object arg, int... indices) {
643             WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length];
644             for (int i = 0; i < indices.length; i++) {
645                 paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]);
646             }
647 
648             WinNT.HRESULT hr;
649             Memory mem;
650             switch (getVarType().intValue()) {
651                 case VT_BOOL:
652                     mem = new Memory(2);
653                     if(arg instanceof Boolean) {
654                         mem.setShort(0, (short) (((Boolean) arg) ? 0xFFFF : 0) );
655                     } else {
656                         mem.setShort(0, (short) (((Number) arg).intValue() > 0 ? 0xFFFF : 0));
657                     }
658                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
659                     COMUtils.checkRC(hr);
660                     break;
661                 case VT_UI1:
662                 case VT_I1:
663                     mem = new Memory(1);
664                     mem.setByte(0, ((Number) arg).byteValue());
665                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
666                     COMUtils.checkRC(hr);
667                     break;
668                 case VT_UI2:
669                 case VT_I2:
670                     mem = new Memory(2);
671                     mem.setShort(0, ((Number) arg).shortValue());
672                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
673                     COMUtils.checkRC(hr);
674                     break;
675                 case VT_UI4:
676                 case VT_UINT:
677                 case VT_I4:
678                 case VT_INT:
679                     mem = new Memory(4);
680                     mem.setInt(0, ((Number) arg).intValue());
681                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
682                     COMUtils.checkRC(hr);
683                     break;
684                 case VT_ERROR:
685                     mem = new Memory(4);
686                     mem.setInt(0, ((Number) arg).intValue());
687                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
688                     COMUtils.checkRC(hr);
689                     break;
690                 case VT_R4:
691                     mem = new Memory(4);
692                     mem.setFloat(0, ((Number) arg).floatValue());
693                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
694                     COMUtils.checkRC(hr);
695                     break;
696                 case VT_R8:
697                     mem = new Memory(8);
698                     mem.setDouble(0, ((Number) arg).doubleValue());
699                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
700                     COMUtils.checkRC(hr);
701                     break;
702                 case VT_DATE:
703                     mem = new Memory(8);
704                     mem.setDouble(0, ((DATE) arg).date);
705                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, mem);
706                     COMUtils.checkRC(hr);
707                     break;
708                 case VT_BSTR:
709                     if(arg instanceof String) {
710                         BSTR bstr = OleAuto.INSTANCE.SysAllocString((String) arg);
711                         hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, bstr.getPointer());
712                         OleAuto.INSTANCE.SysFreeString(bstr);
713                         COMUtils.checkRC(hr);
714                     } else {
715                         hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((BSTR) arg).getPointer());
716                         COMUtils.checkRC(hr);
717                     }
718                     break;
719                 case VT_VARIANT:
720                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((VARIANT) arg).getPointer());
721                     COMUtils.checkRC(hr);
722                     break;
723                 case VT_UNKNOWN:
724                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((Unknown) arg).getPointer());
725                     COMUtils.checkRC(hr);
726                     break;
727                 case VT_DISPATCH:
728                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((Dispatch) arg).getPointer());
729                     COMUtils.checkRC(hr);
730                     break;
731                 case VT_CY:
732                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((CURRENCY) arg).getPointer());
733                     COMUtils.checkRC(hr);
734                     break;
735                 case VT_DECIMAL:
736                     hr = OleAuto.INSTANCE.SafeArrayPutElement(this, paramIndices, ((DECIMAL) arg).getPointer());
737                     COMUtils.checkRC(hr);
738                     break;
739                 case VT_RECORD:
740                 default:
741                     throw new IllegalStateException("Can't parse array content - type not supported: " + getVarType().intValue());
742             }
743         }
744 
745         /**
746          * Retrieve the value at the referenced index from the SAFEARRAY.
747          *
748          * <p>The function creates a copy of the value. The values are
749          * allocated with native functions and need to be freed accordingly.</p>
750          *
751          * @param indices the index, order follows java/C convention
752          * @return the variant
753          */
getElement(int... indices)754         public Object getElement(int... indices) {
755             WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length];
756             for (int i = 0; i < indices.length; i++) {
757                 paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]);
758             }
759 
760             Object result;
761             WinNT.HRESULT hr;
762             Memory mem;
763             PointerByReference pbr;
764             switch (getVarType().intValue()) {
765                 case VT_BOOL:
766                     mem = new Memory(2);
767                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
768                     COMUtils.checkRC(hr);
769                     result = mem.getShort(0) != 0;
770                     break;
771                 case VT_UI1:
772                 case VT_I1:
773                     mem = new Memory(1);
774                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
775                     COMUtils.checkRC(hr);
776                     result = mem.getByte(0);
777                     break;
778                 case VT_UI2:
779                 case VT_I2:
780                     mem = new Memory(2);
781                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
782                     COMUtils.checkRC(hr);
783                     result = mem.getShort(0);
784                     break;
785                 case VT_UI4:
786                 case VT_UINT:
787                 case VT_I4:
788                 case VT_INT:
789                     mem = new Memory(4);
790                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
791                     COMUtils.checkRC(hr);
792                     result = mem.getInt(0);
793                     break;
794                 case VT_ERROR:
795                     mem = new Memory(4);
796                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
797                     COMUtils.checkRC(hr);
798                     result = new SCODE(mem.getInt(0));
799                     break;
800                 case VT_R4:
801                     mem = new Memory(4);
802                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
803                     COMUtils.checkRC(hr);
804                     result = mem.getFloat(0);
805                     break;
806                 case VT_R8:
807                     mem = new Memory(8);
808                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
809                     COMUtils.checkRC(hr);
810                     result = mem.getDouble(0);
811                     break;
812                 case VT_DATE:
813                     mem = new Memory(8);
814                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, mem);
815                     COMUtils.checkRC(hr);
816                     result = new DATE(mem.getDouble(0));
817                     break;
818                 case VT_BSTR:
819                     pbr = new PointerByReference();
820                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer());
821                     COMUtils.checkRC(hr);
822                     BSTR bstr = new BSTR(pbr.getValue());
823                     result = bstr.getValue();
824                     OleAuto.INSTANCE.SysFreeString(bstr);
825                     break;
826                 case VT_VARIANT:
827                     VARIANT holder = new Variant.VARIANT();
828                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, holder.getPointer());
829                     COMUtils.checkRC(hr);
830                     result = holder;
831                     break;
832                 case VT_UNKNOWN:
833                     pbr = new PointerByReference();
834                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer());
835                     COMUtils.checkRC(hr);
836                     result = new Unknown(pbr.getValue());
837                     break;
838                 case VT_DISPATCH:
839                     pbr = new PointerByReference();
840                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, pbr.getPointer());
841                     COMUtils.checkRC(hr);
842                     result = new Dispatch(pbr.getValue());
843                     break;
844                 case VT_CY:
845                     CURRENCY currency = new CURRENCY();
846                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, currency.getPointer());
847                     COMUtils.checkRC(hr);
848                     result = currency;
849                     break;
850                 case VT_DECIMAL:
851                     DECIMAL decimal = new DECIMAL();
852                     hr = OleAuto.INSTANCE.SafeArrayGetElement(this, paramIndices, decimal.getPointer());
853                     COMUtils.checkRC(hr);
854                     result = decimal;
855                     break;
856                 case VT_RECORD:
857                 default:
858                     throw new IllegalStateException("Can't parse array content - type not supported: " + getVarType().intValue());
859             }
860 
861             return result;
862         }
863 
864         /**
865          * Retrieve pointer to data element from array.
866          *
867          * <p>
868          * Caller is responsible for (un)locking the array via
869          * {@link OleAuto#SafeArrayLock} and {@link OleAuto#SafeArrayUnlock} or
870          * the helper methods: {@link SAFEARRAY#lock} and
871          * {@link SAFEARRAY#unlock}.</p>
872          *
873          * @param indices the index, order follows java/C convention
874          * @return the pointer to the data element
875          */
ptrOfIndex(int... indices)876         public Pointer ptrOfIndex(int... indices) {
877             WinDef.LONG[] paramIndices = new WinDef.LONG[indices.length];
878             for (int i = 0; i < indices.length; i++) {
879                 paramIndices[i] = new WinDef.LONG(indices[indices.length - i - 1]);
880             }
881             PointerByReference pbr = new PointerByReference();
882             WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayPtrOfIndex(this, paramIndices, pbr);
883             COMUtils.checkRC(hr);
884             return pbr.getValue();
885         }
886 
887         /**
888          * Destroy the underlying SAFEARRAY and free memory
889          */
destroy()890         public void destroy() {
891             WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayDestroy(this);
892             COMUtils.checkRC(res);
893         }
894 
895         /**
896          * Implemented to satisfy Closeable interface, delegates to destroy.
897          */
close()898         public void close() {
899             destroy();
900         }
901 
902         /**
903          * Retrieve lower bound for the selected dimension.
904          *
905          * <p>As in the all the accessor functions, that index is converted to
906          * java conventions.</p>
907          *
908          * @param dimension zerobased index
909          * @return lower bound for the selected dimension
910          */
getLBound(int dimension)911         public int getLBound(int dimension) {
912             int targetDimension = getDimensionCount() - dimension;
913             WinDef.LONGByReference bound = new WinDef.LONGByReference();
914             WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetLBound(this, new WinDef.UINT(targetDimension), bound);
915             COMUtils.checkRC(res);
916             return bound.getValue().intValue();
917         }
918 
919         /**
920          * Retrieve upper bound for the selected dimension.
921          *
922          * <p>As in the all the accessor functions, that index is converted to
923          * java conventions.</p>
924          *
925          * @param dimension zerobased index
926          * @return upper bound for the selected dimension
927          */
getUBound(int dimension)928         public int getUBound(int dimension) {
929             int targetDimension = getDimensionCount() - dimension;
930             WinDef.LONGByReference bound = new WinDef.LONGByReference();
931             WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetUBound(this, new WinDef.UINT(targetDimension), bound);
932             COMUtils.checkRC(res);
933             return bound.getValue().intValue();
934         }
935 
936         /**
937          * Return number of dimensions of the SAFEARRAY
938          *
939          * @return number of dimensions of the SAFEARRAY
940          */
getDimensionCount()941         public int getDimensionCount() {
942             return OleAuto.INSTANCE.SafeArrayGetDim(this).intValue();
943         }
944 
945         /**
946          * Lock array and retrieve pointer to data
947          *
948          * @return Pointer to arraydata
949          */
accessData()950         public Pointer accessData() {
951             PointerByReference pbr = new PointerByReference();
952             WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayAccessData(this, pbr);
953             COMUtils.checkRC(hr);
954             return pbr.getValue();
955         }
956 
957         /**
958          * Unlock array and invalidate the pointer retrieved via
959          * SafeArrayAccessData
960          */
unaccessData()961         public void unaccessData() {
962             WinNT.HRESULT hr = OleAuto.INSTANCE.SafeArrayUnaccessData(this);
963             COMUtils.checkRC(hr);
964         }
965 
966         /**
967          * Increments the lock count of an array, and places a pointer to the
968          * array data in pvData of the array descriptor.
969          */
lock()970         public void lock() {
971             WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayLock(this);
972             COMUtils.checkRC(res);
973         }
974 
975         /**
976          * Decrements the lock count of an array so it can be freed or resized
977          */
unlock()978         public void unlock() {
979             WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayUnlock(this);
980             COMUtils.checkRC(res);
981         }
982 
983         /**
984          * Changes the right-most (least significant) bound of the specified
985          * safe array.
986          *
987          * @param cElements
988          * @param lLbound
989          */
redim(int cElements, int lLbound)990         public void redim(int cElements, int lLbound) {
991             WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayRedim(this, new OaIdl.SAFEARRAYBOUND(cElements, lLbound));
992             COMUtils.checkRC(res);
993         }
994 
995         /**
996          * Return VARTYPE of the SAFEARRAY
997          *
998          * @return VARTYPE of the SAFEARRAY
999          */
getVarType()1000         public VARTYPE getVarType() {
1001             WTypes.VARTYPEByReference resultHolder = new WTypes.VARTYPEByReference();
1002             WinNT.HRESULT res = OleAuto.INSTANCE.SafeArrayGetVartype(this, resultHolder);
1003             COMUtils.checkRC(res);
1004             return resultHolder.getValue();
1005         }
1006 
1007         /**
1008          * Get size of one element in bytes
1009          *
1010          * @return element size in bytes
1011          */
getElemsize()1012         public long getElemsize() {
1013             return OleAuto.INSTANCE.SafeArrayGetElemsize(this).longValue();
1014         }
1015     }
1016 
1017     @FieldOrder({"pSAFEARRAY"})
1018     public static class SAFEARRAYByReference extends Structure implements Structure.ByReference {
1019 
SAFEARRAYByReference()1020         public SAFEARRAYByReference() {
1021         }
1022 
SAFEARRAYByReference(Pointer p)1023         public SAFEARRAYByReference(Pointer p) {
1024             super(p);
1025             read();
1026         }
1027 
SAFEARRAYByReference(SAFEARRAY.ByReference safeArray)1028         public SAFEARRAYByReference(SAFEARRAY.ByReference safeArray) {
1029             pSAFEARRAY = safeArray;
1030         }
1031 
1032         public SAFEARRAY.ByReference pSAFEARRAY;
1033     }
1034 
1035     @FieldOrder({"cElements", "lLbound"})
1036     public static class SAFEARRAYBOUND extends Structure {
1037         public static class ByReference extends SAFEARRAYBOUND implements
1038                 Structure.ByReference {
1039         }
1040 
1041         public ULONG cElements;
1042         public LONG lLbound;
1043 
SAFEARRAYBOUND()1044         public SAFEARRAYBOUND() {
1045             super();
1046         }
1047 
SAFEARRAYBOUND(Pointer pointer)1048         public SAFEARRAYBOUND(Pointer pointer) {
1049             super(pointer);
1050             this.read();
1051         }
1052 
SAFEARRAYBOUND(int cElements, int lLbound)1053         public SAFEARRAYBOUND(int cElements, int lLbound) {
1054             this.cElements = new ULONG(cElements);
1055             this.lLbound = new LONG(lLbound);
1056             this.write();
1057         }
1058     }
1059 
1060     public static class CURRENCY extends Union {
1061 
1062         public static class ByReference extends CURRENCY implements
1063                 Structure.ByReference {
1064         };
1065 
1066         public _CURRENCY currency;
1067         public LONGLONG int64;
1068 
CURRENCY()1069         public CURRENCY() {
1070             super();
1071         }
1072 
CURRENCY(Pointer pointer)1073         public CURRENCY(Pointer pointer) {
1074             super(pointer);
1075             this.read();
1076         }
1077 
1078         @FieldOrder({"Lo", "Hi"})
1079         public static class _CURRENCY extends Structure {
1080             public ULONG Lo;
1081             public LONG Hi;
1082 
_CURRENCY()1083             public _CURRENCY() {
1084                 super();
1085             }
1086 
_CURRENCY(Pointer pointer)1087             public _CURRENCY(Pointer pointer) {
1088                 super(pointer);
1089                 this.read();
1090             }
1091         }
1092     }
1093 
1094     @FieldOrder({"wReserved", "decimal1", "Hi32", "decimal2"})
1095     public static class DECIMAL extends Structure {
1096         public static class ByReference extends DECIMAL implements
1097                 Structure.ByReference {
1098         };
1099 
1100 
1101         public static class _DECIMAL1 extends Union {
1102 
1103             public USHORT signscale;
1104             public _DECIMAL1_DECIMAL decimal1_DECIMAL;
1105 
_DECIMAL1()1106             public _DECIMAL1() {
1107                 this.setType("signscale");
1108             }
1109 
_DECIMAL1(Pointer pointer)1110             public _DECIMAL1(Pointer pointer) {
1111                 super(pointer);
1112                 this.setType("signscale");
1113                 this.read();
1114             }
1115 
1116             @FieldOrder({"scale", "sign"})
1117             public static class _DECIMAL1_DECIMAL extends Structure {
1118                 public BYTE scale;
1119                 public BYTE sign;
1120 
_DECIMAL1_DECIMAL()1121                 public _DECIMAL1_DECIMAL() {
1122                     super();
1123                 }
1124 
_DECIMAL1_DECIMAL(Pointer pointer)1125                 public _DECIMAL1_DECIMAL(Pointer pointer) {
1126                     super(pointer);
1127                 }
1128             }
1129         }
1130 
1131         public static class _DECIMAL2 extends Union {
1132             public ULONGLONG Lo64;
1133             public _DECIMAL2_DECIMAL decimal2_DECIMAL;
1134 
_DECIMAL2()1135             public _DECIMAL2() {
1136                 this.setType("Lo64");
1137             }
1138 
_DECIMAL2(Pointer pointer)1139             public _DECIMAL2(Pointer pointer) {
1140                 super(pointer);
1141                 this.setType("Lo64");
1142                 this.read();
1143             }
1144 
1145             @FieldOrder({"Lo32", "Mid32"})
1146             public static class _DECIMAL2_DECIMAL extends Structure {
1147 
1148                 public BYTE Lo32;
1149                 public BYTE Mid32;
1150 
_DECIMAL2_DECIMAL()1151                 public _DECIMAL2_DECIMAL() {
1152                     super();
1153                 }
1154 
_DECIMAL2_DECIMAL(Pointer pointer)1155                 public _DECIMAL2_DECIMAL(Pointer pointer) {
1156                     super(pointer);
1157                 }
1158             }
1159         }
1160 
1161         public short wReserved;
1162         public _DECIMAL1 decimal1;
1163         public NativeLong Hi32;
1164         public _DECIMAL2 decimal2;
1165 
DECIMAL()1166         public DECIMAL() {
1167             super();
1168         }
1169 
DECIMAL(Pointer pointer)1170         public DECIMAL(Pointer pointer) {
1171             super(pointer);
1172         }
1173     }
1174 
1175     @FieldOrder({"value"})
1176     public static class SYSKIND extends Structure {
1177         public static class ByReference extends SYSKIND implements
1178                 Structure.ByReference {
1179         }
1180 
1181         public int value;
SYSKIND()1182         public SYSKIND() {
1183             super();
1184         }
1185 
SYSKIND(int value)1186         public SYSKIND(int value) {
1187             this.value = value;
1188         }
1189 
SYSKIND(Pointer pointer)1190         public SYSKIND(Pointer pointer) {
1191             super(pointer);
1192             this.read();
1193         }
1194 
1195         public static final int SYS_WIN16 = 0;
1196         public static final int SYS_WIN32 = SYSKIND.SYS_WIN16 + 1;
1197         public static final int SYS_MAC = SYSKIND.SYS_WIN32 + 1;
1198         public static final int SYS_WIN64 = SYSKIND.SYS_MAC + 1;
1199     }
1200 
1201     @FieldOrder({"value"})
1202     public static class LIBFLAGS extends Structure {
1203         public static class ByReference extends LIBFLAGS implements
1204                 Structure.ByReference {
1205         }
1206 
1207         public int value;
1208 
LIBFLAGS()1209         public LIBFLAGS() {
1210             super();
1211         }
1212 
LIBFLAGS(int value)1213         public LIBFLAGS(int value) {
1214             this.value = value;
1215         }
1216 
LIBFLAGS(Pointer pointer)1217         public LIBFLAGS(Pointer pointer) {
1218             super(pointer);
1219             this.read();
1220         }
1221 
1222         public static final int LIBFLAG_FRESTRICTED = 0x1;
1223         public static final int LIBFLAG_FCONTROL = 0x2;
1224         public static final int LIBFLAG_FHIDDEN = 0x4;
1225         public static final int LIBFLAG_FHASDISKIMAGE = 0x8;
1226     };
1227 
1228     @FieldOrder({"guid", "lcid", "syskind", "wMajorVerNum", "wMinorVerNum", "wLibFlags"})
1229     public static class TLIBATTR extends Structure {
1230         public static class ByReference extends TLIBATTR implements
1231                 Structure.ByReference {
1232 
ByReference()1233             public ByReference() {
1234                 super();
1235             }
1236 
ByReference(Pointer pointer)1237             public ByReference(Pointer pointer) {
1238                 super(pointer);
1239                 this.read();
1240             }
1241         }
1242 
1243         public GUID guid;
1244         public LCID lcid;
1245         public SYSKIND syskind;
1246         public WORD wMajorVerNum;
1247         public WORD wMinorVerNum;
1248         public WORD wLibFlags;
1249 
TLIBATTR()1250         public TLIBATTR() {
1251             super();
1252         }
1253 
TLIBATTR(Pointer pointer)1254         public TLIBATTR(Pointer pointer) {
1255             super(pointer);
1256             this.read();
1257         }
1258     }
1259 
1260     public static class BINDPTR extends Union {
1261         public static class ByReference extends BINDPTR implements
1262                 Structure.ByReference {
1263         };
1264 
1265         // / C type : FUNCDESC*
1266         public FUNCDESC lpfuncdesc;
1267         // / C type : VARDESC*
1268         public VARDESC lpvardesc;
1269         // / C type : ITypeComp*
1270         public TypeComp lptcomp;
1271 
BINDPTR()1272         public BINDPTR() {
1273             super();
1274         }
1275 
1276         // / @param lpvardesc C type : VARDESC*
BINDPTR(VARDESC lpvardesc)1277         public BINDPTR(VARDESC lpvardesc) {
1278             super();
1279             this.lpvardesc = lpvardesc;
1280             setType(VARDESC.class);
1281         }
1282 
1283         // / @param lptcomp C type : ITypeComp*
BINDPTR(TypeComp lptcomp)1284         public BINDPTR(TypeComp lptcomp) {
1285             super();
1286             this.lptcomp = lptcomp;
1287             setType(TypeComp.class);
1288         }
1289 
1290         // / @param lpfuncdesc C type : FUNCDESC*
BINDPTR(FUNCDESC lpfuncdesc)1291         public BINDPTR(FUNCDESC lpfuncdesc) {
1292             super();
1293             this.lpfuncdesc = lpfuncdesc;
1294             setType(FUNCDESC.class);
1295         }
1296     }
1297 
1298     @FieldOrder({"memid", "lprgscode", "lprgelemdescParam", "funckind",
1299         "invkind", "callconv", "cParams", "cParamsOpt", "oVft", "cScodes",
1300         "elemdescFunc", "wFuncFlags"})
1301     public static class FUNCDESC extends Structure {
1302         public static class ByReference extends FUNCDESC implements
1303                 Structure.ByReference {
1304         };
1305 
1306         public MEMBERID memid;
1307         public ScodeArg.ByReference lprgscode;
1308         public ElemDescArg.ByReference lprgelemdescParam;
1309         public FUNCKIND funckind;
1310         public INVOKEKIND invkind;
1311         public CALLCONV callconv;
1312         public SHORT cParams;
1313         public SHORT cParamsOpt;
1314         public SHORT oVft;
1315         public SHORT cScodes;
1316         public ELEMDESC elemdescFunc;
1317         public WORD wFuncFlags;
1318 
FUNCDESC()1319         public FUNCDESC() {
1320             super();
1321         }
1322 
FUNCDESC(Pointer pointer)1323         public FUNCDESC(Pointer pointer) {
1324             super(pointer);
1325             this.read();
1326 
1327             if (this.cParams.shortValue() > 1) {
1328                 this.lprgelemdescParam.elemDescArg = new ELEMDESC[this.cParams
1329                         .shortValue()];
1330                 this.lprgelemdescParam.read();
1331             }
1332         }
1333     }
1334 
1335     @FieldOrder({"elemDescArg"})
1336     public static class ElemDescArg extends Structure {
1337         public static class ByReference extends ElemDescArg implements
1338                 Structure.ByReference {
1339         }
1340 
1341         public ELEMDESC[] elemDescArg = { new ELEMDESC() };
1342 
ElemDescArg()1343         public ElemDescArg() {
1344             super();
1345         }
1346 
ElemDescArg(Pointer pointer)1347         public ElemDescArg(Pointer pointer) {
1348             super(pointer);
1349             this.read();
1350         }
1351     }
1352 
1353     @FieldOrder({"scodeArg"})
1354     public static class ScodeArg extends Structure {
1355         public static class ByReference extends ScodeArg implements
1356                 Structure.ByReference {
1357         }
1358 
1359         public SCODE[] scodeArg = { new SCODE() };
1360 
ScodeArg()1361         public ScodeArg() {
1362             super();
1363         }
1364 
ScodeArg(Pointer pointer)1365         public ScodeArg(Pointer pointer) {
1366             super(pointer);
1367             this.read();
1368         }
1369     }
1370 
1371     @FieldOrder({"memid", "lpstrSchema", "_vardesc", "elemdescVar", "wVarFlags", "varkind"})
1372     public class VARDESC extends Structure {
1373         public static class ByReference extends VARDESC implements
1374                 Structure.ByReference {
1375         };
1376 
1377         // / C type : MEMBERID
1378         public MEMBERID memid;
1379         // / C type : LPOLESTR
1380         public LPOLESTR lpstrSchema;
1381         /**
1382          * [switch_is][switch_type]<br>
1383          * C type : _VARDESC_union
1384          */
1385         public _VARDESC _vardesc;
1386         // / C type : ELEMDESC
1387         public ELEMDESC elemdescVar;
1388         public WORD wVarFlags;
1389         // / C type : VARKIND
1390         public VARKIND varkind;
1391 
1392         // / <i>native declaration : line 6</i>
1393         // / <i>native declaration : line 6</i>
1394         public static class _VARDESC extends Union {
1395             public static class ByReference extends _VARDESC implements
1396                     Structure.ByReference {
1397             };
1398 
1399             // / [case()]
1400             public NativeLong oInst;
1401             /**
1402              * [case()]<br>
1403              * C type : VARIANT*
1404              */
1405             public VARIANT.ByReference lpvarValue;
1406 
_VARDESC()1407             public _VARDESC() {
1408                 setType("lpvarValue");
1409                 this.read();
1410             }
1411 
_VARDESC(Pointer pointer)1412             public _VARDESC(Pointer pointer) {
1413                 super(pointer);
1414                 setType("lpvarValue");
1415                 this.read();
1416             }
1417 
1418             /**
1419              * @param lpvarValue
1420              *            [case()]<br>
1421              *            C type : VARIANT*
1422              */
_VARDESC(VARIANT.ByReference lpvarValue)1423             public _VARDESC(VARIANT.ByReference lpvarValue) {
1424                 this.lpvarValue = lpvarValue;
1425                 setType("lpvarValue");
1426             }
1427 
1428             // / @param oInst [case()]
_VARDESC(NativeLong oInst)1429             public _VARDESC(NativeLong oInst) {
1430                 this.oInst = oInst;
1431                 setType("oInst");
1432             }
1433         };
1434 
VARDESC()1435         public VARDESC() {
1436             super();
1437         }
1438 
VARDESC(Pointer pointer)1439         public VARDESC(Pointer pointer) {
1440             super(pointer);
1441             this._vardesc.setType("lpvarValue");
1442             this.read();
1443         }
1444     }
1445 
1446     @FieldOrder({"tdesc", "_elemdesc"})
1447     public static class ELEMDESC extends Structure {
1448         public static class ByReference extends ELEMDESC implements
1449                 Structure.ByReference {
1450         };
1451 
1452         /**
1453          * the type of the element<br>
1454          * C type : TYPEDESC
1455          */
1456         public TYPEDESC tdesc;
1457         // / C type : DUMMYUNIONNAMEUnion
1458         public _ELEMDESC _elemdesc;
1459 
1460         // / <i>native declaration : line 4</i>
1461         // / <i>native declaration : line 4</i>
1462         public static class _ELEMDESC extends Union {
1463             public static class ByReference extends _ELEMDESC implements
1464                     Structure.ByReference {
1465             };
1466 
1467             /**
1468              * info for remoting the element<br>
1469              * C type : IDLDESC
1470              */
1471             public IDLDESC idldesc;
1472             /**
1473              * info about the parameter<br>
1474              * C type : PARAMDESC
1475              */
1476             public PARAMDESC paramdesc;
1477 
_ELEMDESC()1478             public _ELEMDESC() {
1479             }
1480 
_ELEMDESC(Pointer pointer)1481             public _ELEMDESC(Pointer pointer) {
1482                 super(pointer);
1483                 setType("paramdesc");
1484                 this.read();
1485             }
1486 
1487             /**
1488              * @param paramdesc
1489              *            info about the parameter<br>
1490              *            C type : PARAMDESC
1491              */
_ELEMDESC(PARAMDESC paramdesc)1492             public _ELEMDESC(PARAMDESC paramdesc) {
1493                 this.paramdesc = paramdesc;
1494                 setType("paramdesc");
1495             }
1496 
1497             /**
1498              * @param idldesc
1499              *            info for remoting the element<br>
1500              *            C type : IDLDESC
1501              */
_ELEMDESC(IDLDESC idldesc)1502             public _ELEMDESC(IDLDESC idldesc) {
1503                 this.idldesc = idldesc;
1504                 setType("idldesc");
1505             }
1506         };
1507 
ELEMDESC()1508         public ELEMDESC() {
1509             super();
1510         }
1511 
ELEMDESC(Pointer pointer)1512         public ELEMDESC(Pointer pointer) {
1513             super(pointer);
1514             this.read();
1515         }
1516     }
1517 
1518     @FieldOrder({"value"})
1519     public static class FUNCKIND extends Structure {
1520         public static class ByReference extends FUNCKIND implements
1521                 Structure.ByReference {
1522         };
1523 
1524         // / <i>native declaration : line 20</i>
1525         public static final int FUNC_VIRTUAL = 0;
1526         // / <i>native declaration : line 21</i>
1527         public static final int FUNC_PUREVIRTUAL = FUNC_VIRTUAL + 1;
1528         // / <i>native declaration : line 22</i>
1529         public static final int FUNC_NONVIRTUAL = FUNC_PUREVIRTUAL + 1;
1530         // / <i>native declaration : line 23</i>
1531         public static final int FUNC_STATIC = FUNC_NONVIRTUAL + 1;
1532         // / <i>native declaration : line 24</i>
1533         public static final int FUNC_DISPATCH = FUNC_STATIC + 1;
1534 
1535         public int value;
1536 
FUNCKIND()1537         public FUNCKIND() {
1538             super();
1539         }
1540 
FUNCKIND(int value)1541         public FUNCKIND(int value) {
1542             this.value = value;
1543 
1544         }
1545     }
1546 
1547     @FieldOrder({"value"})
1548     public static class INVOKEKIND extends Structure {
1549         public static class ByReference extends INVOKEKIND implements
1550                 Structure.ByReference {
1551         }
1552 
1553         // / <i>native declaration : line 30</i>
1554         public static final INVOKEKIND INVOKE_FUNC = new INVOKEKIND(1);
1555         // / <i>native declaration : line 31</i>
1556         public static final INVOKEKIND INVOKE_PROPERTYGET = new INVOKEKIND(2);
1557         // / <i>native declaration : line 32</i>
1558         public static final INVOKEKIND INVOKE_PROPERTYPUT = new INVOKEKIND(4);
1559         // / <i>native declaration : line 33</i>
1560         public static final INVOKEKIND INVOKE_PROPERTYPUTREF = new INVOKEKIND(8);
1561 
1562         public int value;
1563 
INVOKEKIND()1564         public INVOKEKIND() {
1565             super();
1566         }
1567 
INVOKEKIND(int value)1568         public INVOKEKIND(int value) {
1569             this.value = value;
1570 
1571         }
1572     }
1573 
1574     @FieldOrder({"value"})
1575     public static class CALLCONV extends Structure {
1576         public static class ByReference extends CALLCONV implements
1577                 Structure.ByReference {
1578         }
1579 
1580         // / <i>native declaration : line 4</i>
1581         public static final int CC_FASTCALL = 0;
1582         // / <i>native declaration : line 5</i>
1583         public static final int CC_CDECL = 1;
1584         // / <i>native declaration : line 6</i>
1585         public static final int CC_MSCPASCAL = CALLCONV.CC_CDECL + 1;
1586         // / <i>native declaration : line 7</i>
1587         public static final int CC_PASCAL = CALLCONV.CC_MSCPASCAL;
1588         // / <i>native declaration : line 8</i>
1589         public static final int CC_MACPASCAL = CALLCONV.CC_PASCAL + 1;
1590         // / <i>native declaration : line 9</i>
1591         public static final int CC_STDCALL = CALLCONV.CC_MACPASCAL + 1;
1592         // / <i>native declaration : line 10</i>
1593         public static final int CC_FPFASTCALL = CALLCONV.CC_STDCALL + 1;
1594         // / <i>native declaration : line 11</i>
1595         public static final int CC_SYSCALL = CALLCONV.CC_FPFASTCALL + 1;
1596         // / <i>native declaration : line 12</i>
1597         public static final int CC_MPWCDECL = CALLCONV.CC_SYSCALL + 1;
1598         // / <i>native declaration : line 13</i>
1599         public static final int CC_MPWPASCAL = CALLCONV.CC_MPWCDECL + 1;
1600         // / <i>native declaration : line 14</i>
1601         public static final int CC_MAX = CALLCONV.CC_MPWPASCAL + 1;
1602 
1603         public int value;
1604 
CALLCONV()1605         public CALLCONV() {
1606         }
1607 
CALLCONV(int value)1608         public CALLCONV(int value) {
1609             this.value = value;
1610         }
1611     }
1612 
1613     @FieldOrder({"value"})
1614     public static class VARKIND extends Structure {
1615         public static class ByReference extends VARKIND implements
1616                 Structure.ByReference {
1617         };
1618 
1619         // / <i>native declaration : line 4</i>
1620         public static final int VAR_PERINSTANCE = 0;
1621         // / <i>native declaration : line 5</i>
1622         public static final int VAR_STATIC = VAR_PERINSTANCE + 1;
1623         // / <i>native declaration : line 6</i>
1624         public static final int VAR_CONST = VAR_STATIC + 1;
1625         // / <i>native declaration : line 7</i>
1626         public static final int VAR_DISPATCH = VAR_CONST + 1;
1627 
1628         public int value;
1629 
VARKIND()1630         public VARKIND() {
1631             super();
1632         }
1633 
VARKIND(int value)1634         public VARKIND(int value) {
1635             this.value = value;
1636         }
1637     }
1638 
1639     @FieldOrder({"_typedesc", "vt"})
1640     public static class TYPEDESC extends Structure {
1641         public static class ByReference extends TYPEDESC implements
1642                 Structure.ByReference {
1643         };
1644 
1645 
1646         public static class _TYPEDESC extends Union {
1647             /**
1648              * [case()]<br>
1649              * C type : tagTYPEDESC*
1650              */
1651             public TYPEDESC.ByReference lptdesc;
1652             /**
1653              * [case()]<br>
1654              * C type : tagARRAYDESC*
1655              */
1656             public ARRAYDESC.ByReference lpadesc;
1657             /**
1658              * [case()]<br>
1659              * C type : HREFTYPE
1660              */
1661             public HREFTYPE hreftype;
1662 
_TYPEDESC()1663             public _TYPEDESC() {
1664                 this.setType("hreftype");
1665                 this.read();
1666             }
1667 
_TYPEDESC(Pointer pointer)1668             public _TYPEDESC(Pointer pointer) {
1669                 super(pointer);
1670                 this.setType("hreftype");
1671                 this.read();
1672             }
1673 
getLptdesc()1674             public TYPEDESC.ByReference getLptdesc() {
1675                 this.setType("lptdesc");
1676                 this.read();
1677                 return this.lptdesc;
1678             }
1679 
getLpadesc()1680             public ARRAYDESC.ByReference getLpadesc() {
1681                 this.setType("lpadesc");
1682                 this.read();
1683                 return this.lpadesc;
1684             }
1685 
getHreftype()1686             public HREFTYPE getHreftype() {
1687                 this.setType("hreftype");
1688                 this.read();
1689                 return this.hreftype;
1690             }
1691         };
1692 
1693         public _TYPEDESC _typedesc;
1694         public VARTYPE vt;
1695 
TYPEDESC()1696         public TYPEDESC() {
1697             this.read();
1698         }
1699 
TYPEDESC(Pointer pointer)1700         public TYPEDESC(Pointer pointer) {
1701             super(pointer);
1702             this.read();
1703         }
1704 
TYPEDESC(_TYPEDESC _typedesc, VARTYPE vt)1705         public TYPEDESC(_TYPEDESC _typedesc, VARTYPE vt) {
1706             this._typedesc = _typedesc;
1707             this.vt = vt;
1708         }
1709     }
1710 
1711     @FieldOrder({"dwReserved", "wIDLFlags"})
1712     public static class IDLDESC extends Structure {
1713         public static class ByReference extends IDLDESC implements
1714                 Structure.ByReference {
1715 
ByReference()1716             public ByReference() {
1717                 super();
1718             }
1719 
ByReference(IDLDESC idldesc)1720             public ByReference(IDLDESC idldesc) {
1721                 super(idldesc.dwReserved, idldesc.wIDLFlags);
1722             }
1723         };
1724 
1725         // / C type : ULONG_PTR
1726         public ULONG_PTR dwReserved;
1727         public USHORT wIDLFlags;
1728 
IDLDESC()1729         public IDLDESC() {
1730             super();
1731         }
1732 
IDLDESC(Pointer pointer)1733         public IDLDESC(Pointer pointer) {
1734             super(pointer);
1735             this.read();
1736         }
1737 
1738         // / @param dwReserved C type : ULONG_PTR
IDLDESC(ULONG_PTR dwReserved, USHORT wIDLFlags)1739         public IDLDESC(ULONG_PTR dwReserved, USHORT wIDLFlags) {
1740             this.dwReserved = dwReserved;
1741             this.wIDLFlags = wIDLFlags;
1742         }
1743     }
1744 
1745     @FieldOrder({"tdescElem", "cDims", "rgbounds"})
1746     public class ARRAYDESC extends Structure {
1747         // / C type : TYPEDESC
1748         public TYPEDESC tdescElem;
1749         public short cDims;
1750         /**
1751          * [size_is]<br>
1752          * C type : SAFEARRAYBOUND[1]
1753          */
1754         public SAFEARRAYBOUND[] rgbounds = { new SAFEARRAYBOUND() };
1755 
ARRAYDESC()1756         public ARRAYDESC() {
1757             super();
1758         }
1759 
ARRAYDESC(Pointer pointer)1760         public ARRAYDESC(Pointer pointer) {
1761             super(pointer);
1762             this.read();
1763         }
1764 
1765         /**
1766          * @param tdescElem
1767          *            C type : TYPEDESC<br>
1768          * @param cDims dimensions
1769          * @param rgbounds
1770          *            [size_is]<br>
1771          *            C type : SAFEARRAYBOUND[1]
1772          */
ARRAYDESC(TYPEDESC tdescElem, short cDims, SAFEARRAYBOUND rgbounds[])1773         public ARRAYDESC(TYPEDESC tdescElem, short cDims, SAFEARRAYBOUND rgbounds[]) {
1774             this.tdescElem = tdescElem;
1775             this.cDims = cDims;
1776             if (rgbounds.length != this.rgbounds.length)
1777                 throw new IllegalArgumentException("Wrong array size !");
1778             this.rgbounds = rgbounds;
1779         }
1780 
1781         public static class ByReference extends ARRAYDESC implements
1782                 Structure.ByReference {
1783 
1784         };
1785     }
1786 
1787     @FieldOrder({"pparamdescex", "wParamFlags"})
1788     public static class PARAMDESC extends Structure {
1789         public static class ByReference extends PARAMDESC implements
1790                 Structure.ByReference {
1791         }
1792 
1793         // replaced PARAMDESCEX.ByReference with Pointer
1794         // because of JNA 4 has a problem with ByReference
1795         public Pointer pparamdescex;
1796         public USHORT wParamFlags;
1797 
PARAMDESC()1798         public PARAMDESC() {
1799             super();
1800         }
1801 
PARAMDESC(Pointer pointer)1802         public PARAMDESC(Pointer pointer) {
1803             super(pointer);
1804             this.read();
1805         }
1806     }
1807 
1808     @FieldOrder({"cBytes", "varDefaultValue"})
1809     public static class PARAMDESCEX extends Structure {
1810         public static class ByReference extends PARAMDESCEX implements
1811                 Structure.ByReference {
1812         };
1813 
1814         public ULONG cBytes;
1815         public VariantArg varDefaultValue;
1816 
PARAMDESCEX()1817         public PARAMDESCEX() {
1818             super();
1819         }
1820 
PARAMDESCEX(Pointer pointer)1821         public PARAMDESCEX(Pointer pointer) {
1822             super(pointer);
1823             this.read();
1824         }
1825     }
1826 
1827     public static class HREFTYPE extends DWORD {
1828         private static final long serialVersionUID = 1L;
1829 
HREFTYPE()1830         public HREFTYPE() {
1831             super();
1832         }
1833 
HREFTYPE(long value)1834         public HREFTYPE(long value) {
1835             super(value);
1836         }
1837     }
1838 
1839     public static class HREFTYPEByReference extends DWORDByReference {
HREFTYPEByReference()1840         public HREFTYPEByReference() {
1841             this(new HREFTYPE(0));
1842         }
1843 
HREFTYPEByReference(DWORD value)1844         public HREFTYPEByReference(DWORD value) {
1845             super(value);
1846         }
1847 
setValue(HREFTYPE value)1848         public void setValue(HREFTYPE value) {
1849             getPointer().setInt(0, value.intValue());
1850         }
1851 
1852         @Override
getValue()1853         public HREFTYPE getValue() {
1854             return new HREFTYPE(getPointer().getInt(0));
1855         }
1856     }
1857 
1858     @FieldOrder({"guid", "lcid", "dwReserved", "memidConstructor",
1859         "memidDestructor", "lpstrSchema", "cbSizeInstance", "typekind",
1860         "cFuncs", "cVars", "cImplTypes", "cbSizeVft", "cbAlignment",
1861         "wTypeFlags", "wMajorVerNum", "wMinorVerNum", "tdescAlias",
1862         "idldescType"})
1863     public class TYPEATTR extends Structure {
1864         public static class ByReference extends TYPEATTR implements
1865                 Structure.ByReference {
1866         };
1867 
1868         // / C type : GUID
1869         public GUID guid;
1870         // / C type : LCID
1871         public LCID lcid;
1872         public DWORD dwReserved;
1873         // / C type : MEMBERID
1874         public MEMBERID memidConstructor;
1875         // / C type : MEMBERID
1876         public MEMBERID memidDestructor;
1877         // / C type : LPOLESTR
1878         public LPOLESTR lpstrSchema;
1879         public ULONG cbSizeInstance;
1880         // / C type : TYPEKIND
1881         public TYPEKIND typekind;
1882         public WORD cFuncs;
1883         public WORD cVars;
1884         public WORD cImplTypes;
1885         public WORD cbSizeVft;
1886         public WORD cbAlignment;
1887         // The type flags. See TYPEFLAGS_...
1888         public WORD wTypeFlags;
1889         public WORD wMajorVerNum;
1890         public WORD wMinorVerNum;
1891         // / C type : TYPEDESC
1892         public TYPEDESC tdescAlias;
1893         // / C type : IDLDESC
1894         public IDLDESC idldescType;
1895 
TYPEATTR()1896         public TYPEATTR() {
1897             super();
1898         }
1899 
TYPEATTR(Pointer pointer)1900         public TYPEATTR(Pointer pointer) {
1901             super(pointer);
1902             this.read();
1903         }
1904 
1905         /**
1906          * A type description that describes an Application object.
1907          */
1908         public final static int TYPEFLAGS_FAPPOBJECT = 0x1;
1909 
1910         /**
1911          * Instances of the type can be created by ITypeInfo::CreateInstance.
1912          */
1913         public final static int TYPEFLAGS_FCANCREATE = 0x2;
1914 
1915         /**
1916          * The type is licensed.
1917          */
1918         public final static int TYPEFLAGS_FLICENSED = 0x4;
1919 
1920         /**
1921          * The type is predefined. The client application should automatically create a single instance of the object
1922          * that has this attribute. The name of the variable that points to the object is the same as the class name of
1923          * the object.
1924          */
1925         public final static int TYPEFLAGS_FPREDECLID = 0x8;
1926 
1927         /**
1928          * The type should not be displayed to browsers.
1929          */
1930         public final static int TYPEFLAGS_FHIDDEN = 0x10;
1931 
1932         /**
1933          * The type is a control from which other types will be derived, and should not be displayed to users.
1934          */
1935         public final static int TYPEFLAGS_FCONTROL = 0x20;
1936 
1937         /**
1938          * The interface supplies both IDispatch and VTBL binding.
1939          */
1940         public final static int TYPEFLAGS_FDUAL = 0x40;
1941 
1942         /**
1943          * The interface cannot add members at run time.
1944          */
1945         public final static int TYPEFLAGS_FNONEXTENSIBLE = 0x80;
1946 
1947         /**
1948          * The types used in the interface are fully compatible with Automation, including VTBL binding support. Setting
1949          * dual on an interface sets this flag in addition to TYPEFLAG_FDUAL. Not allowed on dispinterfaces.
1950          */
1951         public final static int TYPEFLAGS_FOLEAUTOMATION = 0x100;
1952 
1953         /**
1954          * Should not be accessible from macro languages. This flag is intended for system-level types or types that
1955          * type browsers should not display.
1956          */
1957         public final static int TYPEFLAGS_FRESTRICTED = 0x200;
1958 
1959         /**
1960          * The class supports aggregation.
1961          */
1962         public final static int TYPEFLAGS_FAGGREGATABLE = 0x400;
1963 
1964         /**
1965          * The type is replaceable.
1966          */
1967         public final static int TYPEFLAGS_FREPLACEABLE = 0x800;
1968 
1969         /**
1970          * Indicates that the interface derives from IDispatch, either directly or indirectly. This flag is computed.
1971          * There is no Object Description Language for the flag.
1972          */
1973         public final static int TYPEFLAGS_FDISPATCHABLE = 0x1000;
1974 
1975         /**
1976          * The type has reverse binding.
1977          */
1978         public final static int TYPEFLAGS_FREVERSEBIND = 0x2000;
1979 
1980         /**
1981          * Interfaces can be marked with this flag to indicate that they will be using a proxy/stub dynamic link
1982          * library. This flag specifies that the typelib proxy should not be unregistered when the typelib is
1983          * unregistered.
1984          */
1985         public final static int TYPEFLAGS_FPROXY = 0x4000;
1986     }
1987 }
1988