]>
Commit | Line | Data |
---|---|---|
51ebb760 | 1 | #define CINTERFACE |
b24c88b3 | 2 | #include <stdlib.h> |
904d24fe DD |
3 | #include "win32.h" |
4 | #include "shlobj.h" | |
b24c88b3 | 5 | #include "mklink2.h" |
2f0315ad | 6 | #include "filemanip.h" |
904d24fe | 7 | |
b24c88b3 RC |
8 | #if 0 |
9 | static const char *cvsid = | |
10 | "\n%%% $Id$\n"; | |
11 | #endif | |
8507f105 | 12 | |
904d24fe DD |
13 | /* This part of the code must be in C because the C++ interface to COM |
14 | doesn't work. */ | |
15 | ||
51ebb760 | 16 | extern "C" |
904d24fe | 17 | void |
3c054baf | 18 | make_link_2 (char const *exepath, char const *args, char const *icon, char const *lname) |
904d24fe DD |
19 | { |
20 | IShellLink *sl; | |
21 | IPersistFile *pf; | |
4875ac88 | 22 | WCHAR widepath[MAX_PATH]; |
904d24fe | 23 | |
931f2755 RC |
24 | CoCreateInstance (&CLSID_ShellLink, NULL, |
25 | CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID *) & sl); | |
26 | sl->lpVtbl->QueryInterface (sl, &IID_IPersistFile, (void **) &pf); | |
904d24fe DD |
27 | |
28 | sl->lpVtbl->SetPath (sl, exepath); | |
29 | sl->lpVtbl->SetArguments (sl, args); | |
30 | sl->lpVtbl->SetIconLocation (sl, icon, 0); | |
31 | ||
4875ac88 | 32 | MultiByteToWideChar (CP_ACP, 0, lname, -1, widepath, MAX_PATH); |
904d24fe DD |
33 | pf->lpVtbl->Save (pf, widepath, TRUE); |
34 | ||
35 | pf->lpVtbl->Release (pf); | |
36 | sl->lpVtbl->Release (sl); | |
37 | } | |
b24c88b3 RC |
38 | |
39 | #define SYMLINK_COOKIE "!<symlink>" | |
40 | ||
41 | /* Predicate: file is not currently in existence. | |
42 | * A file race can occur otherwise. | |
43 | */ | |
2f0315ad CV |
44 | static int |
45 | mkcygsymlink_9x (const char *from, const char *to) | |
b24c88b3 RC |
46 | { |
47 | char buf[512]; | |
48 | unsigned long w; | |
2f0315ad | 49 | |
b24c88b3 | 50 | HANDLE h = CreateFileA (from, GENERIC_WRITE, 0, 0, CREATE_NEW, |
b41c2908 | 51 | FILE_ATTRIBUTE_NORMAL, 0); |
b24c88b3 RC |
52 | if (h == INVALID_HANDLE_VALUE) |
53 | return 1; | |
54 | strcpy (buf, SYMLINK_COOKIE); | |
55 | strcat (buf, to); | |
56 | if (WriteFile (h, buf, strlen (buf) + 1, &w, NULL)) | |
57 | { | |
58 | CloseHandle (h); | |
59 | SetFileAttributesA (from, FILE_ATTRIBUTE_SYSTEM); | |
60 | return 0; | |
61 | } | |
62 | CloseHandle (h); | |
63 | DeleteFileA (from); | |
64 | return 1; | |
65 | } | |
2f0315ad CV |
66 | |
67 | static int | |
68 | mkcygsymlink_nt (const char *from, const char *to) | |
69 | { | |
70 | char buf[512]; | |
71 | unsigned long w; | |
72 | const size_t len = strlen (from) + 7; | |
73 | WCHAR wfrom[len]; | |
74 | ||
75 | mklongpath (wfrom, from, len); | |
b41c2908 CV |
76 | HANDLE h = CreateFileW (wfrom, STANDARD_RIGHTS_ALL | GENERIC_WRITE, |
77 | 0, 0, CREATE_NEW, | |
78 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, | |
79 | 0); | |
2f0315ad CV |
80 | if (h == INVALID_HANDLE_VALUE) |
81 | return 1; | |
82 | strcpy (buf, SYMLINK_COOKIE); | |
83 | strcat (buf, to); | |
84 | if (WriteFile (h, buf, strlen (buf) + 1, &w, NULL)) | |
85 | { | |
be617b59 | 86 | nt_sec.SetPosixPerms (from, h, 0644); |
2f0315ad CV |
87 | CloseHandle (h); |
88 | SetFileAttributesW (wfrom, FILE_ATTRIBUTE_SYSTEM); | |
89 | return 0; | |
90 | } | |
91 | CloseHandle (h); | |
92 | DeleteFileW (wfrom); | |
93 | return 1; | |
94 | } | |
95 | ||
96 | extern "C" | |
97 | int | |
98 | mkcygsymlink (const char *from, const char *to) | |
99 | { | |
100 | return IsWindowsNT () ? mkcygsymlink_nt (from, to) | |
101 | : mkcygsymlink_9x (from, to); | |
102 | } |