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.
 
 
 
 
 
 

371 lines
11 KiB

using System;
using System.Text;
using System.Net;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.Remoting;
using System.Globalization;
using System.Security;
using System.Security.Policy;
using System.Security.Permissions;
using System.Collections;
using System.Runtime.InteropServices;
using System.Reflection;
using System.Configuration.Assemblies;
using System.Threading;
using System.Xml;
using System.Xml.XPath;
namespace Microsoft.Fusion.ADF
{
//----------------------------------------------------------
// ApplicationMoniker
//----------------------------------------------------------
public class ApplicationMoniker : IWebRequestCreate
{
ManualResetEvent _event;
int _totalRead;
const int BUFFER_SIZE = 0x4000;
Uri _manifestUri;
Uri _appBase;
ApplicationManifestImport _applicationManifestImport;
AssemblyIdentity _assemblyIdentity;
string _manifestFileName;
string _appStorePath;
Progress _progress;
Hashtable _jobTable;
Queue _jobQueue;
bool _bDone;
int _totalSize;
//----------------------------------------------------------
// ctor
//----------------------------------------------------------
public ApplicationMoniker(string manifestUri, string appBase)
{
_manifestUri = new Uri(manifestUri);
string path = _manifestUri.LocalPath;
_manifestFileName = System.IO.Path.GetFileName(path);
if (appBase != null)
_appBase = new Uri(appBase);
else
{
string appBaseString = manifestUri.Substring(0, manifestUri.Length - _manifestFileName.Length);
_appBase = new Uri(appBaseString);
}
_applicationManifestImport = new ApplicationManifestImport(_manifestUri);
_assemblyIdentity = _applicationManifestImport.GetAssemblyIdentity();
string appDirName = _assemblyIdentity.GetDirectoryName();
string userprofile = Environment.GetEnvironmentVariable("userprofile");
_appStorePath = userprofile + "\\Local Settings\\My Programs\\__temp__\\" + appDirName;
_progress = new Progress();
_jobTable = new Hashtable();
_jobQueue = new Queue();
_totalRead = 0;
_totalSize = 0;
}
//----------------------------------------------------------
// ApplicationMoniker
//----------------------------------------------------------
public WebRequest Create(Uri uri)
{
return ApplicationMonikerRequest.Create(uri, _appBase, _appStorePath);
}
//----------------------------------------------------------
// GetApplicationManifestImport
//----------------------------------------------------------
public ApplicationManifestImport GetApplicationManifestImport()
{
return new ApplicationManifestImport(_manifestUri);
}
//----------------------------------------------------------
// AppBase
//----------------------------------------------------------
public string AppBase
{ get { return _appBase.ToString();} }
//----------------------------------------------------------
// GetAppInfo
//----------------------------------------------------------
public void GetAppInfo(ref int nFiles, ref int nAssemblies)
{
DependentFileInfo dfi;
DependentAssemblyInfo dai;
_applicationManifestImport.ResetIterators();
nFiles = nAssemblies = 0;
while ((dfi = _applicationManifestImport.GetNextDependentFileInfo()) != null)
{
Uri httpSite = new Uri(_appBase, dfi["name"]);
nFiles++;
_totalSize += GetContentLength(httpSite);
}
while ((dai = _applicationManifestImport.GetNextDependentAssemblyInfo()) != null)
{
Uri httpSite = new Uri(_appBase, dai["codeBase"]);
nFiles++;
_totalSize += GetContentLength(httpSite);
}
_applicationManifestImport.ResetIterators();
}
//----------------------------------------------------------
// GetContentLength
//----------------------------------------------------------
public int GetContentLength(Uri uri)
{
HttpWebRequest webRequest = (HttpWebRequest) WebRequest.CreateDefault(uri);
webRequest.Method = "HEAD";
WebResponse wr = webRequest.GetResponse();
return (int) wr.ContentLength;
}
//----------------------------------------------------------
// DownloadManifestAndDependencies
//----------------------------------------------------------
public void DownloadManifestAndDependencies()
{
int nTotal = 0, nFiles = 0, nAssemblies = 0;
_bDone = false;
GetAppInfo(ref nFiles, ref nAssemblies);
nTotal = nFiles + nAssemblies;
_totalSize += GetContentLength(_manifestUri);
_progress.SetRange(0, _totalSize);
_progress.SetStatus(0);
_progress.SetText("Downloading...");
_progress.Activate();
_progress.Visible = true;
System.Windows.Forms.Application.DoEvents();
DoDownload(_manifestUri);
while (true)
{
System.Windows.Forms.Application.DoEvents();
if (_bDone == true)
break;
}
_progress.Visible = false;
}
//----------------------------------------------------------
// DoDownload
//----------------------------------------------------------
void DoDownload(Uri appManifestUri)
{
ApplicationMonikerRequest request =
(ApplicationMonikerRequest)
ApplicationMonikerRequest.Create(appManifestUri, _appBase, _appStorePath);
request.type = FileType.ApplicationManifest;
_jobTable[appManifestUri] = request;
RequestState rs = new RequestState();
rs.Request = request;
IAsyncResult r = (IAsyncResult) request.BeginGetResponse(
new AsyncCallback(RespCallback), rs);
}
//----------------------------------------------------------
// RespCallback
//----------------------------------------------------------
void RespCallback(IAsyncResult ar)
{
RequestState rs = (RequestState) ar.AsyncState;
ApplicationMonikerRequest req = rs.Request;
ApplicationMonikerResponse resp = (ApplicationMonikerResponse) req.EndGetResponse(ar);
ApplicationMonikerStream ResponseStream = (ApplicationMonikerStream) resp.GetResponseStream();
rs.ResponseStream = ResponseStream;
IAsyncResult iarRead = ResponseStream.BeginRead(rs.BufferRead, 0,
BUFFER_SIZE, new AsyncCallback(ReadCallBack), rs);
}
//----------------------------------------------------------
// ReadCallback
//----------------------------------------------------------
void ReadCallBack(IAsyncResult asyncResult)
{
RequestState rs = (RequestState) asyncResult.AsyncState;
ApplicationMonikerStream responseStream = rs.ResponseStream;
int read = responseStream.EndRead( asyncResult );
if (read > 0)
{
_totalRead += read;
IAsyncResult ar = responseStream.BeginRead(
rs.BufferRead, 0, BUFFER_SIZE,
new AsyncCallback(ReadCallBack), rs);
}
else
{
_progress.SetStatus((int) _totalRead);
_progress.SetText("Downloading: " + responseStream.path);
_progress.SetTotal("Total: " + _totalRead.ToString() + "/" + _totalSize.ToString() + " bytes read");
responseStream.Close();
if ((rs.Request.type == FileType.ApplicationManifest)
|| (rs.Request.type == FileType.ComponentManifest))
{
IAssemblyManifestImport assemblyManifestImport;
Uri cachePath = responseStream.GetCachePath();
if (rs.Request.type == FileType.ApplicationManifest)
assemblyManifestImport = new ApplicationManifestImport(cachePath);
else
// this is a drag - we can't even do this - the loadfrom will fail if modules not present.
// soln for now is to ignore component constituents (don't enqueue them)
// assemblyManifestImport = new ComponentManifestImport(cachePath);
goto done;
ApplicationMonikerRequest newRequest;
while ((newRequest = GetNextRequest(assemblyManifestImport)) != null)
{
if (_jobTable[newRequest.RequestUri] == null)
{
if (newRequest.CachedCopyExists() != true)
{
_jobQueue.Enqueue(newRequest);
_jobTable[newRequest.RequestUri] = newRequest;
}
else
{
_totalRead += (int) newRequest.GetCacheFileSize();
_progress.SetStatus((int) _totalRead);
newRequest.Dispose();
}
}
}
}
done:
if (_jobQueue.Count == 0)
_bDone = true;
else
{
ApplicationMonikerRequest nextRequest = (ApplicationMonikerRequest) _jobQueue.Dequeue();
RequestState rsnext = new RequestState();
rsnext.Request = nextRequest;
IAsyncResult r = (IAsyncResult) nextRequest.BeginGetResponse(
new AsyncCallback(RespCallback), rsnext);
}
}
return;
}
//----------------------------------------------------------
// PurgeFiles
//----------------------------------------------------------
public void PurgeFiles()
{
DirectoryInfo di = new DirectoryInfo(_appStorePath);
di.Delete(true);
}
//----------------------------------------------------------
// GetNextRequest
//----------------------------------------------------------
public ApplicationMonikerRequest GetNextRequest(IAssemblyManifestImport ami)
{
FileType type;
Uri codebase;
DependentFileInfo dfi;
DependentAssemblyInfo dai;
// we can't do components for now.
if (ami.GetFileType() == FileType.ComponentManifest)
return null;
dfi = ami.GetNextDependentFileInfo();
if (dfi != null)
{
codebase = new Uri(_appBase, dfi["name"]);
type =FileType.RawFile;
}
else
{
// Don't follow component dependencies.
// if (ami.GetFileType() == FileType.ComponentManifest)
// return null;
dai = ami.GetNextDependentAssemblyInfo();
if (dai != null)
{
codebase = new Uri(_appBase, dai["codeBase"]);
type = FileType.ComponentManifest;
}
else
{
codebase = null;
type = FileType.Unknown;
}
}
if (codebase == null)
return null;
ApplicationMonikerRequest request =
(ApplicationMonikerRequest) ApplicationMonikerRequest.Create(codebase, _appBase, _appStorePath);
request.type = type;
return request;
}
}
//----------------------------------------------------------
// RequestState
//----------------------------------------------------------
class RequestState
{
const int BufferSize = 0x4000;
public byte[] BufferRead;
public ApplicationMonikerRequest Request;
public ApplicationMonikerStream ResponseStream;
//----------------------------------------------------------
// ctor
//----------------------------------------------------------
public RequestState()
{
BufferRead = new byte[BufferSize];
Request = null;
ResponseStream = null;
}
}
}