xenadmin/XenCenterLib/Win32.cs
Konstantina Chremmou ceccfcbe79 CA-325439: Pre-populate download locations. Validation corrections on the server status report wizard.
- Moved path validation checks from the wizard to its last page (planning
to remove XenWizardBase.FinishCancelled in future).
- If the directory did not exist, the user saw a message about inability
to write a file which was misleading. Check directory existence explicitly.
- Populate the last wizard page on load rather than on construction to
avoid unnecessary validations.
- Save in the settings the report output directory, not the filename.

Signed-off-by: Konstantina Chremmou <konstantina.chremmou@citrix.com>
2019-09-19 14:06:28 +01:00

780 lines
29 KiB
C#

/* Copyright (c) Citrix Systems, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * 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 THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "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 THE COPYRIGHT HOLDER 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.
*/
using System;
using System.IO;
using System.Reflection;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Text;
using Microsoft.Win32.SafeHandles;
namespace XenCenterLib
{
public static class Win32
{
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
[DllImport("kernel32.dll")]
public static extern void SetLastError(uint dwErrCode);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
/// From George Shepherd's Windows Forms FAQ:
/// http://www.syncfusion.com/FAQ/WindowsForms/FAQ_c73c.aspx
///
/// uiFlags: 0 - Count of GDI objects
/// uiFlags: 1 - Count of USER objects
/// - Win32 GDI objects (pens, brushes, fonts, palettes, regions, device contexts, bitmap headers)
/// - Win32 USER objects:
/// - WIN32 resources (accelerator tables, bitmap resources, dialog box templates, font resources, menu resources, raw data resources, string table entries, message table entries, cursors/icons)
/// - Other USER objects (windows, menus)
///
[DllImport("User32")]
extern public static int GetGuiResources(IntPtr hProcess, int uiFlags);
public static int GetGuiResourcesGDICount(IntPtr processHandle)
{
return GetGuiResources(processHandle, 0);
}
public static int GetGuiResourcesUserCount(IntPtr processHandle)
{
return GetGuiResources(processHandle, 1);
}
public const int TO_UNICODE_BUFFER_SIZE = 64;
[DllImport("user32.dll")]
public extern static int ToUnicode(uint wVirtKey, uint wScanCode, IntPtr lpKeyState,
[Out, MarshalAs(UnmanagedType.LPWStr, SizeConst = TO_UNICODE_BUFFER_SIZE)] StringBuilder pwszBuff,
int cchBuff, uint wFlags);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool FlushFileBuffers(Microsoft.Win32.SafeHandles.SafeFileHandle hFile);
[DllImport("user32.dll")]
public extern static bool GetKeyboardState(IntPtr lpKeyState);
// So we can flash minimized windows in the taskbar to alert the user.
// See http://pinvoke.net/default.aspx/user32.FlashWindowEx and
// http://blogs.msdn.com/hippietim/archive/2006/03/28/563094.aspx
[DllImport("user32.dll")]
public static extern Int32 FlashWindowEx(ref FLASHWINFO pwfi);
[StructLayout(LayoutKind.Sequential)]
public struct FLASHWINFO
{
public UInt32 cbSize;
public IntPtr hwnd;
public UInt32 dwFlags;
public UInt32 uCount;
public UInt32 dwTimeout;
}
/// <summary>
/// Stop flashing. The system restores the window to its original state.
/// </summary>
public const UInt32 FLASHW_STOP = 0;
/// <summary>
/// Flash the window caption.
/// </summary>
public const UInt32 FLASHW_CAPTION = 1;
/// <summary>
/// Flash the taskbar button.
/// </summary>
public const UInt32 FLASHW_TRAY = 2;
/// <summary>
/// Flash both the window caption and taskbar button = FLASHW_CAPTION | FLASHW_TRAY flags.
/// </summary>
public const UInt32 FLASHW_ALL = FLASHW_CAPTION | FLASHW_TRAY;
/// <summary>
/// Flash continuously, until the FLASHW_STOP flag is set.
/// </summary>
public const UInt32 FLASHW_TIMER = 4;
/// <summary>
/// Flash continuously until the window comes to the foreground.
/// </summary>
public const UInt32 FLASHW_TIMERNOFG = 12;
/// <summary>
/// Flash the taskbar button for the given window.
/// </summary>
public static void FlashTaskbar(IntPtr hwnd)
{
FLASHWINFO fwi = new FLASHWINFO();
fwi.cbSize = (UInt32)Marshal.SizeOf(typeof(FLASHWINFO));
fwi.dwFlags = FLASHW_TRAY;
fwi.dwTimeout = 0; // The default, which is the caret blink rate
fwi.uCount = 3;
fwi.hwnd = hwnd;
FlashWindowEx(ref fwi);
}
/// <summary>
/// Stop the given window flashing.
/// </summary>
public static void StopFlashing(IntPtr hwnd)
{
FLASHWINFO fwi = new FLASHWINFO();
fwi.cbSize = (UInt32)Marshal.SizeOf(typeof(FLASHWINFO));
fwi.dwFlags = FLASHW_STOP;
fwi.dwTimeout = 0;
fwi.uCount = 0;
fwi.hwnd = hwnd;
FlashWindowEx(ref fwi);
}
[DllImport("user32.dll")]
public extern static IntPtr GetClipboardViewer();
[DllImport("user32.dll", SetLastError = true)]
public extern static IntPtr SetClipboardViewer(IntPtr hWnd);
[DllImport("user32.dll", SetLastError = true)]
public extern static bool ChangeClipboardChain(IntPtr hWnd, IntPtr hWndNext);
/// <summary>
/// There is not enough space on the disk. See winerror.h.
/// </summary>
public const UInt32 ERROR_DISK_FULL = 112;
public const int CBN_CLOSEUP = 8;
public const int EN_KILLFOCUS = 512;
public const int WM_DESTROY = 2;
public const int WM_ACTIVATE = 6;
/// <summary>
/// Sent when a control gains focus: see VNCGraphicsClient.
/// </summary>
public const int WM_SETFOCUS = 7;
public const int WM_GETTEXT = 13;
public const int WM_GETTEXTLENGTH = 14;
public const int WM_PAINT = 15;
/// <summary>
/// Prevent Redraw background on paint
/// </summary>
public const int WM_ERASEBKGND = 20;
public const int WM_ACTIVATEAPP = 28;
public const int WM_SETCURSOR = 32;
public const int WM_MOUSEACTIVATE = 33;
public const int WM_WINDOWPOSCHANGING = 70;
public const int WM_WINDOWPOSCHANGED = 71;
public const int WM_NOTIFY = 78;
public const int WM_NCHITTEST = 132;
public const int WM_NCPAINT = 133;
public const int WM_NCACTIVATE = 134;
public const int WM_TIMER = 275;
public const int WM_VSCROLL = 277;
public const int WM_KEYDOWN = 0x100;
public const int WM_KEYUP = 0x101;
// Mouse Hooks
public const int HC_ACTION = 0;
public const int WH_MOUSE_LL = 14;
public const int WM_MOUSEMOVE = 0x200;
public const int WM_LBUTTONDOWN = 0x201;
public const int WM_LBUTTONUP = 0x202;
public const int WM_LBUTTONDBLCLK = 0x203;
public const int WM_RBUTTONDOWN = 0x204;
public const int WM_RBUTTONUP = 0x205;
public const int WM_RBUTTONDBLCLK = 0x206;
public const int WM_MBUTTONDOWN = 0x207;
public const int WM_MBUTTONUP = 0x208;
public const int WM_MBUTTONDBLCLK = 0x209;
public const int WM_MOUSEWHEEL = 0x20A;
public const int WM_MOUSEHWHEEL = 0x20E;
public const int WM_PARENTNOTIFY = 0x210;
public const int WM_INITDIALOG = 0x110;
public const int WM_SETFONT = 0x0030;
public const int WM_GETFONT = 0x0031;
public const int WM_SETTEXT = 0x000c;
public const int WM_DRAWCLIPBOARD = 776;
public const int WM_CHANGECBCHAIN = 781;
public const int WM_HSCROLL = 0x114;
public const int OCM_DRAWITEM = 8235;
public const int OCM_NOTIFY = 8270;
public const int OFN_ENABLEHOOK = 0x00000020;
public const int OFN_EXPLORER = 0x00080000;
public const int OFN_FILEMUSTEXIST = 0x00001000;
public const int OFN_HIDEREADONLY = 0x00000004;
public const int OFN_CREATEPROMPT = 0x00002000;
public const int OFN_NOTESTFILECREATE = 0x00010000;
public const int OFN_OVERWRITEPROMPT = 0x00000002;
public const int OFN_PATHMUSTEXIST = 0x00000800;
public const int OFN_SHOWHELP = 0x00000010;
public const int SWP_NOSIZE = 0x0001;
public const int SWP_NOMOVE = 0x0002;
public const int SWP_NOZORDER = 0x0004;
public const int BS_AUTOCHECKBOX = 0x0003;
public const int BS_PUSHBUTTON = 0x0000;
public const int BM_SETCHECK = 0x00f1;
public const int BM_GETCHECK = 0x00f0;
public const int BST_CHECKED = 0x0001;
public const int BST_UNCHECKED = 0x0000;
public const uint WS_VISIBLE = 0x10000000;
public const uint WS_CHILD = 0x40000000;
public const uint WS_TABSTOP = 0x00010000;
public const int CDN_FILEOK = -606;
public const int CDN_HELP = -605;
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern IntPtr CreateWindowEx(uint dwExStyle, string lpClassName, string lpWindowName, uint dwStyle, int x, int y, int nWidth, int nHeight, IntPtr hWndParent, IntPtr hMenu, IntPtr hInstance, IntPtr lpParam);
[DllImport("user32.dll")]
public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);
public struct RECT
{
public int Left;
public int Top;
public int Right;
public int Bottom;
}
public struct POINT
{
public int X;
public int Y;
}
[DllImport("user32.dll")]
public static extern bool ScreenToClient(IntPtr hWnd, ref POINT lpPoint);
[DllImport("user32.dll")]
public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
[DllImport("user32.dll")]
public static extern IntPtr GetParent(IntPtr hWnd);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern bool SetWindowText(int hWnd, string lpString);
[DllImport("user32.dll")]
public static extern bool DestroyWindow(IntPtr hwnd);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, string lParam);
[DllImport("user32.dll")]
public static extern IntPtr SetFocus(IntPtr hwnd);
/// <summary>
/// Get the _HResult field from the given exception.
/// </summary>
public static int GetHResult(Exception exn)
{
/* Since there are no useful subclasses of IOException
* (e.g. DiskFullException), in order to detect a disk full error we have to extract the
* (hidden) HRESULT code from the exception using reflection and manually compare the
* error code bits with the error as defined in winerror.h.
*/
try
{
int hresult = (int)exn.GetType().GetField("_HResult",
BindingFlags.Instance | BindingFlags.NonPublic)
.GetValue(exn);
// The error code is stored in just the lower 16 bits
return hresult & 0xFFFF;
}
catch
{
return 0;
}
}
// Thank you, pinvoke.net!
// http://www.pinvoke.net/default.aspx/kernel32/FormatMessage.html
[DllImport("Kernel32.dll", SetLastError = true)]
static extern uint FormatMessage(uint dwFlags, IntPtr lpSource,
uint dwMessageId, uint dwLanguageId, ref IntPtr lpBuffer,
uint nSize, IntPtr pArguments);
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr LocalFree(IntPtr hMem);
const uint FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
const uint FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
const uint FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;
public static string GetMessageString(uint message)
{
IntPtr lpMsgBuf = IntPtr.Zero;
uint dwChars = FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
IntPtr.Zero,
message,
0, // Default language
ref lpMsgBuf,
0,
IntPtr.Zero);
if (dwChars == 0)
{
return "";
}
string sRet = Marshal.PtrToStringAnsi(lpMsgBuf);
lpMsgBuf = LocalFree(lpMsgBuf);
return sRet;
}
public static string GetWindowsMessageName(int msg)
{
Type t = typeof(Win32);
foreach (FieldInfo f in t.GetFields())
{
object i = f.GetValue(null);
if (i is Int32 && ((Int32)i) == msg)
{
return f.Name;
}
}
return msg.ToString();
}
public delegate bool EnumUILanguagesProc(string lpUILanguageString, IntPtr lParam);
[DllImport("kernel32.dll")]
public static extern bool EnumUILanguages(EnumUILanguagesProc pUILanguageEnumProc,
uint dwFlags, IntPtr lParam);
#region Window scrolling functions
[StructLayout(LayoutKind.Sequential)]
public struct ScrollInfo
{
public uint cbSize;
public uint fMask;
public int nMin;
public int nMax;
public uint nPage;
public int nPos;
public int nTrackPos;
}
public enum ScrollInfoMask
{
SIF_RANGE = 0x1,
SIF_PAGE = 0x2,
SIF_POS = 0x4,
SIF_DISABLENOSCROLL = 0x8,
SIF_TRACKPOS = 0x10,
SIF_ALL = SIF_RANGE + SIF_PAGE + SIF_POS + SIF_TRACKPOS
}
public enum ScrollBarCommands
{
SB_LINEUP = 0,
SB_LINELEFT = 0,
SB_LINEDOWN = 1,
SB_LINERIGHT = 1,
SB_PAGEUP = 2,
SB_PAGELEFT = 2,
SB_PAGEDOWN = 3,
SB_PAGERIGHT = 3,
SB_THUMBPOSITION = 4,
SB_THUMBTRACK = 5,
SB_TOP = 6,
SB_LEFT = 6,
SB_BOTTOM = 7,
SB_RIGHT = 7,
SB_ENDSCROLL = 8
}
public enum ScrollBarConstants
{
/// <summary>
/// The horizontal scroll bar of the specified window
/// </summary>
SB_HORZ = 0,
/// <summary>
/// The vertical scroll bar of the specified window
/// </summary>
SB_VERT = 1,
/// <summary>
/// A scroll bar control
/// </summary>
SB_CTL = 2,
/// <summary>
/// The horizontal and vertical scroll bars of the specified window
/// </summary>
SB_BOTH = 3
}
public enum ScrollState
{
AutoScrolling = 0x0001,
HScrollVisible = 0x0002,
VScrollVisible = 0x0004,
UserHasScrolled = 0x0008,
FullDrag = 0x0010
}
/// <summary>
/// See http://msdn2.microsoft.com/en-us/library/e14hhbe6(VS.80).aspx
/// </summary>
public const int SB_THUMBTRACK = 5;
/// <summary>
/// See http://msdn2.microsoft.com/en-us/library/bb787583.aspx and
/// http://pinvoke.net/default.aspx/user32/GetScrollInfo.html
/// </summary>
[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GetScrollInfo(IntPtr hWnd, int n, ref ScrollInfo lpScrollInfo);
[DllImport("user32.dll")]
public static extern int SetScrollInfo(IntPtr hwnd, int fnBar, [In] ref ScrollInfo lpsi, bool fRedraw);
#endregion
[DllImport("user32.dll", SetLastError = true)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
#region Disk space functions
/// <summary>
/// Will return null if the disk parameters could not be determined.
/// </summary>
/// <param name="path">An absolute path</param>
/// <returns></returns>
public static DiskSpaceInfo GetDiskSpaceInfo(string path)
{
try
{
string DriveLetter = Path.GetPathRoot(path).TrimEnd(new char[] { '\\' });
System.Management.ManagementObject o = new System.Management.ManagementObject(
string.Format("Win32_LogicalDisk.DeviceID=\"{0}\"", DriveLetter));
string fsType = o.Properties["FileSystem"].Value.ToString();
bool isFAT = (fsType == "FAT" || fsType == "FAT32");
UInt64 freeBytes = UInt64.Parse(o.Properties["FreeSpace"].Value.ToString());
UInt64 totalBytes = UInt64.Parse(o.Properties["Size"].Value.ToString());
return new DiskSpaceInfo(freeBytes, totalBytes, isFAT);
}
catch (Exception exn)
{
log.Warn(exn, exn);
return null;
}
}
public class DiskSpaceInfo
{
public readonly UInt64 FreeBytesAvailable;
public readonly UInt64 TotalBytes;
public readonly bool IsFAT;
public DiskSpaceInfo(UInt64 freeBytesAvailable, UInt64 totalBytes, bool isFAT)
{
FreeBytesAvailable = freeBytesAvailable;
TotalBytes = totalBytes;
IsFAT = isFAT;
}
}
public const int CP_NOCLOSE_BUTTON = 0x200;
public const int GWL_WNDPROC = -4;
public delegate IntPtr WndProcDelegate(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
[DllImport("user32.dll", EntryPoint = "GetWindowLong")]
public static extern IntPtr GetWindowLong(IntPtr hWnd, int nIndex);
[DllImport("user32.dll")]
public static extern int SetWindowLong(IntPtr hWnd, int nIndex, IntPtr newWndProc);
[DllImport("user32.dll")]
public static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
public const int LB_ITEMFROMPOINT = 425;
[DllImport("user32.dll")]
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
#endregion
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr hwnd);
[DllImport("user32.dll")]
public static extern int ReleaseDC(IntPtr hwnd, IntPtr hdc);
// pinvoke.net
[DllImport("psapi.dll")]
public static extern uint GetModuleFileNameEx(IntPtr hProcess, IntPtr hModule, [Out] StringBuilder lpBaseName, [In] [MarshalAs(UnmanagedType.U4)] int nSize);
/*
* ToolHelpHandle and related methods are based upon
* http://blogs.msdn.com/jasonz/archive/2007/05/11/code-sample-is-your-process-using-the-silverlight-clr.aspx
* and http://www.csharpfriends.com/Forums/ShowPost.aspx?PostID=27395.
*/
public class ToolHelpHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private ToolHelpHandle() : base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
override protected bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
[DllImport("kernel32.dll", SetLastError = true)]
static public extern bool CloseHandle(IntPtr hHandle);
[DllImport("kernel32.dll")]
static public extern bool Process32First(ToolHelpHandle hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll")]
static public extern bool Process32Next(ToolHelpHandle hSnapshot, ref PROCESSENTRY32 lppe);
[DllImport("kernel32.dll", SetLastError = true)]
static public extern ToolHelpHandle CreateToolhelp32Snapshot(SnapshotFlags dwFlags, uint th32ProcessID);
[Flags]
public enum SnapshotFlags : uint
{
HeapList = 0x00000001,
Process = 0x00000002,
Thread = 0x00000004,
Module = 0x00000008,
Module32 = 0x00000010,
Inherit = 0x80000000,
All = 0x0000001F
}
[StructLayoutAttribute(LayoutKind.Sequential)]
public struct PROCESSENTRY32
{
public uint dwSize;
public uint cntUsage;
public uint th32ProcessID;
public IntPtr th32DefaultHeapID;
public uint th32ModuleID;
public uint cntThreads;
public uint th32ParentProcessID;
public int pcPriClassBase;
public uint dwFlags;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
public string szExeFile;
}
[Flags]
public enum TOKEN_ACCESS : uint
{
TOKEN_QUERY = 0x0008
};
[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, TOKEN_ACCESS DesiredAccess, out IntPtr TokenHandle);
[DllImport("kernel32.dll", SetLastError = true)]
public extern static bool QueryPerformanceCounter(out long x);
[DllImport("kernel32.dll", SetLastError = true)]
public extern static bool QueryPerformanceFrequency(out long x);
public delegate IntPtr OFNHookProcDelegate(IntPtr hdlg, int msg, IntPtr wParam, IntPtr lParam);
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct OPENFILENAME
{
public int lStructSize;
public IntPtr hwndOwner;
public int hInstance;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrFilter;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrCustomFilter;
public int nMaxCustFilter;
public int nFilterIndex;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrFile;
public int nMaxFile;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrFileTitle;
public int nMaxFileTitle;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrInitialDir;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrTitle;
public int Flags;
public short nFileOffset;
public short nFileExtension;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpstrDefExt;
public int lCustData;
public OFNHookProcDelegate lpfnHook;
[MarshalAs(UnmanagedType.LPTStr)]
public string lpTemplateName;
//only if on nt 5.0 or higher
public int pvReserved;
public int dwReserved;
public int FlagsEx;
}
[DllImport("Comdlg32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool GetSaveFileName(ref OPENFILENAME lpofn);
[DllImport("Comdlg32.dll")]
public static extern int CommDlgExtendedError();
/// <summary>
/// Extended message header for WM_NOTIFY
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct NMHEADER
{
public NMHDR hdr;
public int iItem;
public int iButton;
public IntPtr pitem;
}
/// <summary>
/// message header for WM_NOTIFY
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct NMHDR
{
public IntPtr HwndFrom;
public IntPtr IdFrom;
public int code;
}
[StructLayout(LayoutKind.Sequential)]
public struct NMUPDOWN
{
public NMHDR hdr;
public int pos;
public int delta;
}
public const int S_OK = unchecked((int)0x00000000);
public const int E_ACCESSDENIED = unchecked((int)0x80070005);
public const int INET_E_DEFAULT_ACTION = unchecked((int)0x800C0011);
[ComImport, Guid("6d5140c1-7436-11ce-8034-00aa006009fa"),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IServiceProvider
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int QueryService(ref Guid guidService, ref Guid riid, out IntPtr ppvObject);
}
private const string _IID_IAuthenticate = "79eac9d0-baf9-11ce-8c82-00aa004ba90b";
public static readonly Guid IID_IAuthenticate = new Guid(_IID_IAuthenticate);
[ComImport, Guid(_IID_IAuthenticate),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
ComVisible(false)]
public interface IAuthenticate
{
[return: MarshalAs(UnmanagedType.I4)]
[PreserveSig]
int Authenticate(ref IntPtr phwnd, ref IntPtr pszUsername, ref IntPtr pszPassword);
}
#region Shell32.dll
/// <param name="pszPath">Note the API uses CoTaskMemAlloc</param>
[DllImport("shell32.dll")]
private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)] Guid rfid, uint dwFlags, IntPtr hToken, out IntPtr pszPath);
/// <summary>
/// Gets the full path for special folders that are not covered by the Environment.SpecialFolder enum
/// </summary>
/// <param name="folder">The Guid of the folder in question (look it up in the properties of class KnownFolders)</param>
/// <returns>The full path to the special folder path or string.Empty if we cannot retrieve it</returns>
public static string GetKnownFolderPath(Guid folder)
{
IntPtr pPath = IntPtr.Zero;
try
{
if (SHGetKnownFolderPath(folder, 0, IntPtr.Zero, out pPath) == 0)
return Marshal.PtrToStringUni(pPath);
}
finally
{
if (pPath != IntPtr.Zero)
Marshal.FreeCoTaskMem(pPath);
}
return string.Empty;
}
/// <summary>
/// There are many known folders, add those needed as necessary.
/// Uuids listed at http://www.pinvoke.net/default.aspx/shell32.SHGetKnownFolderPath
/// </summary>
public static class KnownFolders
{
public static readonly Guid Downloads = Guid.Parse("374DE290-123F-4565-9164-39C4925E467B");
}
#endregion
}
}