source: trunk/eraser/Eraser.Util/NativeMethods/Shell.cs @ 2057

Revision 2057, 19.0 KB checked in by lowjoel, 5 years ago (diff)

Implemented drag & drop from shell virtual folders (mainly the Recycle Bin)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1/*
2 * $Id$
3 * Copyright 2008-2010 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.Runtime.InteropServices;
26
27namespace Eraser.Util
28{
29    internal static partial class NativeMethods
30    {
31        /// <summary>
32        /// Parses a Unicode command line string and returns an array of pointers to the command
33        /// line arguments, along with a count of such arguments, in a way that is similar to
34        /// the standard C run-time argv and argc values.
35        /// </summary>
36        /// <param name="lpCmdLine">Pointer to a null-terminated Unicode string that contains
37        /// the full command line. If this parameter is an empty string the function returns the
38        /// path to the current executable file.</param>
39        /// <param name="pNumArgs">Pointer to an int that receives the number of array elements
40        /// returned, similar to argc.</param>
41        /// <returns>A pointer to an array of strings, similar to argv.</returns>
42        /// <remarks>The address returned by CommandLineToArgvW is the address of the first
43        /// element in an array of LPWSTR values; the number of pointers in this array is
44        /// indicated by pNumArgs. Each pointer to a null-terminated Unicode string represents
45        /// an individual argument found on the command line.
46        ///
47        /// CommandLineToArgvW allocates a block of contiguous memory for pointers to the
48        /// argument strings, and for the argument strings themselves; the calling application
49        /// must free the memory used by the argument list when it is no longer needed. To free
50        /// the memory, use a single call to the LocalFree function.
51        ///
52        /// For more information about the argv and argc argument convention, see Argument
53        /// Definitions and Parsing C++ Command-Line Arguments.
54        ///
55        /// The GetCommandLineW function can be used to get a command line string that is
56        /// suitable for use as the lpCmdLine parameter.
57        ///
58        /// This function accepts command lines that contain a program name; the program name
59        /// can be enclosed in quotation marks or not.
60        ///
61        /// CommandLineToArgvW has a special interpretation of backslash characters when they
62        /// are followed by a quotation mark character ("), as follows:
63        ///
64        ///     * 2n backslashes followed by a quotation mark produce n backslashes
65        ///       followed by a quotation mark.
66        ///     * (2n) + 1 backslashes followed by a quotation mark again produce n
67        ///       backslashes followed by a quotation mark.
68        ///     * n backslashes not followed by a quotation mark simply produce n
69        ///       backslashes.
70        /// </remarks>
71        [DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
72        public static extern IntPtr CommandLineToArgvW(string lpCmdLine, out int pNumArgs);
73
74        /// <summary>
75        /// Truncates a path to fit within a certain number of characters by
76        /// replacing path components with ellipses.
77        /// </summary>
78        /// <param name="pszOut">[out] The address of the string that has been altered.</param>
79        /// <param name="pszSrc">[in] A pointer to a null-terminated string of maximum
80        /// length MAX_PATH that contains the path to be altered.</param>
81        /// <param name="cchMax">[in] The maximum number of characters to be
82        /// contained in the new string, including the terminating NULL character.
83        /// For example, if cchMax = 8, the resulting string can contain a maximum
84        /// of 7 characters plus the terminating NULL character.</param>
85        /// <param name="dwFlags">Reserved.</param>
86        /// <returns>Returns TRUE if successful, or FALSE otherwise.</returns>
87        [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)]
88        [return: MarshalAs(UnmanagedType.Bool)]
89        public static extern bool PathCompactPathEx(StringBuilder pszOut,
90            string pszSrc, uint cchMax, uint dwFlags);
91
92        /// <summary>
93        /// Empties the Recycle Bin on the specified drive.
94        /// </summary>
95        /// <param name="hwnd">A handle to the parent window of any dialog boxes
96        /// that might be displayed during the operation. This parameter can be
97        /// NULL.</param>
98        /// <param name="pszRootPath">The address of a null-terminated string of
99        /// maximum length MAX_PATH that contains the path of the root drive on
100        /// which the Recycle Bin is located. This parameter can contain the address
101        /// of a string formatted with the drive, folder, and subfolder names, for
102        /// example c:\windows\system\. It can also contain an empty string or NULL.
103        /// If this value is an empty string or NULL, all Recycle Bins on all drives
104        /// will be emptied.</param>
105        /// <param name="dwFlags">One or more of the SHEmptyRecycleBinFlags</param>
106        /// <returns>Returns S_OK if successful, or a COM-defined error value
107        /// otherwise.</returns>
108        [DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
109        public static extern uint SHEmptyRecycleBin(IntPtr hwnd, string pszRootPath,
110            SHEmptyRecycleBinFlags dwFlags);
111
112        public enum SHEmptyRecycleBinFlags : uint
113        {
114            SHERB_NOCONFIRMATION = 0x00000001,
115            SHERB_NOPROGRESSUI = 0x00000002,
116            SHERB_NOSOUND = 0x00000004
117        }
118
119        /// <summary>
120        /// Retrieves information about an object in the file system, such as a
121        /// file, folder, directory, or drive root.
122        /// </summary>
123        /// <param name="path">[in] A pointer to a null-terminated string of maximum
124        /// length MAX_PATH that contains the path and file name. Both absolute
125        /// and relative paths are valid.
126        ///
127        /// If the uFlags parameter includes the SHGFI_PIDL flag, this parameter
128        /// must be the address of an ITEMIDLIST (PIDL) structure that contains
129        /// the list of item identifiers that uniquely identifies the file within
130        /// the Shell's namespace. The pointer to an item identifier list (PIDL)
131        /// must be a fully qualified PIDL. Relative PIDLs are not allowed.
132        ///
133        /// If the uFlags parameter includes the SHGFI_USEFILEATTRIBUTES flag,
134        /// this parameter does not have to be a valid file name. The function
135        /// will proceed as if the file exists with the specified name and with
136        /// the file attributes passed in the dwFileAttributes parameter. This
137        /// allows you to obtain information about a file type by passing just
138        /// the extension for pszPath and passing FILE_ATTRIBUTE_NORMAL in
139        /// dwFileAttributes.
140        ///
141        /// This string can use either short (the 8.3 form) or long file names.</param>
142        /// <param name="fileAttributes">[in] A combination of one or more file
143        /// attribute flags (FILE_ATTRIBUTE_ values as defined in Winnt.h). If
144        /// uFlags does not include the SHGFI_USEFILEATTRIBUTES flag, this
145        /// parameter is ignored.</param>
146        /// <param name="psfi">[out] The address of a SHFILEINFO structure to
147        /// receive the file information.</param>
148        /// <param name="cbFileInfo">[in] The size, in bytes, of the SHFILEINFO
149        /// structure pointed to by the psfi parameter.</param>
150        /// <param name="uFlags">[in] The flags that specify the file information
151        /// to retrieve.
152        /// This parameter can be a combination of the values in SHGetFileInfoFlags</param>
153        /// <returns>Returns a value whose meaning depends on the uFlags parameter.
154        ///
155        /// If uFlags does not contain SHGFI_EXETYPE or SHGFI_SYSICONINDEX, the return
156        /// value is nonzero if successful, or zero otherwise.
157        ///
158        /// If uFlags contains the SHGFI_EXETYPE flag, the return value specifies
159        /// the type of the executable file. It will be one of the following values.
160        ///     0                                               Nonexecutable file or an error condition.
161        ///     LOWORD = NE or PE and HIWORD = Windows version  Microsoft Windows application.
162        ///     LOWORD = MZ and HIWORD = 0                      Windows 95, Windows 98: Microsoft MS-DOS .exe, .com, or .bat file
163        ///                                                     Microsoft Windows NT, Windows 2000, Windows XP: MS-DOS .exe or .com file
164        ///     LOWORD = PE and HIWORD = 0                      Windows 95, Windows 98: Microsoft Win32 console application
165        ///                                                     Windows NT, Windows 2000, Windows XP: Win32 console application or .bat file
166        /// </returns>
167        [DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
168        public static extern IntPtr SHGetFileInfo(string path, uint fileAttributes,
169            ref SHFILEINFO psfi, int cbFileInfo, SHGetFileInfoFlags uFlags);
170
171        public enum SHGetFileInfoFlags
172        {
173            /// <summary>
174            /// Retrieve the handle to the icon that represents the file and the
175            /// index of the icon within the system image list. The handle is
176            /// copied to the hIcon member of the structure specified by psfi,
177            /// and the index is copied to the iIcon member.
178            /// </summary>
179            SHGFI_ICON = 0x000000100,
180
181            /// <summary>
182            /// Retrieve the display name for the file. The name is copied to the
183            /// szDisplayName member of the structure specified in psfi. The returned
184            /// display name uses the long file name, if there is one, rather than
185            /// the 8.3 form of the file name.
186            /// </summary>
187            SHGFI_DISPLAYNAME = 0x000000200,
188
189            /// <summary>
190            /// Retrieve the string that describes the file's type. The string
191            /// is copied to the szTypeName member of the structure specified in
192            /// psfi.
193            /// </summary>
194            SHGFI_TYPENAME = 0x000000400,
195
196            /// <summary>
197            /// Retrieve the item attributes. The attributes are copied to the
198            /// dwAttributes member of the structure specified in the psfi parameter.
199            /// These are the same attributes that are obtained from
200            /// IShellFolder::GetAttributesOf.
201            /// </summary>
202            SHGFI_ATTRIBUTES = 0x000000800,
203
204            /// <summary>
205            /// Retrieve the name of the file that contains the icon representing
206            /// the file specified by pszPath, as returned by the
207            /// IExtractIcon::GetIconLocation method of the file's icon handler.
208            /// Also retrieve the icon index within that file. The name of the
209            /// file containing the icon is copied to the szDisplayName member
210            /// of the structure specified by psfi. The icon's index is copied to
211            /// that structure's iIcon member.
212            /// </summary>
213            SHGFI_ICONLOCATION = 0x000001000,
214
215            /// <summary>
216            /// Retrieve the type of the executable file if pszPath identifies an
217            /// executable file. The information is packed into the return value.
218            /// This flag cannot be specified with any other flags.
219            /// </summary>
220            SHGFI_EXETYPE = 0x000002000,
221
222            /// <summary>
223            /// Retrieve the index of a system image list icon. If successful,
224            /// the index is copied to the iIcon member of psfi. The return value
225            /// is a handle to the system image list. Only those images whose
226            /// indices are successfully copied to iIcon are valid. Attempting
227            /// to access other images in the system image list will result in
228            /// undefined behavior.
229            /// </summary>
230            SHGFI_SYSICONINDEX = 0x000004000,
231
232            /// <summary>
233            /// Modify SHGFI_ICON, causing the function to add the link overlay
234            /// to the file's icon. The SHGFI_ICON flag must also be set.
235            /// </summary>
236            SHGFI_LINKOVERLAY = 0x000008000,
237
238            /// <summary>
239            /// Modify SHGFI_ICON, causing the function to blend the file's icon
240            /// with the system highlight color. The SHGFI_ICON flag must also
241            /// be set.
242            /// </summary>
243            SHGFI_SELECTED = 0x000010000,
244
245            /// <summary>
246            /// Modify SHGFI_ATTRIBUTES to indicate that the dwAttributes member
247            /// of the SHFILEINFO structure at psfi contains the specific attributes
248            /// that are desired. These attributes are passed to IShellFolder::GetAttributesOf.
249            /// If this flag is not specified, 0xFFFFFFFF is passed to
250            /// IShellFolder::GetAttributesOf, requesting all attributes. This flag
251            /// cannot be specified with the SHGFI_ICON flag.
252            /// </summary>
253            SHGFI_ATTR_SPECIFIED = 0x000020000,
254
255            /// <summary>
256            /// Modify SHGFI_ICON, causing the function to retrieve the file's
257            /// large icon. The SHGFI_ICON flag must also be set.
258            /// </summary>
259            SHGFI_LARGEICON = 0x000000000,
260
261            /// <summary>
262            /// Modify SHGFI_ICON, causing the function to retrieve the file's
263            /// small icon. Also used to modify SHGFI_SYSICONINDEX, causing the
264            /// function to return the handle to the system image list that
265            /// contains small icon images. The SHGFI_ICON and/or
266            /// SHGFI_SYSICONINDEX flag must also be set.
267            /// </summary>
268            SHGFI_SMALLICON = 0x000000001,
269
270            /// <summary>
271            /// Modify SHGFI_ICON, causing the function to retrieve the file's
272            /// open icon. Also used to modify SHGFI_SYSICONINDEX, causing the
273            /// function to return the handle to the system image list that
274            /// contains the file's small open icon. A container object displays
275            /// an open icon to indicate that the container is open. The SHGFI_ICON
276            /// and/or SHGFI_SYSICONINDEX flag must also be set.
277            /// </summary>
278            SHGFI_OPENICON = 0x000000002,
279
280            /// <summary>
281            /// Modify SHGFI_ICON, causing the function to retrieve a Shell-sized
282            /// icon. If this flag is not specified the function sizes the icon
283            /// according to the system metric values. The SHGFI_ICON flag must
284            /// also be set.
285            /// </summary>
286            SHGFI_SHELLICONSIZE = 0x000000004,
287
288            /// <summary>
289            /// Indicate that pszPath is the address of an ITEMIDLIST structure
290            /// rather than a path name.
291            /// </summary>
292            SHGFI_PIDL = 0x000000008,
293
294            /// <summary>
295            /// Indicates that the function should not attempt to access the file
296            /// specified by pszPath. Rather, it should act as if the file specified
297            /// by pszPath exists with the file attributes passed in dwFileAttributes.
298            /// This flag cannot be combined with the SHGFI_ATTRIBUTES, SHGFI_EXETYPE,
299            /// or SHGFI_PIDL flags.
300            /// </summary>
301            SHGFI_USEFILEATTRIBUTES = 0x000000010,
302
303            /// <summary>
304            /// Version 5.0. Apply the appropriate overlays to the file's icon.
305            /// The SHGFI_ICON flag must also be set.
306            /// </summary>
307            SHGFI_ADDOVERLAYS = 0x000000020,
308
309            /// <summary>
310            /// Version 5.0. Return the index of the overlay icon. The value of
311            /// the overlay index is returned in the upper eight bits of the iIcon
312            /// member of the structure specified by psfi. This flag requires that
313            /// the SHGFI_ICON be set as well.
314            /// </summary>
315            SHGFI_OVERLAYINDEX = 0x000000040
316        }
317
318        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
319        public struct SHFILEINFO
320        {
321            /// <summary>
322            /// A handle to the icon that represents the file. You are responsible
323            /// for destroying this handle with DestroyIcon when you no longer need it.
324            /// </summary>
325            public IntPtr hIcon;
326
327            /// <summary>
328            /// The index of the icon image within the system image list.
329            /// </summary>
330            public int iIcon;
331
332            /// <summary>
333            /// An array of values that indicates the attributes of the file object.
334            /// For information about these values, see the IShellFolder::GetAttributesOf
335            /// method.
336            /// </summary>
337            public uint dwAttributes;
338
339            /// <summary>
340            /// A string that contains the name of the file as it appears in the
341            /// Microsoft Windows Shell, or the path and file name of the file
342            /// that contains the icon representing the file.
343            /// </summary>
344            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
345            public string szDisplayName;
346
347            /// <summary>
348            /// A string that describes the type of file.
349            /// </summary>
350            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
351            public string szTypeName;
352        }
353
354        /// <summary>
355        /// Retrieves the path of a known folder as an ITEMIDLIST structure.
356        /// </summary>
357        /// <param name="rfid">A reference to the KNOWNFOLDERID that identifies the
358        /// folder. The folders associated with the known folder IDs might not exist
359        /// on a particular system.</param>
360        /// <param name="dwFlags">Flags that specify special retrieval options. This
361        /// value can be 0; otherwise, it is one or more of the KNOWN_FOLDER_FLAG values.</param>
362        /// <param name="hToken">An access token used to represent a particular user. This
363        /// parameter is usually set to NULL, in which case the function tries to access
364        /// the current user's instance of the folder. However, you may need to assign
365        /// a value to hToken for those folders that can have multiple users but are
366        /// treated as belonging to a single user. The most commonly used folder of this
367        /// type is Documents.
368        ///
369        /// The calling application is responsible for correct impersonation when hToken
370        /// is non-null. It must have appropriate security privileges for the particular
371        /// user, including TOKEN_QUERY and TOKEN_IMPERSONATE, and the user's registry
372        /// hive must be currently mounted. See Access Control for further discussion
373        /// of access control issues.
374        ///
375        /// Assigning the hToken parameter a value of -1 indicates the Default User.
376        /// This allows clients of SHGetKnownFolderIDList to find folder locations
377        /// (such as the Desktop folder) for the Default User. The Default User user
378        /// profile is duplicated when any new user account is created, and includes
379        /// special folders such as Documents and Desktop. Any items added to the
380        /// Default User folder also appear in any new user account. Note that access
381        /// to the Default User folders requires administrator privileges.</param>
382        /// <param name="ppidl">When this method returns, contains a pointer to the PIDL
383        /// of the folder. This parameter is passed uninitialized. The caller is
384        /// responsible for freeing the returned PIDL when it is no longer needed
385        /// by calling ILFree.</param>
386        [DllImport("Shell32.dll", CharSet = CharSet.Unicode, PreserveSig = true)]
387        public static extern void SHGetKnownFolderIDList(ref Guid rfid, int dwFlags,
388            IntPtr hToken, out IntPtr ppidl);
389
390        /// <summary>
391        /// Frees an ITEMIDLIST structure allocated by the Shell.
392        /// </summary>
393        /// <param name="pidl">A pointer to the ITEMIDLIST structure to be freed.
394        /// This parameter can be NULL.</param>
395        [DllImport("Shell32.dll")]
396        public static extern void ILFree(IntPtr pidl);
397
398        /// <summary>
399        /// Converts an item identifier list to a file system path.
400        /// </summary>
401        /// <param name="pidl">The address of an item identifier list that specifies
402        /// a file or directory location relative to the root of the namespace'
403        /// (the desktop).</param>
404        /// <param name="pszPath">The address of a buffer to receive the file system path.
405        /// This buffer must be at least MAX_PATH characters in size.</param>
406        /// <returns>Returns TRUE if successful; otherwise, FALSE.</returns>
407        /// <remarks>If the location specified by the pidl parameter is not part of the
408        /// file system, this function will fail.
409        ///
410        /// If the pidl parameter specifies a shortcut, the pszPath will contain the
411        /// path to the shortcut, not to the shortcut's target.</remarks>
412        [DllImport("Shell32.dll", CharSet = CharSet.Unicode)]
413        [return: MarshalAs(UnmanagedType.Bool)]
414        public static extern bool SHGetPathFromIDList(IntPtr pidl,
415            StringBuilder pszPath);
416    }
417}
Note: See TracBrowser for help on using the repository browser.