Skip to content

Commit 8556f69

Browse files
committed
Attempt to unlock WVMCore.dll
1 parent ff14cee commit 8556f69

File tree

2 files changed

+158
-0
lines changed

2 files changed

+158
-0
lines changed

ZuneModCore/FileUtil.cs

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

ZuneModCore/Mods/VideoSyncMod.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,13 @@ public class VideoSyncMod : Mod
2626
// Make a backup of the file
2727
File.Copy(WMVCORE_PATH, Path.Combine(StorageDirectory, "WMVCORE.original.dll"), true);
2828

29+
// NOTE: This is quite dangerous to do blindly, so let's not
30+
// Kill processes that are using WMVCORE.dll
31+
//foreach (System.Diagnostics.Process proc in FileUtil.WhoIsLocking(WMVCORE_PATH))
32+
//{
33+
// proc.Kill();
34+
//}
35+
2936
// Copy the pre-Anniversary Update WMVCORE.dll
3037
File.Copy("Resources\\WMVCORE.dll", WMVCORE_PATH, true);
3138

0 commit comments

Comments
 (0)