using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;
/*****************************************************************************************
* Copyright (c) 2006 T. ALmdal
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
/*******************************************************************************************/
namespace Almdal.AutoPlayListener {
#region enum SHGNO
[Flags]
public enum SHGNO : uint {
SHGDN_NORMAL = 0x0000, // default (display purpose)
SHGDN_INFOLDER = 0x0001, // displayed under a folder (relative)
SHGDN_FOREDITING = 0x1000, // for in-place editing
SHGDN_FORADDRESSBAR = 0x4000, // UI friendly parsing name (remove ugly stuff)
SHGDN_FORPARSING = 0x8000, // parsing name for ParseDisplayName()
}
#endregion
#region enum SHCONTF
[Flags]
public enum SHCONTF : uint {
SHCONTF_FOLDERS = 0x0020, // only want folders enumerated (SFGAO_FOLDER)
SHCONTF_NONFOLDERS = 0x0040, // include non folders
SHCONTF_INCLUDEHIDDEN = 0x0080, // show items normally hidden
SHCONTF_INIT_ON_FIRST_NEXT = 0x0100, // allow EnumObject() to return before validating enum
SHCONTF_NETPRINTERSRCH = 0x0200, // hint that client is looking for printers
SHCONTF_SHAREABLE = 0x0400, // hint that client is looking sharable resources (remote shares)
SHCONTF_STORAGE = 0x0800, // include all items with accessible storage and their ancestors
}
#endregion
#region enum SFGAOF
[Flags]
public enum SFGAOF : uint {
SFGAO_NONE = 0x0,
SFGAO_CANCOPY = 0x1, // Objects can be copied (DROPEFFECT_COPY)
SFGAO_CANMOVE = 0x2, // Objects can be moved (DROPEFFECT_MOVE)
SFGAO_CANLINK = 0x4, // Objects can be linked (DROPEFFECT_LINK)
SFGAO_STORAGE = 0x00000008, // supports BindToObject(IID_IStorage)
SFGAO_CANRENAME = 0x00000010, // Objects can be renamed
SFGAO_CANDELETE = 0x00000020, // Objects can be deleted
SFGAO_HASPROPSHEET = 0x00000040, // Objects have property sheets
SFGAO_DROPTARGET = 0x00000100, // Objects are drop target
SFGAO_CAPABILITYMASK = 0x00000177,
SFGAO_ENCRYPTED = 0x00002000, // object is encrypted (use alt color)
SFGAO_ISSLOW = 0x00004000, // 'slow' object
SFGAO_GHOSTED = 0x00008000, // ghosted icon
SFGAO_LINK = 0x00010000, // Shortcut (link)
SFGAO_SHARE = 0x00020000, // shared
SFGAO_READONLY = 0x00040000, // read-only
SFGAO_HIDDEN = 0x00080000, // hidden object
SFGAO_DISPLAYATTRMASK = 0x000FC000,
SFGAO_FILESYSANCESTOR = 0x10000000, // may contain children with SFGAO_FILESYSTEM
SFGAO_FOLDER = 0x20000000, // support BindToObject(IID_IShellFolder)
SFGAO_FILESYSTEM = 0x40000000, // is a win32 file system object (file/folder/root)
SFGAO_HASSUBFOLDER = 0x80000000, // may contain children with SFGAO_FOLDER
SFGAO_CONTENTSMASK = 0x80000000,
SFGAO_VALIDATE = 0x01000000, // invalidate cached information
SFGAO_REMOVABLE = 0x02000000, // is this removeable media?
SFGAO_COMPRESSED = 0x04000000, // Object is compressed (use alt color)
SFGAO_BROWSABLE = 0x08000000, // supports IShellFolder, but only implements CreateViewObject() (non-folder view)
SFGAO_NONENUMERATED = 0x00100000, // is a non-enumerated object
SFGAO_NEWCONTENT = 0x00200000, // should show bold in explorer tree
SFGAO_CANMONIKER = 0x00400000, // defunct
SFGAO_HASSTORAGE = 0x00400000, // defunct
SFGAO_STREAM = 0x00400000, // supports BindToObject(IID_IStream)
SFGAO_STORAGEANCESTOR = 0x00800000, // may contain children with SFGAO_STORAGE or SFGAO_STREAM
SFGAO_STORAGECAPMASK = 0x70C50008, // for determining storage capabilities, ie for open/save semantics
SFGAO_ALL = 0xffffffff, // all attributes
}
#endregion
#region STRRET
[StructLayout(LayoutKind.Explicit)]
public struct STRRET {
[FieldOffset(0)]
public UInt32 uType; // One of the STRRET_* values
[FieldOffset(4)]
public IntPtr pOleStr; // must be freed by caller of GetDisplayNameOf
[FieldOffset(4)]
public IntPtr pStr; // NOT USED
[FieldOffset(4)]
public UInt32 uOffset; // Offset into SHITEMID
[FieldOffset(4)]
public IntPtr cStr; // Buffer to fill in (ANSI)
}
#endregion
public enum DROPEFFECT : ulong {
NONE = 0,
COPY = 1,
MOVE = 2,
LINK = 4,
SCROLL = 0x80000000,
}
[StructLayout(LayoutKind.Sequential)]
public struct POINTL {
public POINTL(long xx, long yy) { x = xx; y = yy; }
public long x;
public long y;
public override string ToString() {
String s = String.Format("({0},{1})", x, y);
return s;
}
}
public enum DVASPECT : uint {
DVASPECT_CONTENT = 1,
DVASPECT_THUMBNAIL = 2,
DVASPECT_ICON = 4,
DVASPECT_DOCPRINT = 8
}
public enum TYMED : uint {
TYMED_HGLOBAL = 1,
TYMED_FILE = 2,
TYMED_ISTREAM = 4,
TYMED_ISTORAGE = 8,
TYMED_GDI = 16,
TYMED_MFPICT = 32,
TYMED_ENHMF = 64,
TYMED_NULL = 0
}
[StructLayout(LayoutKind.Sequential)]
public struct FORMATETC {
public uint cfFormat; // CLIPFORMAT
public IntPtr ptd;
public DVASPECT dwAspect;
public int lindex;
public TYMED tymed;
}
[StructLayout(LayoutKind.Sequential)]
public struct STGMEDIUM {
public uint tymed;
public IntPtr hGlobal;
public IntPtr pUnkForRelease;
}
#region Interface IMAlloc
// C# representation of the IMalloc interface.
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("00000002-0000-0000-C000-000000000046")]
public interface IMalloc {
[PreserveSig]
IntPtr Alloc([In] int cb);
[PreserveSig]
IntPtr Realloc([In] IntPtr pv, [In] int cb);
[PreserveSig]
void Free([In] IntPtr pv);
[PreserveSig]
int GetSize([In] IntPtr pv);
[PreserveSig]
int DidAlloc(IntPtr pv);
[PreserveSig]
void HeapMinimize();
}
#endregion
#region interface IShellFolder
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214E6-0000-0000-C000-000000000046")]
public interface IShellFolder {
// Translates a file object's or folder's display name into an item
// identifier list.
// Return value: error code, if any
[PreserveSig()]
uint ParseDisplayName(
IntPtr hwnd, // Optional window handle
IntPtr pbc, // Optional bind context that controls the
// parsing operation. This parameter is
// normally set to NULL.
[In(), MarshalAs(UnmanagedType.LPWStr)]
string pszDisplayName, // Null-terminated UNICODE string with the
// display name.
out uint pchEaten, // Pointer to a ULONG value that receives the
// number of characters of the
// display name that was parsed.
out IntPtr ppidl, // Pointer to an ITEMIDLIST pointer that receives
// the item identifier list for
// the object.
ref uint pdwAttributes); // Optional parameter that can be used to
// query for file attributes.
// this can be values from the SFGAO enum
// Allows a client to determine the contents of a folder by creating
// an item identifier enumeration object and returning its
// IEnumIDList interface.
// Return value: error code, if any
[PreserveSig()]
uint EnumObjects(
IntPtr hwnd, // If user input is required to perform the
// enumeration, this window handle
// should be used by the enumeration object as
// the parent window to take
// user input.
SHCONTF grfFlags, // Flags indicating which items to include in the
// enumeration. For a list
// of possible values, see the SHCONTF enum.
out IEnumIDList ppenumIDList); // Address that receives a pointer to the
// IEnumIDList interface of the
// enumeration object created by this method.
// Retrieves an IShellFolder object for a subfolder.
// Return value: error code, if any
[PreserveSig()]
uint BindToObject(
IntPtr pidl, // Address of an ITEMIDLIST structure (PIDL)
// that identifies the subfolder.
IntPtr pbc, // Optional address of an IBindCtx interface on
// a bind context object to be
// used during this operation.
[In()]
ref Guid riid, // Identifier of the interface to return.
//[MarshalAs(UnmanagedType.Interface)]
out IntPtr ppv); // Address that receives the interface pointer.
// Requests a pointer to an object's storage interface.
// Return value: error code, if any
[PreserveSig()]
uint BindToStorage(
IntPtr pidl, // Address of an ITEMIDLIST structure that
// identifies the subfolder relative
// to its parent folder.
IntPtr pbc, // Optional address of an IBindCtx interface on a
// bind context object to be
// used during this operation.
[In()]
ref Guid riid, // Interface identifier (IID) of the requested
// storage interface.
[MarshalAs(UnmanagedType.Interface)]
out object ppv); // Address that receives the interface pointer
// specified by riid.
// Determines the relative order of two file objects or folders, given
// their item identifier lists. Return value: If this method is
// successful, the CODE field of the HRESULT contains one of the
// following values (the code can be retrived using the helper function
// GetHResultCode): Negative A
// negative return value indicates that the first item should precede
// the second (pidl1 < pidl2).
// Positive A positive return value indicates that the first item should
// follow the second (pidl1 > pidl2). Zero A return value of zero
// indicates that the two items are the same (pidl1 = pidl2).
[PreserveSig()]
int CompareIDs(
int lParam, // Value that specifies how the comparison
// should be performed. The lower
// Sixteen bits of lParam define the sorting
// rule.
// The upper sixteen bits of
// lParam are used for flags that modify the
// sorting rule. values can be from
// the SHCIDS enum
IntPtr pidl1, // Pointer to the first item's ITEMIDLIST
// structure.
IntPtr pidl2); // Pointer to the second item's ITEMIDLIST
// structure.
// Requests an object that can be used to obtain information from or interact
// with a folder object.
// Return value: error code, if any
[PreserveSig()]
uint CreateViewObject(
IntPtr hwndOwner, // Handle to the owner window.
[In()]
ref Guid riid, // Identifier of the requested interface.
[MarshalAs(UnmanagedType.Interface)]
out object ppv); // Address of a pointer to the requested
// interface.
// Retrieves the attributes of one or more file objects or subfolders.
// Return value: error code, if any
[PreserveSig()]
uint GetAttributesOf(
int cidl, // Number of file objects from which to retrieve
// attributes.
[In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[]
apidl, // Address of an array of pointers to ITEMIDLIST
// structures, each of which
// uniquely identifies a file object relative to
// the parent folder.
[MarshalAs(UnmanagedType.LPArray)] SFGAOF[]
rgfInOut); // Address of a single ULONG value that, on
// entry,
// contains the attributes that the caller is
// requesting. On exit, this value contains the
// requested attributes that are common to all
// of the specified objects. this value can
// be from the SFGAO enum
// Retrieves an OLE interface that can be used to carry out actions on the
// specified file objects or folders. Return value: error code, if any
[PreserveSig()]
uint GetUIObjectOf(
IntPtr hwndOwner, // Handle to the owner window that the client
// should specify if it displays
// a dialog box or message box.
int cidl, // Number of file objects or subfolders specified
// in the apidl parameter.
[In(), MarshalAs(UnmanagedType.LPArray)] IntPtr[]
apidl, // Address of an array of pointers to ITEMIDLIST
// structures, each of which
// uniquely identifies a file object or subfolder
// relative to the parent folder.
[In()]
ref Guid riid, // Identifier of the COM interface object to
// return.
IntPtr rgfReserved, // Reserved.
[MarshalAs(UnmanagedType.Interface)]
out object ppv); // Pointer to the requested interface.
// Retrieves the display name for the specified file object or subfolder.
// Return value: error code, if any
[PreserveSig()]
uint GetDisplayNameOf(
IntPtr pidl, // Address of an ITEMIDLIST structure (PIDL)
// that uniquely identifies the file
// object or subfolder relative to the parent
// folder.
SHGNO uFlags, // Flags used to request the type of display name
// to return. For a list of possible values.
out STRRET pName); // Address of a STRRET structure in which to
// return the display name.
// Sets the display name of a file object or subfolder, changing the item
// identifier in the process.
// Return value: error code, if any
[PreserveSig()]
uint SetNameOf(
IntPtr hwnd, // Handle to the owner window of any dialog or
// message boxes that the client
// displays.
IntPtr pidl, // Pointer to an ITEMIDLIST structure that
// uniquely
// identifies the file object
// or subfolder relative to the parent folder.
[In(), MarshalAs(UnmanagedType.LPWStr)]
string pszName, // Pointer to a null-terminated string that
// specifies the new display name.
SHGNO uFlags, // Flags indicating the type of name specified by
// the lpszName parameter. For a list of possible
// values, see the description of the SHGNO
// enum.
out IntPtr ppidlOut); // Address of a pointer to an ITEMIDLIST
// structure
// which receives the new ITEMIDLIST.
}
#endregion
#region Interface IEnumIDList
[ComImport]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
[Guid("000214F2-0000-0000-C000-000000000046")]
public interface IEnumIDList {
// Retrieves the specified number of item identifiers in the
// enumeration sequence and advances the current position by
// the number of items retrieved.
[PreserveSig()]
uint Next(
uint celt, // Number of elements in the array pointed to by the rgelt parameter.
out IntPtr rgelt, // Address of an array of ITEMIDLIST pointers that receives the item
// identifiers. The implementation must allocate these item identifiers
// using the Shell's allocator (retrieved by the SHGetMalloc function).
// The calling application is responsible for freeing the item
// identifiers using the Shell's allocator.
out IntPtr pceltFetched // Address of a value that receives a count of the item identifiers
// actually returned in rgelt. The count can be smaller than the value
// specified in the celt parameter. This parameter can be NULL only
// if celt is one.
);
// Skips over the specified number of elements in the enumeration sequence.
[PreserveSig()]
uint Skip(
uint celt // Number of item identifiers to skip.
);
// Returns to the beginning of the enumeration sequence.
[PreserveSig()]
uint Reset();
// Creates a new item enumeration object with the same contents and state as the current one.
[PreserveSig()]
uint Clone(
out IEnumIDList ppenum // Address of a pointer to the new enumeration object. The calling
// application must eventually free the new object by calling its Release member function.
);
}
#endregion
#region Interface IDataObject
[ComImport(),
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
GuidAttribute("0000010e-0000-0000-C000-000000000046")]
public interface IDataObject {
[PreserveSig()]
int GetData(ref FORMATETC a, ref STGMEDIUM b);
[PreserveSig()]
void GetDataHere(int a, out STGMEDIUM b);
[PreserveSig()]
int QueryGetData(ref FORMATETC a);
[PreserveSig()]
int GetCanonicalFormatEtc(FORMATETC a, out FORMATETC b);
[PreserveSig()]
int SetData(ref FORMATETC a, ref STGMEDIUM b, [In, MarshalAs(UnmanagedType.Bool)] bool release);
[PreserveSig()]
int EnumFormatEtc(uint direction, ref Object b);
[PreserveSig()]
int DAdvise(int a, uint b, Object c, ref uint d);
[PreserveSig()]
int DUnadvise(uint a);
[PreserveSig()]
int EnumDAdvise(ref Object a);
}
#endregion
#region Interface IDropTarget
[ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("00000122-0000-0000-C000-000000000046")]
public interface IDropTarget {
[PreserveSig()]
int DragEnter(IntPtr pDataObj, // IDataObject
ulong grfKeyState, // DWORD
POINTL pt,
ref ulong pdwEffect); // DWORD*
[PreserveSig()]
int DragOver(ulong grfKeyState, // DWORD
POINTL pt,
ref ulong pdwEffect); // DWORD*
[PreserveSig()]
int DragLeave();
[PreserveSig()]
int Drop(IntPtr pDataObj, // IDataObject
ulong grfKeyState, // DWORD
POINTL pt,
ref ulong pdwEffect); // DWORD*
}
#endregion
public class WinApi {
public const string CFSTR_AUTOPLAY_SHELLIDLISTS = "Autoplay Enumerated IDList Array";
public const int MAX_PATH = 260;
public static Guid IID_IShellFolder = new Guid("{000214E6-0000-0000-C000-000000000046}");
[DllImport("kernel32", SetLastError = true)]
public extern static IntPtr GlobalLock(IntPtr hMem);
[DllImport("kernel32", SetLastError = true)]
public static extern bool GlobalUnlock(IntPtr hMem);
[DllImport("Shell32.dll")]
public static extern IntPtr ILCombine(IntPtr intPtr, IntPtr intPtr_2);
[DllImport("Shell32.dll")]
public static extern void ILFree(IntPtr intPtr);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern uint RegisterWindowMessage(string lpString);
[DllImport("user32.dll", SetLastError = true, EntryPoint = "RegisterClipboardFormatW")]
public static extern uint RegisterClipboardFormat([MarshalAs(UnmanagedType.LPWStr)] String format);
[DllImport("ole32.dll")]
public static extern void ReleaseStgMedium(ref STGMEDIUM medium);
[DllImport("User32.dll", EntryPoint = "SendMessageW")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wparam, int lparam);
[DllImport("shell32")]
public static extern int SHBindToParent(
IntPtr pidl,
[MarshalAs(UnmanagedType.LPStruct)]
Guid riid,
out IntPtr ppv, /* interface whose IID is riid */
out IntPtr pidlLast);
[DllImport("Shell32.dll")]
public static extern int SHGetMalloc(out IMalloc ppMalloc);
[DllImport("shlwapi.dll", CharSet = CharSet.Auto)]
public static extern int StrRetToBSTR(ref STRRET displayName, IntPtr pidlRoot, out StringBuilder display);
}
}