ReactOS  0.4.14-dev-358-gbef841c
mkshelllink.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
Include dependency graph for mkshelllink.c:

Go to the source code of this file.

Classes

struct  _GUID
 
struct  _FILETIME
 
struct  _LNK_HEADER
 
struct  _LNK_LOCATOR_INFO
 
struct  _LNK_LOCAL_VOLUME_INFO
 
struct  _ID_LIST_FILE
 
struct  _ID_LIST_GUID
 
struct  _ID_LIST_DRIVE
 

Macros

#define SW_SHOWNORMAL   1
 
#define SW_SHOWMINNOACTIVE   7
 
#define DEFINE_GUID2(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8)   const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }
 
#define LINK_ID_LIST   0x01
 
#define LINK_FILE   0x02
 
#define LINK_DESCRIPTION   0x04
 
#define LINK_RELATIVE_PATH   0x08
 
#define LINK_WORKING_DIR   0x10
 
#define LINK_CMD_LINE_ARGS   0x20
 
#define LINK_ICON   0x40
 
#define LINK_UNICODE   0x80
 
#define LOCATOR_LOCAL   0x1
 
#define LOCATOR_NETWORK   0x2
 
#define PT_GUID   0x1F
 
#define PT_DRIVE1   0x2F
 
#define PT_FOLDER   0x31
 
#define PT_VALUE   0x32
 

Typedefs

typedef struct _GUID GUID
 
typedef struct _FILETIME FILETIME
 
typedef struct _FILETIMEPFILETIME
 
typedef struct _LNK_HEADER LNK_HEADER
 
typedef struct _LNK_LOCATOR_INFO LNK_LOCATOR_INFO
 
typedef struct _LNK_LOCAL_VOLUME_INFO LNK_LOCAL_VOLUME_INFO
 
typedef struct _ID_LIST_FILE ID_LIST_FILE
 
typedef struct _ID_LIST_GUID ID_LIST_GUID
 
typedef struct _ID_LIST_DRIVE ID_LIST_DRIVE
 

Functions

 DEFINE_GUID2 (CLSID_ShellLink, 0x00021401L, 0, 0, 0xC0, 0, 0, 0, 0, 0, 0, 0x46)
 
 DEFINE_GUID2 (CLSID_MyComputer, 0x20D04FE0, 0x3AEA, 0x1069, 0xA2, 0xD8, 0x08, 0x00, 0x2B, 0x30, 0x30, 0x9D)
 
int main (int argc, const char *argv[])
 

Macro Definition Documentation

◆ DEFINE_GUID2

#define DEFINE_GUID2 (   name,
  l,
  w1,
  w2,
  b1,
  b2,
  b3,
  b4,
  b5,
  b6,
  b7,
  b8 
)    const GUID name = { l,w1,w2,{ b1,b2,b3,b4,b5,b6,b7,b8 } }

Definition at line 37 of file mkshelllink.c.

◆ LINK_CMD_LINE_ARGS

#define LINK_CMD_LINE_ARGS   0x20

Definition at line 46 of file mkshelllink.c.

◆ LINK_DESCRIPTION

#define LINK_DESCRIPTION   0x04

Definition at line 43 of file mkshelllink.c.

◆ LINK_FILE

#define LINK_FILE   0x02

Definition at line 42 of file mkshelllink.c.

◆ LINK_ICON

#define LINK_ICON   0x40

Definition at line 47 of file mkshelllink.c.

◆ LINK_ID_LIST

#define LINK_ID_LIST   0x01

Definition at line 41 of file mkshelllink.c.

◆ LINK_RELATIVE_PATH

#define LINK_RELATIVE_PATH   0x08

Definition at line 44 of file mkshelllink.c.

◆ LINK_UNICODE

#define LINK_UNICODE   0x80

Definition at line 48 of file mkshelllink.c.

◆ LINK_WORKING_DIR

#define LINK_WORKING_DIR   0x10

Definition at line 45 of file mkshelllink.c.

◆ LOCATOR_LOCAL

#define LOCATOR_LOCAL   0x1

Definition at line 50 of file mkshelllink.c.

◆ LOCATOR_NETWORK

#define LOCATOR_NETWORK   0x2

Definition at line 51 of file mkshelllink.c.

◆ PT_DRIVE1

#define PT_DRIVE1   0x2F

Definition at line 96 of file mkshelllink.c.

◆ PT_FOLDER

#define PT_FOLDER   0x31

Definition at line 97 of file mkshelllink.c.

◆ PT_GUID

#define PT_GUID   0x1F

Definition at line 95 of file mkshelllink.c.

◆ PT_VALUE

#define PT_VALUE   0x32

Definition at line 98 of file mkshelllink.c.

◆ SW_SHOWMINNOACTIVE

#define SW_SHOWMINNOACTIVE   7

Definition at line 22 of file mkshelllink.c.

◆ SW_SHOWNORMAL

#define SW_SHOWNORMAL   1

Definition at line 21 of file mkshelllink.c.

Typedef Documentation

◆ FILETIME

◆ GUID

typedef struct _GUID GUID

◆ ID_LIST_DRIVE

◆ ID_LIST_FILE

◆ ID_LIST_GUID

◆ LNK_HEADER

◆ LNK_LOCAL_VOLUME_INFO

◆ LNK_LOCATOR_INFO

◆ PFILETIME

Function Documentation

◆ DEFINE_GUID2() [1/2]

DEFINE_GUID2 ( CLSID_ShellLink  ,
0x00021401L  ,
,
,
0xC0  ,
,
,
,
,
,
,
0x46   
)

◆ DEFINE_GUID2() [2/2]

DEFINE_GUID2 ( CLSID_MyComputer  ,
0x20D04FE0  ,
0x3AEA  ,
0x1069  ,
0xA2  ,
0xD8  ,
0x08  ,
0x00  ,
0x2B  ,
0x30  ,
0x30  ,
0x9D   
)

◆ main()

int main ( int argc  ,
const char argv[] 
)

Definition at line 130 of file mkshelllink.c.

131 {
132  int i;
133  const char *pszOutputPath = "shortcut.lnk";
134  const char *pszTarget = NULL;
135  const char *pszDescription = "Description";
136  const char *pszWorkingDir = NULL;
137  const char *pszCmdLineArgs = NULL;
138  const char *pszIcon = NULL;
139  int IconNr = 0;
140  GUID Guid = CLSID_MyComputer;
141  int bHelp = 0, bMinimized = 0;
142  FILE *pFile;
144  uint16_t uhTmp;
145  uint32_t dwTmp;
146 
147  for (i = 1; i < argc; ++i)
148  {
149  if (argv[i][0] != '-' && argv[i][0] != '/')
150  pszTarget = argv[i];
151  else if (!strcmp(argv[i] + 1, "h"))
152  bHelp = 1;
153  else if (!strcmp(argv[i] + 1, "o") && i + 1 < argc)
154  pszOutputPath = argv[++i];
155  else if (!strcmp(argv[i] + 1, "d") && i + 1 < argc)
156  pszDescription = argv[++i];
157  else if (!strcmp(argv[i] + 1, "w") && i + 1 < argc)
158  pszWorkingDir = argv[++i];
159  else if (!strcmp(argv[i] + 1, "c") && i + 1 < argc)
160  pszCmdLineArgs = argv[++i];
161  else if (!strcmp(argv[i] + 1, "i") && i + 1 < argc)
162  {
163  pszIcon = argv[++i];
164  if (i + 1 < argc && isdigit(argv[i + 1][0]))
165  IconNr = atoi(argv[++i]);
166  }
167  else if (!strcmp(argv[i] + 1, "m"))
168  bMinimized = 1;
169  else if (!strcmp(argv[i] + 1, "g") && i + 1 < argc)
170  {
171  unsigned Data4Tmp[8], j;
172 
173  sscanf(argv[++i], "{%8x-%4hx-%4hx-%2x%2x-%2x%2x%2x%2x%2x%2x}",
174  &Guid.Data1, &Guid.Data2, &Guid.Data3,
175  &Data4Tmp[0], &Data4Tmp[1], &Data4Tmp[2], &Data4Tmp[3],
176  &Data4Tmp[4], &Data4Tmp[5], &Data4Tmp[6], &Data4Tmp[7]);
177  for (j = 0; j < 8; ++j)
178  Guid.Data4[j] = (uint8_t)Data4Tmp[j];
179  }
180  else
181  printf("Invalid option: %s\n", argv[i]);
182  }
183 
184  if (!pszTarget || bHelp)
185  {
186  printf("Usage: %s [-o path][-d descr][-w path][-c cmd_line_args][-i icon_path [nr]][-h][-g guid] target\n"
187  "-o path\tSets output path\n"
188  "-d descr\tSets shortcut description\n"
189  "-w path\tSets working directory for executable\n"
190  "-c cmd_line_args\tSets command line arguments passed to program\n"
191  "-i icon_path [nr]\tSets icon file and optionally icon index\n"
192  "-m\tStart minimized\n"
193  "-g guid\tSets GUID to which target path is relative. Default value is MyComputer GUID.\n"
194  "target\tAbsolute or relative to guid specified with -g option path\n", argv[0]);
195  return 0;
196  }
197 
198  pFile = fopen(pszOutputPath, "wb");
199  if (!pFile)
200  {
201  printf("Failed to open %s\n", pszOutputPath);
202  return -1;
203  }
204 
205  // Header
206  memset(&Header, 0, sizeof(Header));
207  Header.Signature = (uint32_t)'L';
208  Header.Guid = CLSID_ShellLink;
209  Header.Flags = LINK_ID_LIST;
210  if (pszDescription)
211  Header.Flags |= LINK_DESCRIPTION;
212  if (pszWorkingDir)
213  Header.Flags |= LINK_WORKING_DIR;
214  if (pszCmdLineArgs)
215  Header.Flags |= LINK_CMD_LINE_ARGS;
216  if (pszIcon)
217  Header.Flags |= LINK_ICON;
218  Header.IconNr = IconNr;
219  Header.Show = bMinimized ? SW_SHOWMINNOACTIVE : SW_SHOWNORMAL;
220  fwrite(&Header, sizeof(Header), 1, pFile);
221 
222  if (Header.Flags & LINK_ID_LIST)
223  {
224  ID_LIST_FILE IdListFile;
225  ID_LIST_GUID IdListGuid;
226  ID_LIST_DRIVE IdListDrive;
227  unsigned cbListSize = sizeof(IdListGuid) + sizeof(uint16_t), cchName;
228  const char *pszName = pszTarget;
229 
230  // ID list
231  // It seems explorer does not accept links without id list. List is relative to desktop.
232 
233  pszName = pszTarget;
234 
235  if (pszName[0] && pszName[1] == ':')
236  {
237  cbListSize += sizeof(IdListDrive);
238  pszName += 2;
239  while (*pszName == '\\' || *pszName == '/')
240  ++pszName;
241  }
242 
243  while (*pszName)
244  {
245  cchName = 0;
246  while (pszName[cchName] && pszName[cchName] != '\\' && pszName[cchName] != '/')
247  ++cchName;
248 
249  if (cchName != 1 || pszName[0] != '.')
250  cbListSize += sizeof(IdListFile) + 2 * (cchName + 1);
251 
252  pszName += cchName;
253  while (*pszName == '\\' || *pszName == '/')
254  ++pszName;
255  }
256 
257  uhTmp = cbListSize;
258  fwrite(&uhTmp, sizeof(uhTmp), 1, pFile); // size
259 
260  IdListGuid.Size = sizeof(IdListGuid);
261  IdListGuid.Type = PT_GUID;
262  IdListGuid.dummy = 0x50;
263  IdListGuid.guid = Guid;
264  fwrite(&IdListGuid, sizeof(IdListGuid), 1, pFile);
265 
266  pszName = pszTarget;
267 
268  if (isalpha(pszName[0]) && pszName[1] == ':')
269  {
270  memset(&IdListDrive, 0, sizeof(IdListDrive));
271  IdListDrive.Size = sizeof(IdListDrive);
272  IdListDrive.Type = PT_DRIVE1;
273  sprintf(IdListDrive.szDriveName, "%c:\\", pszName[0]);
274  fwrite(&IdListDrive, sizeof(IdListDrive), 1, pFile);
275  pszName += 2;
276  while(*pszName == '\\' || *pszName == '/')
277  ++pszName;
278  }
279 
280  while (*pszName)
281  {
282  cchName = 0;
283  while (pszName[cchName] && pszName[cchName] != '\\' && pszName[cchName] != '/')
284  ++cchName;
285 
286  if (cchName != 1 || pszName[0] != '.')
287  {
288  memset(&IdListFile, 0, sizeof(IdListFile));
289  IdListFile.Size = sizeof(IdListFile) + 2 * (cchName + 1);
290  if (!pszName[cchName])
291  IdListFile.Type = PT_VALUE; // File
292  else
293  IdListFile.Type = PT_FOLDER;
294  fwrite(&IdListFile, sizeof(IdListFile), 1, pFile);
295  fwrite(pszName, cchName, 1, pFile);
296  fputc(0, pFile);
297  fwrite(pszName, cchName, 1, pFile);
298  fputc(0, pFile);
299  }
300 
301  pszName += cchName;
302  while (*pszName == '\\' || *pszName == '/')
303  ++pszName;
304  }
305 
306  uhTmp = 0; // list end
307  fwrite(&uhTmp, sizeof(uhTmp), 1, pFile);
308  }
309 
310  if (Header.Flags & LINK_DESCRIPTION)
311  {
312  // Dscription
313  uhTmp = strlen(pszDescription);
314  fwrite(&uhTmp, sizeof(uhTmp), 1, pFile);
315  fputs(pszDescription, pFile);
316  }
317 
318  if (Header.Flags & LINK_RELATIVE_PATH)
319  {
320  // Relative Path
321  uhTmp = strlen(pszTarget);
322  fwrite(&uhTmp, sizeof(uhTmp), 1, pFile);
323  fputs(pszTarget, pFile);
324  }
325 
326  if (Header.Flags & LINK_WORKING_DIR)
327  {
328  // Working Dir
329  uhTmp = strlen(pszWorkingDir);
330  fwrite(&uhTmp, sizeof(uhTmp), 1, pFile);
331  fputs(pszWorkingDir, pFile);
332  }
333 
334  if (Header.Flags & LINK_CMD_LINE_ARGS)
335  {
336  // Command line arguments
337  uhTmp = strlen(pszCmdLineArgs);
338  fwrite(&uhTmp, sizeof(uhTmp), 1, pFile);
339  fputs(pszCmdLineArgs, pFile);
340  }
341 
342  if (Header.Flags & LINK_ICON)
343  {
344  // Command line arguments
345  uhTmp = strlen(pszIcon);
346  fwrite(&uhTmp, sizeof(uhTmp), 1, pFile);
347  fputs(pszIcon, pFile);
348  }
349 
350  // Extra stuff
351  dwTmp = 0;
352  fwrite(&dwTmp, sizeof(dwTmp), 1, pFile);
353 
354  fclose(pFile);
355 
356  return 0;
357 }
static int argc
Definition: ServiceArgs.c:12
_Check_return_opt_ _CRTIMP int __cdecl fputc(_In_ int _Ch, _Inout_ FILE *_File)
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define isalpha(c)
Definition: acclib.h:74
unsigned short int uint16_t
Definition: acefiex.h:54
_Check_return_opt_ _CRTIMP size_t __cdecl fwrite(_In_reads_bytes_(_Size *_Count) const void *_Str, _In_ size_t _Size, _In_ size_t _Count, _Inout_ FILE *_File)
#define argv
Definition: mplay32.c:18
#define sprintf(buf, format,...)
Definition: sprintf.c:55
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2713
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
Definition: Header.h:8
static GUID * Guid
Definition: apphelp.c:93
smooth NULL
Definition: ftsmooth.c:416
uint16_t Size
Definition: mkshelllink.c:114
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define isdigit(c)
Definition: acclib.h:68
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
Definition: glfuncs.h:250
uint8_t dummy
Definition: mkshelllink.c:116
uint8_t Type
Definition: mkshelllink.c:115
uint16_t Size
Definition: mkshelllink.c:122
_Check_return_opt_ _CRTIMP int __cdecl fclose(_Inout_ FILE *_File)
_Check_return_ _CRTIMP FILE *__cdecl fopen(_In_z_ const char *_Filename, _In_z_ const char *_Mode)
BYTE uint8_t
Definition: msvideo1.c:66
UINT32 uint32_t
Definition: types.h:75
_Check_return_ int __cdecl atoi(_In_z_ const char *_Str)
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
uint16_t Size
Definition: mkshelllink.c:102
#define uint32_t
Definition: nsiface.idl:61
#define memset(x, y, z)
Definition: compat.h:39
uint8_t Type
Definition: mkshelllink.c:103
_Check_return_opt_ _CRTIMP int __cdecl fputs(_In_z_ const char *_Str, _Inout_ FILE *_File)
char szDriveName[20]
Definition: mkshelllink.c:124
#define printf
Definition: config.h:203