Develop and Download Open Source Software

Browse Subversion Repository

Contents of /trunk/teraterm/teraterm/winjump.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 9610 - (show annotations) (download) (as text)
Mon Dec 20 12:53:06 2021 UTC (2 years, 2 months ago) by zmatsuo
File MIME type: text/x-csrc
File size: 24663 byte(s)
clang でビルドしたとき、リンク時に出る警告対策

- libuuid.a(lib64_libuuid_a-uuid.o): duplicate section `.rdata$PKEY_Volume_IsRoot[PKEY_Volume_IsRoot]' has different size など
1 // based on PuTTY source code
2 /*
3 * winjump.c: support for Windows 7 jump lists.
4 *
5 * The Windows 7 jumplist is a customizable list defined by the
6 * application. It is persistent across application restarts: the OS
7 * maintains the list when the app is not running. The list is shown
8 * when the user right-clicks on the taskbar button of a running app
9 * or a pinned non-running application. We use the jumplist to
10 * maintain a list of recently started saved sessions, started either
11 * by doubleclicking on a saved session, or with the command line
12 * "-load" parameter.
13 *
14 * Since the jumplist is write-only: it can only be replaced and the
15 * current list cannot be read, we must maintain the contents of the
16 * list persistantly in the registry. The file winstore.h contains
17 * functions to directly manipulate these registry entries. This file
18 * contains higher level functions to manipulate the jumplist.
19 */
20
21 /*
22 * Copyright (C) 2011- TeraTerm Project
23 * All rights reserved.
24 *
25 * Redistribution and use in source and binary forms, with or without
26 * modification, are permitted provided that the following conditions
27 * are met:
28 *
29 * 1. Redistributions of source code must retain the above copyright
30 * notice, this list of conditions and the following disclaimer.
31 * 2. Redistributions in binary form must reproduce the above copyright
32 * notice, this list of conditions and the following disclaimer in the
33 * documentation and/or other materials provided with the distribution.
34 * 3. The name of the author may not be used to endorse or promote products
35 * derived from this software without specific prior written permission.
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
38 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
40 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
43 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
45 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
46 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
47 */
48
49 #include <windows.h>
50 #include <assert.h>
51 #include <stdio.h>
52 #include <string.h>
53 #include <shlobj.h>
54 #if !defined(_CRTDBG_MAP_ALLOC)
55 #define _CRTDBG_MAP_ALLOC
56 #endif
57 #include <stdlib.h>
58 #include <crtdbg.h>
59 #if defined(__MINGW32__) || defined(_INC_SDKDDKVER)
60 #define HAS_PROPKEY_H 1
61 #endif
62 #if defined(HAS_PROPKEY_H)
63 #include <propkey.h>
64 #endif
65
66 #include "winjump.h"
67 #include "teraterm.h"
68 #include "tttypes.h"
69
70 #define MAX_JUMPLIST_ITEMS 30 /* PuTTY will never show more items in
71 * the jumplist than this, regardless of
72 * user preferences. */
73
74 /*
75 * COM structures and functions.
76 */
77 #ifndef PROPERTYKEY_DEFINED
78 #define PROPERTYKEY_DEFINED
79 typedef struct _tagpropertykey {
80 GUID fmtid;
81 DWORD pid;
82 } PROPERTYKEY;
83 #endif
84 #ifndef _REFPROPVARIANT_DEFINED
85 #define _REFPROPVARIANT_DEFINED
86 typedef PROPVARIANT *REFPROPVARIANT;
87 #endif
88
89 #ifndef __ICustomDestinationList_INTERFACE_DEFINED__
90
91 static const IID IID_ICustomDestinationList = {
92 0x6332debf, 0x87b5, 0x4670, {0x90,0xc0,0x5e,0x57,0xb4,0x08,0xa4,0x9e}
93 };
94
95 typedef struct ICustomDestinationListVtbl {
96 HRESULT ( __stdcall *QueryInterface ) (
97 /* [in] ICustomDestinationList*/ void *This,
98 /* [in] */ const GUID * const riid,
99 /* [out] */ void **ppvObject);
100
101 ULONG ( __stdcall *AddRef )(
102 /* [in] ICustomDestinationList*/ void *This);
103
104 ULONG ( __stdcall *Release )(
105 /* [in] ICustomDestinationList*/ void *This);
106
107 HRESULT ( __stdcall *SetAppID )(
108 /* [in] ICustomDestinationList*/ void *This,
109 /* [string][in] */ LPCWSTR pszAppID);
110
111 HRESULT ( __stdcall *BeginList )(
112 /* [in] ICustomDestinationList*/ void *This,
113 /* [out] */ UINT *pcMinSlots,
114 /* [in] */ const GUID * const riid,
115 /* [out] */ void **ppv);
116
117 HRESULT ( __stdcall *AppendCategory )(
118 /* [in] ICustomDestinationList*/ void *This,
119 /* [string][in] */ LPCWSTR pszCategory,
120 /* [in] IObjectArray*/ void *poa);
121
122 HRESULT ( __stdcall *AppendKnownCategory )(
123 /* [in] ICustomDestinationList*/ void *This,
124 /* [in] KNOWNDESTCATEGORY*/ int category);
125
126 HRESULT ( __stdcall *AddUserTasks )(
127 /* [in] ICustomDestinationList*/ void *This,
128 /* [in] IObjectArray*/ void *poa);
129
130 HRESULT ( __stdcall *CommitList )(
131 /* [in] ICustomDestinationList*/ void *This);
132
133 HRESULT ( __stdcall *GetRemovedDestinations )(
134 /* [in] ICustomDestinationList*/ void *This,
135 /* [in] */ const IID * const riid,
136 /* [out] */ void **ppv);
137
138 HRESULT ( __stdcall *DeleteList )(
139 /* [in] ICustomDestinationList*/ void *This,
140 /* [string][unique][in] */ LPCWSTR pszAppID);
141
142 HRESULT ( __stdcall *AbortList )(
143 /* [in] ICustomDestinationList*/ void *This);
144
145 } ICustomDestinationListVtbl;
146
147 typedef struct ICustomDestinationList
148 {
149 ICustomDestinationListVtbl *lpVtbl;
150 } ICustomDestinationList;
151 #endif
152
153 #ifndef __IObjectArray_INTERFACE_DEFINED__
154
155 static const IID IID_IObjectArray = {
156 0x92ca9dcd, 0x5622, 0x4bba, {0xa8,0x05,0x5e,0x9f,0x54,0x1b,0xd8,0xc9}
157 };
158
159 typedef struct IObjectArrayVtbl
160 {
161 HRESULT ( __stdcall *QueryInterface )(
162 /* [in] IObjectArray*/ void *This,
163 /* [in] */ const GUID * const riid,
164 /* [out] */ void **ppvObject);
165
166 ULONG ( __stdcall *AddRef )(
167 /* [in] IObjectArray*/ void *This);
168
169 ULONG ( __stdcall *Release )(
170 /* [in] IObjectArray*/ void *This);
171
172 HRESULT ( __stdcall *GetCount )(
173 /* [in] IObjectArray*/ void *This,
174 /* [out] */ UINT *pcObjects);
175
176 HRESULT ( __stdcall *GetAt )(
177 /* [in] IObjectArray*/ void *This,
178 /* [in] */ UINT uiIndex,
179 /* [in] */ const GUID * const riid,
180 /* [out] */ void **ppv);
181
182 } IObjectArrayVtbl;
183
184 typedef struct IObjectArray
185 {
186 IObjectArrayVtbl *lpVtbl;
187 } IObjectArray;
188 #endif
189
190 #ifndef __IShellLink_INTERFACE_DEFINED__
191 #define __IShellLink_INTERFACE_DEFINED__
192 typedef struct IShellLinkVtbl
193 {
194 HRESULT ( __stdcall *QueryInterface )(
195 /* [in] IShellLink*/ void *This,
196 /* [in] */ const GUID * const riid,
197 /* [out] */ void **ppvObject);
198
199 ULONG ( __stdcall *AddRef )(
200 /* [in] IShellLink*/ void *This);
201
202 ULONG ( __stdcall *Release )(
203 /* [in] IShellLink*/ void *This);
204
205 HRESULT ( __stdcall *GetPath )(
206 /* [in] IShellLink*/ void *This,
207 /* [string][out] */ LPSTR pszFile,
208 /* [in] */ int cch,
209 /* [unique][out][in] */ WIN32_FIND_DATAA *pfd,
210 /* [in] */ DWORD fFlags);
211
212 HRESULT ( __stdcall *GetIDList )(
213 /* [in] IShellLink*/ void *This,
214 /* [out] LPITEMIDLIST*/ void **ppidl);
215
216 HRESULT ( __stdcall *SetIDList )(
217 /* [in] IShellLink*/ void *This,
218 /* [in] LPITEMIDLIST*/ void *pidl);
219
220 HRESULT ( __stdcall *GetDescription )(
221 /* [in] IShellLink*/ void *This,
222 /* [string][out] */ LPSTR pszName,
223 /* [in] */ int cch);
224
225 HRESULT ( __stdcall *SetDescription )(
226 /* [in] IShellLink*/ void *This,
227 /* [string][in] */ LPCSTR pszName);
228
229 HRESULT ( __stdcall *GetWorkingDirectory )(
230 /* [in] IShellLink*/ void *This,
231 /* [string][out] */ LPSTR pszDir,
232 /* [in] */ int cch);
233
234 HRESULT ( __stdcall *SetWorkingDirectory )(
235 /* [in] IShellLink*/ void *This,
236 /* [string][in] */ LPCSTR pszDir);
237
238 HRESULT ( __stdcall *GetArguments )(
239 /* [in] IShellLink*/ void *This,
240 /* [string][out] */ LPSTR pszArgs,
241 /* [in] */ int cch);
242
243 HRESULT ( __stdcall *SetArguments )(
244 /* [in] IShellLink*/ void *This,
245 /* [string][in] */ LPCSTR pszArgs);
246
247 HRESULT ( __stdcall *GetHotkey )(
248 /* [in] IShellLink*/ void *This,
249 /* [out] */ WORD *pwHotkey);
250
251 HRESULT ( __stdcall *SetHotkey )(
252 /* [in] IShellLink*/ void *This,
253 /* [in] */ WORD wHotkey);
254
255 HRESULT ( __stdcall *GetShowCmd )(
256 /* [in] IShellLink*/ void *This,
257 /* [out] */ int *piShowCmd);
258
259 HRESULT ( __stdcall *SetShowCmd )(
260 /* [in] IShellLink*/ void *This,
261 /* [in] */ int iShowCmd);
262
263 HRESULT ( __stdcall *GetIconLocation )(
264 /* [in] IShellLink*/ void *This,
265 /* [string][out] */ LPSTR pszIconPath,
266 /* [in] */ int cch,
267 /* [out] */ int *piIcon);
268
269 HRESULT ( __stdcall *SetIconLocation )(
270 /* [in] IShellLink*/ void *This,
271 /* [string][in] */ LPCSTR pszIconPath,
272 /* [in] */ int iIcon);
273
274 HRESULT ( __stdcall *SetRelativePath )(
275 /* [in] IShellLink*/ void *This,
276 /* [string][in] */ LPCSTR pszPathRel,
277 /* [in] */ DWORD dwReserved);
278
279 HRESULT ( __stdcall *Resolve )(
280 /* [in] IShellLink*/ void *This,
281 /* [unique][in] */ HWND hwnd,
282 /* [in] */ DWORD fFlags);
283
284 HRESULT ( __stdcall *SetPath )(
285 /* [in] IShellLink*/ void *This,
286 /* [string][in] */ LPCSTR pszFile);
287
288 } IShellLinkVtbl;
289 #endif
290
291 #ifndef __IObjectCollection_INTERFACE_DEFINED__
292 #define __IObjectCollection_INTERFACE_DEFINED__
293 typedef struct IObjectCollectionVtbl
294 {
295 HRESULT ( __stdcall *QueryInterface )(
296 /* [in] IShellLink*/ void *This,
297 /* [in] */ const GUID * const riid,
298 /* [out] */ void **ppvObject);
299
300 ULONG ( __stdcall *AddRef )(
301 /* [in] IShellLink*/ void *This);
302
303 ULONG ( __stdcall *Release )(
304 /* [in] IShellLink*/ void *This);
305
306 HRESULT ( __stdcall *GetCount )(
307 /* [in] IShellLink*/ void *This,
308 /* [out] */ UINT *pcObjects);
309
310 HRESULT ( __stdcall *GetAt )(
311 /* [in] IShellLink*/ void *This,
312 /* [in] */ UINT uiIndex,
313 /* [in] */ const GUID * const riid,
314 /* [iid_is][out] */ void **ppv);
315
316 HRESULT ( __stdcall *AddObject )(
317 /* [in] IShellLink*/ void *This,
318 /* [in] */ void *punk);
319
320 HRESULT ( __stdcall *AddFromArray )(
321 /* [in] IShellLink*/ void *This,
322 /* [in] */ IObjectArray *poaSource);
323
324 HRESULT ( __stdcall *RemoveObjectAt )(
325 /* [in] IShellLink*/ void *This,
326 /* [in] */ UINT uiIndex);
327
328 HRESULT ( __stdcall *Clear )(
329 /* [in] IShellLink*/ void *This);
330
331 } IObjectCollectionVtbl;
332
333 typedef struct IObjectCollection
334 {
335 IObjectCollectionVtbl *lpVtbl;
336 } IObjectCollection;
337 #endif
338
339 #ifndef __IPropertyStore_INTERFACE_DEFINED__
340
341 static const IID IID_IPropertyStore = {
342 0x886d8eeb, 0x8cf2, 0x4446, {0x8d,0x02,0xcd,0xba,0x1d,0xbd,0xcf,0x99}
343 };
344
345 typedef struct IPropertyStoreVtbl
346 {
347 HRESULT ( __stdcall *QueryInterface )(
348 /* [in] IPropertyStore*/ void *This,
349 /* [in] */ const GUID * const riid,
350 /* [iid_is][out] */ void **ppvObject);
351
352 ULONG ( __stdcall *AddRef )(
353 /* [in] IPropertyStore*/ void *This);
354
355 ULONG ( __stdcall *Release )(
356 /* [in] IPropertyStore*/ void *This);
357
358 HRESULT ( __stdcall *GetCount )(
359 /* [in] IPropertyStore*/ void *This,
360 /* [out] */ DWORD *cProps);
361
362 HRESULT ( __stdcall *GetAt )(
363 /* [in] IPropertyStore*/ void *This,
364 /* [in] */ DWORD iProp,
365 /* [out] */ PROPERTYKEY *pkey);
366
367 HRESULT ( __stdcall *GetValue )(
368 /* [in] IPropertyStore*/ void *This,
369 /* [in] */ const PROPERTYKEY * const key,
370 /* [out] */ PROPVARIANT *pv);
371
372 HRESULT ( __stdcall *SetValue )(
373 /* [in] IPropertyStore*/ void *This,
374 /* [in] */ const PROPERTYKEY * const key,
375 /* [in] */ REFPROPVARIANT propvar);
376
377 HRESULT ( __stdcall *Commit )(
378 /* [in] IPropertyStore*/ void *This);
379 } IPropertyStoreVtbl;
380
381 typedef struct IPropertyStore
382 {
383 IPropertyStoreVtbl *lpVtbl;
384 } IPropertyStore;
385 #endif
386
387 #if !defined(__MINGW32__) && !defined(__ShellCoreObjects_LIBRARY_DEFINED__)
388 static const CLSID CLSID_DestinationList = {
389 0x77f10cf0, 0x3db5, 0x4966, {0xb5,0x20,0xb7,0xc5,0x4f,0xd3,0x5e,0xd6}
390 };
391 static const CLSID CLSID_ShellLink = {
392 0x00021401, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}
393 };
394 static const CLSID CLSID_EnumerableObjectCollection = {
395 0x2d3468c1, 0x36a7, 0x43b6, {0xac,0x24,0xd3,0xf0,0x2f,0xd9,0x60,0x7a}
396 };
397 static const IID IID_IObjectCollection = {
398 0x5632b1a4, 0xe38a, 0x400a, {0x92,0x8a,0xd4,0xcd,0x63,0x23,0x02,0x95}
399 };
400 static const IID IID_IShellLink = {
401 0x000214ee, 0x0000, 0x0000, {0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}
402 };
403 #endif
404
405 #if !defined(HAS_PROPKEY_H)
406 static const PROPERTYKEY PKEY_Title = {
407 {0xf29f85e0, 0x4ff9, 0x1068, {0xab,0x91,0x08,0x00,0x2b,0x27,0xb3,0xd9}},
408 0x00000002
409 };
410 #endif
411
412 /* Type-checking macro to provide arguments for CoCreateInstance() etc.
413 * The pointer arithmetic is a compile-time pointer type check that 'obj'
414 * really is a 'type **', but is intended to have no effect at runtime. */
415 #define COMPTR(type, obj) &IID_##type, \
416 (void **)(void *)((obj) + (sizeof((obj)-(type **)(obj))) \
417 - (sizeof((obj)-(type **)(obj))))
418
419 // LPCWSTR AppID = L"TeraTermProject.TeraTerm.ttermpro";
420
421 static char *IniFile = NULL;
422
423 BOOL isJumpListSupported(void)
424 {
425 return IsWindows7OrLater();
426 }
427
428 /*
429 * Function to make an IShellLink describing a particular PuTTY
430 * command. If 'appname' is null, the command run will be the one
431 * returned by GetModuleFileName, i.e. our own executable; if it's
432 * non-null then it will be assumed to be a filename in the same
433 * directory as our own executable, and the return value will be NULL
434 * if that file doesn't exist.
435 *
436 * If 'sessionname' is null then no command line will be passed to the
437 * program. If it's non-null, the command line will be that text
438 * prefixed with an @ (to load a PuTTY saved session).
439 *
440 * Hence, you can launch a saved session using make_shell_link(NULL,
441 * sessionname), and launch another app using e.g.
442 * make_shell_link("puttygen.exe", NULL).
443 */
444 static IShellLink *make_shell_link(const char *appname,
445 const char *sessionname)
446 {
447 IShellLink *ret;
448 char *app_path, *param_string, *desc_string, *tmp_ptr;
449 static char tt_path[2048];
450 //void *psettings_tmp;
451 IPropertyStore *pPS;
452 PROPVARIANT pv;
453 HRESULT result;
454
455 /* Retrieve path to executable. */
456 if (!tt_path[0])
457 GetModuleFileName(NULL, tt_path, sizeof(tt_path) - 1);
458
459 if (appname) {
460 size_t len;
461 tmp_ptr = strrchr(tt_path, '\\');
462 len = (tmp_ptr - tt_path) + strlen(appname) + 2;
463 app_path = malloc(len);
464 strncpy_s(app_path, len, tt_path, (tmp_ptr - tt_path + 1));
465 strcat_s(app_path, len, appname);
466 }
467 else {
468 app_path = _strdup(tt_path);
469 }
470
471 /* Create the new item. */
472 if (!SUCCEEDED(CoCreateInstance(&CLSID_ShellLink, NULL,
473 CLSCTX_INPROC_SERVER,
474 COMPTR(IShellLink, &ret))))
475 return NULL;
476
477 /* Set path, parameters, icon and description. */
478 result = ret->lpVtbl->SetPath(ret, app_path);
479 #if _DEBUG
480 if (result != S_OK)
481 OutputDebugPrintf("SetPath failed. (%ld)\n", result);
482 #endif
483
484 param_string = _strdup(sessionname);
485 result = ret->lpVtbl->SetArguments(ret, param_string);
486 #if _DEBUG
487 if (result != S_OK)
488 OutputDebugPrintf("SetArguments failed. (%ld)\n", result);
489 #endif
490 free(param_string);
491
492 desc_string = _strdup("Connect to Tera Term session");
493 result = ret->lpVtbl->SetDescription(ret, desc_string);
494 #if _DEBUG
495 if (result != S_OK)
496 OutputDebugPrintf("SetDescription failed. (%ld)\n", result);
497 #endif
498 free(desc_string);
499
500 result = ret->lpVtbl->SetIconLocation(ret, app_path, 0);
501 #if _DEBUG
502 if (result != S_OK)
503 OutputDebugPrintf("SetIconLocation failed. (%ld)\n", result);
504 #endif
505
506 /* To set the link title, we require the property store of the link. */
507 if (SUCCEEDED(ret->lpVtbl->QueryInterface(ret, COMPTR(IPropertyStore, &pPS)))) {
508 PropVariantInit(&pv);
509 pv.vt = VT_LPSTR;
510 pv.pszVal = _strdup(sessionname);
511 result = pPS->lpVtbl->SetValue(pPS, &PKEY_Title, &pv);
512 #if _DEBUG
513 if (result != S_OK)
514 OutputDebugPrintf("SetValue failed. (%ld)\n", result);
515 #endif
516 free(pv.pszVal);
517 result = pPS->lpVtbl->Commit(pPS);
518 #if _DEBUG
519 if (result != S_OK)
520 OutputDebugPrintf("Commit failed. (%ld)\n", result);
521 #endif
522 result = pPS->lpVtbl->Release(pPS);
523 #if _DEBUG
524 if (result != S_OK)
525 OutputDebugPrintf("Release shell link failed. (%ld)\n", result);
526 #endif
527 }
528
529 free(app_path);
530
531 return ret;
532 }
533
534 /* Updates jumplist from registry. */
535 static void update_jumplist_from_registry(void)
536 {
537 char EntName[128];
538 char TempHost[1024];
539
540 const char *piterator = TempHost;
541 UINT num_items;
542 UINT nremoved;
543 int i;
544 HRESULT result;
545
546 /* Variables used by the cleanup code must be initialised to NULL,
547 * so that we don't try to free or release them if they were never
548 * set up. */
549 ICustomDestinationList *pCDL = NULL;
550 IObjectCollection *collection = NULL;
551 IObjectArray *array = NULL;
552 IShellLink *link = NULL;
553 IObjectArray *pRemoved = NULL;
554 int need_abort = FALSE;
555
556 /*
557 * Create an ICustomDestinationList: the top-level object which
558 * deals with jump list management.
559 */
560 if (!SUCCEEDED(CoCreateInstance(&CLSID_DestinationList, NULL,
561 CLSCTX_INPROC_SERVER,
562 COMPTR(ICustomDestinationList, &pCDL))))
563 goto cleanup;
564
565 /*
566 * Call its BeginList method to start compiling a list. This gives
567 * us back 'num_items' (a hint derived from systemwide
568 * configuration about how many things to put on the list) and
569 * 'pRemoved' (user configuration about things to leave off the
570 * list).
571 */
572 if (!SUCCEEDED(pCDL->lpVtbl->BeginList(pCDL, &num_items,
573 COMPTR(IObjectArray, &pRemoved))))
574 goto cleanup;
575 need_abort = TRUE;
576 if (!SUCCEEDED(pRemoved->lpVtbl->GetCount(pRemoved, &nremoved)))
577 nremoved = 0;
578
579 /*
580 * Create an object collection to form the 'Recent Sessions'
581 * category on the jump list.
582 */
583 if (!SUCCEEDED(CoCreateInstance(&CLSID_EnumerableObjectCollection,
584 NULL, CLSCTX_INPROC_SERVER,
585 COMPTR(IObjectCollection, &collection))))
586 goto cleanup;
587
588 /*
589 * Go through the jump list entries from the registry and add each
590 * one to the collection.
591 */
592 for (i = 1; i <= MAX_JUMPLIST_ITEMS; i++) {
593 _snprintf_s(EntName, sizeof(EntName), _TRUNCATE, "Host%d", i);
594 GetPrivateProfileString("Hosts", EntName, "", TempHost, sizeof(TempHost), IniFile);
595 if (strlen(TempHost) == 0) {
596 break;
597 }
598
599 #if _DEBUG
600 OutputDebugPrintf("%s\n", piterator);
601 #endif
602 link = make_shell_link(NULL, piterator);
603 if (link) {
604 UINT j;
605 int found;
606
607 /*
608 * Check that the link isn't in the user-removed list.
609 */
610 for (j = 0, found = FALSE; j < nremoved && !found; j++) {
611 IShellLink *rlink;
612 if (SUCCEEDED(pRemoved->lpVtbl->GetAt
613 (pRemoved, j, COMPTR(IShellLink, &rlink)))) {
614 char desc1[2048], desc2[2048];
615 if (SUCCEEDED(link->lpVtbl->GetDescription
616 (link, desc1, sizeof(desc1) - 1)) &&
617 SUCCEEDED(rlink->lpVtbl->GetDescription
618 (rlink, desc2, sizeof(desc2) - 1)) &&
619 !strcmp(desc1, desc2)) {
620 found = TRUE;
621 }
622 result = rlink->lpVtbl->Release(rlink);
623 #if _DEBUG
624 if (result != S_OK)
625 OutputDebugPrintf("Release rlink failed. (%ld)\n", result);
626 #endif
627 }
628 }
629
630 if (!found) {
631 result = collection->lpVtbl->AddObject(collection, (IUnknown *)link);
632 #if _DEBUG
633 if (result != S_OK)
634 OutputDebugPrintf("AddObject link failed. (%ld)\n", result);
635 #endif
636 }
637
638 result = link->lpVtbl->Release(link);
639 #if _DEBUG
640 if (result != S_OK)
641 OutputDebugPrintf("Release link failed. (%ld)\n", result);
642 #endif
643 link = NULL;
644 }
645 }
646
647 /*
648 * Get the array form of the collection we've just constructed,
649 * and put it in the jump list.
650 */
651 if (!SUCCEEDED(collection->lpVtbl->QueryInterface
652 (collection, COMPTR(IObjectArray, &array))))
653 goto cleanup;
654
655 result = pCDL->lpVtbl->AppendCategory(pCDL, L"Recent Sessions", array);
656 #if _DEBUG
657 if (result != S_OK)
658 OutputDebugPrintf("AppendCategory array failed. (%ld)\n", result);
659 #endif
660
661 /*
662 * Create an object collection to form the 'Tasks' category on the
663 * jump list.
664 */
665 if (!SUCCEEDED(CoCreateInstance(&CLSID_EnumerableObjectCollection,
666 NULL, CLSCTX_INPROC_SERVER,
667 COMPTR(IObjectCollection, &collection))))
668 goto cleanup;
669
670 /*
671 * Get the array form of the collection we've just constructed,
672 * and put it in the jump list.
673 */
674 if (!SUCCEEDED(collection->lpVtbl->QueryInterface
675 (collection, COMPTR(IObjectArray, &array))))
676 goto cleanup;
677
678 result = pCDL->lpVtbl->AddUserTasks(pCDL, array);
679 #if _DEBUG
680 if (result != S_OK)
681 OutputDebugPrintf("AddUserTasks array failed. (0x%x)\n", result);
682 #endif
683
684 /*
685 * Now we can clean up the array and collection variables, so as
686 * to be able to reuse them.
687 */
688 result = array->lpVtbl->Release(array);
689 #if _DEBUG
690 if (result != S_OK)
691 OutputDebugPrintf("Release array failed. (%ld)\n", result);
692 #endif
693 array = NULL;
694 result = collection->lpVtbl->Release(collection);
695 #if _DEBUG
696 if (result != S_OK)
697 OutputDebugPrintf("Release collection failed. (%ld)\n", result);
698 #endif
699 collection = NULL;
700
701 /*
702 * Create another object collection to form the user tasks
703 * category.
704 */
705 if (!SUCCEEDED(CoCreateInstance(&CLSID_EnumerableObjectCollection,
706 NULL, CLSCTX_INPROC_SERVER,
707 COMPTR(IObjectCollection, &collection))))
708 goto cleanup;
709
710 /*
711 * Get the array form of the collection we've just constructed,
712 * and put it in the jump list.
713 */
714 if (!SUCCEEDED(collection->lpVtbl->QueryInterface
715 (collection, COMPTR(IObjectArray, &array))))
716 goto cleanup;
717
718 result = pCDL->lpVtbl->AddUserTasks(pCDL, array);
719 #if _DEBUG
720 if (result != S_OK)
721 OutputDebugPrintf("AddUserTasks array2 failed. (0x%x)\n", result);
722 #endif
723
724 /*
725 * Now we can clean up the array and collection variables, so as
726 * to be able to reuse them.
727 */
728 result = array->lpVtbl->Release(array);
729 #if _DEBUG
730 if (result != S_OK)
731 OutputDebugPrintf("Release array2 failed. (%ld)\n", result);
732 #endif
733 array = NULL;
734 result = collection->lpVtbl->Release(collection);
735 #if _DEBUG
736 if (result != S_OK)
737 OutputDebugPrintf("Release collection2 failed. (%ld)\n", result);
738 #endif
739 collection = NULL;
740
741 /*
742 * Commit the jump list.
743 */
744 result = pCDL->lpVtbl->CommitList(pCDL);
745 #if _DEBUG
746 if (result != S_OK)
747 OutputDebugPrintf("CommitList failed. (%ld)\n", result);
748 #endif
749 need_abort = FALSE;
750
751 /*
752 * Clean up.
753 */
754 cleanup:
755 if (pRemoved) pRemoved->lpVtbl->Release(pRemoved);
756 if (pCDL && need_abort) pCDL->lpVtbl->AbortList(pCDL);
757 if (pCDL) pCDL->lpVtbl->Release(pCDL);
758 if (collection) collection->lpVtbl->Release(collection);
759 if (array) array->lpVtbl->Release(array);
760 if (link) link->lpVtbl->Release(link);
761 }
762
763 void add_to_recent_docs(const char * const sessionname)
764 {
765 IShellLink *link = NULL;
766
767 link = make_shell_link(NULL, sessionname);
768
769 SHAddToRecentDocs(6 /* SHARD_LINK */, link);
770
771 return;
772 }
773
774 /* Clears the entire jumplist. */
775 void clear_jumplist(void)
776 {
777 ICustomDestinationList *pCDL;
778
779 if (CoCreateInstance(&CLSID_DestinationList, NULL, CLSCTX_INPROC_SERVER,
780 COMPTR(ICustomDestinationList, &pCDL)) == S_OK) {
781 pCDL->lpVtbl->DeleteList(pCDL, NULL);
782 pCDL->lpVtbl->Release(pCDL);
783 }
784
785 }
786
787 /* Adds a saved session to the Windows 7 jumplist. */
788 void add_session_to_jumplist(const char * const sessionname, char *inifile)
789 {
790 if (!isJumpListSupported())
791 return; /* do nothing on pre-Win7 systems */
792
793 // add_to_recent_docs(sessionname);
794
795 IniFile = inifile;
796
797 update_jumplist_from_registry();
798 return;
799 }
800
801 /* Removes a saved session from the Windows jumplist. */
802 void remove_session_from_jumplist(const char * const sessionname)
803 {
804 if (!isJumpListSupported())
805 return; /* do nothing on pre-Win7 systems */
806
807 update_jumplist_from_registry();
808 return;
809 }

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26