]>
Commit | Line | Data |
---|---|---|
b24c88b3 | 1 | #include <stdlib.h> |
d2e8d256 | 2 | #include <wchar.h> |
904d24fe | 3 | #include "win32.h" |
d2e8d256 | 4 | #include "ntdll.h" |
904d24fe | 5 | #include "shlobj.h" |
b24c88b3 | 6 | #include "mklink2.h" |
2f0315ad | 7 | #include "filemanip.h" |
904d24fe DD |
8 | |
9 | /* This part of the code must be in C because the C++ interface to COM | |
10 | doesn't work. */ | |
11 | ||
e36b0f1e CV |
12 | /* Initialized in WinMain. This is required under Windows 7. If |
13 | CoCreateInstance gets called from here, it fails to create the | |
14 | instance with an undocumented error code 0x80110474. | |
15 | FIXME: I have no idea why this happens. */ | |
16 | IShellLink *sl; | |
17 | ||
51ebb760 | 18 | extern "C" |
904d24fe | 19 | void |
3c054baf | 20 | make_link_2 (char const *exepath, char const *args, char const *icon, char const *lname) |
904d24fe | 21 | { |
904d24fe | 22 | IPersistFile *pf; |
4875ac88 | 23 | WCHAR widepath[MAX_PATH]; |
e36b0f1e CV |
24 | if (sl) |
25 | { | |
c0e55e84 | 26 | sl->QueryInterface (IID_IPersistFile, (void **) &pf); |
904d24fe | 27 | |
c0e55e84 YS |
28 | sl->SetPath (exepath); |
29 | sl->SetArguments (args); | |
30 | sl->SetIconLocation (icon, 0); | |
904d24fe | 31 | |
e36b0f1e | 32 | MultiByteToWideChar (CP_ACP, 0, lname, -1, widepath, MAX_PATH); |
c0e55e84 | 33 | pf->Save (widepath, TRUE); |
904d24fe | 34 | |
c0e55e84 | 35 | pf->Release (); |
e36b0f1e | 36 | } |
904d24fe | 37 | } |
b24c88b3 RC |
38 | |
39 | #define SYMLINK_COOKIE "!<symlink>" | |
40 | ||
1e029da2 YS |
41 | extern "C" |
42 | int | |
43 | mkcygsymlink (const char *from, const char *to) | |
2f0315ad | 44 | { |
770e3aed | 45 | char buf[strlen (SYMLINK_COOKIE) + 4096]; |
2f0315ad CV |
46 | unsigned long w; |
47 | const size_t len = strlen (from) + 7; | |
48 | WCHAR wfrom[len]; | |
21aa9a8b | 49 | HANDLE h; |
26922cd2 CV |
50 | SECURITY_DESCRIPTOR sd; |
51 | acl_t acl; | |
52 | SECURITY_ATTRIBUTES sa = { sizeof (SECURITY_ATTRIBUTES), | |
53 | nt_sec.GetPosixPerms (from, NULL, NULL, 0644, | |
54 | sd, acl), | |
55 | FALSE }; | |
2f0315ad CV |
56 | |
57 | mklongpath (wfrom, from, len); | |
26922cd2 | 58 | h = CreateFileW (wfrom, GENERIC_WRITE, 0, &sa, CREATE_NEW, |
21aa9a8b | 59 | FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0); |
2f0315ad | 60 | if (h == INVALID_HANDLE_VALUE) |
26922cd2 | 61 | return 1; |
2f0315ad | 62 | strcpy (buf, SYMLINK_COOKIE); |
770e3aed | 63 | strncat (buf, to, 4095); |
2f0315ad CV |
64 | if (WriteFile (h, buf, strlen (buf) + 1, &w, NULL)) |
65 | { | |
66 | CloseHandle (h); | |
67 | SetFileAttributesW (wfrom, FILE_ATTRIBUTE_SYSTEM); | |
68 | return 0; | |
69 | } | |
70 | CloseHandle (h); | |
71 | DeleteFileW (wfrom); | |
72 | return 1; | |
73 | } | |
74 | ||
10b2d051 | 75 | static struct { |
d2e8d256 CV |
76 | FILE_LINK_INFORMATION fli; |
77 | WCHAR namebuf[32768]; | |
78 | } sfli; | |
79 | ||
80 | extern "C" | |
81 | int | |
82 | mkcyghardlink (const char *from, const char *to) | |
83 | { | |
d2e8d256 CV |
84 | size_t flen = strlen (from) + 7; |
85 | size_t tlen = strlen (to) + 7; | |
86 | wchar_t wfrom[flen]; | |
87 | wchar_t wto[tlen]; | |
88 | mklongpath (wfrom, from, flen); | |
89 | wfrom[1] = '?'; | |
90 | mklongpath (wto, to, tlen); | |
91 | wto[1] = '?'; | |
92 | ||
93 | HANDLE fh; | |
94 | NTSTATUS status; | |
95 | UNICODE_STRING uto; | |
96 | OBJECT_ATTRIBUTES attr; | |
97 | IO_STATUS_BLOCK io; | |
98 | ||
99 | /* Open the existing file. */ | |
100 | RtlInitUnicodeString (&uto, wto); | |
101 | InitializeObjectAttributes (&attr, &uto, OBJ_CASE_INSENSITIVE, NULL, NULL); | |
102 | status = NtOpenFile (&fh, READ_CONTROL, &attr, &io, FILE_SHARE_VALID_FLAGS, | |
103 | FILE_OPEN_FOR_BACKUP_INTENT | FILE_OPEN_REPARSE_POINT); | |
104 | if (!NT_SUCCESS (status)) | |
105 | return 1; | |
106 | /* Create from as link to to. */ | |
107 | flen = wcslen (wfrom) * sizeof (WCHAR); | |
108 | ULONG size = sizeof (FILE_LINK_INFORMATION) + flen; | |
109 | sfli.fli.ReplaceIfExists = TRUE; | |
110 | sfli.fli.RootDirectory = NULL; | |
111 | sfli.fli.FileNameLength = flen; | |
112 | memcpy (sfli.fli.FileName, wfrom, flen); | |
113 | status = NtSetInformationFile (fh, &io, &sfli.fli, size, FileLinkInformation); | |
114 | NtClose (fh); | |
115 | return NT_SUCCESS (status) ? 0 : 1; | |
116 | } |