Source code of Windows XP (NT5)
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.

230 lines
7.7 KiB

  1. /*=============================================================================
  2. **
  3. ** Class: ASMExecute
  4. **
  5. ** Purpose: Used to setup the correct hosting environment before executing an
  6. ** assembly
  7. **
  8. ** Date: 2:24 PM 10/20/2000
  9. **
  10. ** Copyright (c) Microsoft, 1999-2000
  11. **
  12. =============================================================================*/
  13. namespace ComHost {
  14. using System;
  15. using System.Text;
  16. using System.Reflection;
  17. using System.Globalization;
  18. using System.Runtime.Remoting;
  19. using System.Security;
  20. using System.Security.Policy;
  21. using System.Security.Permissions;
  22. //using IIEHost;
  23. public class AsmExecute : MarshalByRefObject
  24. {
  25. public static readonly int SECURITY_NONE = 0x00;
  26. public static readonly int SECURITY_ZONE = 0x01;
  27. public static readonly int SECURITY_SITE = 0x02;
  28. public void Execute(string codebase, string flags)
  29. {
  30. string[] args = {codebase, flags};
  31. Process(args);
  32. }
  33. public void Execute(string codebase, string flags, string evidence)
  34. {
  35. string[] args = {codebase, flags, evidence};
  36. Process(args);
  37. }
  38. public void Execute(string codebase, string flags, string evidence1, string evidence2, string evidence2url)
  39. {
  40. string[] args = {codebase, flags, evidence1, evidence2, evidence2url};
  41. Process(args);
  42. }
  43. // Arguments: Codebase, flags, zone, uniqueid, siteurl
  44. // If the flags indicate zone then a zone must be provided.
  45. // If the flags indicate a site then a uniqueid must be provided
  46. //static void Main(string[] args)
  47. private void Process(string[] args)
  48. {
  49. if(args == null || args.Length < 2)
  50. throw new ArgumentException();
  51. int index = 0;
  52. string file = args[index++];
  53. if(file == null)
  54. throw new ArgumentException();
  55. // Find the URL of the executable. For now we assume the
  56. // form to be http://blah/... with forward slashes. This
  57. // need to be update.
  58. // Note: aso works w/ '\' as in file paths
  59. string URL = null;
  60. string Configuration = null;
  61. int k = file.LastIndexOf('/');
  62. if(k <= 0)
  63. {
  64. k = file.LastIndexOf('\\');
  65. if(k == 0)
  66. {
  67. URL = file;
  68. Configuration = file;
  69. }
  70. }
  71. if(k != 0)
  72. {
  73. // if k is still < 0 at this point, URL should be an empty string
  74. // BUGBUG: should URL be null instead??
  75. URL = file.Substring(0,k+1);
  76. if(k+1 < file.Length)
  77. Configuration = file.Substring(k+1);
  78. }
  79. // BUGBUG: should URL be the source of the code, not local?
  80. Console.WriteLine("URL- {0}", URL);
  81. // Build up the configuration File name
  82. if(Configuration != null)
  83. {
  84. k = Configuration.LastIndexOf('.');
  85. StringBuilder bld = new StringBuilder();
  86. if(k > 0)
  87. {
  88. bld.Append(Configuration.Substring(0,k));
  89. bld.Append(".cfg");
  90. }
  91. else
  92. {
  93. bld.Append(Configuration);
  94. bld.Append(".cfg");
  95. }
  96. Configuration = bld.ToString();
  97. }
  98. Console.WriteLine("Config- {0}", Configuration);
  99. // Get the flags
  100. // 0x1 we have Zone
  101. // 0x2 we have a unique id.
  102. int dwFlag = Int32.Parse(args[index++], NumberStyles.HexNumber);//CultureInfo.InvariantCulture);
  103. string friendlyName = GetSiteName(file);
  104. Console.WriteLine("SiteName- {0}", friendlyName);
  105. Evidence documentSecurity = null;
  106. int size = 0;
  107. if((dwFlag & SECURITY_ZONE) != 0)
  108. size++;
  109. if((dwFlag & SECURITY_SITE) != 0)
  110. size++;
  111. if(size != 0)
  112. documentSecurity = new Evidence();
  113. if((dwFlag & SECURITY_ZONE) != 0)
  114. {
  115. if(index == args.Length)
  116. throw new ArgumentException();
  117. int zone = Int32.Parse(args[index++], NumberStyles.HexNumber);//, CultureInfo.InvariantCulture);
  118. documentSecurity.AddHost( new Zone((System.Security.SecurityZone)zone) );
  119. }
  120. if((dwFlag & SECURITY_SITE) != 0)
  121. {
  122. if(index == args.Length-1)
  123. throw new ArgumentException();
  124. byte[] uniqueId = DecodeDomainId(args[index++]);
  125. documentSecurity.AddHost( new Site(uniqueId, args[index]) );//file) ); uses the url instead
  126. }
  127. AppDomain adProxy = AppDomain.CreateDomain(friendlyName, documentSecurity, null);
  128. // if(adProxy != null)
  129. // {
  130. adProxy.SetData(AppDomainFlags.ApplicationBase, URL);
  131. adProxy.SetData(AppDomainFlags.PrivateBinPath, "bin");
  132. if(Configuration != null)
  133. {
  134. adProxy.SetData(AppDomainFlags.Configuration, Configuration);
  135. }
  136. string asmname = Assembly.GetExecutingAssembly().Location;
  137. Console.WriteLine("AsmName- {0}", asmname);
  138. Console.WriteLine("\n========");
  139. // Use remoting. Otherwise asm will be loaded both in current and the new AppDomain
  140. // ... as explained by URT ppl
  141. // asmexec.dll must be found on path (CorPath?) for this to work.
  142. ObjectHandle handle = adProxy.CreateInstanceFrom(asmname, "ComHost.AsmExecute");
  143. if (handle != null)
  144. {
  145. AsmExecute execproxy = (AsmExecute)handle.Unwrap();
  146. if (execproxy != null)
  147. execproxy.RunExecute(file, documentSecurity);
  148. }
  149. Console.WriteLine("\n========");
  150. }
  151. private void RunExecute(string file, Evidence evidence)
  152. {
  153. new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Assert();
  154. AppDomain.CurrentDomain.ExecuteAssembly(file, evidence);
  155. }
  156. private static int ConvertHexDigit(char val)
  157. {
  158. if (val <= '9') return (val - '0');
  159. return ((val - 'A') + 10);
  160. }
  161. public static byte[] DecodeDomainId(string hexString)
  162. {
  163. byte[] sArray = new byte[(hexString.Length / 2)];
  164. int digit;
  165. int rawdigit;
  166. for (int i = 0, j = 0; i < hexString.Length; i += 2, j++) {
  167. digit = ConvertHexDigit(hexString[i]);
  168. rawdigit = ConvertHexDigit(hexString[i+1]);
  169. sArray[j] = (byte) (digit | (rawdigit << 4));
  170. }
  171. return(sArray);
  172. }
  173. public static string GetSiteName(string pURL)
  174. {
  175. // BUGBUG: this does not work w/ UNC or file:// (?)
  176. string siteName = null;
  177. if(pURL != null) {
  178. int j = pURL.IndexOf(':');
  179. // If there is a protocal remove it. In a URL of the form
  180. // yyyy://xxxx/zzzz where yyyy is the protocal, xxxx is
  181. // the site and zzzz is extra we want to get xxxx.
  182. if(j != -1 &&
  183. j+3 < pURL.Length &&
  184. pURL[j+1] == '/' &&
  185. pURL[j+2] == '/')
  186. {
  187. j+=3;
  188. // Remove characters after the
  189. // next /.
  190. int i = pURL.IndexOf('/',j);
  191. if(i > -1)
  192. siteName = pURL.Substring(j,i-j);
  193. else
  194. siteName = pURL.Substring(j);
  195. }
  196. if(siteName == null)
  197. siteName = pURL;
  198. }
  199. return siteName;
  200. }
  201. }
  202. }