Alright before I start, I KNOW THERE IS A WINAPI FOR INIPARSING, I just wanted to do this for my own benefit.
Basically, this is just a really dummified class that *should* be very simple to use for anyone.
The only classes you need worry about are the following:
THE SOURCE CODE:Code:INIPair // <-- Defines a unique Key->Value combination INIGroup // <-- A Group holds a collection of INIPairs, group names are case sensitive and must be unique. INIReader // <-- A reader class that will parse an ini file. INIWriter // <-- A writer class to write a new ini file.
[highlight=C#]
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace IniParser
{
public class INIReader
{
public INIFile IniProperties { get; private set; }
public bool Parsed { get; private set; }
private string SelectedProperty { get; set; }
public INIReader(string fileLocation)
{
this.Parsed = File.Exists(fileLocation);
if (this.Parsed)
this.ReadFile(fileLocation);
}
public INIReader() : this("settings.ini") { }
private void ReadFile(string file)
{
this.IniProperties = new INIFile();
using (StreamReader sReader = new StreamReader(file))
{
string curLine = "";
while (!sReader.EndOfStream)
{
curLine = sReader.ReadLine();
if ( Regex.IsMatch(curLine.Trim(), @"^\[\w+]$") )
{
string property = GetBetween(curLine, "[", "]");
if (!IniProperties.ContainsKey(property))
IniProperties.Add(new INIGroup(property));
this.SelectedProperty = property;
}
else if (!string.IsNullOrEmpty(curLine.Trim()) && curLine.Contains('='))
{
string[] splits = curLine.Trim().Split('=');
if (splits.Length == 2 && !this.IniProperties[this.SelectedProperty].ContainsKey(splits[0].Trim()))
this.IniProperties[this.SelectedProperty].Add(new INIPair(splits[0].Trim(), splits[1].Trim()));
}
}
}
}
private string GetBetween(string subj, string p1, string p2)
{
int start = subj.IndexOf(p1) + p1.Length;
if (start == p1.Length - 1) { return ""; }
int end = subj.IndexOf(p2, start);
if (end == -1) { return ""; }
return subj.Substring(start, end - start);
}
}
public class INIFile : List<INIGroup>
{
public INIGroup this[string Key] { get { return this.itemAtKey(Key); } set { this.set_item(value, Key); }}
private void set_item(INIGroup val, string key)
{
INIGroup kVa = this[key];
kVa = val;
}
private INIGroup itemAtKey(string k)
{
foreach (INIGroup ini in this)
if (ini.GroupName == k) { return ini; }
throw new IndexOutOfRangeException("No group with the given key was found.");
}
public bool ContainsKey(string key)
{
foreach (INIGroup ini in this)
if (ini.GroupName == key) { return true; }
return false;
}
}
public class INIGroup : List<INIPair>
{
public string GroupName { get; set; }
public string this[string key] { get { return get_item(key); } set { set_item(value, key); } }
public string[] Values { get { return get_values(); } set { empty(); } }
private void empty() {}
private string[] get_values()
{
return this.Select(ip => ip.Value).ToArray();
}
private string get_item(string key)
{
return this.itemAtKey(key);
}
private string itemAtKey(string key)
{
foreach (INIPair pair in this)
{
if (pair.Key == key) { return pair.Value; }
}
throw new IndexOutOfRangeException("No group with the given key was found.");
}
private void set_item(string val, string key)
{
string temp = this.get_item(key);
temp = val;
}
public bool ContainsKey(string Key)
{
foreach (INIPair pair in this)
{
if (pair.Key == Key) { return true; }
}
return false;
}
public INIGroup(string groupName, INIPair[] pairs) : base()
{
this.AddRange(pairs);
this.GroupName = groupName;
}
public INIGroup(string groupName) : base()
{
this.GroupName = groupName;
}
public INIGroup(string groupName, INIPair pair) : this(groupName, new INIPair[] { pair }) { }
}
public struct INIPair
{
public string _key;
public string _value;
public string Key { get { return _key; } set { this._key = value; } }
public string Value { get { return _value; } set { this._value = value; } }
public INIPair(string key, string value)
{
this._key = key;
this._value = value;
}
}
public class INIWriter
{
public List<INIGroup> Groups { get; set; }
public string FileName { get; set; }
public INIWriter(INIGroup[] groups, string destFile)
{
this.Groups = new List<INIGroup>();
this.Groups.AddRange(groups);
this.FileName = destFile;
}
public bool WriteFile()
{
try
{
System.Text.StringBuilder sBuilder = new System.Text.StringBuilder();
for(int i = 0; i < this.Groups.Count; i++)
{
INIGroup group = this.Groups[i];
if (group.Count == 0 && i == this.Groups.Count - 1)
sBuilder.Append("[" + group.GroupName + "]");
else
sBuilder.AppendLine("[" + group.GroupName + "]");
foreach(INIPair pair in group)
{
sBuilder.AppendLine(pair.Key + "=" + pair.Value);
}
if ( i != this.Groups.Count - 1 ) sBuilder.AppendLine();
}
File.WriteAllText(this.FileName, sBuilder.ToString());
return true;
}
catch(Exception) { return false; }
}
}
}
[/highlight]
The hierarchy is basically as follows
Usage is simple (at least I think so). Because groupnames and INIPair keys are unique, it allows you to use fast indexing to access the groups you want.Code:INIFile is a collection of INIGroups Each INIGroup is a collection of INIPairs Each INIPair contains a Key and a Value
A simple reading method for the following INI File:
So, here's how to read it, and get a few values:Code:// settings.ini [OPTIONS] InjectAll=ON CloseOnInject=ON StealthMode=ON AutoInject=ON Delay=200 [PROCESS] Process=Engine [FILES] File1=C:\Users\Jason_2\Documents\Visual Studio 2008\Projects\eJect\eJect\bin\x86\Debug\IconExtraction.dll
[highlight=C#]
IniParser.INIReader iReader = new IniParser.INIReader("settings.ini"); //initialize the reader.
if (iReader.Parsed) //if the reading was successful
{
string AutoInjectValue = iReader.IniProperties["OPTIONS"]["AutoInject"] //ON
string ProcessValue = iReader.IniProperties["PROCESS"]["Process"] //Engine
string FileValue = iReader.IniProperties["FILES"]["File1"] //C:\Users\Jaso.....ebug\IconExtraction.dll
}
[/highlight]
Easy as pie. Now for writing:
[highlight=C#]
IniParser.INIGroup OPTIONS = new IniParser.INIGroup("OPTIONS"); //create the group
OPTIONS.Add(New IniParser.INIPair("AutoInject", "ON")); // add a pair
IniParser.INIGroup PROCESS = new IniParser.INIGroup("PROCESS");
PROCESS.Add(New IniParser.INIPair("Process", "Engine"));
IniParser.INIWriter iWriter = new IniParser.INIWriter(new INIGroup[] { OPTIONS, PROCESS }, "settings.ini");
iWriter.WriteFile(); //write the INI.
[/highlight]
See, nothing hard?
Comments, as always are appreciated.
Cheers,
Jason
You can win the rat race,Originally Posted by Jeremy S. Anderson
But you're still nothing but a fucking RAT.
++Latest Projects++
[Open Source] Injection Library
Simple PE Cipher
FilthyHooker - Simple Hooking Class
CLR Injector - Inject .NET dlls with ease
Simple Injection - An in-depth look
MPGH's .NET SDK
eJect - Simple Injector
Basic PE Explorer (BETA)
Jason (07-22-2011)
Gotta love retarded syntax highlighting ([, funny it works here when I copy and paste the garbage). Nice job as usual Jason, will make sure to use this in the future.
Donate:
BTC: 1GEny3y5tsYfw8E8A45upK6PKVAEcUDNv9
Handy Tools/Hacks:
Extreme Injector v3.7.3
A powerful and advanced injector in a simple GUI.
Can scramble DLLs on injection making them harder to detect and even make detected hacks work again!
Minion Since: 13th January 2011
Moderator Since: 6th May 2011
Global Moderator Since: 29th April 2012
Super User/Unknown Since: 23rd July 2013
'Game Hacking' Team Since: 30th July 2013
--My Art--
[Roxas - Pixel Art, WIP]
[Natsu - Drawn]
[Natsu - Coloured]
All drawings are coloured using Photoshop.
--Gifts--
[Kyle]