1*f6dc9357SAndroid Build Coastguard Worker // LinkDialog.cpp
2*f6dc9357SAndroid Build Coastguard Worker
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker
5*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/ErrorMsg.h"
6*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileDir.h"
7*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileFind.h"
8*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileIO.h"
9*f6dc9357SAndroid Build Coastguard Worker #include "../../../Windows/FileName.h"
10*f6dc9357SAndroid Build Coastguard Worker
11*f6dc9357SAndroid Build Coastguard Worker #include "LangUtils.h"
12*f6dc9357SAndroid Build Coastguard Worker
13*f6dc9357SAndroid Build Coastguard Worker #include "BrowseDialog.h"
14*f6dc9357SAndroid Build Coastguard Worker #include "CopyDialogRes.h"
15*f6dc9357SAndroid Build Coastguard Worker #include "LinkDialog.h"
16*f6dc9357SAndroid Build Coastguard Worker #include "resourceGui.h"
17*f6dc9357SAndroid Build Coastguard Worker
18*f6dc9357SAndroid Build Coastguard Worker #include "App.h"
19*f6dc9357SAndroid Build Coastguard Worker
20*f6dc9357SAndroid Build Coastguard Worker #include "resource.h"
21*f6dc9357SAndroid Build Coastguard Worker
22*f6dc9357SAndroid Build Coastguard Worker extern bool g_SymLink_Supported;
23*f6dc9357SAndroid Build Coastguard Worker
24*f6dc9357SAndroid Build Coastguard Worker using namespace NWindows;
25*f6dc9357SAndroid Build Coastguard Worker using namespace NFile;
26*f6dc9357SAndroid Build Coastguard Worker
27*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LANG
28*f6dc9357SAndroid Build Coastguard Worker static const UInt32 kLangIDs[] =
29*f6dc9357SAndroid Build Coastguard Worker {
30*f6dc9357SAndroid Build Coastguard Worker IDB_LINK_LINK,
31*f6dc9357SAndroid Build Coastguard Worker IDT_LINK_PATH_FROM,
32*f6dc9357SAndroid Build Coastguard Worker IDT_LINK_PATH_TO,
33*f6dc9357SAndroid Build Coastguard Worker IDG_LINK_TYPE,
34*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_HARD,
35*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_SYM_FILE,
36*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_SYM_DIR,
37*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_JUNCTION,
38*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_WSL
39*f6dc9357SAndroid Build Coastguard Worker };
40*f6dc9357SAndroid Build Coastguard Worker #endif
41*f6dc9357SAndroid Build Coastguard Worker
42*f6dc9357SAndroid Build Coastguard Worker
GetSymLink(CFSTR path,CReparseAttr & attr,UString & errorMessage)43*f6dc9357SAndroid Build Coastguard Worker static bool GetSymLink(CFSTR path, CReparseAttr &attr, UString &errorMessage)
44*f6dc9357SAndroid Build Coastguard Worker {
45*f6dc9357SAndroid Build Coastguard Worker CByteBuffer buf;
46*f6dc9357SAndroid Build Coastguard Worker if (!NIO::GetReparseData(path, buf, NULL))
47*f6dc9357SAndroid Build Coastguard Worker return false;
48*f6dc9357SAndroid Build Coastguard Worker
49*f6dc9357SAndroid Build Coastguard Worker if (!attr.Parse(buf, buf.Size()))
50*f6dc9357SAndroid Build Coastguard Worker {
51*f6dc9357SAndroid Build Coastguard Worker SetLastError(attr.ErrorCode);
52*f6dc9357SAndroid Build Coastguard Worker return false;
53*f6dc9357SAndroid Build Coastguard Worker }
54*f6dc9357SAndroid Build Coastguard Worker
55*f6dc9357SAndroid Build Coastguard Worker CByteBuffer data2;
56*f6dc9357SAndroid Build Coastguard Worker if (!FillLinkData(data2, attr.GetPath(),
57*f6dc9357SAndroid Build Coastguard Worker !attr.IsMountPoint(), attr.IsSymLink_WSL()))
58*f6dc9357SAndroid Build Coastguard Worker {
59*f6dc9357SAndroid Build Coastguard Worker errorMessage = "Cannot reproduce reparse point";
60*f6dc9357SAndroid Build Coastguard Worker return false;
61*f6dc9357SAndroid Build Coastguard Worker }
62*f6dc9357SAndroid Build Coastguard Worker
63*f6dc9357SAndroid Build Coastguard Worker if (data2.Size() != buf.Size() ||
64*f6dc9357SAndroid Build Coastguard Worker memcmp(data2, buf, buf.Size()) != 0)
65*f6dc9357SAndroid Build Coastguard Worker {
66*f6dc9357SAndroid Build Coastguard Worker errorMessage = "mismatch for reproduced reparse point";
67*f6dc9357SAndroid Build Coastguard Worker return false;
68*f6dc9357SAndroid Build Coastguard Worker }
69*f6dc9357SAndroid Build Coastguard Worker
70*f6dc9357SAndroid Build Coastguard Worker return true;
71*f6dc9357SAndroid Build Coastguard Worker }
72*f6dc9357SAndroid Build Coastguard Worker
73*f6dc9357SAndroid Build Coastguard Worker
74*f6dc9357SAndroid Build Coastguard Worker static const unsigned k_LinkType_Buttons[] =
75*f6dc9357SAndroid Build Coastguard Worker {
76*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_HARD,
77*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_SYM_FILE,
78*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_SYM_DIR,
79*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_JUNCTION,
80*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_WSL
81*f6dc9357SAndroid Build Coastguard Worker };
82*f6dc9357SAndroid Build Coastguard Worker
Set_LinkType_Radio(unsigned idb)83*f6dc9357SAndroid Build Coastguard Worker void CLinkDialog::Set_LinkType_Radio(unsigned idb)
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker CheckRadioButton(
86*f6dc9357SAndroid Build Coastguard Worker k_LinkType_Buttons[0],
87*f6dc9357SAndroid Build Coastguard Worker k_LinkType_Buttons[Z7_ARRAY_SIZE(k_LinkType_Buttons) - 1],
88*f6dc9357SAndroid Build Coastguard Worker idb);
89*f6dc9357SAndroid Build Coastguard Worker }
90*f6dc9357SAndroid Build Coastguard Worker
OnInit()91*f6dc9357SAndroid Build Coastguard Worker bool CLinkDialog::OnInit()
92*f6dc9357SAndroid Build Coastguard Worker {
93*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LANG
94*f6dc9357SAndroid Build Coastguard Worker LangSetWindowText(*this, IDD_LINK);
95*f6dc9357SAndroid Build Coastguard Worker LangSetDlgItems(*this, kLangIDs, Z7_ARRAY_SIZE(kLangIDs));
96*f6dc9357SAndroid Build Coastguard Worker #endif
97*f6dc9357SAndroid Build Coastguard Worker
98*f6dc9357SAndroid Build Coastguard Worker _pathFromCombo.Attach(GetItem(IDC_LINK_PATH_FROM));
99*f6dc9357SAndroid Build Coastguard Worker _pathToCombo.Attach(GetItem(IDC_LINK_PATH_TO));
100*f6dc9357SAndroid Build Coastguard Worker
101*f6dc9357SAndroid Build Coastguard Worker if (!FilePath.IsEmpty())
102*f6dc9357SAndroid Build Coastguard Worker {
103*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo fi;
104*f6dc9357SAndroid Build Coastguard Worker unsigned linkType = 0;
105*f6dc9357SAndroid Build Coastguard Worker if (!fi.Find(us2fs(FilePath)))
106*f6dc9357SAndroid Build Coastguard Worker linkType = IDR_LINK_TYPE_SYM_FILE;
107*f6dc9357SAndroid Build Coastguard Worker else
108*f6dc9357SAndroid Build Coastguard Worker {
109*f6dc9357SAndroid Build Coastguard Worker if (fi.HasReparsePoint())
110*f6dc9357SAndroid Build Coastguard Worker {
111*f6dc9357SAndroid Build Coastguard Worker CReparseAttr attr;
112*f6dc9357SAndroid Build Coastguard Worker UString error;
113*f6dc9357SAndroid Build Coastguard Worker const bool res = GetSymLink(us2fs(FilePath), attr, error);
114*f6dc9357SAndroid Build Coastguard Worker if (!res && error.IsEmpty())
115*f6dc9357SAndroid Build Coastguard Worker {
116*f6dc9357SAndroid Build Coastguard Worker DWORD lastError = GetLastError();
117*f6dc9357SAndroid Build Coastguard Worker if (lastError != 0)
118*f6dc9357SAndroid Build Coastguard Worker error = NError::MyFormatMessage(lastError);
119*f6dc9357SAndroid Build Coastguard Worker }
120*f6dc9357SAndroid Build Coastguard Worker
121*f6dc9357SAndroid Build Coastguard Worker UString s = attr.GetPath();
122*f6dc9357SAndroid Build Coastguard Worker if (!attr.IsSymLink_WSL())
123*f6dc9357SAndroid Build Coastguard Worker if (!attr.IsOkNamePair())
124*f6dc9357SAndroid Build Coastguard Worker {
125*f6dc9357SAndroid Build Coastguard Worker s += " : ";
126*f6dc9357SAndroid Build Coastguard Worker s += attr.PrintName;
127*f6dc9357SAndroid Build Coastguard Worker }
128*f6dc9357SAndroid Build Coastguard Worker
129*f6dc9357SAndroid Build Coastguard Worker if (!res)
130*f6dc9357SAndroid Build Coastguard Worker {
131*f6dc9357SAndroid Build Coastguard Worker s.Insert(0, L"ERROR: ");
132*f6dc9357SAndroid Build Coastguard Worker if (!error.IsEmpty())
133*f6dc9357SAndroid Build Coastguard Worker {
134*f6dc9357SAndroid Build Coastguard Worker s += " : ";
135*f6dc9357SAndroid Build Coastguard Worker s += error;
136*f6dc9357SAndroid Build Coastguard Worker }
137*f6dc9357SAndroid Build Coastguard Worker }
138*f6dc9357SAndroid Build Coastguard Worker
139*f6dc9357SAndroid Build Coastguard Worker
140*f6dc9357SAndroid Build Coastguard Worker SetItemText(IDT_LINK_PATH_TO_CUR, s);
141*f6dc9357SAndroid Build Coastguard Worker
142*f6dc9357SAndroid Build Coastguard Worker const UString destPath = attr.GetPath();
143*f6dc9357SAndroid Build Coastguard Worker _pathFromCombo.SetText(FilePath);
144*f6dc9357SAndroid Build Coastguard Worker _pathToCombo.SetText(destPath);
145*f6dc9357SAndroid Build Coastguard Worker
146*f6dc9357SAndroid Build Coastguard Worker // if (res)
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker if (attr.IsMountPoint())
149*f6dc9357SAndroid Build Coastguard Worker linkType = IDR_LINK_TYPE_JUNCTION;
150*f6dc9357SAndroid Build Coastguard Worker else if (attr.IsSymLink_WSL())
151*f6dc9357SAndroid Build Coastguard Worker linkType = IDR_LINK_TYPE_WSL;
152*f6dc9357SAndroid Build Coastguard Worker else if (attr.IsSymLink_Win())
153*f6dc9357SAndroid Build Coastguard Worker {
154*f6dc9357SAndroid Build Coastguard Worker linkType =
155*f6dc9357SAndroid Build Coastguard Worker fi.IsDir() ?
156*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_SYM_DIR :
157*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_SYM_FILE;
158*f6dc9357SAndroid Build Coastguard Worker // if (attr.IsRelative()) linkType = IDR_LINK_TYPE_SYM_RELATIVE;
159*f6dc9357SAndroid Build Coastguard Worker }
160*f6dc9357SAndroid Build Coastguard Worker
161*f6dc9357SAndroid Build Coastguard Worker if (linkType != 0)
162*f6dc9357SAndroid Build Coastguard Worker Set_LinkType_Radio(linkType);
163*f6dc9357SAndroid Build Coastguard Worker }
164*f6dc9357SAndroid Build Coastguard Worker }
165*f6dc9357SAndroid Build Coastguard Worker else
166*f6dc9357SAndroid Build Coastguard Worker {
167*f6dc9357SAndroid Build Coastguard Worker // no ReparsePoint
168*f6dc9357SAndroid Build Coastguard Worker _pathFromCombo.SetText(AnotherPath);
169*f6dc9357SAndroid Build Coastguard Worker _pathToCombo.SetText(FilePath);
170*f6dc9357SAndroid Build Coastguard Worker if (fi.IsDir())
171*f6dc9357SAndroid Build Coastguard Worker linkType = g_SymLink_Supported ?
172*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_SYM_DIR :
173*f6dc9357SAndroid Build Coastguard Worker IDR_LINK_TYPE_JUNCTION;
174*f6dc9357SAndroid Build Coastguard Worker else
175*f6dc9357SAndroid Build Coastguard Worker linkType = IDR_LINK_TYPE_HARD;
176*f6dc9357SAndroid Build Coastguard Worker }
177*f6dc9357SAndroid Build Coastguard Worker }
178*f6dc9357SAndroid Build Coastguard Worker if (linkType != 0)
179*f6dc9357SAndroid Build Coastguard Worker Set_LinkType_Radio(linkType);
180*f6dc9357SAndroid Build Coastguard Worker }
181*f6dc9357SAndroid Build Coastguard Worker
182*f6dc9357SAndroid Build Coastguard Worker NormalizeSize();
183*f6dc9357SAndroid Build Coastguard Worker return CModalDialog::OnInit();
184*f6dc9357SAndroid Build Coastguard Worker }
185*f6dc9357SAndroid Build Coastguard Worker
OnSize(WPARAM,int xSize,int ySize)186*f6dc9357SAndroid Build Coastguard Worker bool CLinkDialog::OnSize(WPARAM /* wParam */, int xSize, int ySize)
187*f6dc9357SAndroid Build Coastguard Worker {
188*f6dc9357SAndroid Build Coastguard Worker int mx, my;
189*f6dc9357SAndroid Build Coastguard Worker GetMargins(8, mx, my);
190*f6dc9357SAndroid Build Coastguard Worker int bx1, bx2, by;
191*f6dc9357SAndroid Build Coastguard Worker GetItemSizes(IDCANCEL, bx1, by);
192*f6dc9357SAndroid Build Coastguard Worker GetItemSizes(IDB_LINK_LINK, bx2, by);
193*f6dc9357SAndroid Build Coastguard Worker int yPos = ySize - my - by;
194*f6dc9357SAndroid Build Coastguard Worker int xPos = xSize - mx - bx1;
195*f6dc9357SAndroid Build Coastguard Worker
196*f6dc9357SAndroid Build Coastguard Worker InvalidateRect(NULL);
197*f6dc9357SAndroid Build Coastguard Worker
198*f6dc9357SAndroid Build Coastguard Worker {
199*f6dc9357SAndroid Build Coastguard Worker RECT r, r2;
200*f6dc9357SAndroid Build Coastguard Worker GetClientRectOfItem(IDB_LINK_PATH_FROM, r);
201*f6dc9357SAndroid Build Coastguard Worker GetClientRectOfItem(IDB_LINK_PATH_TO, r2);
202*f6dc9357SAndroid Build Coastguard Worker int bx = RECT_SIZE_X(r);
203*f6dc9357SAndroid Build Coastguard Worker int newButtonXpos = xSize - mx - bx;
204*f6dc9357SAndroid Build Coastguard Worker
205*f6dc9357SAndroid Build Coastguard Worker MoveItem(IDB_LINK_PATH_FROM, newButtonXpos, r.top, bx, RECT_SIZE_Y(r));
206*f6dc9357SAndroid Build Coastguard Worker MoveItem(IDB_LINK_PATH_TO, newButtonXpos, r2.top, bx, RECT_SIZE_Y(r2));
207*f6dc9357SAndroid Build Coastguard Worker
208*f6dc9357SAndroid Build Coastguard Worker int newComboXsize = newButtonXpos - mx - mx;
209*f6dc9357SAndroid Build Coastguard Worker ChangeSubWindowSizeX(_pathFromCombo, newComboXsize);
210*f6dc9357SAndroid Build Coastguard Worker ChangeSubWindowSizeX(_pathToCombo, newComboXsize);
211*f6dc9357SAndroid Build Coastguard Worker }
212*f6dc9357SAndroid Build Coastguard Worker
213*f6dc9357SAndroid Build Coastguard Worker MoveItem(IDCANCEL, xPos, yPos, bx1, by);
214*f6dc9357SAndroid Build Coastguard Worker MoveItem(IDB_LINK_LINK, xPos - mx - bx2, yPos, bx2, by);
215*f6dc9357SAndroid Build Coastguard Worker
216*f6dc9357SAndroid Build Coastguard Worker return false;
217*f6dc9357SAndroid Build Coastguard Worker }
218*f6dc9357SAndroid Build Coastguard Worker
OnButtonClicked(unsigned buttonID,HWND buttonHWND)219*f6dc9357SAndroid Build Coastguard Worker bool CLinkDialog::OnButtonClicked(unsigned buttonID, HWND buttonHWND)
220*f6dc9357SAndroid Build Coastguard Worker {
221*f6dc9357SAndroid Build Coastguard Worker switch (buttonID)
222*f6dc9357SAndroid Build Coastguard Worker {
223*f6dc9357SAndroid Build Coastguard Worker case IDB_LINK_PATH_FROM:
224*f6dc9357SAndroid Build Coastguard Worker OnButton_SetPath(false);
225*f6dc9357SAndroid Build Coastguard Worker return true;
226*f6dc9357SAndroid Build Coastguard Worker case IDB_LINK_PATH_TO:
227*f6dc9357SAndroid Build Coastguard Worker OnButton_SetPath(true);
228*f6dc9357SAndroid Build Coastguard Worker return true;
229*f6dc9357SAndroid Build Coastguard Worker case IDB_LINK_LINK:
230*f6dc9357SAndroid Build Coastguard Worker OnButton_Link();
231*f6dc9357SAndroid Build Coastguard Worker return true;
232*f6dc9357SAndroid Build Coastguard Worker }
233*f6dc9357SAndroid Build Coastguard Worker return CModalDialog::OnButtonClicked(buttonID, buttonHWND);
234*f6dc9357SAndroid Build Coastguard Worker }
235*f6dc9357SAndroid Build Coastguard Worker
OnButton_SetPath(bool to)236*f6dc9357SAndroid Build Coastguard Worker void CLinkDialog::OnButton_SetPath(bool to)
237*f6dc9357SAndroid Build Coastguard Worker {
238*f6dc9357SAndroid Build Coastguard Worker UString currentPath;
239*f6dc9357SAndroid Build Coastguard Worker NWindows::NControl::CComboBox &combo = to ?
240*f6dc9357SAndroid Build Coastguard Worker _pathToCombo :
241*f6dc9357SAndroid Build Coastguard Worker _pathFromCombo;
242*f6dc9357SAndroid Build Coastguard Worker combo.GetText(currentPath);
243*f6dc9357SAndroid Build Coastguard Worker // UString title = "Specify a location for output folder";
244*f6dc9357SAndroid Build Coastguard Worker const UString title = LangString(IDS_SET_FOLDER);
245*f6dc9357SAndroid Build Coastguard Worker
246*f6dc9357SAndroid Build Coastguard Worker UString resultPath;
247*f6dc9357SAndroid Build Coastguard Worker if (!MyBrowseForFolder(*this, title, currentPath, resultPath))
248*f6dc9357SAndroid Build Coastguard Worker return;
249*f6dc9357SAndroid Build Coastguard Worker NName::NormalizeDirPathPrefix(resultPath);
250*f6dc9357SAndroid Build Coastguard Worker combo.SetCurSel(-1);
251*f6dc9357SAndroid Build Coastguard Worker combo.SetText(resultPath);
252*f6dc9357SAndroid Build Coastguard Worker }
253*f6dc9357SAndroid Build Coastguard Worker
ShowError(const wchar_t * s)254*f6dc9357SAndroid Build Coastguard Worker void CLinkDialog::ShowError(const wchar_t *s)
255*f6dc9357SAndroid Build Coastguard Worker {
256*f6dc9357SAndroid Build Coastguard Worker ::MessageBoxW(*this, s, L"7-Zip", MB_ICONERROR);
257*f6dc9357SAndroid Build Coastguard Worker }
258*f6dc9357SAndroid Build Coastguard Worker
ShowLastErrorMessage()259*f6dc9357SAndroid Build Coastguard Worker void CLinkDialog::ShowLastErrorMessage()
260*f6dc9357SAndroid Build Coastguard Worker {
261*f6dc9357SAndroid Build Coastguard Worker ShowError(NError::MyFormatMessage(GetLastError()));
262*f6dc9357SAndroid Build Coastguard Worker }
263*f6dc9357SAndroid Build Coastguard Worker
OnButton_Link()264*f6dc9357SAndroid Build Coastguard Worker void CLinkDialog::OnButton_Link()
265*f6dc9357SAndroid Build Coastguard Worker {
266*f6dc9357SAndroid Build Coastguard Worker UString from, to;
267*f6dc9357SAndroid Build Coastguard Worker _pathFromCombo.GetText(from);
268*f6dc9357SAndroid Build Coastguard Worker _pathToCombo.GetText(to);
269*f6dc9357SAndroid Build Coastguard Worker
270*f6dc9357SAndroid Build Coastguard Worker if (from.IsEmpty())
271*f6dc9357SAndroid Build Coastguard Worker return;
272*f6dc9357SAndroid Build Coastguard Worker if (!NName::IsAbsolutePath(from))
273*f6dc9357SAndroid Build Coastguard Worker from.Insert(0, CurDirPrefix);
274*f6dc9357SAndroid Build Coastguard Worker
275*f6dc9357SAndroid Build Coastguard Worker unsigned idb = 0;
276*f6dc9357SAndroid Build Coastguard Worker for (unsigned i = 0;; i++)
277*f6dc9357SAndroid Build Coastguard Worker {
278*f6dc9357SAndroid Build Coastguard Worker if (i >= Z7_ARRAY_SIZE(k_LinkType_Buttons))
279*f6dc9357SAndroid Build Coastguard Worker return;
280*f6dc9357SAndroid Build Coastguard Worker idb = k_LinkType_Buttons[i];
281*f6dc9357SAndroid Build Coastguard Worker if (IsButtonCheckedBool(idb))
282*f6dc9357SAndroid Build Coastguard Worker break;
283*f6dc9357SAndroid Build Coastguard Worker }
284*f6dc9357SAndroid Build Coastguard Worker
285*f6dc9357SAndroid Build Coastguard Worker NFind::CFileInfo info1, info2;
286*f6dc9357SAndroid Build Coastguard Worker const bool finded1 = info1.Find(us2fs(from));
287*f6dc9357SAndroid Build Coastguard Worker const bool finded2 = info2.Find(us2fs(to));
288*f6dc9357SAndroid Build Coastguard Worker
289*f6dc9357SAndroid Build Coastguard Worker const bool isDirLink = (
290*f6dc9357SAndroid Build Coastguard Worker idb == IDR_LINK_TYPE_SYM_DIR ||
291*f6dc9357SAndroid Build Coastguard Worker idb == IDR_LINK_TYPE_JUNCTION);
292*f6dc9357SAndroid Build Coastguard Worker
293*f6dc9357SAndroid Build Coastguard Worker const bool isWSL = (idb == IDR_LINK_TYPE_WSL);
294*f6dc9357SAndroid Build Coastguard Worker
295*f6dc9357SAndroid Build Coastguard Worker if (!isWSL)
296*f6dc9357SAndroid Build Coastguard Worker if ((finded1 && info1.IsDir() != isDirLink) ||
297*f6dc9357SAndroid Build Coastguard Worker (finded2 && info2.IsDir() != isDirLink))
298*f6dc9357SAndroid Build Coastguard Worker {
299*f6dc9357SAndroid Build Coastguard Worker ShowError(L"Incorrect link type");
300*f6dc9357SAndroid Build Coastguard Worker return;
301*f6dc9357SAndroid Build Coastguard Worker }
302*f6dc9357SAndroid Build Coastguard Worker
303*f6dc9357SAndroid Build Coastguard Worker if (idb == IDR_LINK_TYPE_HARD)
304*f6dc9357SAndroid Build Coastguard Worker {
305*f6dc9357SAndroid Build Coastguard Worker if (!NDir::MyCreateHardLink(us2fs(from), us2fs(to)))
306*f6dc9357SAndroid Build Coastguard Worker {
307*f6dc9357SAndroid Build Coastguard Worker ShowLastErrorMessage();
308*f6dc9357SAndroid Build Coastguard Worker return;
309*f6dc9357SAndroid Build Coastguard Worker }
310*f6dc9357SAndroid Build Coastguard Worker }
311*f6dc9357SAndroid Build Coastguard Worker else
312*f6dc9357SAndroid Build Coastguard Worker {
313*f6dc9357SAndroid Build Coastguard Worker if (finded1 && !info1.IsDir() && !info1.HasReparsePoint() && info1.Size != 0)
314*f6dc9357SAndroid Build Coastguard Worker {
315*f6dc9357SAndroid Build Coastguard Worker UString s ("WARNING: reparse point will hide the data of existing file");
316*f6dc9357SAndroid Build Coastguard Worker s.Add_LF();
317*f6dc9357SAndroid Build Coastguard Worker s += from;
318*f6dc9357SAndroid Build Coastguard Worker ShowError(s);
319*f6dc9357SAndroid Build Coastguard Worker return;
320*f6dc9357SAndroid Build Coastguard Worker }
321*f6dc9357SAndroid Build Coastguard Worker
322*f6dc9357SAndroid Build Coastguard Worker const bool isSymLink = (idb != IDR_LINK_TYPE_JUNCTION);
323*f6dc9357SAndroid Build Coastguard Worker
324*f6dc9357SAndroid Build Coastguard Worker CByteBuffer data;
325*f6dc9357SAndroid Build Coastguard Worker if (!FillLinkData(data, to, isSymLink, isWSL))
326*f6dc9357SAndroid Build Coastguard Worker {
327*f6dc9357SAndroid Build Coastguard Worker ShowError(L"Incorrect link");
328*f6dc9357SAndroid Build Coastguard Worker return;
329*f6dc9357SAndroid Build Coastguard Worker }
330*f6dc9357SAndroid Build Coastguard Worker
331*f6dc9357SAndroid Build Coastguard Worker CReparseAttr attr;
332*f6dc9357SAndroid Build Coastguard Worker if (!attr.Parse(data, data.Size()))
333*f6dc9357SAndroid Build Coastguard Worker {
334*f6dc9357SAndroid Build Coastguard Worker ShowError(L"Internal conversion error");
335*f6dc9357SAndroid Build Coastguard Worker return;
336*f6dc9357SAndroid Build Coastguard Worker }
337*f6dc9357SAndroid Build Coastguard Worker
338*f6dc9357SAndroid Build Coastguard Worker bool res;
339*f6dc9357SAndroid Build Coastguard Worker if (to.IsEmpty())
340*f6dc9357SAndroid Build Coastguard Worker {
341*f6dc9357SAndroid Build Coastguard Worker // res = NIO::SetReparseData(us2fs(from), isDirLink, NULL, 0);
342*f6dc9357SAndroid Build Coastguard Worker res = NIO::DeleteReparseData(us2fs(from));
343*f6dc9357SAndroid Build Coastguard Worker }
344*f6dc9357SAndroid Build Coastguard Worker else
345*f6dc9357SAndroid Build Coastguard Worker res = NIO::SetReparseData(us2fs(from), isDirLink, data, (DWORD)data.Size());
346*f6dc9357SAndroid Build Coastguard Worker
347*f6dc9357SAndroid Build Coastguard Worker if (!res)
348*f6dc9357SAndroid Build Coastguard Worker {
349*f6dc9357SAndroid Build Coastguard Worker ShowLastErrorMessage();
350*f6dc9357SAndroid Build Coastguard Worker return;
351*f6dc9357SAndroid Build Coastguard Worker }
352*f6dc9357SAndroid Build Coastguard Worker }
353*f6dc9357SAndroid Build Coastguard Worker
354*f6dc9357SAndroid Build Coastguard Worker End(IDOK);
355*f6dc9357SAndroid Build Coastguard Worker }
356*f6dc9357SAndroid Build Coastguard Worker
Link()357*f6dc9357SAndroid Build Coastguard Worker void CApp::Link()
358*f6dc9357SAndroid Build Coastguard Worker {
359*f6dc9357SAndroid Build Coastguard Worker const unsigned srcPanelIndex = GetFocusedPanelIndex();
360*f6dc9357SAndroid Build Coastguard Worker CPanel &srcPanel = Panels[srcPanelIndex];
361*f6dc9357SAndroid Build Coastguard Worker if (!srcPanel.IsFSFolder())
362*f6dc9357SAndroid Build Coastguard Worker {
363*f6dc9357SAndroid Build Coastguard Worker srcPanel.MessageBox_Error_UnsupportOperation();
364*f6dc9357SAndroid Build Coastguard Worker return;
365*f6dc9357SAndroid Build Coastguard Worker }
366*f6dc9357SAndroid Build Coastguard Worker CRecordVector<UInt32> indices;
367*f6dc9357SAndroid Build Coastguard Worker srcPanel.Get_ItemIndices_Operated(indices);
368*f6dc9357SAndroid Build Coastguard Worker if (indices.IsEmpty())
369*f6dc9357SAndroid Build Coastguard Worker return;
370*f6dc9357SAndroid Build Coastguard Worker if (indices.Size() != 1)
371*f6dc9357SAndroid Build Coastguard Worker {
372*f6dc9357SAndroid Build Coastguard Worker srcPanel.MessageBox_Error_LangID(IDS_SELECT_ONE_FILE);
373*f6dc9357SAndroid Build Coastguard Worker return;
374*f6dc9357SAndroid Build Coastguard Worker }
375*f6dc9357SAndroid Build Coastguard Worker const UInt32 index = indices[0];
376*f6dc9357SAndroid Build Coastguard Worker const UString itemName = srcPanel.GetItemName(index);
377*f6dc9357SAndroid Build Coastguard Worker
378*f6dc9357SAndroid Build Coastguard Worker const UString fsPrefix = srcPanel.GetFsPath();
379*f6dc9357SAndroid Build Coastguard Worker const UString srcPath = fsPrefix + srcPanel.GetItemPrefix(index);
380*f6dc9357SAndroid Build Coastguard Worker UString path = srcPath;
381*f6dc9357SAndroid Build Coastguard Worker {
382*f6dc9357SAndroid Build Coastguard Worker const unsigned destPanelIndex = (NumPanels <= 1) ? srcPanelIndex : (1 - srcPanelIndex);
383*f6dc9357SAndroid Build Coastguard Worker CPanel &destPanel = Panels[destPanelIndex];
384*f6dc9357SAndroid Build Coastguard Worker if (NumPanels > 1)
385*f6dc9357SAndroid Build Coastguard Worker if (destPanel.IsFSFolder())
386*f6dc9357SAndroid Build Coastguard Worker path = destPanel.GetFsPath();
387*f6dc9357SAndroid Build Coastguard Worker }
388*f6dc9357SAndroid Build Coastguard Worker
389*f6dc9357SAndroid Build Coastguard Worker CLinkDialog dlg;
390*f6dc9357SAndroid Build Coastguard Worker dlg.CurDirPrefix = fsPrefix;
391*f6dc9357SAndroid Build Coastguard Worker dlg.FilePath = srcPath + itemName;
392*f6dc9357SAndroid Build Coastguard Worker dlg.AnotherPath = path;
393*f6dc9357SAndroid Build Coastguard Worker
394*f6dc9357SAndroid Build Coastguard Worker if (dlg.Create(srcPanel.GetParent()) != IDOK)
395*f6dc9357SAndroid Build Coastguard Worker return;
396*f6dc9357SAndroid Build Coastguard Worker
397*f6dc9357SAndroid Build Coastguard Worker // fix it: we should refresh panel with changed link
398*f6dc9357SAndroid Build Coastguard Worker
399*f6dc9357SAndroid Build Coastguard Worker RefreshTitleAlways();
400*f6dc9357SAndroid Build Coastguard Worker }
401