root / trunk / install / IzPack / src / native / ShellLink.cpp @ 11445
History | View | Annotate | Download (45.5 KB)
1 |
/*
|
---|---|
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 |
} |
1271 |
|