using System; using System.Collections; using System.Globalization; using System.IO; using System.Net; using System.Text; using System.Windows.Forms; using System.Xml; namespace Microsoft.Samples.AppUpdater { public class WebFileLoader { internal delegate void NotifyUpdateFileInfoEventHandler(object sender, NotifyUpdateFileInfoEventArgs e); private static NotifyUpdateFileInfoEventArgs UpdateFileInfoEventArgs; internal static event NotifyUpdateFileInfoEventHandler OnNotifyUpdateFileInfo; public static bool CheckForFileUpdate(string url, string filePath) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); httpWebRequest.Method = "HEAD"; httpWebRequest.Credentials = CredentialCache.DefaultCredentials; HttpWebResponse httpWebResponse; try { httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); } catch (WebException ex) { if (ex.Response == null) { throw; } HttpWebResponse httpWebResponse2 = (HttpWebResponse)ex.Response; if (httpWebResponse2.StatusCode != HttpStatusCode.NotModified) { ex.Response.Close(); throw; } ex.Response.Close(); return false; } httpWebResponse.Close(); return true; } public static void UpdateFile(string url, string filePath) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); httpWebRequest.Headers.Add("Translate: f"); httpWebRequest.Credentials = CredentialCache.DefaultCredentials; if (File.Exists(filePath)) { httpWebRequest.IfModifiedSince = LastModFromDisk(filePath); } HttpWebResponse httpWebResponse; try { httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); } catch (WebException ex) { if (ex.Response == null) { throw; } HttpWebResponse httpWebResponse2 = (HttpWebResponse)ex.Response; if (httpWebResponse2.StatusCode == HttpStatusCode.NotModified) { ex.Response.Close(); return; } ex.Response.Close(); throw; } Stream stream = null; try { stream = httpWebResponse.GetResponseStream(); CopyStreamToDisk(stream, filePath); DateTime lastWriteTime = Convert.ToDateTime(httpWebResponse.GetResponseHeader("Last-Modified")); File.SetLastWriteTime(filePath, lastWriteTime); } catch (Exception) { throw; } finally { stream?.Close(); httpWebResponse?.Close(); } } public static int CopyDirectory(string url, string filePath, int fileTotal, bool bReport) { int num = 0; SortedList directoryContents = GetDirectoryContents(url, deep: false); foreach (object item in directoryContents) { Resource resource = (Resource)((DictionaryEntry)item).Value; if (fileTotal != 0 && !Directory.Exists(filePath)) { Directory.CreateDirectory(filePath); } if (!resource.IsFolder) { num++; string text = filePath + resource.Name; if (fileTotal != 0 && (!File.Exists(text) || resource.LastModified > LastModFromDisk(text))) { if (bReport && WebFileLoader.OnNotifyUpdateFileInfo != null) { if (UpdateFileInfoEventArgs == null) { UpdateFileInfoEventArgs = new NotifyUpdateFileInfoEventArgs(); } UpdateFileInfoEventArgs.FileTotal = fileTotal; UpdateFileInfoEventArgs.FileName = filePath; UpdateFileInfoEventArgs.CurrentFile = num; WebFileLoader.OnNotifyUpdateFileInfo(null, UpdateFileInfoEventArgs); } UpdateFile(resource.Url, text); } } else { string text = filePath + resource.Name + "\\"; num += CopyDirectory(resource.Url, text, fileTotal, bReport: true); } } return num; } public static SortedList GetDirectoryContents(string url, bool deep) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); httpWebRequest.Headers.Add("Translate: f"); httpWebRequest.Credentials = CredentialCache.DefaultCredentials; string text = ""; httpWebRequest.Method = "PROPFIND"; if (deep) { httpWebRequest.Headers.Add("Depth: infinity"); } else { httpWebRequest.Headers.Add("Depth: 1"); } httpWebRequest.ContentLength = text.Length; httpWebRequest.ContentType = "text/xml"; Stream requestStream = httpWebRequest.GetRequestStream(); requestStream.Write(Encoding.ASCII.GetBytes(text), 0, Encoding.ASCII.GetBytes(text).Length); requestStream.Close(); StreamReader streamReader; try { HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); streamReader = new StreamReader(httpWebResponse.GetResponseStream()); } catch (WebException ex) { throw ex; } StringBuilder stringBuilder = new StringBuilder(); char[] array = new char[1024]; int num = 0; for (num = streamReader.Read(array, 0, 1024); num > 0; num = streamReader.Read(array, 0, 1024)) { stringBuilder.Append(array, 0, num); } streamReader.Close(); XmlDocument xmlDocument = new XmlDocument(); xmlDocument.LoadXml(stringBuilder.ToString()); XmlNamespaceManager xmlNamespaceManager = new XmlNamespaceManager(xmlDocument.NameTable); xmlNamespaceManager.AddNamespace("a", "DAV:"); XmlNodeList xmlNodeList = xmlDocument.SelectNodes("//a:prop/a:displayname", xmlNamespaceManager); XmlNodeList xmlNodeList2 = xmlDocument.SelectNodes("//a:prop/a:iscollection", xmlNamespaceManager); XmlNodeList xmlNodeList3 = xmlDocument.SelectNodes("//a:prop/a:getlastmodified", xmlNamespaceManager); XmlNodeList xmlNodeList4 = xmlDocument.SelectNodes("//a:href", xmlNamespaceManager); SortedList sortedList = new SortedList(); for (int i = 1; i < xmlNodeList.Count; i++) { if (xmlNodeList4[i].InnerText.ToLower(new CultureInfo("en-US")).TrimEnd('/') != url.ToLower(new CultureInfo("en-US")).TrimEnd('/')) { Resource resource = new Resource(); resource.Name = xmlNodeList[i].InnerText; resource.IsFolder = Convert.ToBoolean(Convert.ToInt32(xmlNodeList2[i].InnerText)); resource.Url = xmlNodeList4[i].InnerText; resource.LastModified = Convert.ToDateTime(xmlNodeList3[i].InnerText); sortedList.Add(resource.Url, resource); } } return sortedList; } public static void UpdateFileList(SortedList fileList, string sourceUrl, string destPath) { if (!Directory.Exists(destPath)) { Directory.CreateDirectory(destPath); } foreach (object file in fileList) { Resource resource = (Resource)((DictionaryEntry)file).Value; string url = sourceUrl + resource.Name; string filePath = destPath + resource.Name; UpdateFile(url, filePath); } } public static DateTime GetLastModTime(string url) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); httpWebRequest.Method = "HEAD"; HttpWebResponse httpWebResponse; try { httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); } catch (WebException ex) { if (ex.Response != null) { ex.Response.Close(); } throw; } return Convert.ToDateTime(httpWebResponse.GetResponseHeader("Last-Modified")); } public static Stream LoadFile(string url) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); HttpWebResponse httpWebResponse; try { httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); } catch (WebException) { throw; } return httpWebResponse.GetResponseStream(); } public static bool CheckForFileUpdate(string url, DateTime lastModeTime) { HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); httpWebRequest.Method = "HEAD"; httpWebRequest.IfModifiedSince = lastModeTime; HttpWebResponse httpWebResponse; try { httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse(); } catch (WebException ex) { if (ex.Response == null) { throw; } HttpWebResponse httpWebResponse2 = (HttpWebResponse)ex.Response; if (httpWebResponse2.StatusCode != HttpStatusCode.NotModified) { ex.Response.Close(); throw; } ex.Response.Close(); return false; } httpWebResponse.Close(); return true; } public static int GetFileCount(string filePath) { string[] directories = Directory.GetDirectories(filePath); string[] files = Directory.GetFiles(filePath); int num = 0; num = files.Length + directories.Length; string[] array = directories; foreach (string text in array) { string str = text.Remove(0, text.LastIndexOf("\\") + 1); num += GetFileCount(filePath + str + "\\"); } return num; } private static void CopyStreamToDisk(Stream responseStream, string filePath) { byte[] buffer = new byte[4096]; Random random = new Random(); string str = Environment.GetEnvironmentVariable("temp") + "\\"; str += filePath.Remove(0, filePath.LastIndexOf("\\") + 1); str = str + random.Next(10000).ToString() + ".tmp"; FileStream fileStream = File.Open(str, FileMode.Create, FileAccess.ReadWrite); for (int num = responseStream.Read(buffer, 0, 4096); num > 0; num = responseStream.Read(buffer, 0, 4096)) { fileStream.Write(buffer, 0, num); } fileStream.Close(); if (File.Exists(filePath)) { File.Delete(filePath); } File.Move(str, filePath); } public static DateTime LastModFromDisk(string filePath) { FileInfo fileInfo = new FileInfo(filePath); return fileInfo.LastWriteTime; } public static void CopyAndRename(string source, string dest) { string[] directories = Directory.GetDirectories(source); string[] files = Directory.GetFiles(source); if (!Directory.Exists(dest)) { Directory.CreateDirectory(dest); } string[] array = files; foreach (string text in array) { string text2 = text.Remove(0, text.LastIndexOf("\\") + 1); MessageBox.Show(text2); if (File.Exists(dest + text2)) { File.Delete(dest + text2); } File.Move(text, dest + text2); } string[] array2 = directories; foreach (string text3 in array2) { string text2 = text3.Remove(0, text3.LastIndexOf("\\") + 1); MessageBox.Show(text2); if (!Directory.Exists(dest + text2 + "\\")) { Directory.CreateDirectory(dest + text2 + "\\"); } CopyAndRename(source + text2 + "\\", dest + text2 + "\\"); } Directory.Delete(source, recursive: true); } public static string CreateHttpsUrl(string url) { url = url.ToLower(new CultureInfo("en-US")); if (url.StartsWith("https")) { return url; } return url.Insert(4, "s"); } } }