singrdk/base/Windows/AppReader/ManifestParser.cs

249 lines
7.3 KiB
C#
Raw Normal View History

2008-03-05 09:52:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// 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";
}
}
}