1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  * Port to the D programming language:
11  *     Frank Benoit <benoit@tionex.de>
12  *******************************************************************************/
13 module org.eclipse.swt.ole.win32.OLE;
14 
15 import java.io.File;
16 
17 import org.eclipse.swt.SWT;
18 import org.eclipse.swt.SWTError;
19 import org.eclipse.swt.SWTException;
20 import org.eclipse.swt.internal.ole.win32.COM;
21 import org.eclipse.swt.internal.win32.OS;
22 
23 import java.lang.all;
24 /**
25  *
26  * OLE contains all the constants used to create an ActiveX Control or an OLE Document.
27  *
28  * <p>Definitions for these constants can be found in MSDN.
29  *
30  */
31 public class OLE : SWT {
32 
33     public static const int S_FALSE = 1; // Used for functions that semantically return a bool FALSE result to indicate that the function succeeded.
34     public static const int S_OK    = 0; // Function succeeded.
35     public static const int E_FAIL = -2147467259;  // Unspecified failure.
36     public static const int E_INVALIDARG = -2147024809; // Invalid argument
37     public static const int E_NOINTERFACE = -2147467262;  // QueryInterface did not recognize the requested interface.
38     public static const int E_NOTIMPL = -2147467263; // Not implemented
39 
40     public static const String IID_IUNKNOWN = "{00000000-0000-0000-C000-000000000046}"; //$NON-NLS-1$
41     public static const String IID_IDISPATCH = "{00020400-0000-0000-C000-000000000046}"; //$NON-NLS-1$
42 
43     // Verbs that can be invoked on this client
44     public static const int OLEIVERB_DISCARDUNDOSTATE = -6; // close the OLE object and discard the undo state
45     public static const int OLEIVERB_HIDE             = -3; // hide the OLE object
46     public static const int OLEIVERB_INPLACEACTIVATE  = -5; // open the OLE for editing in-place
47     public static const int OLEIVERB_OPEN             = -2; // open the OLE object for editing in a separate window
48     public static const int OLEIVERB_PRIMARY          =  0; // opens the OLE object for editing
49     public static const int OLEIVERB_PROPERTIES       = -7; // request the OLE object properties dialog
50     public static const int OLEIVERB_SHOW             = -1; // show the OLE object
51     public static const int OLEIVERB_UIACTIVATE       = -4; // activate the UI for the OLE object
52 
53     public static const int PROPERTY_CHANGING = 0;
54     public static const int PROPERTY_CHANGED = 1;
55 
56     /**
57      * Error code for OleError - No specific error information available
58      */
59     public static const int HRESULT_UNSPECIFIED       = 0;
60     /**
61      * Error code for OleError - Failed to create file
62      */
63     public static const int ERROR_CANNOT_CREATE_FILE = 1000;
64     /**
65      * Error code for OleError - Failed to create Ole Client
66      */
67     public static const int ERROR_CANNOT_CREATE_OBJECT = 1001;
68     /**
69      * Error code for OleError - File does not exist, is not accessible to user or does not have the correct format
70      */
71     public static const int ERROR_CANNOT_OPEN_FILE = 1002;
72     /**
73      * Error code for OleError - Failed to find requested interface on OLE Object
74      */
75     public static const int ERROR_INTERFACE_NOT_FOUND = 1003;
76     /**
77      * Error code for OleError - Class ID not found in registry
78      */
79     public static const int ERROR_INVALID_CLASSID = 1004;
80     /**
81      * Error code for OleError - Failed to get the class factory for the specified classID
82      */
83     public static const int ERROR_CANNOT_ACCESS_CLASSFACTORY = 1005;
84     /**
85      * Error code for OleError - Failed to create Licensed instance
86      */
87     public static const int ERROR_CANNOT_CREATE_LICENSED_OBJECT = 1006;
88     /**
89      * Error code for OleError - Out of Memory
90      */
91     public static const int ERROR_OUT_OF_MEMORY = 1007;
92     /**
93      * Error code for OleError - Failed to change Variant type
94      */
95     public static const int ERROR_CANNOT_CHANGE_VARIANT_TYPE = 1010;
96     /**
97      * Error code for OleError - Invalid address received for Ole Interface
98      */
99     public static const int ERROR_INVALID_INTERFACE_ADDRESS = 1011;
100     /**
101      * Error code for OleError - Unable to find Application
102      */
103     public static const int ERROR_APPLICATION_NOT_FOUND = 1013;
104     /**
105      * Error code for OleError - Action can not be performed
106      */
107     public static const int ERROR_ACTION_NOT_PERFORMED = 1014;
108 
109     public static const int OLECMDF_SUPPORTED    = 1;
110     public static const int OLECMDF_ENABLED      = 2;
111     public static const int OLECMDF_LATCHED      = 4;
112     public static const int OLECMDF_NINCHED      = 8;
113 
114     public static const int OLECMDTEXTF_NONE      = 0;
115     public static const int OLECMDTEXTF_NAME      = 1;
116     public static const int OLECMDTEXTF_STATUS    = 2;
117 
118     public static const int OLECMDEXECOPT_DODEFAULT        = 0;
119     public static const int OLECMDEXECOPT_PROMPTUSER       = 1;
120     public static const int OLECMDEXECOPT_DONTPROMPTUSER   = 2;
121     public static const int OLECMDEXECOPT_SHOWHELP         = 3;
122 
123     public static const int OLECMDID_OPEN              = 1;
124     public static const int OLECMDID_NEW               = 2;
125     public static const int OLECMDID_SAVE              = 3;
126     public static const int OLECMDID_SAVEAS            = 4;
127     public static const int OLECMDID_SAVECOPYAS        = 5;
128     public static const int OLECMDID_PRINT             = 6;
129     public static const int OLECMDID_PRINTPREVIEW      = 7;
130     public static const int OLECMDID_PAGESETUP         = 8;
131     public static const int OLECMDID_SPELL             = 9;
132     public static const int OLECMDID_PROPERTIES        = 10;
133     public static const int OLECMDID_CUT               = 11;
134     public static const int OLECMDID_COPY              = 12;
135     public static const int OLECMDID_PASTE             = 13;
136     public static const int OLECMDID_PASTESPECIAL      = 14;
137     public static const int OLECMDID_UNDO              = 15;
138     public static const int OLECMDID_REDO              = 16;
139     public static const int OLECMDID_SELECTALL         = 17;
140     public static const int OLECMDID_CLEARSELECTION    = 18;
141     public static const int OLECMDID_ZOOM              = 19;
142     public static const int OLECMDID_GETZOOMRANGE      = 20;
143     public static const int OLECMDID_UPDATECOMMANDS    = 21;
144     public static const int OLECMDID_REFRESH           = 22;
145     public static const int OLECMDID_STOP              = 23;
146     public static const int OLECMDID_HIDETOOLBARS      = 24;
147     public static const int OLECMDID_SETPROGRESSMAX    = 25;
148     public static const int OLECMDID_SETPROGRESSPOS    = 26;
149     public static const int OLECMDID_SETPROGRESSTEXT   = 27;
150     public static const int OLECMDID_SETTITLE          = 28;
151     public static const int OLECMDID_SETDOWNLOADSTATE  = 29;
152     public static const int OLECMDID_STOPDOWNLOAD      = 30;
153 
154     /* Ole Property Description flags */
155     public static int VARFLAG_FREADONLY = 0x1;
156     public static int VARFLAG_FSOURCE = 0x2;
157     public static int VARFLAG_FBINDABLE = 0x4;
158     public static int VARFLAG_FREQUESTEDIT = 0x8;
159     public static int VARFLAG_FDISPLAYBIND = 0x10;
160     public static int VARFLAG_FDEFAULTBIND = 0x20;
161     public static int VARFLAG_FHIDDEN = 0x40;
162     public static int VARFLAG_FRESTRICTED = 0x80;
163     public static int VARFLAG_FDEFAULTCOLLELEM = 0x100;
164     public static int VARFLAG_FUIDEFAULT = 0x200;
165     public static int VARFLAG_FNONBROWSABLE = 0x400;
166     public static int VARFLAG_FREPLACEABLE = 0x800;
167     public static int VARFLAG_FIMMEDIATEBIND = 0x1000;
168 
169     /* Ole Property Description kind */
170     public static int VAR_PERINSTANCE = 0;
171     public static int VAR_STATIC = 1;
172     public static int VAR_CONST = 2;
173     public static int VAR_DISPATCH = 3;
174 
175     /* Ole Parameter Description flags */
176     public static short IDLFLAG_NONE = 0;
177     public static short IDLFLAG_FIN = 1;
178     public static short IDLFLAG_FOUT = 2;
179     public static short IDLFLAG_FLCID = 4;
180     public static short IDLFLAG_FRETVAL = 8;
181 
182     /* Ole Description types */
183     public static const short VT_BOOL = 11;     // bool; True=-1, False=0.
184     public static const short VT_BSTR = 8;      // Binary String.
185     public static const short VT_BYREF = 16384; // By reference - must be combined with one of the other VT values
186     public static const short VT_CY = 6;        // Currency.
187     public static const short VT_DATE = 7;      // Date.
188     public static const short VT_DISPATCH = 9;  // IDispatch
189     public static const short VT_EMPTY = 0;     // Not specified.
190     public static const short VT_ERROR = 10;    // Scodes.
191     public static const short VT_I2 = 2;        // 2-byte signed int.
192     public static const short VT_I4 = 3;        // 4-byte signed int.
193     public static const short VT_NULL = 1;      // Null.
194     public static const short VT_R4 = 4;        // 4-byte real.
195     public static const short VT_R8 = 5;        // 8-byte real.
196     public static const short VT_UI1 = 17;      // Unsigned char.
197     public static const short VT_UI4 = 19;      // Unsigned int.
198     public static const short VT_UNKNOWN = 13;  // IUnknown FAR*.
199     public static const short VT_VARIANT = 12;  // VARIANT FAR*.
200     public static const short VT_PTR = 26;
201     public static const short VT_USERDEFINED = 29;
202     public static const short VT_HRESULT = 25;
203     public static const short VT_DECIMAL = 14;
204     public static const short VT_I1 = 16;
205     public static const short VT_UI2 = 18;
206     public static const short VT_I8 = 20;
207     public static const short VT_UI8 = 21;
208     public static const short VT_INT = 22;
209     public static const short VT_UINT = 23;
210     public static const short VT_VOID = 24;
211     public static const short VT_SAFEARRAY = 27;
212     public static const short VT_CARRAY = 28;
213     public static const short VT_LPSTR = 30;
214     public static const short VT_LPWSTR = 31;
215     public static const short VT_RECORD = 36;
216     public static const short VT_FILETIME = 64;
217     public static const short VT_BLOB = 65;
218     public static const short VT_STREAM = 66;
219     public static const short VT_STORAGE = 67;
220     public static const short VT_STREAMED_OBJECT = 68;
221     public static const short VT_STORED_OBJECT = 69;
222     public static const short VT_BLOB_OBJECT = 70;
223     public static const short VT_CF = 71;
224     public static const short VT_CLSID = 72;
225     public static const short VT_VERSIONED_STREAM = 73;
226     public static const short VT_BSTR_BLOB = 0xfff;
227     public static const short VT_VECTOR = 0x1000;
228     public static const short VT_ARRAY = 0x2000;
229 
230     /* Ole Function Description Invoke Kind values */
231     public static const int INVOKE_FUNC = 1;
232     public static const int INVOKE_PROPERTYGET = 2;
233     public static const int INVOKE_PROPERTYPUT = 4;
234     public static const int INVOKE_PROPERTYPUTREF = 8;
235 
236     /* Ole Function Description function kind */
237     public static const int FUNC_VIRTUAL = 0;
238     public static const int FUNC_PUREVIRTUAL = 1;
239     public static const int FUNC_NONVIRTUAL = 2;
240     public static const int FUNC_STATIC = 3;
241     public static const int FUNC_DISPATCH = 4;
242 
243     /* Ole Function Description function flags */
244     public static const short FUNCFLAG_FRESTRICTED = 1;
245     public static const short FUNCFLAG_FSOURCE = 0x2;
246     public static const short FUNCFLAG_FBINDABLE = 0x4;
247     public static const short FUNCFLAG_FREQUESTEDIT = 0x8;
248     public static const short FUNCFLAG_FDISPLAYBIND = 0x10;
249     public static const short FUNCFLAG_FDEFAULTBIND = 0x20;
250     public static const short FUNCFLAG_FHIDDEN = 0x40;
251     public static const short FUNCFLAG_FUSESGETLASTERROR = 0x80;
252     public static const short FUNCFLAG_FDEFAULTCOLLELEM = 0x100;
253     public static const short FUNCFLAG_FUIDEFAULT = 0x200;
254     public static const short FUNCFLAG_FNONBROWSABLE = 0x400;
255     public static const short FUNCFLAG_FREPLACEABLE = 0x800;
256     public static const short FUNCFLAG_FIMMEDIATEBIND = 0x1000;
257 
258     /* Ole Function Description calling convention */
259     public static const int CC_FASTCALL = 0;
260     public static const int CC_CDECL = 1;
261     public static const int CC_MSCPASCAL = 2;
262     public static const int CC_PASCAL = 2;
263     public static const int CC_MACPASCAL = 3;
264     public static const int CC_STDCALL = 4;
265     public static const int CC_FPFASTCALL = 5;
266     public static const int CC_SYSCALL = 6;
267     public static const int CC_MPWCDECL = 7;
268     public static const int CC_MPWPASCAL = 8;
269     public static const int CC_MAX = 9;
270 
271     static const String ERROR_NOT_IMPLEMENTED_MSG = "Required functionality not currently supported.";//$NON-NLS-1$
272     static const String ERROR_CANNOT_CREATE_FILE_MSG = "Failed to create file.";//$NON-NLS-1$
273     static const String ERROR_CANNOT_CREATE_OBJECT_MSG = "Failed to create Ole Client.";//$NON-NLS-1$
274     static const String ERROR_CANNOT_OPEN_FILE_MSG = "File does not exist, is not accessible to user or does not have the correct format.";//$NON-NLS-1$
275     static const String ERROR_INTERFACE_NOT_FOUND_MSG = "Failed to find requested interface on OLE Object.";//$NON-NLS-1$
276     static const String ERROR_INVALID_CLASSID_MSG = "Class ID not found in registry";//$NON-NLS-1$
277     static const String ERROR_CANNOT_ACCESS_CLASSFACTORY_MSG = "Failed to get the class factory for the specified classID";//$NON-NLS-1$
278     static const String ERROR_CANNOT_CREATE_LICENSED_OBJECT_MSG = "Failed to create Licensed instance";//$NON-NLS-1$
279     static const String ERROR_OUT_OF_MEMORY_MSG = "Out of Memory";//$NON-NLS-1$
280     static const String ERROR_CANNOT_CHANGE_VARIANT_TYPE_MSG = "Failed to change Variant type";//$NON-NLS-1$
281     static const String ERROR_INVALID_INTERFACE_ADDRESS_MSG = "Invalid address received for Ole Interface.";//$NON-NLS-1$
282     static const String ERROR_APPLICATION_NOT_FOUND_MSG = "Unable to find Application.";//$NON-NLS-1$
283     static const String ERROR_ACTION_NOT_PERFORMED_MSG = "Action can not be performed.";//$NON-NLS-1$
284 
285 
286 public static void error (String file, long line, int code) {
287     error (code, 0);
288 }
289 public static void error (int code) {
290     error (code, 0);
291 }
292 public static void error (String file, long line, int code, int hresult) {
293     error (code, hresult);
294 }
295 public static void error (int code, int hresult) {
296 
297     switch (code) {
298         /* Illegal Arguments (non-fatal) */
299         case ERROR_INVALID_INTERFACE_ADDRESS :{
300             throw new IllegalArgumentException (ERROR_INVALID_INTERFACE_ADDRESS_MSG);
301         }
302 
303         /* SWT Errors (non-fatal) */
304         case ERROR_CANNOT_CREATE_FILE : {
305             String msg = ERROR_CANNOT_CREATE_FILE_MSG;
306             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
307             throw new SWTException (code, msg);
308         }
309         case ERROR_CANNOT_CREATE_OBJECT : {
310             String msg = ERROR_CANNOT_CREATE_OBJECT_MSG;
311             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
312             throw new SWTException (code, msg);//$NON-NLS-1$
313         }
314         case ERROR_CANNOT_OPEN_FILE : {
315             String msg = ERROR_CANNOT_OPEN_FILE_MSG;
316             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
317             throw new SWTException (code, msg);
318         }
319         case ERROR_INTERFACE_NOT_FOUND : {
320             String msg = ERROR_INTERFACE_NOT_FOUND_MSG;
321             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
322             throw new SWTException (code, msg);
323         }
324         case ERROR_INVALID_CLASSID : {
325             String msg = ERROR_INVALID_CLASSID_MSG;
326             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
327             throw new SWTException (code, msg);
328         }
329         case ERROR_CANNOT_ACCESS_CLASSFACTORY : {
330             String msg = ERROR_CANNOT_ACCESS_CLASSFACTORY_MSG;
331             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
332             throw new SWTException (code, msg);
333         }
334         case ERROR_CANNOT_CREATE_LICENSED_OBJECT : {
335             String msg = ERROR_CANNOT_CREATE_LICENSED_OBJECT_MSG;
336             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
337             throw new SWTException (code, msg);
338         }
339         case ERROR_CANNOT_CHANGE_VARIANT_TYPE : {
340             String msg = ERROR_CANNOT_CHANGE_VARIANT_TYPE_MSG;
341             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
342             throw new SWTException (code, msg);
343         }
344         case ERROR_APPLICATION_NOT_FOUND : {
345             String msg = ERROR_APPLICATION_NOT_FOUND_MSG;
346             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
347             throw new SWTException (code, msg);
348         }
349         case ERROR_ACTION_NOT_PERFORMED : {
350             String msg = ERROR_ACTION_NOT_PERFORMED_MSG;
351             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult);//$NON-NLS-1$
352             throw new SWTException (code, msg);
353         }
354 
355         /* OS Failure/Limit (fatal, may occur only on some platforms) */
356         case ERROR_OUT_OF_MEMORY : {
357             String msg = ERROR_ACTION_NOT_PERFORMED_MSG;
358             if (hresult !is 0) msg ~= " result = "~String_valueOf(hresult); //$NON-NLS-1$
359             throw new SWTError (code, msg);
360         }
361         default:
362     }
363 
364     /* Unknown/Undefined Error */
365     SWT.error(code);
366 }
367 
368 /*
369  * Finds the OLE program id that is associated with an extension.
370  * The extension may or may not begin with a '.'.  On platforms
371  * that do not support OLE, an empty string is returned.
372  *
373  * @param extension the program extension
374  * @return a string that is the OLE program id or an empty string
375  *
376  * @exception IllegalArgumentException <ul>
377  *      <li>ERROR_NULL_ARGUMENT when extension is null</li>
378  *  </ul>
379  */
380 public static String findProgramID (String extension) {
381     if (extension is null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
382     if (extension.length is 0) return ""; //$NON-NLS-1$
383 
384     if (extension.charAt (0) !is '.') extension = "." ~ extension; //$NON-NLS-1$
385 
386     /* Use the character encoding for the default locale */
387     StringT extensionKey = StrToTCHARs(0, extension, true);
388     String result = getKeyValue(extensionKey);
389     if (result !is null) {
390         // look for "<programID>\NotInsertable"
391         StringT notInsertableKey = StrToTCHARs(0, result~"\\NotInsertable", true); //$NON-NLS-1$
392         if (getKeyExists(notInsertableKey)) return ""; //$NON-NLS-1$
393         // look for "<programID>\Insertable"
394         StringT insertableKey = StrToTCHARs(0, result~"\\Insertable", true); //$NON-NLS-1$
395         if (getKeyExists(insertableKey)) return result;
396         // look for "<programID>\protocol\StdFileEditing\server"
397         StringT serverKey = StrToTCHARs(0, result~"\\protocol\\StdFileEditing\\server", true); //$NON-NLS-1$
398         if (getKeyExists(serverKey)) return result;
399     }
400 
401     return ""; //$NON-NLS-1$
402 }
403 static String getKeyValue (StringT key) {
404     void* [1] phkResult;
405     if (OS.RegOpenKeyEx (cast(void*)OS.HKEY_CLASSES_ROOT, key.ptr, 0, OS.KEY_READ, phkResult.ptr) !is 0) {
406         return null;
407     }
408     String result = null;
409     uint [1] lpcbData;
410     if (OS.RegQueryValueEx (phkResult [0], null, null, null, null, lpcbData.ptr) is 0) {
411         int length_ = lpcbData [0] / TCHAR.sizeof;
412         if (length_ is 0) {
413             result = "";
414         } else {
415             /* Use the character encoding for the default locale */
416             TCHAR[] lpData = NewTCHARs (0, length_);
417             if (OS.RegQueryValueEx (phkResult [0], null, null, null, cast(ubyte*)lpData.ptr, lpcbData.ptr) is 0) {
418                 length_ = Math.max(0, cast(int)/*64bit*/lpData.length - 1);
419                 result = TCHARsToStr( lpData[ 0 .. length_ ] );
420             }
421         }
422     }
423     if (phkResult [0] !is null) OS.RegCloseKey (phkResult [0]);
424     return result;
425 }
426 private static bool getKeyExists (StringT key) {
427     void* [1] phkResult;
428     if (OS.RegOpenKeyEx (cast(void*)OS.HKEY_CLASSES_ROOT, key.ptr, 0, OS.KEY_READ, phkResult.ptr) !is 0) {
429         return false;
430     }
431     if (phkResult [0] !is null) OS.RegCloseKey (phkResult [0]);
432     return true;
433 }
434 /**
435  * Returns true if the specified file has an OLE Storage format.
436  *
437  * Note all empty files (regardless of extension) will return false.
438  *
439  * @param file the file to be checked
440  *
441  * @return true if this file has an OLE Storage format
442  */
443 public static bool isOleFile(File file) {
444     if (file is null || !file.exists() || file.isDirectory())
445         return false;
446 
447     return (COM.StgIsStorageFile( StrToTCHARz(file.getAbsolutePath()~"\0")) is COM.S_OK);
448 }
449 
450 }