]> cygwin.com Git - cygwin-apps/setup.git/blame_incremental - mklink2.cc
Use solver to check for problems and produce a list of package transactions
[cygwin-apps/setup.git] / mklink2.cc
... / ...
CommitLineData
1#include <stdlib.h>
2#include <wchar.h>
3#include "win32.h"
4#include "ntdll.h"
5#include "shlobj.h"
6#include "mklink2.h"
7#include "filemanip.h"
8
9/* This part of the code must be in C because the C++ interface to COM
10doesn't work. */
11
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
18extern "C"
19void
20make_link_2 (char const *exepath, char const *args, char const *icon, char const *lname)
21{
22 IPersistFile *pf;
23 WCHAR widepath[MAX_PATH];
24 if (sl)
25 {
26 sl->QueryInterface (IID_IPersistFile, (void **) &pf);
27
28 sl->SetPath (exepath);
29 sl->SetArguments (args);
30 sl->SetIconLocation (icon, 0);
31
32 MultiByteToWideChar (CP_ACP, 0, lname, -1, widepath, MAX_PATH);
33 pf->Save (widepath, TRUE);
34
35 pf->Release ();
36 }
37}
38
39#define SYMLINK_COOKIE "!<symlink>"
40
41extern "C"
42int
43mkcygsymlink (const char *from, const char *to)
44{
45 char buf[strlen (SYMLINK_COOKIE) + 4096];
46 unsigned long w;
47 const size_t len = strlen (from) + 7;
48 WCHAR wfrom[len];
49 HANDLE h;
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 };
56
57 mklongpath (wfrom, from, len);
58 h = CreateFileW (wfrom, GENERIC_WRITE, 0, &sa, CREATE_NEW,
59 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
60 if (h == INVALID_HANDLE_VALUE)
61 return 1;
62 strcpy (buf, SYMLINK_COOKIE);
63 strncat (buf, to, 4095);
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
75static struct {
76 FILE_LINK_INFORMATION fli;
77 WCHAR namebuf[32768];
78} sfli;
79
80extern "C"
81int
82mkcyghardlink (const char *from, const char *to)
83{
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.023693 seconds and 5 git commands to generate.