Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

370 lines
11 KiB

  1. using System;
  2. using System.Text;
  3. using System.Net;
  4. using System.IO;
  5. using System.Text.RegularExpressions;
  6. using System.Runtime.Remoting;
  7. using System.Globalization;
  8. using System.Security;
  9. using System.Security.Policy;
  10. using System.Security.Permissions;
  11. using System.Collections;
  12. using System.Runtime.InteropServices;
  13. using System.Reflection;
  14. using System.Configuration.Assemblies;
  15. using System.Threading;
  16. using System.Xml;
  17. using System.Xml.XPath;
  18. namespace Microsoft.Fusion.ADF
  19. {
  20. //----------------------------------------------------------
  21. // ApplicationMoniker
  22. //----------------------------------------------------------
  23. public class ApplicationMoniker : IWebRequestCreate
  24. {
  25. ManualResetEvent _event;
  26. int _totalRead;
  27. const int BUFFER_SIZE = 0x4000;
  28. Uri _manifestUri;
  29. Uri _appBase;
  30. ApplicationManifestImport _applicationManifestImport;
  31. AssemblyIdentity _assemblyIdentity;
  32. string _manifestFileName;
  33. string _appStorePath;
  34. Progress _progress;
  35. Hashtable _jobTable;
  36. Queue _jobQueue;
  37. bool _bDone;
  38. int _totalSize;
  39. //----------------------------------------------------------
  40. // ctor
  41. //----------------------------------------------------------
  42. public ApplicationMoniker(string manifestUri, string appBase)
  43. {
  44. _manifestUri = new Uri(manifestUri);
  45. string path = _manifestUri.LocalPath;
  46. _manifestFileName = System.IO.Path.GetFileName(path);
  47. if (appBase != null)
  48. _appBase = new Uri(appBase);
  49. else
  50. {
  51. string appBaseString = manifestUri.Substring(0, manifestUri.Length - _manifestFileName.Length);
  52. _appBase = new Uri(appBaseString);
  53. }
  54. _applicationManifestImport = new ApplicationManifestImport(_manifestUri);
  55. _assemblyIdentity = _applicationManifestImport.GetAssemblyIdentity();
  56. string appDirName = _assemblyIdentity.GetDirectoryName();
  57. string userprofile = Environment.GetEnvironmentVariable("userprofile");
  58. _appStorePath = userprofile + "\\Local Settings\\My Programs\\__temp__\\" + appDirName;
  59. _progress = new Progress();
  60. _jobTable = new Hashtable();
  61. _jobQueue = new Queue();
  62. _totalRead = 0;
  63. _totalSize = 0;
  64. }
  65. //----------------------------------------------------------
  66. // ApplicationMoniker
  67. //----------------------------------------------------------
  68. public WebRequest Create(Uri uri)
  69. {
  70. return ApplicationMonikerRequest.Create(uri, _appBase, _appStorePath);
  71. }
  72. //----------------------------------------------------------
  73. // GetApplicationManifestImport
  74. //----------------------------------------------------------
  75. public ApplicationManifestImport GetApplicationManifestImport()
  76. {
  77. return new ApplicationManifestImport(_manifestUri);
  78. }
  79. //----------------------------------------------------------
  80. // AppBase
  81. //----------------------------------------------------------
  82. public string AppBase
  83. { get { return _appBase.ToString();} }
  84. //----------------------------------------------------------
  85. // GetAppInfo
  86. //----------------------------------------------------------
  87. public void GetAppInfo(ref int nFiles, ref int nAssemblies)
  88. {
  89. DependentFileInfo dfi;
  90. DependentAssemblyInfo dai;
  91. _applicationManifestImport.ResetIterators();
  92. nFiles = nAssemblies = 0;
  93. while ((dfi = _applicationManifestImport.GetNextDependentFileInfo()) != null)
  94. {
  95. Uri httpSite = new Uri(_appBase, dfi["name"]);
  96. nFiles++;
  97. _totalSize += GetContentLength(httpSite);
  98. }
  99. while ((dai = _applicationManifestImport.GetNextDependentAssemblyInfo()) != null)
  100. {
  101. Uri httpSite = new Uri(_appBase, dai["codeBase"]);
  102. nFiles++;
  103. _totalSize += GetContentLength(httpSite);
  104. }
  105. _applicationManifestImport.ResetIterators();
  106. }
  107. //----------------------------------------------------------
  108. // GetContentLength
  109. //----------------------------------------------------------
  110. public int GetContentLength(Uri uri)
  111. {
  112. HttpWebRequest webRequest = (HttpWebRequest) WebRequest.CreateDefault(uri);
  113. webRequest.Method = "HEAD";
  114. WebResponse wr = webRequest.GetResponse();
  115. return (int) wr.ContentLength;
  116. }
  117. //----------------------------------------------------------
  118. // DownloadManifestAndDependencies
  119. //----------------------------------------------------------
  120. public void DownloadManifestAndDependencies()
  121. {
  122. int nTotal = 0, nFiles = 0, nAssemblies = 0;
  123. _bDone = false;
  124. GetAppInfo(ref nFiles, ref nAssemblies);
  125. nTotal = nFiles + nAssemblies;
  126. _totalSize += GetContentLength(_manifestUri);
  127. _progress.SetRange(0, _totalSize);
  128. _progress.SetStatus(0);
  129. _progress.SetText("Downloading...");
  130. _progress.Activate();
  131. _progress.Visible = true;
  132. System.Windows.Forms.Application.DoEvents();
  133. DoDownload(_manifestUri);
  134. while (true)
  135. {
  136. System.Windows.Forms.Application.DoEvents();
  137. if (_bDone == true)
  138. break;
  139. }
  140. _progress.Visible = false;
  141. }
  142. //----------------------------------------------------------
  143. // DoDownload
  144. //----------------------------------------------------------
  145. void DoDownload(Uri appManifestUri)
  146. {
  147. ApplicationMonikerRequest request =
  148. (ApplicationMonikerRequest)
  149. ApplicationMonikerRequest.Create(appManifestUri, _appBase, _appStorePath);
  150. request.type = FileType.ApplicationManifest;
  151. _jobTable[appManifestUri] = request;
  152. RequestState rs = new RequestState();
  153. rs.Request = request;
  154. IAsyncResult r = (IAsyncResult) request.BeginGetResponse(
  155. new AsyncCallback(RespCallback), rs);
  156. }
  157. //----------------------------------------------------------
  158. // RespCallback
  159. //----------------------------------------------------------
  160. void RespCallback(IAsyncResult ar)
  161. {
  162. RequestState rs = (RequestState) ar.AsyncState;
  163. ApplicationMonikerRequest req = rs.Request;
  164. ApplicationMonikerResponse resp = (ApplicationMonikerResponse) req.EndGetResponse(ar);
  165. ApplicationMonikerStream ResponseStream = (ApplicationMonikerStream) resp.GetResponseStream();
  166. rs.ResponseStream = ResponseStream;
  167. IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0,
  168. BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
  169. }
  170. //----------------------------------------------------------
  171. // ReadCallback
  172. //----------------------------------------------------------
  173. void ReadCallBack(IAsyncResult asyncResult)
  174. {
  175. RequestState rs = (RequestState) asyncResult.AsyncState;
  176. ApplicationMonikerStream responseStream = rs.ResponseStream;
  177. int read = responseStream.EndRead( asyncResult );
  178. if (read > 0)
  179. {
  180. _totalRead += read;
  181. IAsyncResult ar = responseStream.BeginRead(
  182. rs.BufferRead, 0, BUFFER_SIZE,
  183. new AsyncCallback(ReadCallBack), rs);
  184. }
  185. else
  186. {
  187. _progress.SetStatus((int) _totalRead);
  188. _progress.SetText("Downloading: " + responseStream.path);
  189. _progress.SetTotal("Total: " + _totalRead.ToString() + "/" + _totalSize.ToString() + " bytes read");
  190. responseStream.Close();
  191. if ((rs.Request.type == FileType.ApplicationManifest)
  192. || (rs.Request.type == FileType.ComponentManifest))
  193. {
  194. IAssemblyManifestImport assemblyManifestImport;
  195. Uri cachePath = responseStream.GetCachePath();
  196. if (rs.Request.type == FileType.ApplicationManifest)
  197. assemblyManifestImport = new ApplicationManifestImport(cachePath);
  198. else
  199. // this is a drag - we can't even do this - the loadfrom will fail if modules not present.
  200. // soln for now is to ignore component constituents (don't enqueue them)
  201. // assemblyManifestImport = new ComponentManifestImport(cachePath);
  202. goto done;
  203. ApplicationMonikerRequest newRequest;
  204. while ((newRequest = GetNextRequest(assemblyManifestImport)) != null)
  205. {
  206. if (_jobTable[newRequest.RequestUri] == null)
  207. {
  208. if (newRequest.CachedCopyExists() != true)
  209. {
  210. _jobQueue.Enqueue(newRequest);
  211. _jobTable[newRequest.RequestUri] = newRequest;
  212. }
  213. else
  214. {
  215. _totalRead += (int) newRequest.GetCacheFileSize();
  216. _progress.SetStatus((int) _totalRead);
  217. newRequest.Dispose();
  218. }
  219. }
  220. }
  221. }
  222. done:
  223. if (_jobQueue.Count == 0)
  224. _bDone = true;
  225. else
  226. {
  227. ApplicationMonikerRequest nextRequest = (ApplicationMonikerRequest) _jobQueue.Dequeue();
  228. RequestState rsnext = new RequestState();
  229. rsnext.Request = nextRequest;
  230. IAsyncResult r = (IAsyncResult) nextRequest.BeginGetResponse(
  231. new AsyncCallback(RespCallback), rsnext);
  232. }
  233. }
  234. return;
  235. }
  236. //----------------------------------------------------------
  237. // PurgeFiles
  238. //----------------------------------------------------------
  239. public void PurgeFiles()
  240. {
  241. DirectoryInfo di = new DirectoryInfo(_appStorePath);
  242. di.Delete(true);
  243. }
  244. //----------------------------------------------------------
  245. // GetNextRequest
  246. //----------------------------------------------------------
  247. public ApplicationMonikerRequest GetNextRequest(IAssemblyManifestImport ami)
  248. {
  249. FileType type;
  250. Uri codebase;
  251. DependentFileInfo dfi;
  252. DependentAssemblyInfo dai;
  253. // we can't do components for now.
  254. if (ami.GetFileType() == FileType.ComponentManifest)
  255. return null;
  256. dfi = ami.GetNextDependentFileInfo();
  257. if (dfi != null)
  258. {
  259. codebase = new Uri(_appBase, dfi["name"]);
  260. type =FileType.RawFile;
  261. }
  262. else
  263. {
  264. // Don't follow component dependencies.
  265. // if (ami.GetFileType() == FileType.ComponentManifest)
  266. // return null;
  267. dai = ami.GetNextDependentAssemblyInfo();
  268. if (dai != null)
  269. {
  270. codebase = new Uri(_appBase, dai["codeBase"]);
  271. type = FileType.ComponentManifest;
  272. }
  273. else
  274. {
  275. codebase = null;
  276. type = FileType.Unknown;
  277. }
  278. }
  279. if (codebase == null)
  280. return null;
  281. ApplicationMonikerRequest request =
  282. (ApplicationMonikerRequest) ApplicationMonikerRequest.Create(codebase, _appBase, _appStorePath);
  283. request.type = type;
  284. return request;
  285. }
  286. }
  287. //----------------------------------------------------------
  288. // RequestState
  289. //----------------------------------------------------------
  290. class RequestState
  291. {
  292. const int BufferSize = 0x4000;
  293. public byte[] BufferRead;
  294. public ApplicationMonikerRequest Request;
  295. public ApplicationMonikerStream ResponseStream;
  296. //----------------------------------------------------------
  297. // ctor
  298. //----------------------------------------------------------
  299. public RequestState()
  300. {
  301. BufferRead = new byte[BufferSize];
  302. Request = null;
  303. ResponseStream = null;
  304. }
  305. }
  306. }