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.

256 lines
8.3 KiB

  1. using System;
  2. using System.Collections;
  3. using System.IO;
  4. using System.Text;
  5. using System.Security.Cryptography;
  6. using System.Xml;
  7. namespace Microsoft.Fusion.ADF
  8. {
  9. public class MGDepTracker : IFileOperator
  10. {
  11. static string MSKEY1 = "b77a5c561934e089";
  12. static string MSKEY2 = "b03f5f7f11d50a3a";
  13. static string AVALONKEY = "a29c01bbd4e39ac5";
  14. Hashtable fileTable;
  15. ArrayList appAssms, appModules;
  16. public MGDepTracker()
  17. {
  18. fileTable = new Hashtable();
  19. appAssms = new ArrayList();
  20. appModules = new ArrayList();
  21. }
  22. /*
  23. public static byte[] ComputePublicKeyHash(byte[] data)
  24. {
  25. SHA1 sha = new SHA1Managed();
  26. byte[] result = sha.ComputeHash(data);
  27. return result;
  28. }
  29. */
  30. public static string ComputeFileHash(FileInfo fInf)
  31. {
  32. SHA1 sha = new SHA1Managed();
  33. byte[] byteHash = sha.ComputeHash(fInf.OpenRead());
  34. return Util.ByteArrToString(byteHash, null);
  35. }
  36. public static bool IsPlatform(string key)
  37. {
  38. bool retVal = false;
  39. if(key == null) return false;
  40. if(key.ToLower().Equals(MSKEY1) || key.ToLower().Equals(MSKEY2) || key.ToLower().Equals(AVALONKEY)) retVal = true;
  41. return retVal;
  42. }
  43. public void DumpData()
  44. {
  45. foreach(Object obj in appAssms)
  46. {
  47. MGTrackerNode tempNode = (MGTrackerNode) obj;
  48. Console.WriteLine("Assembly " + tempNode.assmName + "; version " + tempNode.nVers);
  49. if(!tempNode.isConfNode) Console.WriteLine("\tThis assembly is referenced by " + tempNode.depAssmName + " but isn't there");
  50. Console.WriteLine("Size: " + tempNode.size + "; Total Size: " + tempNode.totalSize);
  51. }
  52. Console.WriteLine();
  53. foreach(Object obj in appModules)
  54. {
  55. MGTrackerNode tempNode = (MGTrackerNode) obj;
  56. Console.WriteLine("File " + tempNode.installPath + "; depends on " + tempNode.depAssmName);
  57. Console.WriteLine("Size: " + tempNode.size);
  58. }
  59. }
  60. public void VerifyDependencies()
  61. {
  62. foreach(Object obj in appAssms)
  63. {
  64. MGTrackerNode tempNode = (MGTrackerNode) obj;
  65. if(!tempNode.isConfNode)
  66. throw new MGDependencyException(tempNode.assmName + ", dependency of " + tempNode.depAssmName + ", is missing.");
  67. }
  68. foreach(Object obj in appModules)
  69. {
  70. MGTrackerNode tempNode = (MGTrackerNode) obj;
  71. if(!tempNode.isConfNode)
  72. throw new MGDependencyException(tempNode.installPath + ", dependency of " + tempNode.depAssmName + ", is missing.");
  73. }
  74. }
  75. public void CalculateSizes()
  76. {
  77. foreach(Object obj in appAssms)
  78. {
  79. MGTrackerNode tempNode = (MGTrackerNode) obj;
  80. tempNode.totalSize = tempNode.size;
  81. }
  82. foreach(Object obj in appModules)
  83. {
  84. MGTrackerNode tempNode = (MGTrackerNode) obj;
  85. if(!tempNode.depAssmKey.Equals(""))
  86. {
  87. MGTrackerNode tempNode2 = (MGTrackerNode) fileTable[tempNode.depAssmKey];
  88. tempNode2.totalSize += tempNode.size;
  89. }
  90. }
  91. }
  92. public void FileXmlOutput(XmlTextWriter xtw)
  93. {
  94. foreach(Object obj in appModules)
  95. {
  96. MGTrackerNode tempNode = (MGTrackerNode) obj;
  97. if(tempNode.depAssmKey.Equals(""))
  98. {
  99. xtw.WriteStartElement("file");
  100. xtw.WriteAttributeString("name", tempNode.installPath);
  101. xtw.WriteAttributeString("hash", tempNode.calcHashCode);
  102. xtw.WriteAttributeString("size", tempNode.size.ToString());
  103. xtw.WriteEndElement();
  104. }
  105. }
  106. }
  107. public void AssmXmlOutput(XmlTextWriter xtw) // this is always inside a dependency block
  108. {
  109. foreach(Object obj in appAssms)
  110. {
  111. MGTrackerNode tempNode = (MGTrackerNode) obj;
  112. xtw.WriteStartElement("dependentAssembly");
  113. xtw.WriteStartElement("assemblyIdentity");
  114. xtw.WriteAttributeString("name", tempNode.assmName);
  115. xtw.WriteAttributeString("version", tempNode.nVers.ToString());
  116. xtw.WriteAttributeString("publicKeyToken", tempNode.publicKeyToken);
  117. xtw.WriteAttributeString("processorArchitecture", tempNode.procArch);
  118. xtw.WriteAttributeString("language", tempNode.lang);
  119. xtw.WriteEndElement();
  120. xtw.WriteStartElement("install");
  121. xtw.WriteAttributeString("codebase", tempNode.installPath);
  122. xtw.WriteAttributeString("size", tempNode.totalSize.ToString());
  123. xtw.WriteEndElement();
  124. xtw.WriteEndElement();
  125. }
  126. }
  127. void IFileOperator.ProcessDirectory(string startDir, string relPathDir)
  128. {
  129. // doesn't do anything here
  130. }
  131. void IFileOperator.ProcessFile(string startDir, string relPathDir, string fileName)
  132. {
  133. IAssemblyManifestImport currAssm = null;
  134. AssemblyIdentity assmID = null;
  135. DependentAssemblyInfo[] depAssmInfoArr = null;
  136. DependentFileInfo[] depFileInfoArr = null;
  137. MGTrackerNode tempNode;
  138. string relPath = Path.Combine(relPathDir, fileName);
  139. string absPath = Path.Combine(startDir, relPath);
  140. FileInfo fInf = new FileInfo(absPath);
  141. //Console.Write("Processing " + absPath + "... ");
  142. try
  143. {
  144. currAssm = DefaultAssemblyManifestImporter.GetAssemblyManifestImport(absPath);
  145. assmID = currAssm.GetAssemblyIdentity();
  146. depAssmInfoArr = currAssm.GetDependentAssemblyInfo();
  147. depFileInfoArr = currAssm.GetDependentFileInfo();
  148. }
  149. catch (BadImageFormatException bife)
  150. {
  151. // This file is a module; update hash table
  152. tempNode = (MGTrackerNode) fileTable[relPath];
  153. if(tempNode == null)
  154. {
  155. tempNode = new MGTrackerNode();
  156. fileTable[relPath] = tempNode;
  157. tempNode.hashKey = relPath;
  158. tempNode.installPath = relPath;
  159. appModules.Add(tempNode);
  160. }
  161. tempNode.isConfNode = true;
  162. tempNode.calcHashCode = ComputeFileHash(fInf);
  163. tempNode.size = fInf.Length;
  164. // Finished updating module entry
  165. }
  166. if(currAssm != null)
  167. {
  168. // This file is an assembly; update hash table
  169. if(!IsPlatform(assmID.PublicKeyTokenString)) // completely ignore if it's part of a platform
  170. {
  171. tempNode = (MGTrackerNode) fileTable[assmID.FullName];
  172. if(tempNode == null)
  173. {
  174. tempNode = new MGTrackerNode();
  175. fileTable[assmID.FullName] = tempNode;
  176. tempNode.hashKey = assmID.FullName;
  177. tempNode.assmName = assmID.Name;
  178. tempNode.isAssm = true;
  179. tempNode.nVers = assmID.Vers;
  180. tempNode.publicKeyToken = assmID.PublicKeyTokenString;
  181. appAssms.Add(tempNode);
  182. }
  183. tempNode.isConfNode = true;
  184. tempNode.installPath = relPath;
  185. tempNode.size = fInf.Length;
  186. // Finished updating assembly entry
  187. // Now we process assembly dependencies
  188. //depAssmInfoArr = currAssm.GetDependentAssemblyInfo();
  189. foreach(DependentAssemblyInfo depAssmInfo in depAssmInfoArr)
  190. {
  191. AssemblyIdentity depAssmID = depAssmInfo.AssmID;
  192. if(!IsPlatform(depAssmID.PublicKeyTokenString)) // maybe call this "IsPlatform", "CheckPlatform"
  193. {
  194. tempNode = (MGTrackerNode) fileTable[depAssmID.FullName];
  195. if(tempNode == null)
  196. {
  197. tempNode = new MGTrackerNode();
  198. fileTable[depAssmID.FullName] = tempNode;
  199. tempNode.hashKey = depAssmID.FullName;
  200. tempNode.assmName = depAssmID.Name;
  201. tempNode.isAssm = true;
  202. tempNode.nVers = depAssmID.Vers;
  203. tempNode.publicKeyToken = depAssmID.PublicKeyTokenString;
  204. appAssms.Add(tempNode);
  205. }
  206. tempNode.depAssmKey = assmID.FullName;
  207. tempNode.depAssmName = assmID.Name;
  208. }
  209. }
  210. // Done with assembly dependencies
  211. // Now we process file dependencies
  212. //depFileInfoArr = currAssm.GetDependentFileInfo();
  213. foreach(DependentFileInfo depFileInfo in depFileInfoArr)
  214. {
  215. // For the hashtable, we actually need the relative path from the application root to the file,
  216. // because we want this file entry's hash key to match the file entry that is obtained by discovering
  217. // the actual location of the file
  218. string fileHashKey = Path.Combine(relPathDir, depFileInfo.Name);
  219. tempNode = (MGTrackerNode) fileTable[fileHashKey];
  220. if(tempNode == null)
  221. {
  222. tempNode = new MGTrackerNode();
  223. fileTable[fileHashKey] = tempNode;
  224. tempNode.hashKey = fileHashKey;
  225. tempNode.installPath = fileHashKey;
  226. appModules.Add(tempNode);
  227. }
  228. tempNode.depAssmKey = assmID.FullName;
  229. tempNode.depAssmName = assmID.Name;
  230. }
  231. // Done with file dependencies
  232. }
  233. }
  234. //Console.WriteLine("done");
  235. }
  236. }
  237. }