How to determine the default browser with C#? - c#

I have the following code in C# .NET Core Windows 10:
public string getBrowser()
{
string browserName = "iexplore.exe";
using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(#"\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice"))
{
if (userChoiceKey != null)
{
object progIdValue = userChoiceKey.GetValue("Progid");
if (progIdValue != null)
{
if (progIdValue.ToString().ToLower().Contains("chrome"))
browserName = "chrome.exe";
else if (progIdValue.ToString().ToLower().Contains("firefox"))
browserName = "firefox.exe";
else if (progIdValue.ToString().ToLower().Contains("opera"))
browserName = "opera.exe";
}
}
}
return browserName;
}
The problem is that
userChoiceKey
is always null.
I practically copy paste the path from the registry Computer\HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\Shell\Associations\UrlAssociations\https\UserChoice
And still not working.
Any help will be highly appreciated.
Thanks in advance!

Try this:
internal string GetSystemDefaultBrowser()
{
string name = string.Empty;
RegistryKey regKey = null;
try
{
var regDefault = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\FileExts\\.htm\\UserChoice", false);
var stringDefault = regDefault.GetValue("ProgId");
regKey = Registry.ClassesRoot.OpenSubKey(stringDefault + "\\shell\\open\\command", false);
name = regKey.GetValue(null).ToString().ToLower().Replace("" + (char)34, "");
if (!name.EndsWith("exe"))
name = name.Substring(0, name.LastIndexOf(".exe") + 4);
}
catch (Exception ex)
{
name = string.Format("ERROR: An exception of type: {0} occurred in method: {1} in the following module: {2}", ex.GetType(), ex.TargetSite, this.GetType());
}
finally
{
if (regKey != null)
regKey.Close();
}
return name;
}

Related

default class for an outlook item(specificaly a calendar)

Hi have been reading about form regions for the last week.I finally managed to create a new interacting form using windows controls (i deprecated forms with vbscript).In the end though i have to associate the new seperate form with a specific calendar from c# code...
but let's get to code...This is how i did it using outlook-vbscript forms.(using ofts):
private bool CreateCustomCalendar(string registryname, string newCalendarName, string outlookformpathandfilename)
{
app = this.Application;
Outlook.MAPIFolder primaryCalendar = (Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderCalendar);
bool needFolder = true;
if (debugmode) writer.WriteToLog("RootCalendar :" + primaryCalendar.Name + " found");
Outlook.MAPIFolder personalCalendar = primaryCalendar
.Folders.Add(newCalendarName,
Outlook.OlDefaultFolders.olFolderCalendar);
personalCalendar.Name = newCalendarName;
if (debugmode) writer.WriteToLog("Creating Calendar stage1 complete");
//Access new calendar by its name that has the habit to append this computer only
bool notfound1 = true; bool notfound2 = true;
try
{
string mName = primaryCalendar.Folders[newCalendarName].Name;
if (debugmode) writer.WriteToLog("calendar accesible by name:" + mName);
notfound1 = false;
}
catch (SystemException sex)
{
throw;
}
Outlook.MAPIFolder setcalendar = primaryCalendar.Folders[newCalendarName];
if (debugmode) writer.WriteToLog("calendar is set");
PublishFormToPersonalFormsLibrary(setcalendar, outlookformpathandfilename, registryname, registryname, registryname, registryname + "version 1.0.0.1", "1.0.0.1", Application);
if (debugmode) writer.WriteToLog("Creating Calendar stage2 complete");
SetFolderDefaultForm_forappointments(setcalendar, "IPM.Appointment." + registryname, newCalendarName);
if (debugmode) writer.WriteToLog("Creating Calendar stage3 complete");
return needFolder;
}
void SetFolderDefaultForm_forappointments(Outlook.MAPIFolder fld, string msgClass, string displayname)
{
Outlook.PropertyAccessor objPA = fld.PropertyAccessor;
string strBaseType;
string strMsg;
int intLoc;
bool blnBadForm;
int i;
string PR_DEF_POST_MSGCLASS =
"http://schemas.microsoft.com/mapi/proptag/0x36E5001E";
string PR_DEF_POST_DISPLAYNAME =
"http://schemas.microsoft.com/mapi/proptag/0x36E6001E";
string[] arrSchema = { PR_DEF_POST_MSGCLASS, PR_DEF_POST_DISPLAYNAME };
string[] arrValues = { msgClass, displayname };
string[] arrErrors;
if (debugmode) writer.WriteToLog("prepared for setting default item");
try
{
objPA = fld.PropertyAccessor;
objPA.SetProperty(PR_DEF_POST_MSGCLASS, msgClass);
objPA.SetProperty(PR_DEF_POST_DISPLAYNAME, displayname);
if (debugmode) writer.WriteToLog("default folder set");
// arrErrors = objPA.SetProperties(arrSchema, arrValues);
}
catch (SystemException sex)
{
Console.WriteLine("This is catch with system exception : {0}", sex.ToString());
}
}
public void PublishFormToPersonalFormsLibrary(Outlook.MAPIFolder calendarfolder, string oftFilePath, string messageClass, string name, string displayName, string description, string version, Outlook.Application application)
{
object missing = System.Reflection.Missing.Value;
string existingVersion = "";
// try to create an existing Instance of the Form to check the current installed Version
try
{
// create atemplatefolder object
Outlook.MAPIFolder templateFolder = application.Session.GetDefaultFolder(Microsoft.Office.Interop.Outlook.OlDefaultFolders.olFolderDrafts);
if (debugmode) writer.WriteToLog("templateFolder is set");
// we add our new object here
object existingItem = templateFolder.Items.Add(messageClass);
if (debugmode) writer.WriteToLog("added form " + messageClass + " as templates");
// did we installed the form
if (existingItem != null)
{
// yes, we did it before
// get the formdescription with latebinding
Type existingItemType = existingItem.GetType();
Outlook.FormDescription existingFormDescription = (Outlook.FormDescription)existingItemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, existingItem, null);
if (debugmode) writer.WriteToLog("formdescription allocated to existingformdescription");
// get the installed version
existingVersion = existingFormDescription.Version;
// discard the temporary item
object[] args = { Outlook.OlInspectorClose.olDiscard };
existingItemType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, existingItem, args);
if (debugmode) writer.WriteToLog("GarbageCollection");
}
}
catch (System.Exception ex)
{
}
// if the existing Version is equal, no need for publishing the form
// if (version == existingVersion) return;
// check, if the templatefile exists
if (!System.IO.File.Exists(oftFilePath)) throw new System.IO.FileNotFoundException("Form template could not be found!", oftFilePath);
// create the item from TemplateFile
object item = application.CreateItemFromTemplate(oftFilePath, missing);
if (debugmode) writer.WriteToLog("created item from template");
// get the FormDescription Property using LateBinding
Type itemType = item.GetType();
Outlook.FormDescription formDescription = (Outlook.FormDescription)itemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, item, null);
// Apply some Parameters to the Formdescription
formDescription.Name = name;
formDescription.DisplayName = displayName;
formDescription.Category = "uncategorized";
formDescription.Comment = description;
formDescription.Version = version;
if (debugmode) writer.WriteToLog("Set custom form and its properties");
// Publish Form to Personal Froms Library
//formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olPersonalRegistry );
formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olFolderRegistry, calendarfolder);
if (debugmode) writer.WriteToLog("associating complete");
}
the question is how to do it with form-regions(using .ofs)
any solutions\documentation would be welcomed.
Many thnx to the creators of stack-overflow for this great resource and all developers that altruistically contribute to our problems
I finally did it!!! the replacement code for outlook.addin item goes like this:
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Outlook.Folder taskList =Application.Session.GetDefaultFolder(
Outlook.OlDefaultFolders.olFolderTasks)
as Outlook.Folder;
Outlook.TaskItem taskItem = taskList.Items.Add(
"IPM.Task.twoformMssges") as Outlook.TaskItem;
taskItem.Subject = "IPM.Task.twoformMssges Created On " +
System.DateTime.Now.ToLongDateString();
taskItem.Save();
Outlook.MAPIFolder primarytaskfolder = (Outlook.MAPIFolder)
this.Application.ActiveExplorer().Session.GetDefaultFolder
(Outlook.OlDefaultFolders.olFolderTasks);
Outlook.MAPIFolder settaskfolder = primarytaskfolder.Folders["testassociation"];
Outlook.Application app = this.Application;
string formpropstring= "twotabs";
// PublishFormToPersonalFormsLibrary(taskItem,settaskfolder, "c:\\" , "IPM.Task.twoformMssges",registryname, registryname,registryname + "version 0.0.0.1", "0.0.0.1", Application);
object missing = System.Reflection.Missing.Value;
string existingVersion = "";
try
{
if (taskItem != null)
{
Type existingItemType = taskItem.GetType();
Outlook.FormDescription existingFormDescription = (Outlook.FormDescription)existingItemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, taskItem, null);
//if (debugmode) writer.WriteToLog("formdescription allocated to existingformdescription");
// get the installed version
existingVersion = existingFormDescription.Version;
// discard the temporary item
object[] args = { Outlook.OlInspectorClose.olDiscard };
existingItemType.InvokeMember("Close", System.Reflection.BindingFlags.InvokeMethod, null, taskItem, args);
//if (debugmode) writer.WriteToLog("GarbageCollection");
}
}
catch (System.Exception ex)
{
}
Type itemType = taskItem.GetType();
Outlook.FormDescription formDescription = (Outlook.FormDescription)itemType.InvokeMember("FormDescription", System.Reflection.BindingFlags.GetProperty, null, taskItem, null);
// Apply some Parameters to the Formdescription
formDescription.Name = formpropstring;
formDescription.DisplayName = formpropstring;
formDescription.Category = "uncategorized";
formDescription.Comment = formpropstring;
formDescription.Version = "0.0.0.1";
//formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olPersonalRegistry );
formDescription.PublishForm(Microsoft.Office.Interop.Outlook.OlFormRegistry.olFolderRegistry, settaskfolder);
//if (debugmode) writer.WriteToLog("associating complete");
Outlook.PropertyAccessor objPA = settaskfolder.PropertyAccessor;
string strBaseType;
string strMsg;
int intLoc;
bool blnBadForm;
int i;
string PR_DEF_POST_MSGCLASS =
"http://schemas.microsoft.com/mapi/proptag/0x36E5001E";
string PR_DEF_POST_DISPLAYNAME =
"http://schemas.microsoft.com/mapi/proptag/0x36E6001E";
\\string[] arrSchema = { PR_DEF_POST_MSGCLASS, PR_DEF_POST_DISPLAYNAME };
\\string[] arrValues = { "IPM.Task.twoformMssges" , "testassociation" };
\\string[] arrErrors;
try
{
objPA = settaskfolder.PropertyAccessor;
objPA.SetProperty(PR_DEF_POST_MSGCLASS, "IPM.Task.twoformMssges");
objPA.SetProperty(PR_DEF_POST_DISPLAYNAME, "testassociation");
// if (debugmode) writer.WriteToLog("default folder set");
// arrErrors = objPA.SetProperties(arrSchema, arrValues);
}
catch (SystemException sex)
{
Console.WriteLine("This is catch with system exception : {0}", sex.ToString());
}
}
also required a couple of attributes(code in brackets) needs to be added
[Microsoft.Office.Tools.Outlook.FormRegionMessageClass("IPM.Task.twoformMssges")]
[Microsoft.Office.Tools.Outlook.FormRegionName("FormInVsto20136.msgclassregion1")]
public partial class msgclassregion1Factory{ blah blah blah ...
...and that does the trick
(I now wonder how to differentiate between save and update)

C# code to change the default program attached with an extension using a custom progid with hash in windows 8

Purpose: Associate a new progid to an extension so that file will open with new associated program.
Programming Language: C#
Description:
I want to create a program to associate another program with an extension from my recommended program list. My program is working in windows-xp and windows-7 but it is not working in windows-8. when i searched for the issue, i found that in Windows-8 there is an additional key called "Hash".
I am not able to find the hash for my new progid.
Steps Being Followed:
Created a class say "MyTest.txt" in HKEY_CLASSES_ROOT eg: HKEY_CLASSES_ROOT MyTest.txt Shell Open Command (Default) "[PATH TO NOTEPAD] "%1""
I noticed that same key is also created in LOCAL_MACHINE folder
Now I want to assign this "MyTest.txt" ProgID to
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts.txt\UserChoice]
"Hash"="????"
"ProgId"="MyTest.txt"
But I am unable to find the Hash for my newly created ProgId "MyTest.txt" in C#.
Code Using C#:
public void changeExtensionDefaultProgram(string fileext,string operationmode, string oldkeyname, string fileopenerpath)
{
try
{
if (!string.IsNullOrEmpty(fileext))
{
//Global declaration for new custom key
string sCustomkeyName = string.Format("MYTest.{0}", fileext);
RegistryKey OurKey = Registry.LocalMachine;
RegistryKey ParentKey = Registry.LocalMachine;
RegistryKey GlobalLocalMachineKey = Registry.LocalMachine;
RegistryKey GlobalRootKey = Registry.ClassesRoot;
string keyToCopy = #"SOFTWARE\Classes";
ParentKey = ParentKey.OpenSubKey(keyToCopy, true);
string programopencommand = string.Format(#"SOFTWARE\Classes\{0}\Shell\{1}\Command", oldkeyname, operationmode);
OurKey = OurKey.OpenSubKey(programopencommand, true);
if (OurKey != null)
{
//check if backup exists then do not take backup, along with source key
string backupkeyName = string.Format("MyBKP{0}", fileext);
RegistryKey rBackupKeyName = GlobalRootKey.OpenSubKey(backupkeyName, true);
if (rBackupKeyName==null)
{
//backup the keys with a new name MyBKP{ext}
FileAssoc.CopyKey(GlobalRootKey, oldkeyname, backupkeyName);
MessageBox.Show(string.Format("Backup Done -- GlobalRootKey=> oldkeyname:{0} as newbackupname:{1}", oldkeyname, backupkeyName));
}
//check if MyTest.{ext} Custom Class for extension exists
RegistryKey rCustomkeyName = GlobalRootKey.OpenSubKey(sCustomkeyName, true);
if (rCustomkeyName == null)
{
//copy the keys with a new name MyTest.{ext}
FileAssoc.CopyKey(GlobalRootKey, oldkeyname, sCustomkeyName);
}
if (rBackupKeyName != null)
{
rBackupKeyName.Close();
}
if (rCustomkeyName != null)
{
rCustomkeyName.Close();
}
//Perform in localmachine
bool isFlagSet = setMicrosoftDefaultProgID(fileext, sCustomkeyName, fileopenerpath);
if (isFlagSet)
{
string newopencommand = string.Format(#"SOFTWARE\Classes\{0}\Shell\{1}\Command", sCustomkeyName, operationmode);
rCustomkeyName = GlobalLocalMachineKey.OpenSubKey(newopencommand, true);
if (rCustomkeyName != null)
{
rCustomkeyName.SetValue("", "\"" + fileopenerpath + "\"" + " \"%1\"");
MessageBox.Show(string.Format("going to set GlobalRootKey\\{0} with fileopenerpath:{1}", programopencommand, fileopenerpath));
rCustomkeyName.Close();
}
else
{
MessageBox.Show(string.Format("Failed to modify GlobalRootKey\\{0} with fileopenerpath:{1}", programopencommand, fileopenerpath));
}
}
}
};
}
catch (Exception ex)
{
MessageBox.Show("changeExtensionDefaultProgram()::Exception raised" + ex.ToString());
}
}
public bool setMicrosoftDefaultProgID(string fileextension, string keyname, string fileopenerpath)
{
try
{
RegistryKey OurKey = Registry.CurrentUser;
//HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice = MyTest.txt
string programopencommand = string.Format(#"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\UserChoice", fileextension);
try
{
cSecurityOwnerShip sec = new cSecurityOwnerShip();
string name = sec.UserName(cSecurity.EXTENDED_NAME_FORMAT.NameSamCompatible);
if (name == null)
{
name = sec.UserName();
}
string sKey = OurKey.ToString()+#"\" + programopencommand;
try
{
sec.ChangeMYKeyOwnership(sKey, cSecurityOwnerShip.SE_OBJECT_TYPE.SE_REGISTRY_KEY);
}
catch (Exception ex)
{
sec.ChangeMyKeyPermissions(cSecurityOwnerShip.ROOT_KEY.HKEY_CURRENT_USER, programopencommand, name, cSecurityOwnerShip.eRegAccess.Full_Control, cSecurityOwnerShip.eAccsType.Access_Allowed, cSecurityOwnerShip.eFlags.Inherit_Child);
}
RegistryKey NewSubKey = OurKey.CreateSubKey(programopencommand);
if (NewSubKey != null)
{
try
{
if (NewSubKey != null)
{
NewSubKey.SetValue("ProgID", keyname);
//NewSubKey.SetValue("Hash", "v8gh4ng+Pro=");
return true;
}
else
return false;
}
catch (Exception ex)
{
MessageBox.Show("setMicrosoftDefaultProgID()::SetValue() Exception raised" + ex.ToString());
return false;
}
}
else
{
MessageBox.Show(string.Format("setMicrosoftDefaultProgID()::programopencommand:{0} not exist", programopencommand));
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("setMicrosoftDefaultProgID()::Exception raised :{0}", ex.ToString()));
return false;
}
}
catch (Exception ex)
{
MessageBox.Show("setMicrosoftDefaultProgID()::Exception raised" + ex.ToString());
return false;
}
finally
{
}
}
Issue i am facing is in this commented line to find and change "Hash"
//NewSubKey.SetValue("Hash", "v8gh4ng+Pro=");
Windows 8 does not want random apps tampering with default application associations. Users and only users get to decide what application they choose for a file extension.
Don't do this. Let the user choose default application by opening "Default Programs" dialog from Control Panel.
If you're in a corporate environment and want to copy settings, you can export associations using group policies. See Windows 8: Associate a file Type or protocol with a specific app using GPO.

ItemUpdated Event, After or Before Property Title name is null. Sharepoint 2010

No matter what I do, before and after for title are always null. This is an item updated receiver in the meetings or event list
!
[public override void ItemUpdated(SPItemEventProperties properties)
{
Logger.LogDebug("MeetingCalendarEvents", "ItemUpdated(SPItemEventProperties properties)", "BEGIN");
base.ItemUpdated(properties);
try
{
base.EventFiringEnabled = false;
SPSite site = properties.Web.Site;
string sitename= properties.BeforeProperties\["Title"\].ToString();
SPWeb web = site.RootWeb.Webs\[sitename\];
web.AllowUnsafeUpdates = true;
string prefix = properties.BeforeProperties\["Title"\].ToString().Substring(0, 2);
web.Title = properties.AfterProperties\["Title"\].ToString();
DateTime eventDate = properties.AfterProperties.GetValueAsDateTime(MeetingsCommon.Constants.FIELDS_EVENTDATE_NAME);
if (eventDate != DateTime.MinValue)
{
string titleMeetingCalendarItem = eventDate.ToString("yyyyMMdd");
titleMeetingCalendarItem = string.Format("{0}{1}", prefix, titleMeetingCalendarItem);
properties.AfterProperties.SetAfterPropertyValue("Title", titleMeetingCalendarItem);
web.ServerRelativeUrl = "/" + titleMeetingCalendarItem;
}
web.Update();
web.AllowUnsafeUpdates = false;
base.EventFiringEnabled = true;
}
catch (Exception ex)
{
Logger.LogError("MeetingCalendarEvents", "ItemUpdated(SPItemEventProperties properties)", ex);
properties.ErrorMessage = ex.Message;
properties.Cancel = true;
}
finally
{
base.EventFiringEnabled = true;
}
Logger.LogDebug("MeetingCalendarEvents", "ItemUpdated(SPItemEventProperties properties)", "END");
}]
answer here:
http://www.synergyonline.com/Blog/Lists/Posts/Post.aspx?ID=122

SSRS wont publish report but it returns successful as if it did

public static void ListFolders()
{
HomeFolderListing = new List<string>();
ReportingServiceSoapClient rs = new ReportingServiceSoapClient();
rs.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
CatalogItem[] HomeFolders = null;
string reportPath = "/";
rs.ListChildren(reportPath, true, out HomeFolders);
foreach (var homeF in HomeFolders)
{
if (homeF.Name.ToString().ToLower().Contains("base"))
{
if (homeF.Path.ToString().ToLower().Contains("/data sources/"))
{
}
else
{
Console.WriteLine("Adding reporting folder: " + homeF.Name.ToString());
HomeFolderListing.Add(homeF.Path.ToString());
}
}
}
}
public static void PublishReport()
{
foreach (string HomeFold in HomeFolderListing)
{
ReportingServiceSoapClient rs = new ReportingServiceSoapClient();
rs.ClientCredentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
BatchHeader bh = new BatchHeader();
string batchID = null;
rs.CreateBatch(out batchID);
bh.BatchID = batchID;
Byte[] definition = null;
Warning[] warnings = null;
try
{
FileStream stream = File.OpenRead(ReportInformation.Report2Deploy);
definition = new Byte[stream.Length];
stream.Read(definition, 0, (int)stream.Length);
stream.Close();
}
catch (Exception ex)
{
}
try
{
string filename = ReportInformation.ReportDeployNameOnly;
Console.WriteLine("Deploying Report: " + filename + " to: " + HomeFold);
rs.CreateReport(bh, filename, HomeFold, true, definition, null, out warnings);
if (warnings != null)
{
foreach (Warning warning in warnings)
{
Console.WriteLine(warning.Message);
}
}
else
Console.WriteLine("Report: {0} created successfully with no warnings", filename);
}
catch (Exception ex)
{
}
}
}
when i execute rs.CreateReport() it comes back as if it was successful with no warning, however, when i view the server it just isn't there. And yes I've looking in all the folders.
Are you sure there is no error? There's an empty catch block. The documenation says to catch a SoapException. Try this in the catch:
catch (SoapException e)
{
//Do something with the error, sample code write to console
Console.WriteLine(e.Detail.InnerXml.ToString());
}
Taken from:
http://msdn.microsoft.com/en-us/library/aa225813(v=sql.80).aspx

Why do I get the error DTD is not allowed on this document?

Heres the code:
// iBEC/iBSS -> SHSH Generator Tool
using System;
using System.Collections.Generic;
using System.Text;
namespace SHSH_Tool
{
public enum VersionMode
{
V3_0 = 0,
V3_0_1
}
class Program
{
static void PrintUsage()
{
Console.WriteLine("iBEC/iBSS to SHSH Tool");
Console.WriteLine("Usage: SHSH_Tool -tmpfiles X:\\Path\\To\\Tmp\\Directories -output X:\\Path\\To\\00.SHSH");
Console.WriteLine("Note: If you have files for 3.0.1, use the -301 switch.");
}
static void Main(string[] args)
{
VersionMode toolMode = VersionMode.V3_0;
string firmwareRootPath = null; // #"E:\Work\Dev\iPhone\iBEC_iBSS_Grabber";
string outputFilename = null; // #"E:\Work\Dev\svn\iPhone\SHSH_Tool\3.0.shsh";
string lastArg = null;
foreach (string arg in args)
{
if (arg == "-301")
{
toolMode = VersionMode.V3_0_1;
}
if (lastArg == "-tmpfiles")
{
firmwareRootPath = arg;
}
else if (lastArg == "-output")
{
outputFilename = arg;
}
lastArg = arg.ToLower();
}
if (firmwareRootPath == null || outputFilename == null)
{
PrintUsage();
return;
}
if (!System.IO.Directory.Exists(firmwareRootPath))
{
Console.WriteLine("Unable to open TMP directories path.");
PrintUsage();
return;
}
string restoreRamDiskToIgnore = "018-5304-002.dmg";
string manifestFilename = "BuildManifest.30.xml";
string shshTemplateFilename = "3.0.shsh.template";
if (toolMode == VersionMode.V3_0_1)
{
restoreRamDiskToIgnore = "018-5804-001.dmg";
manifestFilename = "BuildManifest.30.xml";
shshTemplateFilename = "3.0.1.shsh.template";
Console.WriteLine("Operating in 3.0.1 Mode");
}
else
{
Console.WriteLine("Operating in 3.0 Mode");
}
try
{
Console.WriteLine("Reading IPSW Manifest File...");
//System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(Util.ReadEmbeddedResource(manifestFilename));
BuildManifestReader manifestReader = new BuildManifestReader(manifestFilename);
Console.WriteLine("Found Manifest Files:");
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
Console.WriteLine(" - Key: " + manifestItem.Key + " [Digest: " + manifestItem.PartialDigest + "]");
}
Console.WriteLine("Processing TMP files...");
string strECID = null;
string[] subdirs = System.IO.Directory.GetDirectories(firmwareRootPath);
foreach (string subdir in subdirs)
{
if (!(subdir.Contains("Per") && subdir.EndsWith(".tmp")))
continue;
Console.WriteLine(" - Entering directory: " + subdir);
ProcessSubdirectory(subdir, manifestReader, ref strECID);
}
// Process current directory
ProcessSubdirectory(firmwareRootPath, manifestReader, ref strECID);
bool blobsOK = true;
Console.WriteLine("Verifying BLOB Data...");
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
if (manifestItem.BlobData == null && manifestItem.Path != restoreRamDiskToIgnore)
{
if (manifestItem.Found)
{
Console.WriteLine(" - ERROR: Invalid signed data for " + manifestItem.Path);
}
else
{
Console.WriteLine(" - ERROR: File not found for " + manifestItem.Path);
}
blobsOK = false;
}
}
if (blobsOK)
{
Console.WriteLine("Creating custom SHSH file...");
System.IO.StreamReader shshTemplateFileHdl = new System.IO.StreamReader(Util.ReadEmbeddedResource(shshTemplateFilename));
string shshTemplateFile = shshTemplateFileHdl.ReadToEnd();
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
shshTemplateFile = shshTemplateFile.Replace("[BLOB-" + manifestItem.Path + "]", manifestItem.BlobData);
shshTemplateFile = shshTemplateFile.Replace("[DIGEST-" + manifestItem.Path + "]", manifestItem.PartialDigest);
}
System.IO.StreamWriter shshFileWriter = new System.IO.StreamWriter(outputFilename);
shshFileWriter.Write(shshTemplateFile);
shshFileWriter.Close();
if (toolMode == VersionMode.V3_0)
{
Console.WriteLine("Success! 3.0 SHSH File stored at " + outputFilename);
}
else if (toolMode == VersionMode.V3_0_1)
{
Console.WriteLine("Success! 3.0.1 SHSH File stored at " + outputFilename);
}
}
else
{
Console.WriteLine("There were errors while trying to create SHSH file.");
}
}
catch (System.Exception e)
{
Console.WriteLine("There were errors while trying to create SHSH file.");
Console.WriteLine("Diagnostic: " + e.Message + " " + e.StackTrace);
}
finally
{
Console.WriteLine("Complete.");
}
}
static bool ProcessSubdirectory(string subdir, BuildManifestReader manifestReader, ref string strECID)
{
foreach (BuildManifestItem manifestItem in manifestReader.ManifestItems.Values)
{
if (manifestItem.BlobData != null)
continue;
string path = manifestItem.Path.Replace("/", "\\");
string searchPath = subdir + "\\" + path;
if (System.IO.File.Exists(searchPath))
{
Console.WriteLine(" - " + manifestItem.Path);
if (!ProcessFile(searchPath, manifestItem, ref strECID))
return false;
}
else
{
string fileOnly = manifestItem.Path.Substring(manifestItem.Path.LastIndexOf("/") + 1);
searchPath = subdir + "\\" + fileOnly;
if (System.IO.File.Exists(searchPath))
{
Console.WriteLine(" - [Alternate Path] " + fileOnly);
if (!ProcessFile(searchPath, manifestItem, ref strECID))
return false;
}
}
}
return true;
}
static bool ProcessFile(string filename, BuildManifestItem manifestItem, ref string strECID)
{
manifestItem.Found = true;
System.IO.BinaryReader binaryReader = new System.IO.BinaryReader(System.IO.File.OpenRead(filename));
binaryReader.BaseStream.Seek(-2125, System.IO.SeekOrigin.End);
byte[] magic = binaryReader.ReadBytes(4);
StringBuilder sb = new StringBuilder(100);
foreach (byte b in magic)
{
sb.Append((char)b);
}
string magicstr = sb.ToString();
if (magicstr != "DICE")
{
Console.WriteLine(" - ERROR: Magic string not found! (DICE)");
return false;
}
// chew bytes to get to the ecid
binaryReader.ReadBytes(8);
// get the ECID
byte[] ecid = binaryReader.ReadBytes(8);
StringBuilder sbECID = new StringBuilder(20);
for (int idxECID = ecid.Length - 1; idxECID >= 0; idxECID--)
{
sbECID.Append(ecid[idxECID].ToString("x2"));
}
string strThisECID = sbECID.ToString();
if (strECID != null && strThisECID != strECID)
{
Console.WriteLine(" - ERROR: ECID Mismatch (Had: " + strECID + " Found: " + strThisECID + ")");
return false;
}
else if (strECID == null)
{
strECID = strThisECID;
Console.WriteLine("Detected ECID: " + strECID);
}
binaryReader.BaseStream.Seek(-2125, System.IO.SeekOrigin.End);
byte[] signedBytes = binaryReader.ReadBytes(2125);
string signedBytesEncoded = System.Convert.ToBase64String(signedBytes);
StringBuilder formattedBlobDataBuilder = new StringBuilder(3000);
for (int idxChar = 0, colCount = 0; idxChar < signedBytesEncoded.Length; idxChar++, colCount++)
{
formattedBlobDataBuilder.Append(signedBytesEncoded[idxChar]);
if (colCount + 1 == 60)
{
formattedBlobDataBuilder.Append("\n\t\t");
colCount = -1;
}
}
string formattedBlobData = formattedBlobDataBuilder.ToString();
manifestItem.BlobData = formattedBlobData;
return true;
}
}
public class BuildManifestItem
{
string _key;
public string Key
{
get { return _key; }
set { _key = value; }
}
string _path;
public string Path
{
get { return _path; }
set { _path = value; }
}
string _partialDigest;
public string PartialDigest
{
get { return _partialDigest; }
set { _partialDigest = value; }
}
string _blobData;
public string BlobData
{
get { return _blobData; }
set { _blobData = value; }
}
bool _found;
public bool Found
{
get { return _found; }
set { _found = value; }
}
}
public class BuildManifestReader
{
private Dictionary<string, BuildManifestItem> _manifestItems;
public Dictionary<string, BuildManifestItem> ManifestItems
{
get { return _manifestItems; }
set { _manifestItems = value; }
}
public BuildManifestReader(string manifestFilename)
{
_manifestItems = new Dictionary<string, BuildManifestItem>();
System.Xml.XmlReader xmlReader = System.Xml.XmlReader.Create(Util.ReadEmbeddedResource(manifestFilename));
string elementName = null;
bool foundManifest = false;
BuildManifestItem manifestItem = null;
while (xmlReader.Read())
{
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element)
{
elementName = xmlReader.Name;
}
else if (elementName == "key" && xmlReader.Depth == 5 && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
if (xmlReader.Value == "ApBoardID")
{
foundManifest = false;
}
else if (xmlReader.Value == "Manifest")
{
foundManifest = true;
}
}
else if (elementName == "key" && xmlReader.Depth == 6 && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
if (foundManifest)
{
manifestItem = new BuildManifestItem();
manifestItem.Key = xmlReader.Value;
}
}
else if (elementName == "key" && xmlReader.NodeType == System.Xml.XmlNodeType.Text && xmlReader.Value == "Path")
{
string path = GetPath(xmlReader);
manifestItem.Path = path;
}
else if (elementName == "key" && xmlReader.NodeType == System.Xml.XmlNodeType.Text && xmlReader.Value == "PartialDigest")
{
string digest = GetPartialDigest(xmlReader);
digest = digest.Replace("\n", "");
digest = digest.Replace("\t", "");
manifestItem.PartialDigest = digest;
if (!_manifestItems.ContainsKey(manifestItem.Key + "-" + manifestItem.Path))
{
_manifestItems.Add(manifestItem.Key + "-" + manifestItem.Path, manifestItem);
}
manifestItem = null;
}
}
}
string GetPath(System.Xml.XmlReader xmlReader)
{
string elementName = null;
while (xmlReader.Read())
{
if (xmlReader.NodeType != System.Xml.XmlNodeType.Element && xmlReader.NodeType != System.Xml.XmlNodeType.Text)
continue;
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element)
{
elementName = xmlReader.Name;
}
else if (elementName == "string" && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
return xmlReader.Value;
}
else
{
return null;
}
}
return null;
}
string GetPartialDigest(System.Xml.XmlReader xmlReader)
{
string elementName = null;
while (xmlReader.Read())
{
if (xmlReader.NodeType != System.Xml.XmlNodeType.Element && xmlReader.NodeType != System.Xml.XmlNodeType.Text)
continue;
if (xmlReader.NodeType == System.Xml.XmlNodeType.Element)
{
elementName = xmlReader.Name;
}
else if (elementName == "data" && xmlReader.NodeType == System.Xml.XmlNodeType.Text)
{
return xmlReader.Value;
}
else
{
return null;
}
}
return null;
}
}
class Util
{
public static System.IO.Stream ReadEmbeddedResource(string resourceName)
{
System.Reflection.Assembly curAssembly = System.Reflection.Assembly.GetExecutingAssembly();
string [] resources = curAssembly.GetManifestResourceNames();
foreach (string resource in resources)
{
if (resource.EndsWith(resourceName))
{
return curAssembly.GetManifestResourceStream(resource);
}
}
return null;
}
}
}
Diagnostic: For security reasons DTD is prohibited in this XML document. To enab
le DTD processing set the ProhibitDtd property on XmlReaderSettings to false and
pass the settings into XmlReader.Create method. at System.Xml.XmlTextReaderI
mpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo(String res, String arg)
at System.Xml.XmlTextReaderImpl.ParseDoctypeDecl()
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at SHSH_Tool.BuildManifestReader..ctor(String manifestFilename) in C:\Users\A
dministrator\Desktop\shsh\Program.cs:line 323
at SHSH_Tool.Program.Main(String[] args) in C:\Users\Administrator\Desktop\sh
sh\Program.cs:line 87
Complete.
I don't think you gave us the actual XML document that you are reading. It probably has a "DOCTYPE" at the top which specifies a .DTD file.
Either edit the document to not have the DOCTYPE, or programatically ignore the DOCTYPE. Here is how you can do that: Ignore DOCTYPE .dtd, but .dtd file must still exist

Categories