#region /* ----------------------------------------------------------------------- * * * Copyright 2011-2012 GRNET S.A. All rights reserved. * * Redistribution and use in source and binary forms, with or * without modification, are permitted provided that the following * conditions are met: * * 1. Redistributions of source code must retain the above * copyright notice, this list of conditions and the following * disclaimer. * * 2. Redistributions in binary form must reproduce the above * copyright notice, this list of conditions and the following * disclaimer in the documentation and/or other materials * provided with the distribution. * * * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and * documentation are those of the authors and should not be * interpreted as representing official policies, either expressed * or implied, of GRNET S.A. * * ----------------------------------------------------------------------- */ #endregion using System; using System.Diagnostics; using System.Text; using Microsoft.Win32; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; namespace Pithos.ShellExtensions { #region Shell Interfaces [Flags] public enum ISIOI { ISIOI_ICONFILE = 1, ISIOI_ICONINDEX = 2 } [ComVisible(false)] [ComImport] [Guid("0C6C4200-C589-11D0-999A-00C04FD655E1")] [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IShellIconOverlayIdentifier { [PreserveSig] int IsMemberOf( [MarshalAs(UnmanagedType.LPWStr)] string path, uint attributes); [PreserveSig] int GetOverlayInfo( IntPtr iconFileBuffer, int iconFileBufferSize, out int iconIndex, out uint flags); [PreserveSig] int GetPriority( out int priority); } [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("000214e8-0000-0000-c000-000000000046")] internal interface IShellExtInit { void Initialize( IntPtr /*LPCITEMIDLIST*/ pidlFolder, IntPtr /*LPDATAOBJECT*/ pDataObj, IntPtr /*HKEY*/ hKeyProgID); } [ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] [Guid("000214e4-0000-0000-c000-000000000046")] internal interface IContextMenu { [PreserveSig] int QueryContextMenu( IntPtr /*HMENU*/ hMenu, uint iMenu, uint idCmdFirst, uint idCmdLast, uint uFlags); void InvokeCommand(IntPtr pici); void GetCommandString( UIntPtr idCmd, uint uFlags, IntPtr pReserved, StringBuilder pszName, uint cchMax); } #endregion #region Shell Registration internal class ShellExtReg { private const string _approvedKey = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Shell Extensions\Approved"; public static void RegisterIconOverlayIdentifier(Guid clsid, string friendlyName) { if (clsid == Guid.Empty) { throw new ArgumentException("clsid must not be empty"); } if (string.IsNullOrEmpty(friendlyName)) { throw new ArgumentException("friendlyName must not be null or empty"); } // Create the key HKLM\SOFTWARE\TortoiseOverlays\\Pithos={}. string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}", friendlyName); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName,true)) { // Set the default value of the key. if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B"))) { key.SetValue("Pithos", clsid.ToString("B"),RegistryValueKind.String); } } } internal static void UnregisterIconOverlayIdentifier(Guid clsid, string friendlyName) { if (clsid == null) { throw new ArgumentException("clsid must not be null"); } if (string.IsNullOrEmpty(friendlyName)) { throw new ArgumentException("friendlyName must not be null or empty"); } string keyName = string.Format(@"SOFTWARE\TortoiseOverlays\{0}", friendlyName); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(keyName, true)) { // Set the default value of the key. if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B"))) { key.DeleteValue("Pithos"); } } } /// /// Register the context menu handler. /// /// The CLSID of the component. /// /// The file type that the context menu handler is associated with. For /// example, '*' means all file types; '.txt' means all .txt files. The /// parameter must not be NULL or an empty string. /// /// The friendly name of the component. public static void RegisterShellExtContextMenuHandler(Guid clsid, string fileType, string friendlyName) { if (clsid == Guid.Empty) { throw new ArgumentException("clsid must not be empty"); } if (string.IsNullOrEmpty(fileType)) { throw new ArgumentException("fileType must not be null or empty"); } // If fileType starts with '.', try to read the default value of the // HKCR\ key which contains the ProgID to which the file type // is linked. if (fileType.StartsWith(".")) { using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType)) { if (key != null) { // If the key exists and its default value is not empty, use // the ProgID as the file type. string defaultVal = key.GetValue(null) as string; if (!string.IsNullOrEmpty(defaultVal)) { fileType = defaultVal; } } } } // Create the key HKCR\\shellex\ContextMenuHandlers\{}. string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}", fileType, friendlyName); using (RegistryKey key = Registry.ClassesRoot.CreateSubKey(keyName)) { // Set the default value of the key. if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B"))) { key.SetValue(null, clsid.ToString("B")); } } } /// /// Unregister the context menu handler. /// /// The CLSID of the component. /// /// The file type that the context menu handler is associated with. For /// example, '*' means all file types; '.txt' means all .txt files. The /// parameter must not be NULL or an empty string. /// public static void UnregisterShellExtContextMenuHandler(Guid clsid, string fileType, string friendlyName) { if (clsid == null) { throw new ArgumentException("clsid must not be null"); } if (string.IsNullOrEmpty(fileType)) { throw new ArgumentException("fileType must not be null or empty"); } // If fileType starts with '.', try to read the default value of the // HKCR\ key which contains the ProgID to which the file type // is linked. if (fileType.StartsWith(".")) { using (RegistryKey key = Registry.ClassesRoot.OpenSubKey(fileType)) { if (key != null) { // If the key exists and its default value is not empty, use // the ProgID as the file type. string defaultVal = key.GetValue(null) as string; if (!string.IsNullOrEmpty(defaultVal)) { fileType = defaultVal; } } } } // Remove the key HKCR\\shellex\ContextMenuHandlers\{}. string keyName = string.Format(@"{0}\shellex\ContextMenuHandlers\{1}", fileType, friendlyName); Registry.ClassesRoot.DeleteSubKeyTree(keyName, false); } public static void MarkApproved(Guid guid, string friendlyName) { Debug.WriteLine(String.Format("Marking approved {0} {1}", guid, friendlyName), LogCategories.Shell); using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey)) { // Set the default value of the key. if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B"))) { key.SetValue(guid.ToString("B"), friendlyName, RegistryValueKind.String); } else { Debug.WriteLine("Error - failed to open key " + _approvedKey,LogCategories.Shell); } } } public static void RemoveApproved(Guid guid) { using (RegistryKey key = Registry.LocalMachine.OpenSubKey(_approvedKey)) { // Set the default value of the key. if (key != null)//&& !string.IsNullOrEmpty(clsid.ToString("B"))) { key.DeleteValue(guid.ToString("B"), false); } else { Debug.WriteLine("Error - failed to open key " + _approvedKey, LogCategories.Shell); } } } } #endregion #region Enums & Structs #region enum HChangeNotifyEventID /// /// Describes the event that has occurred. /// Typically, only one event is specified at a time. /// If more than one event is specified, the values contained /// in the dwItem1 and dwItem2 /// parameters must be the same, respectively, for all specified events. /// This parameter can be one or more of the following values. /// /// /// Windows NT/2000/XP: dwItem2 contains the index /// in the system image list that has changed. /// dwItem1 is not used and should be . /// Windows 95/98: dwItem1 contains the index /// in the system image list that has changed. /// dwItem2 is not used and should be . /// [Flags] enum HChangeNotifyEventID { /// /// All events have occurred. /// SHCNE_ALLEVENTS = 0x7FFFFFFF, /// /// A file type association has changed. /// must be specified in the uFlags parameter. /// dwItem1 and dwItem2 are not used and must be . /// SHCNE_ASSOCCHANGED = 0x08000000, /// /// The attributes of an item or folder have changed. /// or /// must be specified in uFlags. /// dwItem1 contains the item or folder that has changed. /// dwItem2 is not used and should be . /// SHCNE_ATTRIBUTES = 0x00000800, /// /// A nonfolder item has been created. /// or /// must be specified in uFlags. /// dwItem1 contains the item that was created. /// dwItem2 is not used and should be . /// SHCNE_CREATE = 0x00000002, /// /// A nonfolder item has been deleted. /// or /// must be specified in uFlags. /// dwItem1 contains the item that was deleted. /// dwItem2 is not used and should be . /// SHCNE_DELETE = 0x00000004, /// /// A drive has been added. /// or /// must be specified in uFlags. /// dwItem1 contains the root of the drive that was added. /// dwItem2 is not used and should be . /// SHCNE_DRIVEADD = 0x00000100, /// /// A drive has been added and the Shell should create a new window for the drive. /// or /// must be specified in uFlags. /// dwItem1 contains the root of the drive that was added. /// dwItem2 is not used and should be . /// SHCNE_DRIVEADDGUI = 0x00010000, /// /// A drive has been removed. or /// must be specified in uFlags. /// dwItem1 contains the root of the drive that was removed. /// dwItem2 is not used and should be . /// SHCNE_DRIVEREMOVED = 0x00000080, /// /// Not currently used. /// SHCNE_EXTENDED_EVENT = 0x04000000, /// /// The amount of free space on a drive has changed. /// or /// must be specified in uFlags. /// dwItem1 contains the root of the drive on which the free space changed. /// dwItem2 is not used and should be . /// SHCNE_FREESPACE = 0x00040000, /// /// Storage media has been inserted into a drive. /// or /// must be specified in uFlags. /// dwItem1 contains the root of the drive that contains the new media. /// dwItem2 is not used and should be . /// SHCNE_MEDIAINSERTED = 0x00000020, /// /// Storage media has been removed from a drive. /// or /// must be specified in uFlags. /// dwItem1 contains the root of the drive from which the media was removed. /// dwItem2 is not used and should be . /// SHCNE_MEDIAREMOVED = 0x00000040, /// /// A folder has been created. /// or must be specified in uFlags. /// dwItem1 contains the folder that was created. /// dwItem2 is not used and should be . /// SHCNE_MKDIR = 0x00000008, /// /// A folder on the local computer is being shared via the network. /// or /// must be specified in uFlags. /// dwItem1 contains the folder that is being shared. /// dwItem2 is not used and should be . /// SHCNE_NETSHARE = 0x00000200, /// /// A folder on the local computer is no longer being shared via the network. /// or /// must be specified in uFlags. /// dwItem1 contains the folder that is no longer being shared. /// dwItem2 is not used and should be . /// SHCNE_NETUNSHARE = 0x00000400, /// /// The name of a folder has changed. /// or /// must be specified in uFlags. /// dwItem1 contains the previous pointer to an item identifier list (PIDL) or name of the folder. /// dwItem2 contains the new PIDL or name of the folder. /// SHCNE_RENAMEFOLDER = 0x00020000, /// /// The name of a nonfolder item has changed. /// or /// must be specified in uFlags. /// dwItem1 contains the previous PIDL or name of the item. /// dwItem2 contains the new PIDL or name of the item. /// SHCNE_RENAMEITEM = 0x00000001, /// /// A folder has been removed. /// or /// must be specified in uFlags. /// dwItem1 contains the folder that was removed. /// dwItem2 is not used and should be . /// SHCNE_RMDIR = 0x00000010, /// /// The computer has disconnected from a server. /// or /// must be specified in uFlags. /// dwItem1 contains the server from which the computer was disconnected. /// dwItem2 is not used and should be . /// SHCNE_SERVERDISCONNECT = 0x00004000, /// /// The contents of an existing folder have changed, /// but the folder still exists and has not been renamed. /// or /// must be specified in uFlags. /// dwItem1 contains the folder that has changed. /// dwItem2 is not used and should be . /// If a folder has been created, deleted, or renamed, use SHCNE_MKDIR, SHCNE_RMDIR, or /// SHCNE_RENAMEFOLDER, respectively, instead. /// SHCNE_UPDATEDIR = 0x00001000, /// /// An image in the system image list has changed. /// must be specified in uFlags. /// SHCNE_UPDATEIMAGE = 0x00008000, } #endregion // enum HChangeNotifyEventID #region public enum HChangeNotifyFlags /// /// Flags that indicate the meaning of the dwItem1 and dwItem2 parameters. /// The uFlags parameter must be one of the following values. /// [Flags] public enum HChangeNotifyFlags { /// /// The dwItem1 and dwItem2 parameters are DWORD values. /// SHCNF_DWORD = 0x0003, /// /// dwItem1 and dwItem2 are the addresses of ITEMIDLIST structures that /// represent the item(s) affected by the change. /// Each ITEMIDLIST must be relative to the desktop folder. /// SHCNF_IDLIST = 0x0000, /// /// dwItem1 and dwItem2 are the addresses of null-terminated strings of /// maximum length MAX_PATH that contain the full path names /// of the items affected by the change. /// SHCNF_PATHA = 0x0001, /// /// dwItem1 and dwItem2 are the addresses of null-terminated strings of /// maximum length MAX_PATH that contain the full path names /// of the items affected by the change. /// SHCNF_PATHW = 0x0005, /// /// dwItem1 and dwItem2 are the addresses of null-terminated strings that /// represent the friendly names of the printer(s) affected by the change. /// SHCNF_PRINTERA = 0x0002, /// /// dwItem1 and dwItem2 are the addresses of null-terminated strings that /// represent the friendly names of the printer(s) affected by the change. /// SHCNF_PRINTERW = 0x0006, /// /// The function should not return until the notification /// has been delivered to all affected components. /// As this flag modifies other data-type flags, it cannot by used by itself. /// SHCNF_FLUSH = 0x1000, /// /// The function should begin delivering notifications to all affected components /// but should return as soon as the notification process has begun. /// As this flag modifies other data-type flags, it cannot by used by itself. /// SHCNF_FLUSHNOWAIT = 0x2000 } #endregion // enum HChangeNotifyFlags internal enum GCS : uint { GCS_VERBA = 0x00000000, GCS_HELPTEXTA = 0x00000001, GCS_VALIDATEA = 0x00000002, GCS_VERBW = 0x00000004, GCS_HELPTEXTW = 0x00000005, GCS_VALIDATEW = 0x00000006, GCS_VERBICONW = 0x00000014, GCS_UNICODE = 0x00000004 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct CMINVOKECOMMANDINFO { public uint cbSize; public CMIC fMask; public IntPtr hwnd; public IntPtr verb; [MarshalAs(UnmanagedType.LPStr)] public string parameters; [MarshalAs(UnmanagedType.LPStr)] public string directory; public int nShow; public uint dwHotKey; public IntPtr hIcon; } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct CMINVOKECOMMANDINFOEX { public uint cbSize; public CMIC fMask; public IntPtr hwnd; public IntPtr verb; [MarshalAs(UnmanagedType.LPStr)] public string parameters; [MarshalAs(UnmanagedType.LPStr)] public string directory; public int nShow; public uint dwHotKey; public IntPtr hIcon; [MarshalAs(UnmanagedType.LPStr)] public string title; public IntPtr verbW; public string parametersW; public string directoryW; public string titleW; POINT ptInvoke; } [Flags] internal enum CMIC : uint { CMIC_MASK_ICON = 0x00000010, CMIC_MASK_HOTKEY = 0x00000020, CMIC_MASK_NOASYNC = 0x00000100, CMIC_MASK_FLAG_NO_UI = 0x00000400, CMIC_MASK_UNICODE = 0x00004000, CMIC_MASK_NO_CONSOLE = 0x00008000, CMIC_MASK_ASYNCOK = 0x00100000, CMIC_MASK_NOZONECHECKS = 0x00800000, CMIC_MASK_FLAG_LOG_USAGE = 0x04000000, CMIC_MASK_SHIFT_DOWN = 0x10000000, CMIC_MASK_PTINVOKE = 0x20000000, CMIC_MASK_CONTROL_DOWN = 0x40000000 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] public struct POINT { public int X; public int Y; } internal enum CLIPFORMAT : uint { CF_TEXT = 1, CF_BITMAP = 2, CF_METAFILEPICT = 3, CF_SYLK = 4, CF_DIF = 5, CF_TIFF = 6, CF_OEMTEXT = 7, CF_DIB = 8, CF_PALETTE = 9, CF_PENDATA = 10, CF_RIFF = 11, CF_WAVE = 12, CF_UNICODETEXT = 13, CF_ENHMETAFILE = 14, CF_HDROP = 15, CF_LOCALE = 16, CF_MAX = 17, CF_OWNERDISPLAY = 0x0080, CF_DSPTEXT = 0x0081, CF_DSPBITMAP = 0x0082, CF_DSPMETAFILEPICT = 0x0083, CF_DSPENHMETAFILE = 0x008E, CF_PRIVATEFIRST = 0x0200, CF_PRIVATELAST = 0x02FF, CF_GDIOBJFIRST = 0x0300, CF_GDIOBJLAST = 0x03FF } [Flags] internal enum CMF : uint { CMF_NORMAL = 0x00000000, CMF_DEFAULTONLY = 0x00000001, CMF_VERBSONLY = 0x00000002, CMF_EXPLORE = 0x00000004, CMF_NOVERBS = 0x00000008, CMF_CANRENAME = 0x00000010, CMF_NODEFAULT = 0x00000020, CMF_INCLUDESTATIC = 0x00000040, CMF_ITEMMENU = 0x00000080, CMF_EXTENDEDVERBS = 0x00000100, CMF_DISABLEDVERBS = 0x00000200, CMF_ASYNCVERBSTATE = 0x00000400, CMF_OPTIMIZEFORINVOKE = 0x00000800, CMF_SYNCCASCADEMENU = 0x00001000, CMF_DONOTPICKDEFAULT = 0x00002000, CMF_RESERVED = 0xFFFF0000 } [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] internal struct MENUITEMINFO { public uint cbSize; public MIIM fMask; public MFT fType; public MFS fState; public uint wID; public IntPtr hSubMenu; public IntPtr hbmpChecked; public IntPtr hbmpUnchecked; public UIntPtr dwItemData; public string dwTypeData; public uint cch; public IntPtr hbmpItem; } [Flags] internal enum MIIM : uint { MIIM_STATE = 0x00000001, MIIM_ID = 0x00000002, MIIM_SUBMENU = 0x00000004, MIIM_CHECKMARKS = 0x00000008, MIIM_TYPE = 0x00000010, MIIM_DATA = 0x00000020, MIIM_STRING = 0x00000040, MIIM_BITMAP = 0x00000080, MIIM_FTYPE = 0x00000100 } [Flags] internal enum MFT : uint { MFT_STRING = 0x00000000, MFT_BITMAP = 0x00000004, MFT_MENUBARBREAK = 0x00000020, MFT_MENUBREAK = 0x00000040, MFT_OWNERDRAW = 0x00000100, MFT_RADIOCHECK = 0x00000200, MFT_SEPARATOR = 0x00000800, MFT_RIGHTORDER = 0x00002000, MFT_RIGHTJUSTIFY = 0x00004000 } [Flags] internal enum MFS : uint { MFS_ENABLED = 0x00000000, MFS_UNCHECKED = 0x00000000, MFS_UNHILITE = 0x00000000, MFS_GRAYED = 0x00000003, MFS_DISABLED = 0x00000003, MFS_CHECKED = 0x00000008, MFS_HILITE = 0x00000080, MFS_DEFAULT = 0x00001000 } [Flags] internal enum MF: uint { MF_BYCOMMAND = 0x00000000, MF_ENABLED = 0x00000000, MF_DISABLED = 0x00000002, MF_BITMAP = 0x00000004, MF_CHECKED = 0x00000008, MF_BYPOSITION = 0x00000400, MF_SEPARATOR = 0x00000800 } #endregion internal class NativeMethods { /// /// Retrieve the names of dropped files that result from a successful drag- /// and-drop operation. /// /// /// Identifier of the structure that contains the file names of the dropped /// files. /// /// /// Index of the file to query. If the value of this parameter is 0xFFFFFFFF, /// DragQueryFile returns a count of the files dropped. /// /// /// The address of a buffer that receives the file name of a dropped file /// when the function returns. /// /// /// The size, in characters, of the pszFile buffer. /// /// A non-zero value indicates a successful call. [DllImport("shell32", CharSet = CharSet.Unicode)] public static extern uint DragQueryFile( IntPtr hDrop, uint iFile, StringBuilder pszFile, int cch); /// /// Free the specified storage medium. /// /// /// Reference of the storage medium that is to be freed. /// [DllImport("ole32.dll", CharSet = CharSet.Unicode)] public static extern void ReleaseStgMedium(ref STGMEDIUM pmedium); /// /// Insert a new menu item at the specified position in a menu. /// /// /// A handle to the menu in which the new menu item is inserted. /// /// /// The identifier or position of the menu item before which to insert the /// new item. The meaning of this parameter depends on the value of /// fByPosition. /// /// /// Controls the meaning of uItem. If this parameter is false, uItem is a /// menu item identifier. Otherwise, it is a menu item position. /// /// /// A reference of a MENUITEMINFO structure that contains information about /// the new menu item. /// /// /// If the function succeeds, the return value is true. /// [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InsertMenuItem( IntPtr hMenu, uint uItem, [MarshalAs(UnmanagedType.Bool)]bool fByPosition, ref MENUITEMINFO mii); [DllImport("user32", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool InsertMenu( IntPtr hMenu, uint uPosition, MF uFlags, uint uIDNewItem, string lpNewItem); [DllImport("shell32", CharSet = CharSet.Unicode, SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool SHGetPathFromIDList( IntPtr pidl, StringBuilder pszpath); [DllImport("shell32.dll")] public static extern void SHChangeNotify(HChangeNotifyEventID wEventId, HChangeNotifyFlags uFlags, IntPtr dwItem1, IntPtr dwItem2); [DllImport("gdi32.dll")] public static extern bool DeleteObject(IntPtr hObject); public static int HighWord(int number) { return ((number & 0x80000000) == 0x80000000) ? (number >> 16) : ((number >> 16) & 0xffff); } public static int LowWord(int number) { return number & 0xffff; } } internal static class WinError { public const int S_OK = 0x0000; public const int S_FALSE = 0x0001; public const int E_FAIL = -2147467259; public const int E_INVALIDARG = -2147024809; public const int E_OUTOFMEMORY = -2147024882; public const int STRSAFE_E_INSUFFICIENT_BUFFER = -2147024774; public const uint SEVERITY_SUCCESS = 0; public const uint SEVERITY_ERROR = 1; /// /// Create an HRESULT value from component pieces. /// /// The severity to be used /// The facility to be used /// The error number /// A HRESULT constructed from the above 3 values public static int MAKE_HRESULT(uint sev, uint fac, uint code) { return (int)((sev << 31) | (fac << 16) | code); } } }