249 lines
7.3 KiB
C#
249 lines
7.3 KiB
C#
///////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Microsoft Research Singularity
|
|
//
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
namespace ManifestReader
|
|
{
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections;
|
|
using System.Xml;
|
|
using System.Diagnostics;
|
|
|
|
public abstract class ManifestParser
|
|
{
|
|
public ManifestParser()
|
|
{
|
|
// do nothing for now
|
|
}
|
|
|
|
public static Hashtable registryConflictTable = new Hashtable();
|
|
public static Hashtable provideFileTable = new Hashtable();
|
|
public static Hashtable requiresFileTable = new Hashtable();
|
|
public static Hashtable appFileTable = new Hashtable();
|
|
public static Hashtable appRegistryTable = new Hashtable();
|
|
public static Hashtable nameTable = new Hashtable();
|
|
public static Hashtable fileTypeTable = new Hashtable();
|
|
public static Hashtable customActionsTable = new Hashtable();
|
|
public static void addEntry(string path, string val, string appName)
|
|
{
|
|
if (!registryConflictTable.ContainsKey(path))
|
|
{
|
|
registryConflictTable[path] = new ArrayList();
|
|
}
|
|
Pair tempP = new Pair(val, appName);
|
|
((ArrayList)(registryConflictTable[path])).Add(tempP);
|
|
|
|
// also compute all the prefixes and put them in the appRegistryTable
|
|
if (!appRegistryTable.ContainsKey(appName))
|
|
{
|
|
appRegistryTable[appName] = new Hashtable();
|
|
}
|
|
string prefix = "";
|
|
string[] pathElts = path.Split(new char[] {'\\'}, 40);
|
|
for(int i = 0; i < pathElts.Length; i++)
|
|
{
|
|
prefix += "\\" + pathElts[i];
|
|
if (!((Hashtable)appRegistryTable[appName]).ContainsKey(prefix))
|
|
{
|
|
((Hashtable)appRegistryTable[appName])[prefix] = 1;
|
|
}
|
|
else
|
|
{
|
|
((Hashtable)appRegistryTable[appName])[prefix] = (int)((Hashtable)appRegistryTable[appName])[prefix] + 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void addCustomAction(string appName)
|
|
{
|
|
if (!customActionsTable.ContainsKey(appName))
|
|
{
|
|
customActionsTable[appName] = 0;
|
|
}
|
|
customActionsTable[appName] = (int)customActionsTable[appName] + 1;
|
|
}
|
|
|
|
public static void addProvidesFile(string path, string filename, string appName)
|
|
{
|
|
|
|
string file = path + "\\" + filename;
|
|
if (path.Equals("\\"))
|
|
{
|
|
file = "\\" + filename;
|
|
}
|
|
// grab off the suffix and put it in the file extension table
|
|
string[] fileComponents = filename.Split(new char[] {'.'}, 50);
|
|
string extension = fileComponents[fileComponents.Length - 1].ToLower();
|
|
if (fileComponents.Length > 1)
|
|
{
|
|
// then we probably have a real file extension (there's at least on '.')
|
|
if (!fileTypeTable.ContainsKey(appName))
|
|
{
|
|
// this hash maps file types to the count for this manifest
|
|
fileTypeTable[appName] = new Hashtable();
|
|
}
|
|
|
|
if (!((Hashtable)fileTypeTable[appName]).ContainsKey(extension))
|
|
{
|
|
((Hashtable)fileTypeTable[appName])[extension] = 0;
|
|
}
|
|
|
|
((Hashtable)fileTypeTable[appName])[extension] = (int)((Hashtable)fileTypeTable[appName])[extension] + 1;
|
|
}
|
|
|
|
if (!provideFileTable.ContainsKey(file))
|
|
{
|
|
provideFileTable[file] = new ArrayList();
|
|
}
|
|
((ArrayList)provideFileTable[file]).Add(appName);
|
|
|
|
|
|
if (!appFileTable.ContainsKey(appName))
|
|
{
|
|
appFileTable[appName] = new Hashtable();
|
|
}
|
|
|
|
if (!((Hashtable)appFileTable[appName]).ContainsKey(file))
|
|
{
|
|
((Hashtable)appFileTable[appName])[file] = 1;
|
|
}
|
|
else
|
|
{
|
|
((Hashtable)appFileTable[appName])[file] = (int)((Hashtable)appFileTable[appName])[file] + 1;
|
|
}
|
|
return;
|
|
}
|
|
|
|
public static void addRequiresFile(string path, string filename, string appName)
|
|
{
|
|
string file = path + "\\" + filename;
|
|
|
|
if (!requiresFileTable.ContainsKey(file))
|
|
{
|
|
// I don't care if I end up adding it twice: I'll sort it out in the end
|
|
requiresFileTable[file] = new ArrayList();
|
|
}
|
|
((ArrayList)requiresFileTable[file]).Add(appName);
|
|
return;
|
|
}
|
|
|
|
public static void setName(string appPathName, string appTrueName)
|
|
{
|
|
nameTable[appPathName] = appTrueName;
|
|
return;
|
|
}
|
|
|
|
public abstract Hashtable Parse(string appName, string file, Hashtable elementTranslator);
|
|
|
|
protected bool isCodeSuffix(string suffix)
|
|
{
|
|
return suffix.Equals("exe") ||
|
|
suffix.Equals("dll") ||
|
|
suffix.Equals("com") ||
|
|
suffix.Equals("bin") ||
|
|
suffix.Equals("ocx") ||
|
|
suffix.Equals("sys");
|
|
}
|
|
|
|
protected bool isImageSuffix(string suffix)
|
|
{
|
|
return suffix.Equals("avi") ||
|
|
suffix.Equals("bmp") ||
|
|
suffix.Equals("gif") ||
|
|
suffix.Equals("tif") ||
|
|
suffix.Equals("xbm") ||
|
|
suffix.Equals("jpg") ||
|
|
suffix.Equals("ico");
|
|
}
|
|
|
|
protected bool isFontSuffix(string suffix)
|
|
{
|
|
return suffix.Equals("ttf") ||
|
|
suffix.Equals("fon");
|
|
}
|
|
|
|
protected string getCodeType(string suffix)
|
|
{
|
|
if (suffix.Equals("exe") ||
|
|
suffix.Equals("com"))
|
|
{
|
|
return "Code NonLinked";
|
|
}
|
|
else if (suffix.Equals("ocx") ||
|
|
suffix.Equals("sys"))
|
|
{
|
|
return "Code Linked Dynamic";
|
|
}
|
|
// despite the name, if it's a DLL, we can't tell
|
|
else if (suffix.Equals("dll"))
|
|
{
|
|
return "Code";
|
|
}
|
|
return "Code";
|
|
}
|
|
|
|
|
|
// grab the Hashtable that will give us the paths for Manifest elements
|
|
public static Hashtable GetManifestHashtable(string filename)
|
|
{
|
|
StreamReader ios = new StreamReader(filename);
|
|
Hashtable outTable = new Hashtable();
|
|
string curLine;
|
|
while((curLine = ios.ReadLine()) != null)
|
|
{
|
|
// take the first word, and leave the rest
|
|
int firstSpaceIndex = curLine.IndexOf(' ');
|
|
string first = curLine.Substring(0, firstSpaceIndex);
|
|
//"Got first = ***{0}***", first);
|
|
string rest = curLine.Substring(firstSpaceIndex + 1);
|
|
//"Got rest = ***{0}***", rest);
|
|
outTable[first] = rest;
|
|
}
|
|
return outTable;
|
|
}
|
|
|
|
protected string parseRegistry(string fullpath, string val, string file)
|
|
{
|
|
// just add this Registry entry to the Hashtable
|
|
ManifestParser.addEntry(fullpath, val, file);
|
|
|
|
// split off the first two elements from the path
|
|
string[] components = fullpath.Split(new char[] {'\\'}, 10);
|
|
string rootname = components[0];
|
|
string toplevelname = components[1];
|
|
if (rootname.Equals("HKCR"))
|
|
{
|
|
if (toplevelname.Equals("CLSID") ||
|
|
toplevelname.Equals("Interface"))
|
|
{
|
|
return "Code NonLinked";
|
|
}
|
|
}
|
|
else if (rootname.Equals("HKCU"))
|
|
{
|
|
if (toplevelname.Equals("Printers"))
|
|
{
|
|
return "Code NonLinked";
|
|
}
|
|
}
|
|
else if (rootname.Equals("HKLM"))
|
|
{
|
|
if (toplevelname.Equals("HARDWARE"))
|
|
{
|
|
return "Hardware";
|
|
}
|
|
else if (toplevelname.Equals("SYSTEM"))
|
|
{
|
|
return "Data Config Settings Permanent";
|
|
}
|
|
}
|
|
return "Data Config Settings";
|
|
}
|
|
}
|
|
}
|