root / trunk / install / IzPack / src / native / ShellLink.cpp @ 11445
History | View | Annotate | Download (45.5 KB)
1 | 5819 | cesar | /*
|
---|---|---|---|
2 | * IzPack Version 3.0.0 pre4 (build 2002.06.15)
|
||
3 | * Copyright (C) 2002 by Elmar Grom
|
||
4 | *
|
||
5 | * File : ShellLink.c
|
||
6 | * Description : Represents a MS-Windows Shell Link (shortcut)
|
||
7 | * This is the native counterpart to ShellLink.java
|
||
8 | * Author's email : elmar@grom.net
|
||
9 | * Website : http://www.izforge.com
|
||
10 | *
|
||
11 | * This program is free software; you can redistribute it and/or
|
||
12 | * modify it under the terms of the GNU General Public License
|
||
13 | * as published by the Free Software Foundation; either version 2
|
||
14 | * of the License, or any later version.
|
||
15 | *
|
||
16 | * This program is distributed in the hope that it will be useful,
|
||
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
19 | * GNU General Public License for more details.
|
||
20 | *
|
||
21 | * You should have received a copy of the GNU General Public License
|
||
22 | * along with this program; if not, write to the Free Software
|
||
23 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
24 | */
|
||
25 | |||
26 | #include "com_izforge_izpack_util_os_ShellLink.h" |
||
27 | #include <winerror.h> |
||
28 | #include <objbase.h> |
||
29 | #include <basetyps.h> |
||
30 | #include <shlobj.h> |
||
31 | #include <objidl.h> |
||
32 | #include <windows.h> |
||
33 | #include <tchar.h> |
||
34 | |||
35 | // --------------------------------------------------------------------------
|
||
36 | // Gound rules used for the implementation of this native interface
|
||
37 | // of ShellLink:
|
||
38 | //
|
||
39 | // 1) all functions return an integer success code
|
||
40 | // 2) positive success codes report that everything went ok
|
||
41 | // 3) negative success codes report some type of problem
|
||
42 | // 4) a success code of 0 does not exist
|
||
43 | // 5) 'get' functions deposit their results in the corresponding member
|
||
44 | // variables on the Java side.
|
||
45 | // 6) "set' functions retrieve their input from the corresponding member
|
||
46 | // variables on the Java side.
|
||
47 | // 7) functions other than 'get' and 'set' recive their input -if any- in
|
||
48 | // the form of arguments.
|
||
49 | // 8) functions that are exposed on the Java side (public, protectd)
|
||
50 | // follow the Java naming conventions, in that they begin with a lower
|
||
51 | // case character.
|
||
52 | // 9) all functions that have a Java wrapper by the same name follow the
|
||
53 | // Windows naming convention, in that they start with an upper case
|
||
54 | // letter. This avoids having to invent new method names for Java and
|
||
55 | // it allows to keep a clean naming convention on the Java side.
|
||
56 | // ============================================================================
|
||
57 | //
|
||
58 | // I M P O R T A N T !
|
||
59 | // -------------------
|
||
60 | //
|
||
61 | // This interface communicates with the OS via COM. In order for things to
|
||
62 | // work properly, it is necessary to observe the following pattern of
|
||
63 | // operation and to observe the order of execution (i.e. do not call
|
||
64 | // getInterface() before calling initializeCOM()).
|
||
65 | //
|
||
66 | // 1) call initializeCOM() - It's best to do this in the constructor
|
||
67 | // 2) call getInterface() - It's best to do this in the constructor as well
|
||
68 | //
|
||
69 | // 3) do your stuff (load, save, get, set ...)
|
||
70 | //
|
||
71 | // 4) call releaseInterface() before terminating the application, best done
|
||
72 | // in the finalizer
|
||
73 | // 5) call releaseCOM() before terminating the application, best done
|
||
74 | // in the finalizer. Do NOT call this if the call to initializeCOM() did
|
||
75 | // not succeed, otherwise you'll mess things up pretty badly!
|
||
76 | // ============================================================================
|
||
77 | // Variables that must be declared on the Java side:
|
||
78 | //
|
||
79 | // private int nativeHandle;
|
||
80 | //
|
||
81 | // private String linkPath;
|
||
82 | // private String linkName;
|
||
83 | //
|
||
84 | // private String arguments;
|
||
85 | // private String description;
|
||
86 | // private String iconPath;
|
||
87 | // private String targetPath;
|
||
88 | // private String workingDirectory;
|
||
89 | //
|
||
90 | // private int hotkey;
|
||
91 | // private int iconIndex;
|
||
92 | // private int showCommand;
|
||
93 | // private int linkType;
|
||
94 | // --------------------------------------------------------------------------
|
||
95 | |||
96 | // --------------------------------------------------------------------------
|
||
97 | // Macro Definitions
|
||
98 | // --------------------------------------------------------------------------
|
||
99 | #define ACCESS 0 // index for retrieving the registry access key |
||
100 | #define MIN_KEY 0 // for verifying that an index received in the form of a call parameter is actually leagal |
||
101 | #define MAX_KEY 5 // for verifying that an index received in the form of a call parameter is actually leagal |
||
102 | |||
103 | // --------------------------------------------------------------------------
|
||
104 | // Prototypes
|
||
105 | // --------------------------------------------------------------------------
|
||
106 | // Hey C crowd, don't freak out! ShellLink.h is auto generated and I'd like
|
||
107 | // to have everything close by in this package. Besides, these are only used
|
||
108 | // in this file...
|
||
109 | // --------------------------------------------------------------------------
|
||
110 | int getNewHandle ();
|
||
111 | void freeLinks ();
|
||
112 | |||
113 | // --------------------------------------------------------------------------
|
||
114 | // Constant Definitions
|
||
115 | // --------------------------------------------------------------------------
|
||
116 | |||
117 | // the registry keys to get access to the various shortcut locations for the current user
|
||
118 | const char CURRENT_USER_KEY [5][100] = |
||
119 | { |
||
120 | "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", // this is where the details are stored in the registry |
||
121 | "Desktop", // this is where desktop shortcuts go |
||
122 | "Programs", // this is where items of the progams menu go |
||
123 | "Start Menu", // this is right in the start menu |
||
124 | "Startup" // this is where stuff goes that should be executed on OS launch |
||
125 | }; |
||
126 | |||
127 | // the registry keys to get access to the various shortcut locations for all users
|
||
128 | const char ALL_USER_KEY [5][100] = |
||
129 | { |
||
130 | "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders", // this is where the details are stored in the registry |
||
131 | "Common Desktop", // this is where desktop shortcuts go |
||
132 | "Common Programs", // this is where items of the progams menu go |
||
133 | "Common Start Menu", // this is right in the start menu |
||
134 | "Common Startup" // this is where stuff goes that should be executed on OS launch |
||
135 | }; |
||
136 | |||
137 | // Success Codes
|
||
138 | const jint SL_OK = 1; // returned if a call was successful |
||
139 | const jint SL_ERROR = -1; // unspecific return if a call was not successful |
||
140 | const jint SL_INITIALIZED = -2; // return value from initialization functions if already initialized |
||
141 | const jint SL_NOT_INITIALIZED = -3; // return value from uninitialization functions if never initialized |
||
142 | const jint SL_OUT_OF_HANDLES = -4; // there are no more interface handles available |
||
143 | const jint SL_NO_IPERSIST = -5; // could not get a handle for the IPersist interface |
||
144 | const jint SL_NO_SAVE = -6; // could not save the link |
||
145 | const jint SL_WRONG_DATA_TYPE = -7; // an unexpected data type has been passed or received |
||
146 | const jint SL_CAN_NOT_READ_PATH = -8; // was not able to read the link path from the Windows Registry |
||
147 | |||
148 | const int MAX_TEXT_LENGTH = 1000; // buffer size for text buffers |
||
149 | const int ALLOC_INCREMENT = 10; // allocation increment for allocation of additional storage space for link references |
||
150 | |||
151 | // --------------------------------------------------------------------------
|
||
152 | // Variable Declarations
|
||
153 | // --------------------------------------------------------------------------
|
||
154 | int referenceCount = 0; |
||
155 | |||
156 | // --------------------------------------------------------
|
||
157 | // DLLs are not objects!
|
||
158 | // --------------------
|
||
159 | // What this means is that if multiple references are made
|
||
160 | // to the same DLL in the same program space, no new
|
||
161 | // storage is allocated for the variables in the DLL.
|
||
162 | // For all practical purposes, variables in DLLs are equal
|
||
163 | // to static variables in classes - all instances share
|
||
164 | // the same storage space.
|
||
165 | // ========================================================
|
||
166 | // Since this code is designed to operate in conjunction
|
||
167 | // with a Java class, there is a possibility for multiple
|
||
168 | // instances of the class to acces this code 'simultaniously'.
|
||
169 | // As a result, one instance could be modifying the link
|
||
170 | // data for another instance. To avoid this, I am
|
||
171 | // artificially creating multiple DLL 'instances' by
|
||
172 | // providing a storage array for pointers to multiple
|
||
173 | // instances of IShellLink. Each Java instance must
|
||
174 | // access its IShellLink through a handle (the array
|
||
175 | // index where its corresponding pointer is stored).
|
||
176 | // ========================================================
|
||
177 | // For details on how this works see:
|
||
178 | // - getNewHandle()
|
||
179 | // - freeLinks()
|
||
180 | // --------------------------------------------------------
|
||
181 | int linkCapacity = 0; // indicates the current capacity for storing pointers |
||
182 | IShellLink** p_shellLink = NULL; // pointers to the IShellLink interface |
||
183 | |||
184 | // --------------------------------------------------------------------------
|
||
185 | // Gain COM access
|
||
186 | //
|
||
187 | // returns: SL_OK if the initialization was successfull
|
||
188 | // SL_ERROR otherwise
|
||
189 | //
|
||
190 | // I M P O R T A N T !!
|
||
191 | // --------------------
|
||
192 | //
|
||
193 | // 1) This method must be called first!
|
||
194 | // 2) The application must call releaseCOM() just before terminating but
|
||
195 | // only if a result of SL_OK was retruned form this function!
|
||
196 | // --------------------------------------------------------------------------
|
||
197 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_initializeCOM (JNIEnv *env, |
||
198 | jobject obj) |
||
199 | { |
||
200 | HRESULT hres; |
||
201 | |||
202 | if (referenceCount > 0) |
||
203 | { |
||
204 | referenceCount++; |
||
205 | return (SL_OK);
|
||
206 | } |
||
207 | |||
208 | hres = CoInitializeEx (NULL, COINIT_APARTMENTTHREADED);
|
||
209 | |||
210 | if (SUCCEEDED (hres))
|
||
211 | { |
||
212 | referenceCount++; |
||
213 | return (SL_OK);
|
||
214 | } |
||
215 | |||
216 | return (SL_ERROR);
|
||
217 | } |
||
218 | |||
219 | // --------------------------------------------------------------------------
|
||
220 | // Releases COM and frees associated resources. This function should be
|
||
221 | // called as the very last operation before the application terminates.
|
||
222 | // Call this function only if a prior call to initializeCOM() returned SL_OK.
|
||
223 | //
|
||
224 | // returns: SL_OK under normal circumstances
|
||
225 | // SL_NOT_INITIALIZED if the reference count indicates that no
|
||
226 | // current users exist.
|
||
227 | // --------------------------------------------------------------------------
|
||
228 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_releaseCOM (JNIEnv *env, |
||
229 | jobject obj) |
||
230 | { |
||
231 | referenceCount--; |
||
232 | |||
233 | if (referenceCount == 0) |
||
234 | { |
||
235 | CoUninitialize (); |
||
236 | // This is the end of things, so this is a good time to
|
||
237 | // free the storage for the IShellLink pointers.
|
||
238 | freeLinks (); |
||
239 | return (SL_OK);
|
||
240 | } |
||
241 | else if (referenceCount < 0) |
||
242 | { |
||
243 | referenceCount++; |
||
244 | return (SL_NOT_INITIALIZED);
|
||
245 | } |
||
246 | else
|
||
247 | { |
||
248 | return (SL_OK);
|
||
249 | } |
||
250 | } |
||
251 | |||
252 | // --------------------------------------------------------------------------
|
||
253 | // This function gains access to the ISchellLink interface. It must be
|
||
254 | // called before any other calls can be made but after initializeCOM().
|
||
255 | //
|
||
256 | // I M P O R T A N T !!
|
||
257 | // --------------------
|
||
258 | //
|
||
259 | // releaseInterface() must be called before terminating the application!
|
||
260 | // --------------------------------------------------------------------------
|
||
261 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_getInterface (JNIEnv *env, |
||
262 | jobject obj) |
||
263 | { |
||
264 | HRESULT hres; |
||
265 | int handle;
|
||
266 | |||
267 | // Get a handle
|
||
268 | handle = getNewHandle (); |
||
269 | if (handle < 0) |
||
270 | { |
||
271 | return (SL_OUT_OF_HANDLES);
|
||
272 | } |
||
273 | |||
274 | // Store the handle on the Java side
|
||
275 | jclass cls = (env)->GetObjectClass (obj); |
||
276 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
277 | |||
278 | (env)->SetIntField (obj, handleID, (jint)handle); |
||
279 | |||
280 | /*
|
||
281 | * Note: CoCreateInstance() supports only the creation of a single instance.
|
||
282 | * Need to find out how to use CoGetClassObject() to create multiple instances.
|
||
283 | * It should be possible to have multiple instances available, got to make this work!
|
||
284 | */
|
||
285 | |||
286 | // Get a pointer to the IShellLink interface
|
||
287 | hres = CoCreateInstance (CLSID_ShellLink, |
||
288 | NULL,
|
||
289 | CLSCTX_INPROC_SERVER, |
||
290 | IID_IShellLink, |
||
291 | (void **)&p_shellLink [handle]);
|
||
292 | |||
293 | // Do error handling
|
||
294 | if (SUCCEEDED (hres))
|
||
295 | { |
||
296 | return (SL_OK);
|
||
297 | } |
||
298 | |||
299 | return (SL_ERROR);
|
||
300 | } |
||
301 | |||
302 | // --------------------------------------------------------------------------
|
||
303 | // This function returns a new handle to be used for the next client. If no
|
||
304 | // more handles are available -1 is returnd.
|
||
305 | // --------------------------------------------------------------------------
|
||
306 | int getNewHandle ()
|
||
307 | { |
||
308 | IShellLink* pointer; |
||
309 | |||
310 | // loop through the array to find an unoccupied location
|
||
311 | int i;
|
||
312 | for (i = 0; i < linkCapacity; i++) |
||
313 | { |
||
314 | pointer = p_shellLink [i]; |
||
315 | // if an unoccupied location is found return the index
|
||
316 | if (pointer == NULL) |
||
317 | { |
||
318 | return (i);
|
||
319 | } |
||
320 | } |
||
321 | |||
322 | // if we get here, all locations are in use and we need to
|
||
323 | // create more storage space to satisfy the request
|
||
324 | int newSize = sizeof (IShellLink*) * (linkCapacity + ALLOC_INCREMENT); |
||
325 | void* tempPointer = realloc ((void *)p_shellLink, newSize); |
||
326 | |||
327 | if (tempPointer != NULL) |
||
328 | { |
||
329 | p_shellLink = (IShellLink**)tempPointer; |
||
330 | linkCapacity = linkCapacity + ALLOC_INCREMENT; |
||
331 | |||
332 | for (int k = i; k < linkCapacity; k++) |
||
333 | { |
||
334 | p_shellLink [k] = NULL;
|
||
335 | } |
||
336 | return (i);
|
||
337 | } |
||
338 | else
|
||
339 | { |
||
340 | return (-1); |
||
341 | } |
||
342 | } |
||
343 | |||
344 | // --------------------------------------------------------------------------
|
||
345 | // This function frees the storage that was allocated for the storage of
|
||
346 | // pointers to IShellLink interfaces. It also cleans up any interfaces that
|
||
347 | // have not yet been reliquished (clients left a mess -> bad boy!).
|
||
348 | // --------------------------------------------------------------------------
|
||
349 | void freeLinks ()
|
||
350 | { |
||
351 | if (p_shellLink != NULL) |
||
352 | { |
||
353 | // loop through the array and release any interfaces that
|
||
354 | // have not been freed yet
|
||
355 | IShellLink* pointer; |
||
356 | for (int i = 0; i < linkCapacity; i++) |
||
357 | { |
||
358 | pointer = p_shellLink [i]; |
||
359 | // if an unoccupied location is found, return the index
|
||
360 | if (pointer != NULL) |
||
361 | { |
||
362 | pointer->Release (); |
||
363 | p_shellLink [i] = NULL;
|
||
364 | } |
||
365 | } |
||
366 | |||
367 | // free the pointer storage itself
|
||
368 | linkCapacity = 0;
|
||
369 | free (p_shellLink); |
||
370 | } |
||
371 | } |
||
372 | |||
373 | // --------------------------------------------------------------------------
|
||
374 | // This function frees this dll, allowing the operating system to remove
|
||
375 | // the code from memory and releasing the reference to the dll on disk.
|
||
376 | // After this call this dll can not be used any more.
|
||
377 | //
|
||
378 | // THIS FUNCTION DOES NOT RETURN !!!
|
||
379 | // --------------------------------------------------------------------------
|
||
380 | JNIEXPORT void JNICALL Java_com_izforge_izpack_util_os_ShellLink_FreeLibrary (JNIEnv *env,
|
||
381 | jobject obj, |
||
382 | jstring name) |
||
383 | { |
||
384 | // convert the name from Java string type
|
||
385 | const char *libraryName = (env)->GetStringUTFChars (name, 0); |
||
386 | |||
387 | // get a module handle
|
||
388 | HMODULE handle = GetModuleHandle (libraryName); |
||
389 | |||
390 | // release the string object
|
||
391 | (env)->ReleaseStringUTFChars (name, libraryName); |
||
392 | |||
393 | // now we are rady to free the library
|
||
394 | FreeLibraryAndExitThread (handle, 0);
|
||
395 | } |
||
396 | |||
397 | // --------------------------------------------------------------------------
|
||
398 | // Releases the interface
|
||
399 | // --------------------------------------------------------------------------
|
||
400 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_releaseInterface (JNIEnv *env, |
||
401 | jobject obj) |
||
402 | { |
||
403 | // Get the handle from the Java side
|
||
404 | jclass cls = (env)->GetObjectClass (obj); |
||
405 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
406 | jint handle = (env)->GetIntField (obj, handleID); |
||
407 | |||
408 | if (handle < 0) |
||
409 | { |
||
410 | return (SL_OK);
|
||
411 | } |
||
412 | |||
413 | if (p_shellLink [handle] == NULL) |
||
414 | { |
||
415 | return (SL_NOT_INITIALIZED);
|
||
416 | } |
||
417 | |||
418 | p_shellLink [handle]->Release (); |
||
419 | p_shellLink [handle] = NULL;
|
||
420 | (env)->SetIntField (obj, handleID, -1);
|
||
421 | return (SL_OK);
|
||
422 | } |
||
423 | |||
424 | // --------------------------------------------------------------------------
|
||
425 | // Retrieves the command-line arguments associated with a shell link object
|
||
426 | //
|
||
427 | // Result is deposited in 'arguments'
|
||
428 | // --------------------------------------------------------------------------
|
||
429 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetArguments (JNIEnv *env, |
||
430 | jobject obj) |
||
431 | { |
||
432 | char arguments [MAX_TEXT_LENGTH];
|
||
433 | HRESULT hres; |
||
434 | |||
435 | // Get the handle from the Java side
|
||
436 | jclass cls = (env)->GetObjectClass (obj); |
||
437 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
438 | jint handle = (env)->GetIntField (obj, handleID); |
||
439 | |||
440 | hres = p_shellLink [handle]->GetArguments (arguments, |
||
441 | MAX_TEXT_LENGTH); |
||
442 | |||
443 | // ------------------------------------------------------
|
||
444 | // set the member variables
|
||
445 | // ------------------------------------------------------
|
||
446 | if (SUCCEEDED (hres))
|
||
447 | { |
||
448 | jfieldID argumentsID = (env)->GetFieldID (cls, "arguments", "Ljava/lang/String;"); |
||
449 | jstring j_arguments = (env)->NewStringUTF (arguments); |
||
450 | |||
451 | (env)->SetObjectField (obj, argumentsID, j_arguments); |
||
452 | return (SL_OK);
|
||
453 | } |
||
454 | else
|
||
455 | { |
||
456 | return (SL_ERROR);
|
||
457 | } |
||
458 | } |
||
459 | |||
460 | // --------------------------------------------------------------------------
|
||
461 | // Retrieves the description string for a shell link object.
|
||
462 | //
|
||
463 | // Result is deposited in 'description'
|
||
464 | // --------------------------------------------------------------------------
|
||
465 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetDescription (JNIEnv *env, |
||
466 | jobject obj) |
||
467 | { |
||
468 | char description [MAX_TEXT_LENGTH];
|
||
469 | HRESULT hres; |
||
470 | |||
471 | // Get the handle from the Java side
|
||
472 | jclass cls = (env)->GetObjectClass (obj); |
||
473 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
474 | jint handle = (env)->GetIntField (obj, handleID); |
||
475 | |||
476 | hres = p_shellLink [handle]->GetDescription (description, |
||
477 | MAX_TEXT_LENGTH); |
||
478 | |||
479 | if (SUCCEEDED (hres))
|
||
480 | { |
||
481 | jfieldID descriptionID = (env)->GetFieldID (cls, "description", "Ljava/lang/String;"); |
||
482 | jstring j_description = (env)->NewStringUTF (description); // convert to Java String type
|
||
483 | |||
484 | (env)->SetObjectField (obj, descriptionID, j_description); |
||
485 | return (SL_OK);
|
||
486 | } |
||
487 | else
|
||
488 | { |
||
489 | return (SL_ERROR);
|
||
490 | } |
||
491 | } |
||
492 | |||
493 | // --------------------------------------------------------------------------
|
||
494 | // Retrieves the hot key for a shell link object.
|
||
495 | //
|
||
496 | // Result is deposited in 'hotkey'
|
||
497 | // --------------------------------------------------------------------------
|
||
498 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetHotkey (JNIEnv *env, |
||
499 | jobject obj) |
||
500 | { |
||
501 | WORD hotkey; |
||
502 | HRESULT hres; |
||
503 | |||
504 | // Get the handle from the Java side
|
||
505 | jclass cls = (env)->GetObjectClass (obj); |
||
506 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
507 | jint handle = (env)->GetIntField (obj, handleID); |
||
508 | |||
509 | hres = p_shellLink [handle]->GetHotkey (&hotkey); |
||
510 | |||
511 | if (SUCCEEDED (hres))
|
||
512 | { |
||
513 | jfieldID hotkeyID = (env)->GetFieldID (cls, "hotkey", "I"); |
||
514 | |||
515 | (env)->SetIntField (obj, hotkeyID, (jint)hotkey); |
||
516 | return (SL_OK);
|
||
517 | } |
||
518 | else
|
||
519 | { |
||
520 | return (SL_ERROR);
|
||
521 | } |
||
522 | } |
||
523 | |||
524 | // --------------------------------------------------------------------------
|
||
525 | // Retrieves the location (path and index) of the icon for a shell link object.
|
||
526 | //
|
||
527 | // The path is deposited in 'iconPath'
|
||
528 | // The index is deposited in 'iconIndex'
|
||
529 | // --------------------------------------------------------------------------
|
||
530 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetIconLocation (JNIEnv *env, |
||
531 | jobject obj) |
||
532 | { |
||
533 | HRESULT hres; |
||
534 | char iconPath [MAX_PATH];
|
||
535 | int iconIndex;
|
||
536 | |||
537 | // Get the handle from the Java side
|
||
538 | jclass cls = (env)->GetObjectClass (obj); |
||
539 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
540 | jint handle = (env)->GetIntField (obj, handleID); |
||
541 | |||
542 | hres = p_shellLink [handle]->GetIconLocation (iconPath, |
||
543 | MAX_PATH, |
||
544 | &iconIndex); |
||
545 | |||
546 | // ------------------------------------------------------
|
||
547 | // set the member variables
|
||
548 | // ------------------------------------------------------
|
||
549 | if (SUCCEEDED (hres))
|
||
550 | { |
||
551 | jfieldID pathID = (env)->GetFieldID (cls, "iconPath", "Ljava/lang/String;"); |
||
552 | jfieldID indexID = (env)->GetFieldID (cls, "iconIndex", "I"); |
||
553 | jstring j_iconPath = (env)->NewStringUTF (iconPath); |
||
554 | |||
555 | (env)->SetObjectField (obj, pathID, j_iconPath); |
||
556 | (env)->SetIntField (obj, indexID, (jint)iconIndex); |
||
557 | return (SL_OK);
|
||
558 | } |
||
559 | else
|
||
560 | { |
||
561 | return (SL_ERROR);
|
||
562 | } |
||
563 | } |
||
564 | |||
565 | // --------------------------------------------------------------------------
|
||
566 | // Retrieves the path and filename of a shell link object.
|
||
567 | //
|
||
568 | // Result is deposited in 'targetPath'
|
||
569 | // --------------------------------------------------------------------------
|
||
570 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetPath (JNIEnv *env, |
||
571 | jobject obj) |
||
572 | { |
||
573 | WIN32_FIND_DATA findData; |
||
574 | char targetPath [MAX_PATH];
|
||
575 | HRESULT hres; |
||
576 | |||
577 | // Get the handle from the Java side
|
||
578 | jclass cls = (env)->GetObjectClass (obj); |
||
579 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
580 | jint handle = (env)->GetIntField (obj, handleID); |
||
581 | |||
582 | hres = p_shellLink [handle]->GetPath (targetPath, |
||
583 | MAX_PATH, |
||
584 | &findData, |
||
585 | SLGP_UNCPRIORITY); |
||
586 | |||
587 | // ------------------------------------------------------
|
||
588 | // set the member variables
|
||
589 | // ------------------------------------------------------
|
||
590 | if (SUCCEEDED (hres))
|
||
591 | { |
||
592 | jfieldID pathID = (env)->GetFieldID (cls, "targetPath", "Ljava/lang/String;"); |
||
593 | jstring j_targetPath = (env)->NewStringUTF (targetPath); |
||
594 | |||
595 | (env)->SetObjectField (obj, pathID, j_targetPath); |
||
596 | return (SL_OK);
|
||
597 | } |
||
598 | else
|
||
599 | { |
||
600 | return (SL_ERROR);
|
||
601 | } |
||
602 | } |
||
603 | |||
604 | // --------------------------------------------------------------------------
|
||
605 | // Retrieves the show (SW_) command for a shell link object.
|
||
606 | //
|
||
607 | // Result is deposited in 'showCommand'
|
||
608 | // --------------------------------------------------------------------------
|
||
609 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetShowCommand (JNIEnv *env, |
||
610 | jobject obj) |
||
611 | { |
||
612 | HRESULT hres; |
||
613 | int showCommand;
|
||
614 | |||
615 | // Get the handle from the Java side
|
||
616 | jclass cls = (env)->GetObjectClass (obj); |
||
617 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
618 | jint handle = (env)->GetIntField (obj, handleID); |
||
619 | |||
620 | hres = p_shellLink [handle]->GetShowCmd (&showCommand); |
||
621 | |||
622 | // ------------------------------------------------------
|
||
623 | // set the member variables
|
||
624 | // ------------------------------------------------------
|
||
625 | if (SUCCEEDED (hres))
|
||
626 | { |
||
627 | jfieldID commandID = (env)->GetFieldID (cls, "showCommand", "I"); |
||
628 | |||
629 | (env)->SetIntField (obj, commandID, (jint)showCommand); |
||
630 | return (SL_OK);
|
||
631 | } |
||
632 | else
|
||
633 | { |
||
634 | return (SL_ERROR);
|
||
635 | } |
||
636 | } |
||
637 | |||
638 | // --------------------------------------------------------------------------
|
||
639 | // Retrieves the name of the working directory for a shell link object.
|
||
640 | //
|
||
641 | // Result is deposited in 'workingDirectory'
|
||
642 | // --------------------------------------------------------------------------
|
||
643 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetWorkingDirectory (JNIEnv *env, |
||
644 | jobject obj) |
||
645 | { |
||
646 | HRESULT hres; |
||
647 | char workingDirectory [MAX_PATH];
|
||
648 | |||
649 | // Get the handle from the Java side
|
||
650 | jclass cls = (env)->GetObjectClass (obj); |
||
651 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
652 | jint handle = (env)->GetIntField (obj, handleID); |
||
653 | |||
654 | hres = p_shellLink [handle]->GetWorkingDirectory (workingDirectory, |
||
655 | MAX_PATH); |
||
656 | |||
657 | // ------------------------------------------------------
|
||
658 | // set the member variables
|
||
659 | // ------------------------------------------------------
|
||
660 | if (SUCCEEDED (hres))
|
||
661 | { |
||
662 | jfieldID directoryID = (env)->GetFieldID (cls, "workingDirectory", "Ljava/lang/String;"); |
||
663 | jstring j_workingDirectory = (env)->NewStringUTF (workingDirectory); |
||
664 | |||
665 | (env)->SetObjectField (obj, directoryID, j_workingDirectory); |
||
666 | return (SL_OK);
|
||
667 | } |
||
668 | else
|
||
669 | { |
||
670 | return (SL_ERROR);
|
||
671 | } |
||
672 | } |
||
673 | |||
674 | // --------------------------------------------------------------------------
|
||
675 | // Resolves a shell link by searching for the shell link object and
|
||
676 | // updating the shell link path and its list of identifiers (if necessary).
|
||
677 | //
|
||
678 | // I recommend to call this function before saving the shortcut. This will
|
||
679 | // ensure that the link is working and all the identifiers are updated, so
|
||
680 | // that the link will actually work when used later on. If for some reason
|
||
681 | // the link can not be resolved, at least the creating application knows
|
||
682 | // about this.
|
||
683 | // --------------------------------------------------------------------------
|
||
684 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_Resolve (JNIEnv *env, |
||
685 | jobject obj) |
||
686 | { |
||
687 | HRESULT hres; |
||
688 | |||
689 | // Get the handle from the Java side
|
||
690 | jclass cls = (env)->GetObjectClass (obj); |
||
691 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
692 | jint handle = (env)->GetIntField (obj, handleID); |
||
693 | |||
694 | hres = p_shellLink [handle]->Resolve (NULL,
|
||
695 | SLR_NO_UI | SLR_UPDATE); |
||
696 | |||
697 | if (SUCCEEDED (hres))
|
||
698 | { |
||
699 | return (SL_OK);
|
||
700 | } |
||
701 | else
|
||
702 | { |
||
703 | return (SL_ERROR);
|
||
704 | } |
||
705 | } |
||
706 | |||
707 | // --------------------------------------------------------------------------
|
||
708 | // Sets the command-line arguments associated with a shell link object.
|
||
709 | //
|
||
710 | // Input is taken from 'arguments'
|
||
711 | // --------------------------------------------------------------------------
|
||
712 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_SetArguments (JNIEnv *env, |
||
713 | jobject obj) |
||
714 | { |
||
715 | HRESULT hres; |
||
716 | |||
717 | // Get the handle from the Java side
|
||
718 | jclass cls = (env)->GetObjectClass (obj); |
||
719 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
720 | jint handle = (env)->GetIntField (obj, handleID); |
||
721 | |||
722 | // ------------------------------------------------------
|
||
723 | // get the member variables
|
||
724 | // ------------------------------------------------------
|
||
725 | jfieldID argumentsID = (env)->GetFieldID (cls, "arguments", "Ljava/lang/String;"); |
||
726 | jstring j_arguments = (jstring)(env)->GetObjectField (obj, argumentsID); |
||
727 | const char *arguments = (env)->GetStringUTFChars (j_arguments, 0); |
||
728 | |||
729 | hres = p_shellLink [handle]->SetArguments (arguments); |
||
730 | |||
731 | (env)->ReleaseStringUTFChars (j_arguments, arguments); |
||
732 | |||
733 | if (SUCCEEDED (hres))
|
||
734 | { |
||
735 | return (SL_OK);
|
||
736 | } |
||
737 | else
|
||
738 | { |
||
739 | return (SL_ERROR);
|
||
740 | } |
||
741 | } |
||
742 | |||
743 | // --------------------------------------------------------------------------
|
||
744 | // Sets the description string for a shell link object.
|
||
745 | //
|
||
746 | // Input is taken from 'description'
|
||
747 | // --------------------------------------------------------------------------
|
||
748 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_SetDescription (JNIEnv *env, |
||
749 | jobject obj) |
||
750 | { |
||
751 | HRESULT hres; |
||
752 | |||
753 | // Get the handle from the Java side
|
||
754 | jclass cls = (env)->GetObjectClass (obj); |
||
755 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
756 | jint handle = (env)->GetIntField (obj, handleID); |
||
757 | |||
758 | // ------------------------------------------------------
|
||
759 | // get the member variables
|
||
760 | // ------------------------------------------------------
|
||
761 | jfieldID descriptionID = (env)->GetFieldID (cls, "description", "Ljava/lang/String;"); |
||
762 | jstring j_description = (jstring)(env)->GetObjectField (obj, descriptionID); |
||
763 | const char *description = (env)->GetStringUTFChars (j_description, 0); |
||
764 | |||
765 | hres = p_shellLink [handle]->SetDescription (description); |
||
766 | |||
767 | (env)->ReleaseStringUTFChars (j_description, description); |
||
768 | |||
769 | if (SUCCEEDED (hres))
|
||
770 | { |
||
771 | return (SL_OK);
|
||
772 | } |
||
773 | else
|
||
774 | { |
||
775 | return (SL_ERROR);
|
||
776 | } |
||
777 | } |
||
778 | |||
779 | // --------------------------------------------------------------------------
|
||
780 | // Sets the hot key for a shell link object.
|
||
781 | //
|
||
782 | // Input is taken from 'hotkey'
|
||
783 | // --------------------------------------------------------------------------
|
||
784 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_SetHotkey (JNIEnv *env, |
||
785 | jobject obj) |
||
786 | { |
||
787 | HRESULT hres; |
||
788 | |||
789 | // Get the handle from the Java side
|
||
790 | jclass cls = (env)->GetObjectClass (obj); |
||
791 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
792 | jint handle = (env)->GetIntField (obj, handleID); |
||
793 | |||
794 | // ------------------------------------------------------
|
||
795 | // get the member variables
|
||
796 | // ------------------------------------------------------
|
||
797 | jfieldID hotkeyID = (env)->GetFieldID (cls, "hotkey", "I"); |
||
798 | jint hotkey = (env)->GetIntField (obj, hotkeyID); |
||
799 | |||
800 | hres = p_shellLink [handle]->SetHotkey ((unsigned short)hotkey); |
||
801 | if (SUCCEEDED (hres))
|
||
802 | { |
||
803 | return (SL_OK);
|
||
804 | } |
||
805 | else
|
||
806 | { |
||
807 | return (SL_ERROR);
|
||
808 | } |
||
809 | } |
||
810 | |||
811 | // --------------------------------------------------------------------------
|
||
812 | // Sets the location (path and index) of the icon for a shell link object.
|
||
813 | //
|
||
814 | // The path is taken from 'iconPath'
|
||
815 | // The index is taken from 'iconIndex'
|
||
816 | // --------------------------------------------------------------------------
|
||
817 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_SetIconLocation (JNIEnv *env, |
||
818 | jobject obj) |
||
819 | { |
||
820 | HRESULT hres; |
||
821 | |||
822 | // Get the handle from the Java side
|
||
823 | jclass cls = (env)->GetObjectClass (obj); |
||
824 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
825 | jint handle = (env)->GetIntField (obj, handleID); |
||
826 | |||
827 | // ------------------------------------------------------
|
||
828 | // get the member variables
|
||
829 | // ------------------------------------------------------
|
||
830 | jfieldID pathID = (env)->GetFieldID (cls, "iconPath", "Ljava/lang/String;"); |
||
831 | jstring j_iconPath = (jstring)(env)->GetObjectField (obj, pathID); |
||
832 | const char *iconPath = (env)->GetStringUTFChars (j_iconPath, 0); |
||
833 | |||
834 | jfieldID indexID = (env)->GetFieldID (cls, "iconIndex", "I"); |
||
835 | jint iconIndex = (env)->GetIntField (obj, indexID); |
||
836 | |||
837 | hres = p_shellLink [handle]->SetIconLocation (iconPath, |
||
838 | iconIndex); |
||
839 | |||
840 | (env)->ReleaseStringUTFChars (j_iconPath, iconPath); |
||
841 | |||
842 | if (SUCCEEDED (hres))
|
||
843 | { |
||
844 | return (SL_OK);
|
||
845 | } |
||
846 | else
|
||
847 | { |
||
848 | return (SL_ERROR);
|
||
849 | } |
||
850 | } |
||
851 | |||
852 | // --------------------------------------------------------------------------
|
||
853 | // Sets the path and filename of a shell link object.
|
||
854 | //
|
||
855 | // Input is taken from 'targetPath'
|
||
856 | // --------------------------------------------------------------------------
|
||
857 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_SetPath (JNIEnv *env, |
||
858 | jobject obj) |
||
859 | { |
||
860 | HRESULT hres; |
||
861 | |||
862 | // Get the handle from the Java side
|
||
863 | jclass cls = (env)->GetObjectClass (obj); |
||
864 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
865 | jint handle = (env)->GetIntField (obj, handleID); |
||
866 | |||
867 | // ------------------------------------------------------
|
||
868 | // get the member variables
|
||
869 | // ------------------------------------------------------
|
||
870 | jfieldID pathID = (env)->GetFieldID (cls, "targetPath", "Ljava/lang/String;"); |
||
871 | jstring j_targetPath = (jstring)(env)->GetObjectField (obj, pathID); |
||
872 | const char *targetPath = (env)->GetStringUTFChars (j_targetPath, 0); |
||
873 | |||
874 | hres = p_shellLink [handle]->SetPath (targetPath); |
||
875 | |||
876 | (env)->ReleaseStringUTFChars (j_targetPath, targetPath); |
||
877 | |||
878 | if (SUCCEEDED (hres))
|
||
879 | { |
||
880 | return (SL_OK);
|
||
881 | } |
||
882 | else
|
||
883 | { |
||
884 | return (SL_ERROR);
|
||
885 | } |
||
886 | } |
||
887 | |||
888 | // --------------------------------------------------------------------------
|
||
889 | // Sets the show (SW_) command for a shell link object.
|
||
890 | //
|
||
891 | // Input is taken from 'showCommand'
|
||
892 | // --------------------------------------------------------------------------
|
||
893 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_SetShowCommand (JNIEnv *env, |
||
894 | jobject obj) |
||
895 | { |
||
896 | HRESULT hres; |
||
897 | |||
898 | // Get the handle from the Java side
|
||
899 | jclass cls = (env)->GetObjectClass (obj); |
||
900 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
901 | jint handle = (env)->GetIntField (obj, handleID); |
||
902 | |||
903 | // ------------------------------------------------------
|
||
904 | // get the member variables
|
||
905 | // ------------------------------------------------------
|
||
906 | jfieldID commandID = (env)->GetFieldID (cls, "showCommand", "I"); |
||
907 | jint showCommand = (env)->GetIntField (obj, commandID); |
||
908 | |||
909 | hres = p_shellLink [handle]->SetShowCmd (showCommand); |
||
910 | if (SUCCEEDED (hres))
|
||
911 | { |
||
912 | return (SL_OK);
|
||
913 | } |
||
914 | else
|
||
915 | { |
||
916 | return (SL_ERROR);
|
||
917 | } |
||
918 | } |
||
919 | |||
920 | // --------------------------------------------------------------------------
|
||
921 | // Sets the name of the working directory for a shell link object.
|
||
922 | //
|
||
923 | // Input is taken from 'workingDirectory'
|
||
924 | // --------------------------------------------------------------------------
|
||
925 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_SetWorkingDirectory (JNIEnv *env, |
||
926 | jobject obj) |
||
927 | { |
||
928 | HRESULT hres; |
||
929 | |||
930 | // Get the handle from the Java side
|
||
931 | jclass cls = (env)->GetObjectClass (obj); |
||
932 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
933 | jint handle = (env)->GetIntField (obj, handleID); |
||
934 | |||
935 | // ------------------------------------------------------
|
||
936 | // get the member variables
|
||
937 | // ------------------------------------------------------
|
||
938 | jfieldID pathID = (env)->GetFieldID (cls, "workingDirectory", "Ljava/lang/String;"); |
||
939 | jstring j_workingDirectory = (jstring)(env)->GetObjectField (obj, pathID); |
||
940 | const char *workingDirectory = (env)->GetStringUTFChars (j_workingDirectory, 0); |
||
941 | |||
942 | hres = p_shellLink [handle]->SetWorkingDirectory (workingDirectory); |
||
943 | |||
944 | (env)->ReleaseStringUTFChars (j_workingDirectory, workingDirectory); |
||
945 | |||
946 | if (SUCCEEDED (hres))
|
||
947 | { |
||
948 | return (SL_OK);
|
||
949 | } |
||
950 | else
|
||
951 | { |
||
952 | return (SL_ERROR);
|
||
953 | } |
||
954 | } |
||
955 | |||
956 | // --------------------------------------------------------------------------
|
||
957 | // This function saves the shell link.
|
||
958 | //
|
||
959 | // name - the fully qualified path for saving the shortcut.
|
||
960 | // --------------------------------------------------------------------------
|
||
961 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_saveLink (JNIEnv *env, |
||
962 | jobject obj, |
||
963 | jstring name) |
||
964 | { |
||
965 | // Get the handle from the Java side
|
||
966 | jclass cls = (env)->GetObjectClass (obj); |
||
967 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
968 | jint handle = (env)->GetIntField (obj, handleID); |
||
969 | |||
970 | // ----------------------------------------------------
|
||
971 | // Query IShellLink for the IPersistFile interface for
|
||
972 | // saving the shell link in persistent storage.
|
||
973 | // ----------------------------------------------------
|
||
974 | IPersistFile* p_persistFile; |
||
975 | HRESULT hres = p_shellLink [handle]->QueryInterface (IID_IPersistFile, |
||
976 | (void **)&p_persistFile);
|
||
977 | |||
978 | if (!SUCCEEDED (hres))
|
||
979 | { |
||
980 | return (SL_NO_IPERSIST);
|
||
981 | } |
||
982 | |||
983 | // ----------------------------------------------------
|
||
984 | // convert from Java string type
|
||
985 | // ----------------------------------------------------
|
||
986 | const unsigned short *pathName = (env)->GetStringChars (name, 0); |
||
987 | |||
988 | // ----------------------------------------------------
|
||
989 | // Save the link
|
||
990 | // ----------------------------------------------------
|
||
991 | hres = p_persistFile->Save ((wchar_t*)pathName, FALSE);
|
||
992 | p_persistFile->SaveCompleted ((wchar_t*)pathName);
|
||
993 | |||
994 | // ----------------------------------------------------
|
||
995 | // Release the pointer to IPersistFile
|
||
996 | // and the string object
|
||
997 | // ----------------------------------------------------
|
||
998 | p_persistFile->Release (); |
||
999 | (env)->ReleaseStringChars (name, pathName); |
||
1000 | |||
1001 | // ------------------------------------------------------
|
||
1002 | // return success code
|
||
1003 | // ------------------------------------------------------
|
||
1004 | if (SUCCEEDED (hres))
|
||
1005 | { |
||
1006 | return (SL_OK);
|
||
1007 | } |
||
1008 | else
|
||
1009 | { |
||
1010 | return (SL_NO_SAVE);
|
||
1011 | } |
||
1012 | } |
||
1013 | |||
1014 | // --------------------------------------------------------------------------
|
||
1015 | // This function loads a shell link.
|
||
1016 | //
|
||
1017 | // name - the fully qualified path for loading the shortcut.
|
||
1018 | // --------------------------------------------------------------------------
|
||
1019 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_loadLink (JNIEnv *env, |
||
1020 | jobject obj, |
||
1021 | jstring name) |
||
1022 | { |
||
1023 | HRESULT hres; |
||
1024 | |||
1025 | // Get the handle from the Java side
|
||
1026 | jclass cls = (env)->GetObjectClass (obj); |
||
1027 | jfieldID handleID = (env)->GetFieldID (cls, "nativeHandle", "I"); |
||
1028 | jint handle = (env)->GetIntField (obj, handleID); |
||
1029 | |||
1030 | // ----------------------------------------------------
|
||
1031 | // Query IShellLink for the IPersistFile interface for
|
||
1032 | // saving the shell link in persistent storage.
|
||
1033 | // ----------------------------------------------------
|
||
1034 | IPersistFile* p_persistFile; |
||
1035 | hres = p_shellLink [handle]->QueryInterface (IID_IPersistFile, |
||
1036 | (void **)&p_persistFile);
|
||
1037 | |||
1038 | if (SUCCEEDED (hres))
|
||
1039 | { |
||
1040 | // convert from Java string type
|
||
1041 | const unsigned short *pathName = (env)->GetStringChars (name, 0); |
||
1042 | |||
1043 | // --------------------------------------------------
|
||
1044 | // Load the link
|
||
1045 | // --------------------------------------------------
|
||
1046 | hres = p_persistFile->Load ((wchar_t *)pathName,
|
||
1047 | STGM_DIRECT | |
||
1048 | STGM_READWRITE | |
||
1049 | STGM_SHARE_EXCLUSIVE); |
||
1050 | |||
1051 | // --------------------------------------------------
|
||
1052 | // Release the pointer to IPersistFile
|
||
1053 | // --------------------------------------------------
|
||
1054 | p_persistFile->Release (); |
||
1055 | (env)->ReleaseStringChars (name, pathName); |
||
1056 | } |
||
1057 | |||
1058 | // ------------------------------------------------------
|
||
1059 | // return success code
|
||
1060 | // ------------------------------------------------------
|
||
1061 | if (SUCCEEDED (hres))
|
||
1062 | { |
||
1063 | return (SL_OK);
|
||
1064 | } |
||
1065 | else
|
||
1066 | { |
||
1067 | return (SL_ERROR);
|
||
1068 | } |
||
1069 | } |
||
1070 | |||
1071 | |||
1072 | // --------------------------------------------------------------------------
|
||
1073 | // resolves a Windows Standard path using SHGetPathFromIDList
|
||
1074 | // inputs:
|
||
1075 | // inc iCsidl - one of the CSIDL
|
||
1076 | // valid CSIDL_COMMON_DESKTOPDIRECTORY
|
||
1077 | // CSIDL_COMMON_STARTMENU
|
||
1078 | // CSIDL_COMMON_PROGRAMS
|
||
1079 | // CSIDL_COMMON_STARTUP
|
||
1080 | // CSIDL_DESKTOPDIRECTORY
|
||
1081 | // CSIDL_STARTMENU
|
||
1082 | // CSIDL_PROGRAMS
|
||
1083 | // CSIDL_STARTUP
|
||
1084 | // returns:
|
||
1085 | // the Windows Standard Path in szPath.
|
||
1086 | // --------------------------------------------------------------------------
|
||
1087 | LONG GetLinkPath( int iCsidl, LPTSTR szPath )
|
||
1088 | { |
||
1089 | HRESULT hr; |
||
1090 | |||
1091 | // Allocate a pointer to an Item ID list
|
||
1092 | LPITEMIDLIST pidl; |
||
1093 | |||
1094 | // Get a pointer to an item ID list that
|
||
1095 | // represents the path of a special folder
|
||
1096 | hr = SHGetSpecialFolderLocation(NULL, iCsidl, &pidl);
|
||
1097 | |||
1098 | if ( SUCCEEDED(hr) )
|
||
1099 | { |
||
1100 | // Convert the item ID list's binary
|
||
1101 | // representation into a file system path
|
||
1102 | BOOL f = SHGetPathFromIDList(pidl, szPath); |
||
1103 | |||
1104 | // Allocate a pointer to an IMalloc interface
|
||
1105 | LPMALLOC pMalloc; |
||
1106 | |||
1107 | // Get the address of our task allocator's IMalloc interface
|
||
1108 | hr = SHGetMalloc(&pMalloc); |
||
1109 | |||
1110 | // Free the item ID list allocated by SHGetSpecialFolderLocation
|
||
1111 | pMalloc->Free(pidl); |
||
1112 | |||
1113 | // Free our task allocator
|
||
1114 | pMalloc->Release(); |
||
1115 | |||
1116 | if ( f == FALSE )
|
||
1117 | { |
||
1118 | *szPath = TCHAR('\0');
|
||
1119 | return E_FAIL;
|
||
1120 | } |
||
1121 | |||
1122 | // return the special folder's path (contained in szPath)
|
||
1123 | return S_OK;
|
||
1124 | } |
||
1125 | else
|
||
1126 | { |
||
1127 | // null path for error return.
|
||
1128 | *szPath = TCHAR('\0');
|
||
1129 | } |
||
1130 | |||
1131 | return E_FAIL;
|
||
1132 | } |
||
1133 | |||
1134 | // --------------------------------------------------------------------------
|
||
1135 | // This function retrieves the location of the folders that hold shortcuts.
|
||
1136 | // The information comes from SHGetSpecialFolderLocation,
|
||
1137 | // since it's more accurate.
|
||
1138 | // SHGetSpecialFolderLocation (since shell32.dll ver 4.0 - win 95, IE 3).
|
||
1139 | //
|
||
1140 | // target - where the path should point. The following are legal values
|
||
1141 | // to use
|
||
1142 | //
|
||
1143 | // 1 - path for shortcuts that show on the desktop
|
||
1144 | // 2 - path for shortcuts that show in the Programs menu
|
||
1145 | // 3 - path for shortcuts that show in the start menu
|
||
1146 | // 4 - path to the Startup group. These shortcuts are executed
|
||
1147 | // at OS launch time
|
||
1148 | //
|
||
1149 | // Note: all other values cause an empty string to be returned
|
||
1150 | //
|
||
1151 | // Program groups (sub-menus) in the programs and start menus can be created
|
||
1152 | // by creating a new folder at the indicated location and placing the links
|
||
1153 | // in that folder. These folders can be nested to any depth with each level
|
||
1154 | // creating an additional menu level.
|
||
1155 | //
|
||
1156 | // Results are deposited in 'currentUserLinkPath' and 'allUsersLinkPath'
|
||
1157 | // respectively
|
||
1158 | // --------------------------------------------------------------------------
|
||
1159 | // --------------------------------------------------------------------------
|
||
1160 | JNIEXPORT jint JNICALL Java_com_izforge_izpack_util_os_ShellLink_GetFullLinkPath |
||
1161 | (JNIEnv *env, jobject obj, jint utype, jint ltype) |
||
1162 | { |
||
1163 | ULONG ul_size = MAX_PATH; // buffer size
|
||
1164 | TCHAR szPath [MAX_PATH]; // path we are looking for
|
||
1165 | int csidl;
|
||
1166 | jclass cls; |
||
1167 | jfieldID pathID; |
||
1168 | jstring j_path; |
||
1169 | LONG successCode; |
||
1170 | |||
1171 | if ((ltype > MIN_KEY) && (ltype < MAX_KEY))
|
||
1172 | { |
||
1173 | //translate request into a CSIDL, based on user-type and link-type
|
||
1174 | |||
1175 | // user type
|
||
1176 | if ( utype == com_izforge_izpack_util_os_ShellLink_ALL_USERS )
|
||
1177 | { |
||
1178 | switch ( ltype ) // link type |
||
1179 | { |
||
1180 | case ( com_izforge_izpack_util_os_ShellLink_DESKTOP ) :
|
||
1181 | csidl = CSIDL_COMMON_DESKTOPDIRECTORY; |
||
1182 | break;
|
||
1183 | |||
1184 | case ( com_izforge_izpack_util_os_ShellLink_START_MENU ) :
|
||
1185 | csidl = CSIDL_COMMON_STARTMENU; |
||
1186 | break;
|
||
1187 | |||
1188 | case ( com_izforge_izpack_util_os_ShellLink_PROGRAM_MENU ) :
|
||
1189 | csidl = CSIDL_COMMON_PROGRAMS; |
||
1190 | break;
|
||
1191 | |||
1192 | case ( com_izforge_izpack_util_os_ShellLink_STARTUP ) :
|
||
1193 | csidl = CSIDL_COMMON_STARTUP; |
||
1194 | break;
|
||
1195 | |||
1196 | default :
|
||
1197 | break;
|
||
1198 | } |
||
1199 | |||
1200 | successCode = GetLinkPath( csidl, szPath ); |
||
1201 | |||
1202 | if ( SUCCEEDED(successCode) )
|
||
1203 | { |
||
1204 | |||
1205 | // ------------------------------------------------------
|
||
1206 | // set the member variables
|
||
1207 | // ------------------------------------------------------
|
||
1208 | cls = (env)->GetObjectClass (obj); |
||
1209 | pathID = (env)->GetFieldID (cls, "allUsersLinkPath", "Ljava/lang/String;"); |
||
1210 | j_path = (env)->NewStringUTF (szPath); |
||
1211 | |||
1212 | (env)->SetObjectField (obj, pathID, j_path); |
||
1213 | return (SL_OK);
|
||
1214 | } |
||
1215 | else
|
||
1216 | { |
||
1217 | // failure code from GetLinkPath()
|
||
1218 | return successCode;
|
||
1219 | } |
||
1220 | } |
||
1221 | else if ( utype == com_izforge_izpack_util_os_ShellLink_CURRENT_USER ) |
||
1222 | { |
||
1223 | switch ( ltype ) // link type |
||
1224 | { |
||
1225 | case ( com_izforge_izpack_util_os_ShellLink_DESKTOP ) :
|
||
1226 | csidl = CSIDL_DESKTOPDIRECTORY; |
||
1227 | break;
|
||
1228 | |||
1229 | case ( com_izforge_izpack_util_os_ShellLink_START_MENU ) :
|
||
1230 | csidl = CSIDL_STARTMENU; |
||
1231 | break;
|
||
1232 | |||
1233 | case ( com_izforge_izpack_util_os_ShellLink_PROGRAM_MENU ) :
|
||
1234 | csidl = CSIDL_PROGRAMS; |
||
1235 | break;
|
||
1236 | |||
1237 | case ( com_izforge_izpack_util_os_ShellLink_STARTUP ) :
|
||
1238 | csidl = CSIDL_STARTUP; |
||
1239 | break;
|
||
1240 | |||
1241 | default :
|
||
1242 | break;
|
||
1243 | } |
||
1244 | |||
1245 | successCode = GetLinkPath( csidl, szPath ); |
||
1246 | |||
1247 | if ( SUCCEEDED(successCode) )
|
||
1248 | { |
||
1249 | // ------------------------------------------------------
|
||
1250 | // set the member variables
|
||
1251 | // ------------------------------------------------------
|
||
1252 | cls = (env)->GetObjectClass (obj); |
||
1253 | pathID = (env)->GetFieldID (cls, "currentUserLinkPath", "Ljava/lang/String;"); |
||
1254 | j_path = (env)->NewStringUTF (szPath); |
||
1255 | |||
1256 | (env)->SetObjectField (obj, pathID, j_path); |
||
1257 | |||
1258 | return (SL_OK);
|
||
1259 | } |
||
1260 | else
|
||
1261 | { |
||
1262 | // failure code from GetLinkPath()
|
||
1263 | return successCode;
|
||
1264 | } |
||
1265 | } |
||
1266 | |||
1267 | } |
||
1268 | |||
1269 | return SL_CAN_NOT_READ_PATH;
|
||
1270 | } |