Skip to content

Commit 17c1ed7

Browse files
authored
Properly toggle "permanent delete" check in confirmation dialog (#7500)
1 parent 0bd8df1 commit 17c1ed7

File tree

8 files changed

+345
-50
lines changed

8 files changed

+345
-50
lines changed

src/Common/ShellOperationResult.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ public ShellOperationResult()
1616
public class ShellOperationItemResult
1717
{
1818
public bool Succeeded { get; set; }
19-
public int HRresult { get; set; }
19+
public int HResult { get; set; }
2020
public string Source { get; set; }
2121
public string Destination { get; set; }
2222
}
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Runtime.InteropServices;
5+
6+
namespace FilesFullTrust.Helpers
7+
{
8+
// https://stackoverflow.com/questions/317071/how-do-i-find-out-which-process-is-locking-a-file-using-net/317209#317209
9+
public static class FileUtils
10+
{
11+
[StructLayout(LayoutKind.Sequential)]
12+
struct RM_UNIQUE_PROCESS
13+
{
14+
public int dwProcessId;
15+
public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;
16+
}
17+
18+
const int RmRebootReasonNone = 0;
19+
const int CCH_RM_MAX_APP_NAME = 255;
20+
const int CCH_RM_MAX_SVC_NAME = 63;
21+
22+
enum RM_APP_TYPE
23+
{
24+
RmUnknownApp = 0,
25+
RmMainWindow = 1,
26+
RmOtherWindow = 2,
27+
RmService = 3,
28+
RmExplorer = 4,
29+
RmConsole = 5,
30+
RmCritical = 1000
31+
}
32+
33+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
34+
struct RM_PROCESS_INFO
35+
{
36+
public RM_UNIQUE_PROCESS Process;
37+
38+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]
39+
public string strAppName;
40+
41+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]
42+
public string strServiceShortName;
43+
44+
public RM_APP_TYPE ApplicationType;
45+
public uint AppStatus;
46+
public uint TSSessionId;
47+
[MarshalAs(UnmanagedType.Bool)]
48+
public bool bRestartable;
49+
}
50+
51+
[DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]
52+
static extern int RmRegisterResources(uint pSessionHandle,
53+
UInt32 nFiles,
54+
string[] rgsFilenames,
55+
UInt32 nApplications,
56+
[In] RM_UNIQUE_PROCESS[] rgApplications,
57+
UInt32 nServices,
58+
string[] rgsServiceNames);
59+
60+
[DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]
61+
static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);
62+
63+
[DllImport("rstrtmgr.dll")]
64+
static extern int RmEndSession(uint pSessionHandle);
65+
66+
[DllImport("rstrtmgr.dll")]
67+
static extern int RmGetList(uint dwSessionHandle,
68+
out uint pnProcInfoNeeded,
69+
ref uint pnProcInfo,
70+
[In, Out] RM_PROCESS_INFO[] rgAffectedApps,
71+
ref uint lpdwRebootReasons);
72+
73+
/// <summary>
74+
/// Find out what process(es) have a lock on the specified file.
75+
/// </summary>
76+
/// <param name="path">Path of the file.</param>
77+
/// <returns>Processes locking the file</returns>
78+
/// <remarks>See also:
79+
/// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx
80+
/// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing)
81+
///
82+
/// </remarks>
83+
static public List<Process> WhoIsLocking(string path)
84+
{
85+
uint handle;
86+
string key = Guid.NewGuid().ToString();
87+
List<Process> processes = new List<Process>();
88+
89+
int res = RmStartSession(out handle, 0, key);
90+
if (res != 0) throw new Exception("Could not begin restart session. Unable to determine file locker.");
91+
92+
try
93+
{
94+
const int ERROR_MORE_DATA = 234;
95+
uint pnProcInfoNeeded = 0,
96+
pnProcInfo = 0,
97+
lpdwRebootReasons = RmRebootReasonNone;
98+
99+
string[] resources = new string[] { path }; // Just checking on one resource.
100+
101+
res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);
102+
103+
if (res != 0) throw new Exception("Could not register resource.");
104+
105+
//Note: there's a race condition here -- the first call to RmGetList() returns
106+
// the total number of process. However, when we call RmGetList() again to get
107+
// the actual processes this number may have increased.
108+
res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);
109+
110+
if (res == ERROR_MORE_DATA)
111+
{
112+
// Create an array to store the process results
113+
RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded];
114+
pnProcInfo = pnProcInfoNeeded;
115+
116+
// Get the list
117+
res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);
118+
if (res == 0)
119+
{
120+
processes = new List<Process>((int)pnProcInfo);
121+
122+
// Enumerate all of the results and add them to the
123+
// list to be returned
124+
for (int i = 0; i < pnProcInfo; i++)
125+
{
126+
try
127+
{
128+
processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));
129+
}
130+
// catch the error -- in case the process is no longer running
131+
catch (ArgumentException) { }
132+
}
133+
}
134+
else throw new Exception("Could not list processes locking resource.");
135+
}
136+
else if (res != 0) throw new Exception("Could not list processes locking resource. Failed to get size of result.");
137+
}
138+
finally
139+
{
140+
RmEndSession(handle);
141+
}
142+
143+
return processes;
144+
}
145+
}
146+
}

src/Files.Launcher/Helpers/ShellFolderHelpers.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,5 +92,14 @@ public static ShellLinkItem GetShellLinkItem(ShellLink linkItem)
9292
link.TargetPath = linkItem.TargetPath;
9393
return link;
9494
}
95+
96+
public static string GetParsingPath(this ShellItem item)
97+
{
98+
if (item == null)
99+
{
100+
return null;
101+
}
102+
return item.IsFileSystem ? item.FileSystemPath : item.ParsingName;
103+
}
95104
}
96105
}

0 commit comments

Comments
 (0)