385{
386 const char *pszOutputPath = "shortcut.lnk";
387 const char *pszTarget =
NULL;
388 const char *pszDescription =
NULL;
389 const char *pszWorkingDir =
NULL;
390 const char *pszCmdLineArgs =
NULL;
391 const char *pszIcon =
NULL;
395 bool bHelp = false, bUnicode = false, bMinimized = false;
404
405
407 {
408 if ((
argv[
i][0] ==
'-' ||
argv[
i][0] ==
'/') &&
410 {
412 break;
413 }
414 }
415
416
418 {
420
424 bHelp = true;
426 ;
428 {
431 pszOutputPath =
argv[
i];
432 }
434 bUnicode = true;
436 {
439 pszDescription =
argv[
i];
440 }
442 {
445 pszWorkingDir =
argv[
i];
446 }
448 {
451 pszCmdLineArgs =
argv[
i];
452 }
454 {
458 }
460 bMinimized = true;
462 {
463 unsigned Data4Tmp[8],
j;
464
467 sscanf(
argv[
i],
"{%8x-%4hx-%4hx-%2x%2x-%2x%2x%2x%2x%2x%2x}",
469 &Data4Tmp[0], &Data4Tmp[1], &Data4Tmp[2], &Data4Tmp[3],
470 &Data4Tmp[4], &Data4Tmp[5], &Data4Tmp[6], &Data4Tmp[7]);
471 for (
j = 0;
j < 8; ++
j)
473 }
474 else
475 {
477 bHelp = true;
478 }
479 }
482
483 if (!pszTarget || bHelp)
484 {
485 printf(
"Usage: %s [-h][-v][-o path][-u][-d descr][-w path][-c cmdline_args][-i [icon_path[,nr]]][-g guid] target\n"
486 "-h\tShows this help.\n"
487 "-v\tEnables verbose mode for diagnostics.\n"
488 "-o path\tSets the output path.\n"
489 "-u\tCreates a Unicode-aware shortcut.\n"
490 "-d descr\tSets the shortcut description.\n"
491 "-w path\tSets the working directory for the executable.\n"
492 "-c cmdline_args\tSets the command-line arguments passed to the program.\n"
493 "-i [icon_path[,nr]]\tSets the icon path and optionally its index. If only an index is given (but no path), the target file is used instead.\n"
494 "-m\tStart minimized.\n"
495 "-g guid\tSets the GUID to which the target path is relative. Default value is MyComputer GUID.\n"
496 "target\tAbsolute or relative to GUID specified with the -g option path.\n",
argv[0]);
497 return 0;
498 }
499
500
501 if (pszTarget)
503 if (pszWorkingDir)
505 if (pszCmdLineArgs)
507 if (pszIcon)
508 {
510
512
513
514 dwTmp =
strtol(pszIcon, &endptr, 0);
515 if (endptr && endptr != pszIcon)
516 {
517
519 pszIcon = (char*)1;
520 }
521 else
522 {
523
526 {
527
529 if (endptr && endptr != (
ptr+1))
530 {
531
534 }
535 }
536 pszIcon = pszIcon;
537 }
538 }
539
540 trace(
"OutputPath = %s\n"
541 "Target = %s\n"
542 "Description = %s\n"
543 "WorkingDir = %s\n"
544 "CmdLineArgs = %s\n"
545 "Icon = %s (%d)\n\n",
546 pszOutputPath, pszTarget, pszDescription,
547 pszWorkingDir, pszCmdLineArgs,
548 (pszIcon == (
char*)1) ? pszTarget : pszIcon,
IconIndex);
549
552 {
553 printf(
"Failed to open %s\n", pszOutputPath);
554 return -1;
555 }
556
557
560 Header.Guid = CLSID_ShellLink;
562 if (bUnicode)
564 if (pszDescription)
566 if (pszWorkingDir)
568 if (pszCmdLineArgs)
570 if (pszIcon)
574
575
577 if (special)
579
580
582 {
584 Header.Flags &= ~LINK_ID_LIST;
585 }
587 Header.Flags &= ~LINK_RELATIVE_PATH;
588
589
590
593
594
595
596
597
598
603
604 trace(
"Header.Flags = 0x%08x\n"
605 "Header.IconIndex = %d\n"
606 "Header.ShowCmd = %u\n",
608
610
612 {
616 unsigned int cbListSize =
sizeof(IdListGuid) +
sizeof(
uint16_t);
618 const char *pszName;
619 const char *pszOrgTarget = pszTarget;
620 size_t specialPathLen = 0;
622
623
624
625 if (special)
626 {
627 CsidlBlock.
cbSize =
sizeof(CsidlBlock);
632 pszTarget = targetpath;
633 }
634 pszName = pszTarget;
635
636 if (pszName[0] && pszName[0] != ':' && pszName[1] == ':')
637 {
638 cbListSize += sizeof(IdListDrive);
639 pszName += 2;
641 ++pszName;
642 }
643
644 while (*pszName)
645 {
649
650 if (
cchName != 1 || pszName[0] !=
'.')
651 {
652
653
654 cbListSize +=
sizeof(IdListFile) + (
cchName + 1) + 1;
655 }
656
657 if (special && ((pszName+
cchName)-pszTarget == specialPathLen))
658 {
659
661 pCsidlBlock = &CsidlBlock;
662 }
663
666 ++pszName;
667 }
668
669
670 uhTmp = cbListSize;
672
673 IdListGuid.
Size =
sizeof(IdListGuid);
678
679 pszName = pszTarget;
680
681 if (
isalpha(pszName[0]) && pszName[1] ==
':')
682 {
683 memset(&IdListDrive, 0,
sizeof(IdListDrive));
684 IdListDrive.
Size =
sizeof(IdListDrive);
687 fwrite(&IdListDrive,
sizeof(IdListDrive), 1,
pFile);
688 pszName += 2;
690 ++pszName;
691 }
692
693 while (*pszName)
694 {
698
699 if (
cchName != 1 || pszName[0] !=
'.')
700 {
701 memset(&IdListFile, 0,
sizeof(IdListFile));
702
703
704 IdListFile.
Size =
sizeof(IdListFile) + (
cchName + 1) + 1;
707 else
712
713
715 }
716
719 ++pszName;
720 }
721
722
723 uhTmp = 0;
725
726
727 if (special)
728 {
730 pszTarget = targetpath;
731 }
732 }
733
734
735 if (pszIcon == (char*)1)
736 pszIcon = pszTarget;
737
739 {
740 memset(&SzLinkBlock, 0,
sizeof(SzLinkBlock));
741 SzLinkBlock.
cbSize =
sizeof(SzLinkBlock);
743
744
747
748 pSzLinkBlock = &SzLinkBlock;
749 }
750
752 {
753 memset(&SzIconBlock, 0,
sizeof(SzIconBlock));
754 SzIconBlock.
cbSize =
sizeof(SzIconBlock);
756
757
760
761 pSzIconBlock = &SzIconBlock;
762 }
763
764
767
768
771
772
775
776
779
780
783
784
785 if (pCsidlBlock)
786 fwrite(pCsidlBlock,
sizeof(*pCsidlBlock), 1,
pFile);
787 if (pSzLinkBlock)
788 fwrite(pSzLinkBlock,
sizeof(*pSzLinkBlock), 1,
pFile);
789 if (pSzIconBlock)
790 fwrite(pSzIconBlock,
sizeof(*pSzIconBlock), 1,
pFile);
791
792 dwTmp = 0;
794
796
797 return 0;
798}
int CDECL fclose(FILE *file)
FILE *CDECL fopen(const char *path, const char *mode)
int CDECL fputc(int c, FILE *file)
size_t CDECL fwrite(const void *ptr, size_t size, size_t nmemb, FILE *file)
_ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl _ACRTIMP int __cdecl sscanf(const char *, const char *,...) __WINE_CRT_SCANF_ATTR(2
_ACRTIMP __msvcrt_long __cdecl strtol(const char *, char **, int)
_ACRTIMP int __cdecl strcmp(const char *, const char *)
_ACRTIMP char *__cdecl strrchr(const char *, int)
static const WCHAR IconIndex[]
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 GLint GLint j
static bool has_env_variables(const char *str)
static const struct SPECIALFOLDER * get_special_folder(const char *target)
#define LINK_RELATIVE_PATH
#define LINK_CMDLINE_ARGS
#define EXP_SPECIAL_FOLDER_SIG
static void write_string(FILE *pFile, bool bUnicode, const char *str)
static void strip_quotes_and_unescape_envvars(char **pstr)
#define REGITEMORDER_MYCOMPUTER
#define SLDF_HAS_EXP_ICON_SZ
#define SW_SHOWMINNOACTIVE
WCHAR szwTarget[MAX_PATH]
_Must_inspect_result_ _In_ WDFOBJECT _In_ CONST GUID * Guid
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName