Skip to content

Commit b184d62

Browse files
committedOct 5, 2018
1 parent 0714037 commit b184d62

18 files changed

+1866
-683
lines changed
 

‎CHANGELOG.md

+19
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,25 @@
22
All notable changes to this project will be documented in this file.
33
This project adheres to [Semantic Versioning](http://semver.org/).
44

5+
6+
## [0.7] - 2018-10-05
7+
### Added
8+
- option to disable update facilitation services
9+
- ability to "manually" install updates
10+
11+
### Changed
12+
- automatic update GPO handling, now much more user friendly
13+
- reworked error handling to allow limited non admin operation
14+
- reworked status codes for better ui expirience
15+
- when download fails but the file was already downloaded in the previuse session the old file is used
16+
- reworked UAC bypass handling
17+
18+
### Fixed
19+
- windows 10 version detection
20+
- issue when started rom a read only directory, fallback to ...\{UserProfile}\Downloads\WuMgr\
21+
- crash bug when firewall blocks downloads
22+
- issue client not properl abborting operations on cancesss
23+
524
## [0.6b] - 2018-09-30
625

726
### Fixed

‎wumgr/Common/AppLog.cs

+8-7
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@
33
using System.Linq;
44
using System.Text;
55
using System.Threading.Tasks;
6-
6+
using System.Windows.Threading;
77

88
class AppLog
99
{
1010
private List<string> mLogList = new List<string>();
11+
private Dispatcher mDispatcher;
1112

1213
static public void Line(string str, params object[] args)
1314
{
@@ -22,23 +23,21 @@ static public void Line(String line)
2223

2324
public void logLine(String line)
2425
{
25-
if (Logger != null)
26-
{
26+
mDispatcher.BeginInvoke(new Action(() => {
2727
mLogList.Add(line);
2828
while (mLogList.Count > 100)
2929
mLogList.RemoveAt(0);
3030

31-
LogEventArgs args = new LogEventArgs();
32-
args.line = line;
33-
Logger(this, args);
34-
}
31+
Logger?.Invoke(this, new LogEventArgs(line));
32+
}));
3533
}
3634

3735
static public List<string> GetLog() { return mInstance.mLogList; }
3836

3937
public class LogEventArgs : EventArgs
4038
{
4139
public string line { get; set; }
40+
public LogEventArgs(string _line) { line = _line; }
4241
}
4342

4443
static public event EventHandler<LogEventArgs> Logger;
@@ -56,6 +55,8 @@ public AppLog()
5655
{
5756
mInstance = this;
5857

58+
mDispatcher = Dispatcher.CurrentDispatcher;
59+
5960
Logger += LineLogger;
6061
}
6162
}

‎wumgr/Common/FileOps.cs

+42
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,21 @@ static public void SetFileAdminSec(String filePath)
124124
File.SetAccessControl(filePath, fs);
125125
}
126126

127+
static public bool TestWrite(string filePath)
128+
{
129+
FileInfo fi = new FileInfo(filePath);
130+
try
131+
{
132+
FileStream f_out = fi.OpenWrite();
133+
f_out.Close();
134+
return true;
135+
}
136+
catch
137+
{
138+
return false;
139+
}
140+
}
141+
127142
public static string SID_null = "S-1-0-0"; // Null SID
128143
public static string SID_Worls = "S-1-1-0"; // World
129144
public static string SID_Local = "S-1-2-0"; // Local
@@ -185,4 +200,31 @@ static public void SetFileAdminSec(String filePath)
185200
public static string SID_PPLevel = "S-1-16-20480"; // Protected Process Mandatory Level
186201
public static string SID_SPLevel = "S-1-16-28672"; // Secure Process Mandatory Level
187202

203+
internal static bool TakeOwn(string path)
204+
{
205+
bool ret = true;
206+
try
207+
{
208+
//TokenManipulator.AddPrivilege("SeRestorePrivilege");
209+
//TokenManipulator.AddPrivilege("SeBackupPrivilege");
210+
TokenManipulator.AddPrivilege("SeTakeOwnershipPrivilege");
211+
212+
213+
FileSecurity ac = File.GetAccessControl(path);
214+
ac.SetOwner(new SecurityIdentifier(FileOps.SID_Admins));
215+
File.SetAccessControl(path, ac);
216+
}
217+
catch (PrivilegeNotHeldException err)
218+
{
219+
AppLog.Line("Enable SkipUAC Error {0}", err.ToString());
220+
ret = false;
221+
}
222+
finally
223+
{
224+
//TokenManipulator.RemovePrivilege("SeRestorePrivilege");
225+
//TokenManipulator.RemovePrivilege("SeBackupPrivilege");
226+
TokenManipulator.RemovePrivilege("SeTakeOwnershipPrivilege");
227+
}
228+
return ret;
229+
}
188230
}

‎wumgr/Common/HttpTask.cs

+37-10
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,6 @@ private void Finish(int Success, int ErrCode, Exception Error = null)
153153
Finished?.Invoke(this, new FinishedEventArgs(Success > 0 ? 0 : Canceled ? -1 : ErrCode, Error));
154154
}
155155

156-
private void ReportProgress()
157-
{
158-
Progress?.Invoke(this, new ProgressEventArgs(mLength > 0 ? (int)((Int64)100 * mOffset / mLength) : -1));
159-
}
160-
161156
static public string GetNextTempFile(string path, string baseName)
162157
{
163158
for (int i = 0; i < 10000; i++)
@@ -235,10 +230,33 @@ private static void RespCallback(IAsyncResult asynchronousResult)
235230
task.streamWriter = info.OpenWrite();
236231

237232
// Begin the Reading of the contents of the HTML page and print it to the console.
238-
IAsyncResult asynchronousInputRead = task.streamResponse.BeginRead(task.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), task);
233+
task.streamResponse.BeginRead(task.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), task);
239234
return;
240235
}
241236
}
237+
catch (WebException e)
238+
{
239+
if (e.Response != null)
240+
{
241+
string fileName = Path.GetFileName(e.Response.ResponseUri.AbsolutePath.ToString());
242+
243+
if (task.mDlName == null)
244+
task.mDlName = fileName;
245+
246+
FileInfo testInfo = new FileInfo(task.mDlPath + @"\" + task.mDlName);
247+
if (testInfo.Exists)
248+
Success = 2;
249+
}
250+
251+
if(Success == 0)
252+
{
253+
ErrCode = -2;
254+
Error = e;
255+
Console.WriteLine("\nRespCallback Exception raised!");
256+
Console.WriteLine("\nMessage:{0}", e.Message);
257+
Console.WriteLine("\nStatus:{0}", e.Status);
258+
}
259+
}
242260
catch (Exception e)
243261
{
244262
ErrCode = -2;
@@ -251,6 +269,8 @@ private static void RespCallback(IAsyncResult asynchronousResult)
251269
}));
252270
}
253271

272+
private int mOldPercent = -1;
273+
254274
private static void ReadCallBack(IAsyncResult asyncResult)
255275
{
256276
int Success = 0;
@@ -266,12 +286,17 @@ private static void ReadCallBack(IAsyncResult asyncResult)
266286
task.streamWriter.Write(task.BufferRead, 0, read);
267287
task.mOffset += read;
268288

269-
task.mDispatcher.Invoke(new Action(() => {
270-
task.ReportProgress();
271-
}));
289+
int Percent = task.mLength > 0 ? (int)((Int64)100 * task.mOffset / task.mLength) : -1;
290+
if (Percent != task.mOldPercent)
291+
{
292+
task.mOldPercent = Percent;
293+
task.mDispatcher.Invoke(new Action(() => {
294+
task.Progress?.Invoke(task, new ProgressEventArgs(Percent));
295+
}));
296+
}
272297

273298
// setup next read
274-
IAsyncResult asynchronousResult = task.streamResponse.BeginRead(task.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), task);
299+
task.streamResponse.BeginRead(task.BufferRead, 0, BUFFER_SIZE, new AsyncCallback(ReadCallBack), task);
275300
return;
276301
}
277302
else
@@ -308,10 +333,12 @@ public string GetError()
308333
return Error.ToString();
309334
switch(ErrCode)
310335
{
336+
case 0: return "Ok";
311337
case -1: return "Canceled";
312338
default: return ErrCode.ToString();
313339
}
314340
}
341+
public bool Success { get { return ErrCode == 0; } }
315342
public bool Cancelled { get { return ErrCode == -1; } }
316343

317344
public int ErrCode = 0;

‎wumgr/Common/KnownFolders.cs

+109
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
using System;
2+
using System.Runtime.InteropServices;
3+
4+
/// <summary>
5+
/// Class containing methods to retrieve specific file system paths.
6+
/// </summary>
7+
public static class KnownFolders
8+
{
9+
private static string[] _knownFolderGuids = new string[]
10+
{
11+
"{56784854-C6CB-462B-8169-88E350ACB882}", // Contacts
12+
"{B4BFCC3A-DB2C-424C-B029-7FE99A87C641}", // Desktop
13+
"{FDD39AD0-238F-46AF-ADB4-6C85480369C7}", // Documents
14+
"{374DE290-123F-4565-9164-39C4925E467B}", // Downloads
15+
"{1777F761-68AD-4D8A-87BD-30B759FA33DD}", // Favorites
16+
"{BFB9D5E0-C6A9-404C-B2B2-AE6DB6AF4968}", // Links
17+
"{4BD8D571-6D19-48D3-BE97-422220080E43}", // Music
18+
"{33E28130-4E1E-4676-835A-98395C3BC3BB}", // Pictures
19+
"{4C5C32FF-BB9D-43B0-B5B4-2D72E54EAAA4}", // SavedGames
20+
"{7D1D3A04-DEBB-4115-95CF-2F29DA2920DA}", // SavedSearches
21+
"{18989B1D-99B5-455B-841C-AB7C74E4DDFC}", // Videos
22+
};
23+
24+
/// <summary>
25+
/// Gets the current path to the specified known folder as currently configured. This does
26+
/// not require the folder to be existent.
27+
/// </summary>
28+
/// <param name="knownFolder">The known folder which current path will be returned.</param>
29+
/// <returns>The default path of the known folder.</returns>
30+
/// <exception cref="System.Runtime.InteropServices.ExternalException">Thrown if the path
31+
/// could not be retrieved.</exception>
32+
public static string GetPath(KnownFolder knownFolder)
33+
{
34+
return GetPath(knownFolder, false);
35+
}
36+
37+
/// <summary>
38+
/// Gets the current path to the specified known folder as currently configured. This does
39+
/// not require the folder to be existent.
40+
/// </summary>
41+
/// <param name="knownFolder">The known folder which current path will be returned.</param>
42+
/// <param name="defaultUser">Specifies if the paths of the default user (user profile
43+
/// template) will be used. This requires administrative rights.</param>
44+
/// <returns>The default path of the known folder.</returns>
45+
/// <exception cref="System.Runtime.InteropServices.ExternalException">Thrown if the path
46+
/// could not be retrieved.</exception>
47+
public static string GetPath(KnownFolder knownFolder, bool defaultUser)
48+
{
49+
return GetPath(knownFolder, KnownFolderFlags.DontVerify, defaultUser);
50+
}
51+
52+
private static string GetPath(KnownFolder knownFolder, KnownFolderFlags flags,
53+
bool defaultUser)
54+
{
55+
int result = SHGetKnownFolderPath(new Guid(_knownFolderGuids[(int)knownFolder]),
56+
(uint)flags, new IntPtr(defaultUser ? -1 : 0), out IntPtr outPath);
57+
if (result >= 0)
58+
{
59+
string path = Marshal.PtrToStringUni(outPath);
60+
Marshal.FreeCoTaskMem(outPath);
61+
return path;
62+
}
63+
else
64+
{
65+
//throw new ExternalException("Unable to retrieve the known folder path. It may not be available on this system.", result);
66+
return null;
67+
}
68+
}
69+
70+
[DllImport("Shell32.dll")]
71+
private static extern int SHGetKnownFolderPath(
72+
[MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags, IntPtr hToken,
73+
out IntPtr ppszPath);
74+
75+
[Flags]
76+
private enum KnownFolderFlags : uint
77+
{
78+
SimpleIDList = 0x00000100,
79+
NotParentRelative = 0x00000200,
80+
DefaultPath = 0x00000400,
81+
Init = 0x00000800,
82+
NoAlias = 0x00001000,
83+
DontUnexpand = 0x00002000,
84+
DontVerify = 0x00004000,
85+
Create = 0x00008000,
86+
NoAppcontainerRedirection = 0x00010000,
87+
AliasOnly = 0x80000000
88+
}
89+
}
90+
91+
/// <summary>
92+
/// Standard folders registered with the system. These folders are installed with Windows Vista
93+
/// and later operating systems, and a computer will have only folders appropriate to it
94+
/// installed.
95+
/// </summary>
96+
public enum KnownFolder
97+
{
98+
Contacts,
99+
Desktop,
100+
Documents,
101+
Downloads,
102+
Favorites,
103+
Links,
104+
Music,
105+
Pictures,
106+
SavedGames,
107+
SavedSearches,
108+
Videos
109+
}

0 commit comments

Comments
 (0)
Please sign in to comment.