ReactOS 0.4.16-dev-959-g2ec3a19
lnktool.cpp
Go to the documentation of this file.
1/*
2 * PROJECT: lnktool
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: ShellLink (.lnk) utility
5 * COPYRIGHT: Copyright 2025 Whindmar Saksit <whindsaks@proton.me>
6 */
7
8#define INDENT " "
9static const char g_Usage[] = ""
10 "lnktool <Create|Dump|RemoveDatablock> <LnkFile> [Options]\n"
11 "\n"
12 "Create Options:\n"
13 "/Pidl <Path>\n"
14 "/Path <TargetPath>\n"
15 "/Icon <Path,Index>\n"
16 "/Arguments <String>\n"
17 "/RelativePath <LnkPath>\n"
18 "/WorkingDir <Path>\n"
19 "/Comment <String>\n"
20 "/ShowCmd <Number>\n"
21 "/SpecialFolderOffset <CSIDL> <Offset|-Count>\n"
22 "/AddExp <TargetPath>\n"
23 "/AddExpIcon <Path>\n"
24 "/RemoveExpIcon\n" // Removes the EXP_SZ_ICON block and flag
25 "/AddSLDF <Flag>\n"
26 "/RemoveSLDF <Flag>\n";
27
28#include <windows.h>
29#include <shlobj.h>
30#include <shlwapi.h>
31#include <wchar.h>
32#include <stdio.h> // For shellutils.h (sprintf)
33#include <shellutils.h>
34#include <shlwapi_undoc.h>
35#include <undocshell.h> // SHELL_LINK_HEADER
36
37enum { slgp_relativepriority = 0x08 };
38#define PT_DESKTOP_REGITEM 0x1F
39#define PT_COMPUTER_REGITEM 0x2E
40#define PT_FS 0x30
41#define PT_FS_UNICODE_FLAG 0x04
42
43static const struct { UINT Flag; PCSTR Name; } g_SLDF[] =
44{
45 { SLDF_HAS_ID_LIST, "IDLIST" },
46 { SLDF_HAS_LINK_INFO, "LINKINFO" },
47 { SLDF_HAS_NAME, "NAME" },
48 { SLDF_HAS_RELPATH, "RELPATH" },
49 { SLDF_HAS_WORKINGDIR, "WORKINGDIR" },
50 { SLDF_HAS_ARGS, "ARGS" },
51 { SLDF_HAS_ICONLOCATION, "ICONLOCATION" },
52 { SLDF_UNICODE, "UNICODE" },
53 { SLDF_FORCE_NO_LINKINFO, "FORCE_NO_LINKINFO" },
54 { SLDF_HAS_EXP_SZ, "EXP_SZ" },
55 { SLDF_RUN_IN_SEPARATE, "RUN_IN_SEPARATE" },
56 { 0x00000800, "LOGO3ID" },
57 { SLDF_HAS_DARWINID, "DARWINID" },
58 { SLDF_RUNAS_USER, "RUNAS_USER" },
59 { SLDF_HAS_EXP_ICON_SZ, "EXP_ICON_SZ" },
60 { SLDF_NO_PIDL_ALIAS, "NO_PIDL_ALIAS" },
61 { SLDF_FORCE_UNCNAME, "FORCE_UNCNAME" },
62 { SLDF_RUN_WITH_SHIMLAYER, "RUN_WITH_SHIMLAYER" },
63 { 0x00040000, "FORCE_NO_LINKTRACK" },
64 { 0x00080000, "ENABLE_TARGET_METADATA" },
65 { 0x00100000, "DISABLE_LINK_PATH_TRACKING" },
66 { 0x00200000, "DISABLE_KNOWNFOLDER_RELATIVE_TRACKING" },
67 { 0x00400000, "NO_KF_ALIAS" },
68 { 0x00800000, "ALLOW_LINK_TO_LINK" },
69 { 0x01000000, "UNALIAS_ON_SAVE" },
70 { 0x02000000, "PREFER_ENVIRONMENT_PATH" },
71 { 0x04000000, "KEEP_LOCAL_IDLIST_FOR_UNC_TARGET" },
72 { 0x08000000, "PERSIST_VOLUME_ID_RELATIVE" },
73};
74
75static const struct { UINT Flag; PCSTR Name; } g_DBSig[] =
76{
77 { EXP_SZ_LINK_SIG, "SZ_LINK" },
78 { EXP_SZ_ICON_SIG, "SZ_ICON" },
79 { EXP_SPECIAL_FOLDER_SIG, "SPECIALFOLDER" },
80 { EXP_TRACKER_SIG, "TRACKER" },
81 { 0xA0000009, "PROPERTYSTORAGE" },
82 { EXP_KNOWN_FOLDER_SIG, "KNOWNFOLDER" },
83 { EXP_VISTA_ID_LIST_SIG, "VISTAPIDL" },
84};
85
87{
88 PWCHAR end;
89 LONG v = wcstol(in, &end, 0);
90 if (v == LONG_MAX)
91 v = wcstoul(in, &end, 0);
92 return (end > in) ? v : 0;
93}
94
95template<class T>
96static UINT MapToNumber(PCWSTR Name, const T &Map)
97{
98 CHAR buf[200];
100 buf[_countof(buf) - 1] = ANSI_NULL;
101 for (UINT i = 0; i < _countof(Map); ++i)
102 {
103 if (!StrCmpIA(buf, Map[i].Name))
104 return Map[i].Flag;
105 }
106 return StrToNum(Name);
107}
108
109template<class T>
110static PCSTR MapToName(UINT Value, const T &Map, PCSTR Fallback = NULL)
111{
112 for (UINT i = 0; i < _countof(Map); ++i)
113 {
114 if (Map[i].Flag == Value)
115 return Map[i].Name;
116 }
117 return Fallback;
118}
119
120#define GetSLDF(Name) MapToNumber((Name), g_SLDF)
121#define GetDatablockSignature(Name) MapToNumber((Name), g_DBSig)
122
123static int ErrMsg(int Error)
124{
125 WCHAR buf[400];
126 for (UINT e = Error, cch; ;)
127 {
128 lstrcpynW(buf, L"?", _countof(buf));
130 while (cch && buf[cch - 1] <= ' ')
131 buf[--cch] = UNICODE_NULL; // Remove trailing newlines
132 if (cch || HIWORD(e) != HIWORD(HRESULT_FROM_WIN32(1)))
133 break;
134 e = HRESULT_CODE(e); // "WIN32_FROM_HRESULT"
135 }
136 wprintf(Error < 0 ? L"Error 0x%.8X %s\n" : L"Error %d %s\n", Error, buf);
137 return Error;
138}
139
141{
142 return Error ? ErrMsg(Error) : Error;
143}
144
145static inline HRESULT Seek(IStream *pStrm, int Move, int Origin = FILE_CURRENT, ULARGE_INTEGER *pNewPos = NULL)
146{
148 Pos.QuadPart = Move;
149 return pStrm->Seek(Pos, Origin, pNewPos);
150}
151
153{
154 HMODULE hShell32 = LoadLibraryA("SHELL32");
156 (FARPROC&)ILLFS = GetProcAddress(hShell32, (char*)26); // NT5
157 if (!ILLFS)
158 (FARPROC&)ILLFS = GetProcAddress(hShell32, (char*)846); // NT6
159 return ILLFS(pStrm, ppidl);
160}
161
163{
164 HMODULE hShell32 = LoadLibraryA("SHELL32");
165 int (WINAPI*SHPDN)(PCWSTR, void*, PIDLIST_ABSOLUTE*, UINT, UINT*);
166 (FARPROC&)SHPDN = GetProcAddress(hShell32, "SHParseDisplayName");
167 if (SHPDN)
168 return SHPDN(Path, NULL, ppidl, 0, NULL);
169 return SHILCreateFromPath(Path, ppidl, NULL);
170}
171
173{
174 if (!Simple)
175 return SHParseName(Path, ppidl);
177 return *ppidl ? S_OK : E_FAIL;
178}
179
181{
182 LPITEMIDLIST pidlDup = NULL, pidlChild;
183 if (Depth > 0)
184 {
185 if ((pidl = pidlDup = pidlChild = ILClone(pidl)) == NULL)
186 return 0;
187 while (Depth--)
188 {
189 if (LPITEMIDLIST pidlNext = ILGetNext(pidlChild))
190 pidlChild = pidlNext;
191 }
192 pidlChild->mkid.cb = 0;
193 }
194 INT_PTR ret = SHGetFileInfoW((PWSTR)pidl, 0, &shfi, sizeof(shfi), Flags | SHGFI_PIDL);
195 ILFree(pidlDup);
196 return ret;
197}
198
199static void PrintOffsetString(PCSTR Name, LPCVOID Base, UINT Min, UINT Ansi, UINT Unicode, PCSTR Indent = "")
200{
201 if (Unicode && Unicode >= Min)
202 wprintf(L"%hs%hs=%ls", Indent, Name, (PWSTR)((BYTE*)Base + Unicode));
203 else
204 wprintf(L"%hs%hs=%hs", Indent, Name, Ansi >= Min ? (char*)Base + Ansi : "");
205 wprintf(L"\n"); // Separate function call in case the (untrusted) input ends with a DEL character
206}
207
208static void Print(PCSTR Name, REFGUID Guid, PCSTR Indent = "")
209{
210 WCHAR Buffer[39];
212 wprintf(L"%hs%hs=%ls\n", Indent, Name, Buffer);
213}
214
215template<class V, class T>
216static void DumpFlags(V Value, T *pInfo, UINT Count, PCSTR Prefix = NULL)
217{
218 if (!Prefix)
219 Prefix = "";
220 for (SIZE_T i = 0; i < Count; ++i)
221 {
222 if (Value & pInfo[i].Flag)
223 wprintf(L"%hs%#.8x:%hs\n", Prefix, pInfo[i].Flag, const_cast<PCSTR>(pInfo[i].Name));
224 Value &= ~pInfo[i].Flag;
225 }
226 if (Value)
227 wprintf(L"%hs%#.8x:%hs\n", Prefix, Value, "?");
228}
229
230static void Dump(LPITEMIDLIST pidl, PCSTR Heading = NULL)
231{
232 struct GUIDPIDL { WORD cb; BYTE Type, Unknown; GUID guid; };
233 struct DRIVE { BYTE cb1, cb2, Type; char Name[4]; BYTE Unk[18]; };
234 struct FS95 { WORD cb; BYTE Type, Unknown, Data[4+2+2+2]; char Name[1]; };
235 if (Heading)
236 wprintf(L"%hs ", Heading);
237 if (!pidl || !pidl->mkid.cb)
238 wprintf(L"[Desktop (%hs)]", pidl ? "Empty" : "NULL");
239 for (UINT i = 0; pidl && pidl->mkid.cb; ++i, pidl = ILGetNext(pidl))
240 {
241 SHFILEINFOW shfi;
242 PWSTR buf = shfi.szDisplayName;
243 GUIDPIDL *pidlGUID = (GUIDPIDL*)pidl;
244 UINT cb = pidl->mkid.cb;
245 UINT type = cb >= 3 ? (pidlGUID->Type & ~0x80) : 0, folder = type & 0x70;
246 if (i)
247 wprintf(L" ");
248 if (cb < 3)
249 {
250 wprintf(L"[? %ub]", cb);
251 }
252 else if (i == 0 && cb == sizeof(GUIDPIDL) && type == PT_DESKTOP_REGITEM) guiditem:
253 {
254 if (!SHGetPidlInfo(pidl, shfi, SHGFI_DISPLAYNAME, 1))
255 StringFromGUID2(*(GUID*)((char*)pidl + cb - 16), buf, 39);
256 wprintf(L"[%.2X %ub %s]", pidl->mkid.abID[0], cb, buf);
257 }
258 else if (i == 1 && cb == sizeof(GUIDPIDL) && type == PT_COMPUTER_REGITEM)
259 {
260 goto guiditem;
261 }
262 else if (i == 1 && cb == sizeof(DRIVE) && folder == 0x20)
263 {
264 DRIVE *p = (DRIVE*)pidl;
265 wprintf(L"[%.2X %ub \"%.3hs\"]", p->Type, cb, p->Name);
266 }
267 else if (cb > FIELD_OFFSET(FS95, Name) && folder == PT_FS)
268 {
269 FS95 *p = (FS95*)pidl;
270 const BOOL wide = type & PT_FS_UNICODE_FLAG;
271 wprintf(wide ? L"[%.2X %ub \"%.256ls\"]" : L"[%.2X %ub \"%.256hs\"]", p->Type, cb, p->Name);
272 }
273 else
274 {
275 wprintf(L"[%.2X %ub ?]", pidl->mkid.abID[0], cb);
276 }
277 }
278 wprintf(L"\n");
279}
280
281static HRESULT Save(IShellLink *pSL, PCWSTR LnkPath)
282{
283 HRESULT hr;
284 IPersistFile *pPF;
286 {
287 if (SUCCEEDED(hr = pPF->Save(LnkPath, FALSE)) && hr != S_OK)
288 hr = E_FAIL;
289 pPF->Release();
290 }
291 return hr;
292}
293
294static HRESULT Load(IUnknown *pUnk, IStream *pStream)
295{
296 IPersistStream *pPS;
298 if (SUCCEEDED(hr))
299 {
300 hr = pPS->Load(pStream);
301 pPS->Release();
302 }
303 return hr;
304}
305
306static HRESULT Open(PCWSTR Path, IStream **ppStream, IShellLink **ppLink, UINT Mode = STGM_READ)
307{
309 Mode = (Mode & ~STGM_WRITE) | STGM_READWRITE | STGM_SHARE_DENY_WRITE;
310 else
312 IStream *pStream;
314 if (SUCCEEDED(hr) && ppLink)
315 {
316 hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellLink, ppLink));
317 if (SUCCEEDED(hr) && !(Mode & STGM_CREATE))
318 {
319 if (FAILED(hr = Load(*ppLink, pStream)))
320 {
321 (*ppLink)->Release();
322 *ppLink = NULL;
323 }
324 IStream_Reset(pStream);
325 }
326 }
327
328 if (SUCCEEDED(hr) && ppStream)
329 *ppStream = pStream;
330 else if (pStream)
331 pStream->Release();
332 return hr;
333}
334
335#define FreeBlock SHFree
337{
338 return (LPDATABLOCK_HEADER)((char*)pdbh + pdbh->cbSize);
339}
340
341template<class T>
342static HRESULT ReadBlock(IStream *pStream, T **ppData = NULL)
343{
344 DWORD cb = 0;
345 HRESULT hr = IStream_Read(pStream, &cb, sizeof(cb));
346 if (SUCCEEDED(hr))
347 {
348 UINT Remain = cb - min(sizeof(DWORD), cb);
349 if (!ppData)
350 return Seek(pStream, Remain);
351 *ppData = (T*)SHAlloc(Remain + sizeof(DWORD));
352 if (!*ppData)
353 return E_OUTOFMEMORY;
354 ((DATABLOCK_HEADER*)*ppData)->cbSize = cb;
355 if (SUCCEEDED(hr = IStream_Read(pStream, &((DATABLOCK_HEADER*)*ppData)->dwSignature, Remain)))
356 return cb;
357 }
358 return hr;
359}
360
362{
364
366 {
367 if (m_It && m_It->cbSize >= FIELD_OFFSET(DATABLOCK_HEADER, dwSignature))
368 return m_It + (m_It->dwSignature == ~0UL); // SHFindDataBlock compatible
369 return NULL;
370 }
371 void Next()
372 {
373 if (m_It && m_It->cbSize)
375 }
377};
378
380{
381 if (!(Id & slh.dwFlags))
382 return S_OK;
383 WORD cch;
384 HRESULT hr = IStream_Read(pStream, &cch, sizeof(cch));
385 if (FAILED(hr))
386 return hr;
387 UINT cb = (UINT)cch * ((slh.dwFlags & SLDF_UNICODE) ? sizeof(WCHAR) : sizeof(CHAR));
388 void *data = SHAlloc(cb);
389 if (!data)
390 return E_OUTOFMEMORY;
391 if (FAILED(hr = IStream_Read(pStream, data, cb)))
392 return hr;
393 if (slh.dwFlags & SLDF_UNICODE)
394 wprintf(L"%hs=%.*ls\n", Name, cch, (PWSTR)data);
395 else
396 wprintf(L"%hs=%.*hs\n", Name, cch, (PCSTR)data);
397 SHFree(data);
398 return S_OK;
399}
400
402{
403 IStream *pStream;
404 HRESULT hr = Open(Path, &pStream, NULL);
405 if (FAILED(hr))
406 return hr;
407
408 LPITEMIDLIST pidl;
410 if (SUCCEEDED(hr = IStream_Read(pStream, &slh, sizeof(slh))))
411 {
412 #define DUMPSLH(name, fmt, field) wprintf(L"%hs=" fmt L"\n", (name), (slh).field)
413 DUMPSLH("Flags", L"%#.8x", dwFlags);
415 DUMPSLH("FileAttributes", L"%#.8x", dwFileAttributes);
416 DUMPSLH("Size", L"%u", nFileSizeLow);
417 DUMPSLH("IconIndex", L"%d", nIconIndex);
418 DUMPSLH("ShowCommand", L"%d", nShowCommand);
419 DUMPSLH("HotKey", L"%#.4x", wHotKey);
420
421 if (SUCCEEDED(hr) && (slh.dwFlags & SLDF_HAS_ID_LIST))
422 {
423 if (SUCCEEDED(hr = IL_LoadFromStream(pStream, &pidl)))
424 {
425 Dump(pidl, "PIDL:");
426 ILFree(pidl);
427 }
428 }
429 if (SUCCEEDED(hr) && (slh.dwFlags & SLDF_HAS_LINK_INFO))
430 {
431 int offset;
433 if ((hr = ReadBlock(pStream, &p)) >= (signed)sizeof(SHELL_LINK_INFOA))
434 {
435 wprintf(L"%hs:\n", "LINKINFO");
436 wprintf(L"%hs%hs=%#.8x\n", INDENT, "Flags", p->dwFlags);
437 if (p->dwFlags & SLI_VALID_LOCAL)
438 {
439 if (p->cbVolumeIDOffset)
440 {
441 SHELL_LINK_INFO_VOLUME_IDW *pVol = (SHELL_LINK_INFO_VOLUME_IDW*)((char*)p + p->cbVolumeIDOffset);
442 wprintf(L"%hs%hs=%d\n", INDENT, "DriveType", pVol->dwDriveType);
443 wprintf(L"%hs%hs=%#.8x\n", INDENT, "Serial", pVol->nDriveSerialNumber);
444 offset = pVol->cbVolumeLabelOffset == 0x14 ? pVol->cbVolumeLabelUnicodeOffset : 0;
445 if (offset || pVol->cbVolumeLabelOffset != 0x14) // 0x14 from [MS-SHLLINK] documentation
446 PrintOffsetString("Label", pVol, 0x10, pVol->cbVolumeLabelOffset, offset, INDENT);
447 }
448 offset = p->cbHeaderSize >= sizeof(SHELL_LINK_INFOW) ? p->cbCommonPathSuffixUnicodeOffset : 0;
449 PrintOffsetString("CommonSuffix", p, sizeof(SHELL_LINK_INFOA), p->cbCommonPathSuffixOffset, offset, INDENT);
450
451 offset = p->cbHeaderSize >= sizeof(SHELL_LINK_INFOW) ? p->cbLocalBasePathUnicodeOffset : 0;
452 PrintOffsetString("LocalBase", p, sizeof(SHELL_LINK_INFOA), p->cbLocalBasePathOffset, offset, INDENT);
453 }
454 SHELL_LINK_INFO_CNR_LINKW *pCNR = (SHELL_LINK_INFO_CNR_LINKW*)((char*)p + p->cbCommonNetworkRelativeLinkOffset);
455 if ((p->dwFlags & SLI_VALID_NETWORK) && p->cbCommonNetworkRelativeLinkOffset)
456 {
457 wprintf(L"%hs%hs=%#.8x\n", INDENT, "CNR", pCNR->dwFlags);
458 wprintf(L"%hs%hs=%#.8x\n", INDENT, "Provider", pCNR->dwNetworkProviderType); // WNNC_NET_*
459
460 offset = pCNR->cbNetNameOffset > 0x14 ? pCNR->cbNetNameUnicodeOffset : 0;
462
463 offset = pCNR->cbNetNameOffset > 0x14 ? pCNR->cbDeviceNameUnicodeOffset : 0;
464 if (pCNR->dwFlags & SLI_CNR_VALID_DEVICE)
465 PrintOffsetString("DeviceName", pCNR, sizeof(SHELL_LINK_INFO_CNR_LINKA), pCNR->cbDeviceNameOffset, offset, INDENT);
466 }
467 FreeBlock(p);
468 }
469 }
470 if (SUCCEEDED(hr))
471 hr = ReadAndDumpString("NAME", SLDF_HAS_NAME, slh, pStream);
472 if (SUCCEEDED(hr))
473 hr = ReadAndDumpString("RELPATH", SLDF_HAS_RELPATH, slh, pStream);
474 if (SUCCEEDED(hr))
475 hr = ReadAndDumpString("WORKINGDIR", SLDF_HAS_WORKINGDIR, slh, pStream);
476 if (SUCCEEDED(hr))
477 hr = ReadAndDumpString("ARGS", SLDF_HAS_ARGS, slh, pStream);
478 if (SUCCEEDED(hr))
479 hr = ReadAndDumpString("ICONLOCATION", SLDF_HAS_ICONLOCATION, slh, pStream);
480
481 LPDATABLOCK_HEADER pDBListHead, pDBH;
482 if (SUCCEEDED(hr) && SUCCEEDED(hr = SHReadDataBlockList(pStream, &pDBListHead)))
483 {
484 for (DataBlockEnum it(pDBListHead); (pDBH = it.Get()) != NULL; it.Next())
485 {
486 PCSTR SigName = MapToName(pDBH->dwSignature, g_DBSig, NULL);
487 wprintf(L"DataBlock: %.8X %ub", pDBH->dwSignature, pDBH->cbSize);
488 void *pFirstMember = ((EXP_SZ_LINK*)pDBH)->szTarget;
489 if (pDBH->dwSignature == EXP_SZ_LINK_SIG && pDBH->cbSize > FIELD_OFFSET(EXP_SZ_LINK, szwTarget))
490 {
491 wprintf(L" %hs\n", "SZ_LINK");
492 printdbpaths:
493 EXP_SZ_LINK *p = (EXP_SZ_LINK*)pDBH;
494 wprintf(L"%hs%hs=%.260hs\n", INDENT, "Ansi", p->szTarget);
495 wprintf(L"%hs%hs=%.260ls\n", INDENT, "Wide", p->szwTarget);
496 }
497 else if (pDBH->dwSignature == EXP_SZ_ICON_SIG && pDBH->cbSize > FIELD_OFFSET(EXP_SZ_LINK, szwTarget))
498 {
499 wprintf(L" %hs\n", "SZ_ICON/LOGO3");
500 goto printdbpaths;
501 }
502 else if (pDBH->dwSignature == EXP_DARWIN_ID_SIG && pDBH->cbSize == sizeof(EXP_DARWIN_LINK))
503 {
504 wprintf(L" %hs\n", "DARWIN_LINK");
505 goto printdbpaths;
506 }
507 else if (pDBH->dwSignature == NT_CONSOLE_PROPS_SIG && pDBH->cbSize >= sizeof(NT_CONSOLE_PROPS))
508 {
509 wprintf(L" %hs\n", "NT_CONSOLE_PROPS");
510 NT_CONSOLE_PROPS *p = (NT_CONSOLE_PROPS*)pDBH;
511 wprintf(L"%hsInsert=%d Quick=%d %ls\n", INDENT, p->bInsertMode, p->bQuickEdit, p->FaceName);
512 }
513 else if (pDBH->dwSignature == EXP_SPECIAL_FOLDER_SIG && pDBH->cbSize == sizeof(EXP_SPECIAL_FOLDER))
514 {
515 wprintf(L" %hs\n", SigName);
517 wprintf(L"%hsCSIDL=%#x Offset=%#x\n", INDENT, p->idSpecialFolder, p->cbOffset);
518 }
519 else if (pDBH->dwSignature == EXP_TRACKER_SIG)
520 {
521 wprintf(L" %hs\n", SigName);
522 EXP_TRACKER *p = (EXP_TRACKER*)pDBH;
523 UINT len = FIELD_OFFSET(EXP_TRACKER, nLength) + p->nLength;
524 if (len >= FIELD_OFFSET(EXP_TRACKER, szMachineID))
525 wprintf(L"%hsVersion=%d\n", INDENT, p->nVersion);
526 if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidVolume))
527 wprintf(L"%hsMachine=%hs\n", INDENT, p->szMachineID);
528 if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidObject))
529 Print("Volume", p->guidDroidVolume, INDENT);
530 if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidBirthVolume))
531 Print("Object", p->guidDroidObject, INDENT);
532 if (len >= FIELD_OFFSET(EXP_TRACKER, guidDroidBirthObject))
533 Print("BirthVolume", p->guidDroidBirthVolume, INDENT);
534 if (len >= sizeof(EXP_TRACKER))
535 Print("BirthObject", p->guidDroidBirthObject, INDENT);
536 }
537 else if (pDBH->dwSignature == EXP_SHIM_SIG)
538 {
539 wprintf(L" %hs\n", SigName ? SigName : "SHIM");
540 wprintf(L"%hs%ls\n", INDENT, (PWSTR)pFirstMember);
541 }
542 else if (pDBH->dwSignature == EXP_VISTA_ID_LIST_SIG && pDBH->cbSize >= 8 + 2)
543 {
544 wprintf(L" %hs\n", SigName);
545 Dump((LPITEMIDLIST)pFirstMember, INDENT + 1);
546 }
547 else
548 {
549 wprintf(SigName ? L" %hs\n" : L"\n", SigName);
550 }
551 }
552 SHFreeDataBlockList(pDBListHead);
553 }
554 }
555 pStream->Release();
556
557 // Now dump using the API
558 HRESULT hr2;
559 WCHAR buf[MAX_PATH * 2];
560 IShellLink *pSL;
561 if (FAILED(hr2 = Open(Path, NULL, &pSL)))
562 return hr2;
563 wprintf(L"\n");
564
565 if (SUCCEEDED(hr2 = pSL->GetIDList(&pidl)))
566 {
567 Dump(pidl, "GetIDList:");
568 ILFree(pidl);
569 }
570 else
571 {
572 wprintf(L"%hs: %#x\n", "GetIDList", hr2);
573 }
574
575 static const BYTE GetPathFlags[] = { 0, SLGP_SHORTPATH, SLGP_RAWPATH, slgp_relativepriority };
576 for (UINT i = 0; i < _countof(GetPathFlags); ++i)
577 {
578 if (SUCCEEDED(hr2 = pSL->GetPath(buf, _countof(buf), NULL, GetPathFlags[i])))
579 wprintf(L"GetPath(%#.2x): %ls\n", GetPathFlags[i], buf);
580 else
581 wprintf(L"GetPath(%#.2x): %#x\n", GetPathFlags[i], hr2);
582 }
583
584 if (SUCCEEDED(hr2 = pSL->GetWorkingDirectory(buf, _countof(buf))))
585 wprintf(L"%hs: %ls\n", "GetWorkingDirectory", buf);
586 else
587 wprintf(L"%hs: %#x\n", "GetWorkingDirectory", hr2);
588
589 if (SUCCEEDED(hr2 = pSL->GetArguments(buf, _countof(buf))))
590 wprintf(L"%hs: %ls\n", "GetArguments", buf);
591 else
592 wprintf(L"%hs: %#x\n", "GetArguments", hr2);
593
594 if (SUCCEEDED(hr2 = pSL->GetDescription(buf, _countof(buf))))
595 wprintf(L"%hs: %ls\n", "GetDescription", buf);
596 else
597 wprintf(L"%hs: %#x\n", "GetDescription", hr2);
598
599 int index = 123456789;
600 if (SUCCEEDED(hr2 = pSL->GetIconLocation(buf, _countof(buf), &index)))
601 wprintf(L"%hs: %ls,%d\n", "GetIconLocation", buf, index);
602 else
603 wprintf(L"%hs: %#x\n", "GetIconLocation", hr2);
604
605 IExtractIconW *pEI;
606 if (SUCCEEDED(pSL->QueryInterface(IID_PPV_ARG(IExtractIconW, &pEI))))
607 {
608 index = 123456789;
609 UINT flags = 0;
610 if (SUCCEEDED(hr2 = pEI->GetIconLocation(0, buf, _countof(buf), &index, &flags)))
611 wprintf(L"%hs: %#x %ls,%d %#.4x\n", "EI:GetIconLocation", hr2, buf, index, flags);
612 else
613 wprintf(L"%hs: %#x %#.4x\n", "EI:GetIconLocation", hr2, flags);
614 pEI->Release();
615 }
616
617 pSL->Release();
618 return hr;
619}
620
621#define RemoveSLDF(pSL, Flag) RemoveDatablock((pSL), 0, (Flag))
622#define AddSLDF(pSL, Flag) RemoveDatablock((pSL), 0, 0, (Flag))
623
625{
626 IShellLinkDataList *pSLDL;
628 if (SUCCEEDED(hr))
629 {
630 if (Signature)
631 hr = pSLDL->RemoveDataBlock(Signature);
632 DWORD OrgFlags;
633 if ((AddFlag | KillFlag) && SUCCEEDED(pSLDL->GetFlags(&OrgFlags)))
634 pSLDL->SetFlags((OrgFlags & ~KillFlag) | AddFlag);
635 pSLDL->Release();
636 }
637 return hr;
638}
639
640template<class T>
641static HRESULT AddDataBlock(IShellLinkW *pSL, T &DataBlock)
642{
643 IShellLinkDataList *pSLDL;
645 if (SUCCEEDED(hr))
646 {
647 hr = pSLDL->AddDataBlock(&DataBlock);
648 pSLDL->Release();
649 }
650 return hr;
651}
652
654{
655 PIDLIST_ABSOLUTE pidlNew;
656 if (pSL->GetIDList(&pidlNew) == S_OK)
657 {
658 ILFree(pidl);
659 pidl = pidlNew;
660 }
661 return pidl != NULL;
662}
663
665{
666 IShellLinkW *pSL;
667 HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARG(IShellLinkW, &pSL));
668 if (FAILED(hr))
669 return hr;
670
671 UINT TargetCount = 0, DumpResult = 0, ForceAddSLDF = 0, ForceRemoveSLDF = 0;
672 PIDLIST_ABSOLUTE pidlTarget = NULL;
673 for (UINT i = 0; i < argc && SUCCEEDED(hr); ++i)
674 {
676 if (!StrCmpIW(argv[i], L"/Pidl") && i + 1 < argc)
677 {
678 bool Simple = !StrCmpIW(argv[i + 1], L"/Force") && i + 2 < argc && ++i;
679 if (SUCCEEDED(hr = SHParseNameEx(argv[++i], &pidlTarget, Simple)))
680 TargetCount += SUCCEEDED(hr = pSL->SetIDList(pidlTarget));
681 }
682 else if (!StrCmpIW(argv[i], L"/Path") && i + 1 < argc)
683 {
684 TargetCount += SUCCEEDED(hr = pSL->SetPath(argv[++i]));
685 }
686 else if (!StrCmpIW(argv[i], L"/Icon") && i + 1 < argc)
687 {
689 hr = pSL->SetIconLocation(argv[i], index);
690 }
691 else if (!StrCmpIW(argv[i], L"/Arguments") && i + 1 < argc)
692 {
693 hr = pSL->SetArguments(argv[++i]);
694 }
695 else if (!StrCmpIW(argv[i], L"/RelativePath") && i + 1 < argc)
696 {
697 hr = pSL->SetRelativePath(argv[++i], 0);
698 }
699 else if (!StrCmpIW(argv[i], L"/WorkingDir") && i + 1 < argc)
700 {
701 hr = pSL->SetWorkingDirectory(argv[++i]);
702 }
703 else if (!StrCmpIW(argv[i], L"/Comment") && i + 1 < argc)
704 {
705 hr = pSL->SetDescription(argv[++i]);
706 }
707 else if (!StrCmpIW(argv[i], L"/ShowCmd") && i + 1 < argc)
708 {
709 if (int sw = StrToNum(argv[++i])) // Don't allow SW_HIDE
710 hr = pSL->SetShowCmd(sw);
711 }
712 else if (!StrCmpIW(argv[i], L"/AddExp") && ++i < argc)
713 {
714 EXP_SZ_LINK db = { sizeof(db), EXP_SZ_LINK_SIG };
717 if (SUCCEEDED(hr = AddDataBlock(pSL, db)))
718 TargetCount += SUCCEEDED(hr = AddSLDF(pSL, SLDF_HAS_EXP_SZ));
719 }
720 else if (!StrCmpIW(argv[i], L"/AddExpIcon") && ++i < argc)
721 {
722 EXP_SZ_LINK db = { sizeof(db), EXP_SZ_ICON_SIG };
725 if (SUCCEEDED(hr = AddDataBlock(pSL, db)))
727 }
728 else if (!StrCmpIW(argv[i], L"/RemoveExpIcon"))
729 {
731 }
732 else if (!StrCmpIW(argv[i], L"/SpecialFolderOffset") && i + 2 < argc)
733 {
734 EXP_SPECIAL_FOLDER db = { sizeof(db), EXP_SPECIAL_FOLDER_SIG };
735 if ((db.idSpecialFolder = StrToNum(argv[++i])) == 0)
736 {
737 if (!StrCmpIW(argv[i], L"Windows"))
739 if (!StrCmpIW(argv[i], L"System"))
741 }
742 db.cbOffset = StrToNum(argv[++i]);
743 if ((signed)db.cbOffset < 0 && TryGetUpdatedPidl(pSL, pidlTarget))
744 {
745 UINT i = 0, c = -(signed)db.cbOffset;
746 db.cbOffset = 0;
747 for (PIDLIST_ABSOLUTE pidl = pidlTarget; i < c && pidl->mkid.cb; ++i, pidl = ILGetNext(pidl))
748 db.cbOffset += pidl->mkid.cb;
749 }
750 hr = AddDataBlock(pSL, db);
751 }
752 else if (!StrCmpIW(argv[i], L"/RemoveDatablock"))
753 {
754 if (UINT sig = GetDatablockSignature(argv[++i]))
755 hr = RemoveDatablock(pSL, sig);
756 }
757 else if (!StrCmpIW(argv[i], L"/AddSLDF") && i + 1 < argc)
758 {
759 bool Force = !StrCmpIW(argv[i + 1], L"/Force") && i + 2 < argc && ++i;
760 UINT Flag = GetSLDF(argv[++i]);
761 if (Flag > SLDF_UNICODE)
762 hr = AddSLDF(pSL, Flag);
763 if (Force)
764 ForceAddSLDF |= Flag;
765 }
766 else if (!StrCmpIW(argv[i], L"/RemoveSLDF") && i + 1 < argc)
767 {
768 bool Force = !StrCmpIW(argv[i + 1], L"/Force") && i + 2 < argc && ++i;
769 UINT Flag = GetSLDF(argv[++i]);
770 if (Flag)
771 hr = RemoveSLDF(pSL, Flag);
772 if (Force)
773 ForceRemoveSLDF |= Flag;
774 }
775 else if (!StrCmpIW(argv[i], L"/Dump"))
776 {
777 DumpResult++;
778 hr = S_OK;
779 }
780 else if (!StrCmpIW(argv[i], L"/ForceCreate"))
781 {
782 TargetCount++;
783 hr = S_OK;
784 }
785 else
786 {
787 wprintf(L"%hsUnable to parse \"%ls\"!\n", "Error: ", argv[i]);
788 }
789 }
790
791 if (SUCCEEDED(hr))
792 {
793 if (TargetCount)
794 {
795 if (SUCCEEDED(hr = Save(pSL, LnkPath)) && (ForceAddSLDF | ForceRemoveSLDF))
796 {
797 IStream *pStream;
798 if (SUCCEEDED(Open(LnkPath, &pStream, NULL, STGM_READWRITE)))
799 {
801 if (SUCCEEDED(IStream_Read(pStream, &slh, sizeof(slh))))
802 {
803 slh.dwFlags = (slh.dwFlags & ~ForceRemoveSLDF) | ForceAddSLDF;
804 if (SUCCEEDED(Seek(pStream, 0, FILE_BEGIN)))
805 IStream_Write(pStream, &slh, sizeof(slh));
806 }
807 pStream->Release();
808 }
809 }
810 }
811 else
812 {
814 }
815
816 if (SUCCEEDED(hr) && DumpResult)
817 DumpCommand(LnkPath);
818 }
819 pSL->Release();
820 ILFree(pidlTarget);
821 return hr;
822}
823
825{
826 IShellLink *pSL;
827 HRESULT hr = Open(LnkPath, NULL, &pSL, STGM_READWRITE);
828 if (FAILED(hr))
829 return hr;
830
832 for (UINT i = 0; i < argc; ++i)
833 {
835 if (!Sig)
836 {
838 break;
839 }
840 hr = RemoveDatablock(pSL, Sig);
841 }
842
843 if (SUCCEEDED(hr))
844 hr = Save(pSL, LnkPath);
845 pSL->Release();
846 return hr;
847}
848
850{
851 if (argc < 3)
852 {
853 wprintf(L"%hs", g_Usage);
854 return argc < 2 ? 0 : ERROR_INVALID_PARAMETER;
855 }
856
857 if (!StrCmpIW(argv[1], L"Dump"))
859 if (!StrCmpIW(argv[1], L"Create"))
860 return SuccessOrReportError(CreateCommand(argv[2], argc - 3, &argv[3]));
861 if (!StrCmpIW(argv[1], L"RemoveDatablock"))
863
865}
866
868{
869 HRESULT hrInit = OleInitialize(NULL);
871 if (SUCCEEDED(hrInit))
873 return result;
874}
DWORD Id
PRTL_UNICODE_STRING_BUFFER Path
DWORD dwFileAttributes
static int argc
Definition: ServiceArgs.c:12
Type
Definition: Type.h:7
xD9 x84 xD8 xAD xD9 x80 xF0 x90 xAC x9A xE0 xA7 xA6 xE0 xA7 xAA xF0 x91 x84 xA4 xF0 x91 x84 x89 xF0 x91 x84 x9B xF0 x90 x8A xAB xF0 x90 x8B x89 xE2 xB2 x9E xE2 xB2 x9F xD0 xBE xD0 x9E xF0 x90 x90 x84 xF0 x90 x90 xAC xE1 x83 x98 xE1 x83 x94 xE1 x83 x90 xE1 xB2 xBF xE2 xB0 x95 xE2 xB1 x85 xCE xBF xCE x9F xE0 xA8 xA0 xE0 xA8 xB0 xE0 xA9 xA6 Kayah xEA xA4 x8D xEA xA4 x80 Khmer xE1 xA7 xA1 xE1 xA7 xAA xE0 xBB x90 Latin Subscript Fallback
Definition: afscript.h:223
BOOL Move(DWORD dwLen, PBYTE &pData, DWORD &dwSize)
Definition: asn.cpp:118
static void AddFlag(BOARD *p_board, unsigned col, unsigned row)
Definition: main.c:574
BOOL Error
Definition: chkdsk.c:66
#define EXTERN_C
Definition: basetyps.h:12
_Inout_ PVCB _In_ BOOLEAN Force
Definition: cdprocs.h:1417
#define Min(a, b)
Definition: cdprocs.h:74
Definition: bufpool.h:45
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_FAIL
Definition: ddrawi.h:102
ush Pos
Definition: deflate.h:92
LPWSTR Name
Definition: desk.c:124
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define FILE_BEGIN
Definition: compat.h:761
int(* FARPROC)()
Definition: compat.h:36
#define CP_ACP
Definition: compat.h:109
#define GetProcAddress(x, y)
Definition: compat.h:753
#define MAX_PATH
Definition: compat.h:34
#define WideCharToMultiByte
Definition: compat.h:111
#define lstrcpynW
Definition: compat.h:738
HINSTANCE WINAPI DECLSPEC_HOTPATCH LoadLibraryA(LPCSTR lpLibFileName)
Definition: loader.c:111
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
Definition: compobj.c:2434
HRESULT WINAPI DECLSPEC_HOTPATCH OleInitialize(LPVOID reserved)
Definition: ole2.c:169
void WINAPI DECLSPEC_HOTPATCH OleUninitialize(void)
Definition: ole2.c:230
static const WCHAR Signature[]
Definition: parser.c:141
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:304
HRESULT WINAPI SHReadDataBlockList(IStream *lpStream, LPDBLIST *lppList)
Definition: clist.c:235
VOID WINAPI SHFreeDataBlockList(LPDBLIST lpList)
Definition: clist.c:331
HRESULT WINAPI IStream_Reset(IStream *lpStream)
Definition: istream.c:640
HRESULT WINAPI SHCreateStreamOnFileW(LPCWSTR lpszPath, DWORD dwMode, IStream **lppStream)
Definition: istream.c:484
int WINAPI StrCmpIW(LPCWSTR lpszStr, LPCWSTR lpszComp)
Definition: string.c:353
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
static void *static void *static LPDIRECTPLAY IUnknown * pUnk
Definition: dplayx.c:30
int Simple(int arg)
Definition: ehframes.cpp:45
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLuint GLuint end
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLintptr offset
Definition: glext.h:5920
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLbitfield flags
Definition: glext.h:7161
GLuint64EXT * result
Definition: glext.h:11304
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLsizei len
Definition: glext.h:6722
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
_In_ ULONG Mode
Definition: hubbusif.h:303
@ Unknown
Definition: i8042prt.h:114
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
HRESULT GetIconLocation([in] UINT uFlags, [out, size_is(cchMax)] LPWSTR szIconFile, [in] UINT cchMax, [out] INT *piIndex, [out] UINT *pwFlags)
HRESULT Save([in, unique] LPCOLESTR pszFileName, [in] BOOL fRemember)
HRESULT Load([in, unique] IStream *pStm)
HRESULT RemoveDataBlock([in] DWORD dwSig)
HRESULT GetFlags([out] DWORD *pdwFlags)
HRESULT AddDataBlock([in] void *pDataBlock)
HRESULT SetFlags([in] DWORD dwFlags)
HRESULT SetArguments([in] LPCWSTR pszArgs)
HRESULT SetIDList([in] PCIDLIST_ABSOLUTE pidl)
HRESULT SetPath([in] LPCWSTR pszFile)
HRESULT SetIconLocation([in] LPCWSTR pszIconPath, [in] int iIcon)
HRESULT SetShowCmd([in] int iShowCmd)
HRESULT SetDescription([in] LPCWSTR pszName)
HRESULT SetRelativePath([in] LPCWSTR pszPathRel, [in] DWORD dwReserved)
HRESULT SetWorkingDirectory([in] LPCWSTR pszDir)
HRESULT GetIDList([out] PIDLIST_ABSOLUTE *ppidl)
HRESULT Seek([in] LARGE_INTEGER dlibMove, [in] DWORD dwOrigin, [out] ULARGE_INTEGER *plibNewPosition)
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
nsresult QueryInterface(nsIIDRef riid, void **result)
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define LONG_MAX
Definition: intsafe.h:154
#define FAILED(hr)
Definition: intsafe.h:51
#define e
Definition: ke_i.h:82
#define T
Definition: mbstring.h:31
#define Open
Definition: syshdrs.h:62
if(dx< 0)
Definition: linetemp.h:194
static const char g_Usage[]
Definition: lnktool.cpp:9
static void Dump(LPITEMIDLIST pidl, PCSTR Heading=NULL)
Definition: lnktool.cpp:230
static HRESULT RemoveDatablock(IShellLinkW *pSL, UINT Signature, UINT KillFlag=0, UINT AddFlag=0)
Definition: lnktool.cpp:624
#define FreeBlock
Definition: lnktool.cpp:335
static void Print(PCSTR Name, REFGUID Guid, PCSTR Indent="")
Definition: lnktool.cpp:208
static BOOL TryGetUpdatedPidl(IShellLinkW *pSL, PIDLIST_ABSOLUTE &pidl)
Definition: lnktool.cpp:653
#define DUMPSLH(name, fmt, field)
static void DumpFlags(V Value, T *pInfo, UINT Count, PCSTR Prefix=NULL)
Definition: lnktool.cpp:216
static HRESULT ReadAndDumpString(PCSTR Name, UINT Id, const SHELL_LINK_HEADER &slh, IStream *pStream)
Definition: lnktool.cpp:379
static HRESULT RemoveDatablockCommand(PCWSTR LnkPath, UINT argc, WCHAR **argv)
Definition: lnktool.cpp:824
static const struct @1574 g_SLDF[]
static const struct @1575 g_DBSig[]
static void PrintOffsetString(PCSTR Name, LPCVOID Base, UINT Min, UINT Ansi, UINT Unicode, PCSTR Indent="")
Definition: lnktool.cpp:199
#define INDENT
Definition: lnktool.cpp:8
static HRESULT AddDataBlock(IShellLinkW *pSL, T &DataBlock)
Definition: lnktool.cpp:641
#define PT_FS_UNICODE_FLAG
Definition: lnktool.cpp:41
static INT_PTR SHGetPidlInfo(LPCITEMIDLIST pidl, SHFILEINFOW &shfi, UINT Flags, UINT Depth=0)
Definition: lnktool.cpp:180
static HRESULT Load(IUnknown *pUnk, IStream *pStream)
Definition: lnktool.cpp:294
static LPDATABLOCK_HEADER NextBlock(LPDATABLOCK_HEADER pdbh)
Definition: lnktool.cpp:336
static PCSTR MapToName(UINT Value, const T &Map, PCSTR Fallback=NULL)
Definition: lnktool.cpp:110
static HRESULT SHParseNameEx(PCWSTR Path, PIDLIST_ABSOLUTE *ppidl, bool Simple)
Definition: lnktool.cpp:172
static HRESULT IL_LoadFromStream(IStream *pStrm, PIDLIST_ABSOLUTE *ppidl)
Definition: lnktool.cpp:152
UINT Flag
Definition: lnktool.cpp:43
static HRESULT Seek(IStream *pStrm, int Move, int Origin=FILE_CURRENT, ULARGE_INTEGER *pNewPos=NULL)
Definition: lnktool.cpp:145
static int ProcessCommandLine(int argc, WCHAR **argv)
Definition: lnktool.cpp:849
static LONG StrToNum(PCWSTR in)
Definition: lnktool.cpp:86
#define RemoveSLDF(pSL, Flag)
Definition: lnktool.cpp:621
static HRESULT CreateCommand(PCWSTR LnkPath, UINT argc, WCHAR **argv)
Definition: lnktool.cpp:664
static HRESULT ReadBlock(IStream *pStream, T **ppData=NULL)
Definition: lnktool.cpp:342
static UINT MapToNumber(PCWSTR Name, const T &Map)
Definition: lnktool.cpp:96
static HRESULT Save(IShellLink *pSL, PCWSTR LnkPath)
Definition: lnktool.cpp:281
PCSTR Name
Definition: lnktool.cpp:43
#define GetDatablockSignature(Name)
Definition: lnktool.cpp:121
#define AddSLDF(pSL, Flag)
Definition: lnktool.cpp:622
@ slgp_relativepriority
Definition: lnktool.cpp:37
#define PT_FS
Definition: lnktool.cpp:40
static HRESULT DumpCommand(PCWSTR Path)
Definition: lnktool.cpp:401
#define PT_COMPUTER_REGITEM
Definition: lnktool.cpp:39
#define GetSLDF(Name)
Definition: lnktool.cpp:120
#define PT_DESKTOP_REGITEM
Definition: lnktool.cpp:38
static int ErrMsg(int Error)
Definition: lnktool.cpp:123
static int SuccessOrReportError(int Error)
Definition: lnktool.cpp:140
static HRESULT SHParseName(PCWSTR Path, PIDLIST_ABSOLUTE *ppidl)
Definition: lnktool.cpp:162
const GUID * guid
#define for
Definition: utility.h:88
#define ERROR_FILE_NOT_FOUND
Definition: disk.h:79
PSDBQUERYRESULT_VISTA PVOID * ppData
Definition: env.c:56
static DWORD DWORD void LPSTR DWORD cch
Definition: str.c:202
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static HMODULE hShell32
Definition: string.c:34
#define min(a, b)
Definition: monoChain.cc:55
#define argv
Definition: mplay32.c:18
unsigned int UINT
Definition: ndis.h:50
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2478
int Count
Definition: noreturn.cpp:7
#define UNICODE_NULL
#define ANSI_NULL
#define L(x)
Definition: ntvdm.h:50
#define STGM_CREATE
Definition: objbase.h:926
#define STGM_SHARE_DENY_NONE
Definition: objbase.h:920
#define STGM_READWRITE
Definition: objbase.h:919
#define STGM_SHARE_DENY_WRITE
Definition: objbase.h:922
#define STGM_WRITE
Definition: objbase.h:918
#define STGM_READ
Definition: objbase.h:917
long LONG
Definition: pedump.c:60
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1044
LPITEMIDLIST WINAPI ILGetNext(LPCITEMIDLIST pidl)
Definition: pidl.c:970
#define signed
Definition: prototyp.h:114
int wmain()
DWORD_PTR WINAPI SHGetFileInfoW(LPCWSTR path, DWORD dwFileAttributes, SHFILEINFOW *psfi, UINT sizeofpsfi, UINT flags)
Definition: shell32_main.c:430
#define SHGFI_DISPLAYNAME
Definition: shellapi.h:167
#define SHGFI_PIDL
Definition: shellapi.h:181
HRESULT hr
Definition: shlfolder.c:183
HRESULT WINAPI SHILCreateFromPath(_In_ PCWSTR, _Outptr_ PIDLIST_ABSOLUTE *, _Inout_opt_ DWORD *)
#define EXP_DARWIN_ID_SIG
Definition: shlobj.h:2063
#define EXP_SZ_LINK_SIG
Definition: shlobj.h:2059
@ SLDF_HAS_RELPATH
Definition: shlobj.h:1955
@ SLDF_HAS_EXP_SZ
Definition: shlobj.h:1961
@ SLDF_HAS_ID_LIST
Definition: shlobj.h:1952
@ SLDF_HAS_DARWINID
Definition: shlobj.h:1966
@ SLDF_RUN_IN_SEPARATE
Definition: shlobj.h:1962
@ SLDF_HAS_LINK_INFO
Definition: shlobj.h:1953
@ SLDF_HAS_WORKINGDIR
Definition: shlobj.h:1956
@ SLDF_HAS_ARGS
Definition: shlobj.h:1957
@ SLDF_FORCE_NO_LINKINFO
Definition: shlobj.h:1960
@ SLDF_NO_PIDL_ALIAS
Definition: shlobj.h:1969
@ SLDF_HAS_EXP_ICON_SZ
Definition: shlobj.h:1968
@ SLDF_RUNAS_USER
Definition: shlobj.h:1967
@ SLDF_UNICODE
Definition: shlobj.h:1959
@ SLDF_RUN_WITH_SHIMLAYER
Definition: shlobj.h:1971
@ SLDF_HAS_ICONLOCATION
Definition: shlobj.h:1958
@ SLDF_FORCE_UNCNAME
Definition: shlobj.h:1970
@ SLDF_HAS_NAME
Definition: shlobj.h:1954
#define CSIDL_SYSTEM
Definition: shlobj.h:2217
#define EXP_SZ_ICON_SIG
Definition: shlobj.h:2067
#define EXP_SPECIAL_FOLDER_SIG
Definition: shlobj.h:2062
#define NT_CONSOLE_PROPS_SIG
Definition: shlobj.h:2060
PIDLIST_ABSOLUTE WINAPI SHSimpleIDListFromPath(PCWSTR)
#define CSIDL_WINDOWS
Definition: shlobj.h:2216
#define StrCmpIA
Definition: shlwapi.h:1541
#define PathParseIconLocation
Definition: shlwapi.h:1026
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
LPDATABLOCK_HEADER m_It
Definition: lnktool.cpp:376
void Next()
Definition: lnktool.cpp:371
LPDATABLOCK_HEADER Get()
Definition: lnktool.cpp:365
DataBlockEnum(LPDATABLOCK_HEADER pHead)
Definition: lnktool.cpp:363
DWORD idSpecialFolder
Definition: shlobj.h:2049
WORD cb
Definition: ItemIDList.cpp:26
Definition: xml2sdb.h:80
Definition: scsiwmi.h:51
WCHAR szDisplayName[MAX_PATH]
Definition: shellapi.h:376
Definition: fci.c:116
#define UL
Definition: tui.h:164
uint16_t * PWSTR
Definition: typedefs.h:56
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * PCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
const char * PCSTR
Definition: typedefs.h:52
uint16_t * PWCHAR
Definition: typedefs.h:56
#define HIWORD(l)
Definition: typedefs.h:247
#define SLI_VALID_NETWORK
Definition: undocshell.h:1089
struct tagSHELL_LINK_INFOW SHELL_LINK_INFOW
#define SLI_VALID_LOCAL
Definition: undocshell.h:1087
#define EXP_SHIM_SIG
Definition: undocshell.h:1219
#define EXP_VISTA_ID_LIST_SIG
Definition: undocshell.h:1221
#define EXP_TRACKER_SIG
Definition: undocshell.h:1218
#define EXP_KNOWN_FOLDER_SIG
Definition: undocshell.h:1220
#define SLI_CNR_VALID_DEVICE
Definition: undocshell.h:1166
int ret
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
Definition: wdfobject.h:762
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
#define wprintf(...)
Definition: whoami.c:18
#define FormatMessage
Definition: winbase.h:3826
#define FORMAT_MESSAGE_IGNORE_INSERTS
Definition: winbase.h:446
#define FILE_CURRENT
Definition: winbase.h:114
#define FORMAT_MESSAGE_FROM_SYSTEM
Definition: winbase.h:449
_In_ DWORD nLength
Definition: wincon.h:473
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
CONST void * LPCVOID
Definition: windef.h:191
#define HRESULT
Definition: msvc.h:7
#define WINAPI
Definition: msvc.h:6
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define HRESULT_CODE(hr)
Definition: winerror.h:76
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_In_opt_ PALLOCATE_FUNCTION _In_opt_ PFREE_FUNCTION _In_ ULONG _In_ SIZE_T _In_ ULONG _In_ USHORT Depth
Definition: exfuncs.h:819
_In_ __drv_aliasesMem PSTRING Prefix
Definition: rtlfuncs.h:1647
#define IID_PPV_ARG(Itype, ppType)
__wchar_t WCHAR
Definition: xmlstorage.h:180
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193