]> cygwin.com Git - cygwin-apps/setup.git/blame - mklink2.cc
Use solver to check for problems and produce a list of package transactions
[cygwin-apps/setup.git] / mklink2.cc
CommitLineData
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
10doesn'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. */
16IShellLink *sl;
17
51ebb760 18extern "C"
904d24fe 19void
3c054baf 20make_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
41extern "C"
42int
43mkcygsymlink (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 75static struct {
d2e8d256
CV
76 FILE_LINK_INFORMATION fli;
77 WCHAR namebuf[32768];
78} sfli;
79
80extern "C"
81int
82mkcyghardlink (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}
This page took 0.089515 seconds and 5 git commands to generate.