205 lines
5.3 KiB
C#
205 lines
5.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 class INFParser : ManifestParser
|
||
|
{
|
||
|
public override Hashtable Parse(string appName, string file, Hashtable elementTranslator)
|
||
|
{
|
||
|
Hashtable outTable = new Hashtable();
|
||
|
StreamReader ios = new StreamReader(file);
|
||
|
|
||
|
#region Parse INF File
|
||
|
ArrayList sections = new ArrayList();
|
||
|
INFSection curSection = null;
|
||
|
INFVersionSection versionSection = null;
|
||
|
INFStringSection strSection = null;
|
||
|
string curLine = ios.ReadLine();
|
||
|
while(curLine != null)
|
||
|
{
|
||
|
|
||
|
// get rid of the whitespace on both sides
|
||
|
curLine = curLine.Trim();
|
||
|
|
||
|
if (curLine.Equals(""))
|
||
|
{
|
||
|
curLine = ios.ReadLine();
|
||
|
continue;
|
||
|
}
|
||
|
// we don't like lines that start with control characters
|
||
|
if (curLine[0] < 32)
|
||
|
{
|
||
|
curLine = ios.ReadLine();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (curLine.StartsWith("#pragma"))
|
||
|
{
|
||
|
// I can't believe this is in an INF file!
|
||
|
curLine = ios.ReadLine();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (curLine.StartsWith("----"))
|
||
|
{
|
||
|
curLine = ios.ReadLine();
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
//Console.WriteLine(curLine);
|
||
|
if (INFSection.IsComment(curLine))
|
||
|
{
|
||
|
//Console.WriteLine("***Ignoring comment");
|
||
|
curLine = ios.ReadLine();
|
||
|
continue;
|
||
|
}
|
||
|
if (INFSection.IsSection(curLine))
|
||
|
{
|
||
|
//Console.WriteLine("***Found Section");
|
||
|
if (curSection != null)
|
||
|
{
|
||
|
sections.Add(curSection);
|
||
|
}
|
||
|
if (INFSection.IsStringSection(curLine))
|
||
|
{
|
||
|
//Console.WriteLine("***It's a Strings section");
|
||
|
|
||
|
curSection = new INFStringSection(curLine);
|
||
|
strSection = (INFStringSection)curSection;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (INFSection.IsVersionSection(curLine))
|
||
|
{
|
||
|
//Console.WriteLine("***It's a version section");
|
||
|
|
||
|
curSection = new INFVersionSection(curLine);
|
||
|
versionSection = (INFVersionSection)curSection;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
curSection = new INFSection(curLine);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
// I can only assume that the real INF parser just ignores
|
||
|
// everything that's not in a section, given what I've seen
|
||
|
// at the top of INF files so far
|
||
|
if (curSection != null)
|
||
|
{
|
||
|
//Console.WriteLine("***Adding Line to Section " + curSection.Name);
|
||
|
|
||
|
curSection.AddLine(curLine);
|
||
|
}
|
||
|
}
|
||
|
curLine = ios.ReadLine();
|
||
|
}
|
||
|
if (curSection != null)
|
||
|
{
|
||
|
sections.Add(curSection);
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
#region Replace Strings
|
||
|
//Debug.Assert(versionSection != null);
|
||
|
// make sure we have a string table somewhere
|
||
|
if (strSection != null)
|
||
|
{
|
||
|
|
||
|
// now grab the INFStringSection and pass it to each INFSection
|
||
|
// so they can update their strings to be correct
|
||
|
for(int i = 0; i < sections.Count; i++)
|
||
|
{
|
||
|
((INFSection)sections[i]).UpdateStrings(strSection);
|
||
|
}
|
||
|
}
|
||
|
#endregion
|
||
|
|
||
|
#region Record Registry Changes
|
||
|
|
||
|
// now that we've replaced the strings, we can safely
|
||
|
// discover all the Registry section lines
|
||
|
for(int i = 0; i < sections.Count; i++)
|
||
|
{
|
||
|
((INFSection)sections[i]).DiscoverRegistryLines();
|
||
|
}
|
||
|
|
||
|
// walk the sections again and accumulate all the AddReg and DelReg sections
|
||
|
Hashtable addRegSections = new Hashtable();
|
||
|
Hashtable delRegSections = new Hashtable();
|
||
|
for (int i = 0; i < sections.Count; i++)
|
||
|
{
|
||
|
((INFSection)sections[i]).GetAddRegSections(addRegSections);
|
||
|
((INFSection)sections[i]).GetDelRegSections(delRegSections);
|
||
|
}
|
||
|
|
||
|
for(int i = 0; i < sections.Count; i++)
|
||
|
{
|
||
|
string secName = ((INFSection)sections[i]).Name;
|
||
|
if (addRegSections.ContainsKey(secName) ||
|
||
|
delRegSections.ContainsKey(secName))
|
||
|
{
|
||
|
// now walk its lines and enter the registry values
|
||
|
ArrayList lines = ((INFSection)sections[i]).Lines;
|
||
|
for(int j = 0; j < lines.Count; j++)
|
||
|
{
|
||
|
string line = (string)lines[j];
|
||
|
if (line.Equals("")) continue;
|
||
|
string versionGUID = null;
|
||
|
if (versionSection != null)
|
||
|
{
|
||
|
versionGUID = versionSection.Guid;
|
||
|
}
|
||
|
string regKey = INFSection.GetRegKey(line, versionGUID);
|
||
|
if (regKey != null)
|
||
|
{
|
||
|
//Console.WriteLine("Got RegKey " + regKey);
|
||
|
string regValue = INFSection.GetRegValue(line);
|
||
|
// remove all but the innermost double-quote strings from this value
|
||
|
int removeCount = 0;
|
||
|
for(int k = 0; k < regValue.Length; k++)
|
||
|
{
|
||
|
if (regValue[k] == '"')
|
||
|
{
|
||
|
removeCount++;
|
||
|
}
|
||
|
}
|
||
|
if (removeCount > 0)
|
||
|
{
|
||
|
regValue = regValue.TrimStart(new char[] {'"'});
|
||
|
regValue = regValue.TrimEnd(new char[] {'"'});
|
||
|
regValue = "\"" + regValue + "\"";
|
||
|
}
|
||
|
|
||
|
//Console.WriteLine("Got RegValue " + regValue);
|
||
|
|
||
|
ManifestParser.addEntry(regKey, regValue, appName);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
#endregion
|
||
|
|
||
|
return outTable;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
}
|