diff options
Diffstat (limited to 'openjdk/sun/awt/shell/Win32ShellFolder2.java')
-rw-r--r-- | openjdk/sun/awt/shell/Win32ShellFolder2.java | 1145 |
1 files changed, 0 insertions, 1145 deletions
diff --git a/openjdk/sun/awt/shell/Win32ShellFolder2.java b/openjdk/sun/awt/shell/Win32ShellFolder2.java deleted file mode 100644 index 0f5f6816..00000000 --- a/openjdk/sun/awt/shell/Win32ShellFolder2.java +++ /dev/null @@ -1,1145 +0,0 @@ -/* - * Copyright (c) 2003, 2009, Oracle and/or its affiliates. All rights reserved. - * Copyright (C) 2009 Volker Berlin (i-net software) - * Copyright (C) 2010 Karsten Heinrich (i-net software) - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.awt.shell; - -import java.awt.Image; -import java.awt.image.BufferedImage; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.util.*; -import java.util.concurrent.*; -import javax.swing.SwingConstants; - -import cli.System.IntPtr; -import cli.System.Drawing.Bitmap; - -// NOTE: This class basically a conversion of the OpenJDK Wen32ShellFolder2, but uses -// .NET pointers and objects instead of representing pointers as long - -/** - * Win32 Shell Folders - * <P> - * <BR> - * There are two fundamental types of shell folders : file system folders - * and non-file system folders. File system folders are relatively easy - * to deal with. Non-file system folders are items such as My Computer, - * Network Neighborhood, and the desktop. Some of these non-file system - * folders have special values and properties. - * <P> - * <BR> - * Win32 keeps two basic data structures for shell folders. The first - * of these is called an ITEMIDLIST. Usually a pointer, called an - * LPITEMIDLIST, or more frequently just "PIDL". This structure holds - * a series of identifiers and can be either relative to the desktop - * (an absolute PIDL), or relative to the shell folder that contains them. - * Some Win32 functions can take absolute or relative PIDL values, and - * others can only accept relative values. - * <BR> - * The second data structure is an IShellFolder COM interface. Using - * this interface, one can enumerate the relative PIDLs in a shell - * folder, get attributes, etc. - * <BR> - * All Win32ShellFolder2 objects which are folder types (even non-file - * system folders) contain an IShellFolder object. Files are named in - * directories via relative PIDLs. - * - * @author Michael Martak - * @author Leif Samuelsson - * @author Kenneth Russell - * @author Volker Berlin - * @author Karsten Heinrich - * @since 1.4 */ - -final class Win32ShellFolder2 extends ShellFolder { - - // Win32 Shell Folder Constants - public static final int DESKTOP = 0x0000; - public static final int INTERNET = 0x0001; - public static final int PROGRAMS = 0x0002; - public static final int CONTROLS = 0x0003; - public static final int PRINTERS = 0x0004; - public static final int PERSONAL = 0x0005; - public static final int FAVORITES = 0x0006; - public static final int STARTUP = 0x0007; - public static final int RECENT = 0x0008; - public static final int SENDTO = 0x0009; - public static final int BITBUCKET = 0x000a; - public static final int STARTMENU = 0x000b; - public static final int DESKTOPDIRECTORY = 0x0010; - public static final int DRIVES = 0x0011; - public static final int NETWORK = 0x0012; - public static final int NETHOOD = 0x0013; - public static final int FONTS = 0x0014; - public static final int TEMPLATES = 0x0015; - public static final int COMMON_STARTMENU = 0x0016; - public static final int COMMON_PROGRAMS = 0X0017; - public static final int COMMON_STARTUP = 0x0018; - public static final int COMMON_DESKTOPDIRECTORY = 0x0019; - public static final int APPDATA = 0x001a; - public static final int PRINTHOOD = 0x001b; - public static final int ALTSTARTUP = 0x001d; - public static final int COMMON_ALTSTARTUP = 0x001e; - public static final int COMMON_FAVORITES = 0x001f; - public static final int INTERNET_CACHE = 0x0020; - public static final int COOKIES = 0x0021; - public static final int HISTORY = 0x0022; - - // Win32 shell folder attributes - public static final int ATTRIB_CANCOPY = 0x00000001; - public static final int ATTRIB_CANMOVE = 0x00000002; - public static final int ATTRIB_CANLINK = 0x00000004; - public static final int ATTRIB_CANRENAME = 0x00000010; - public static final int ATTRIB_CANDELETE = 0x00000020; - public static final int ATTRIB_HASPROPSHEET = 0x00000040; - public static final int ATTRIB_DROPTARGET = 0x00000100; - public static final int ATTRIB_LINK = 0x00010000; - public static final int ATTRIB_SHARE = 0x00020000; - public static final int ATTRIB_READONLY = 0x00040000; - public static final int ATTRIB_GHOSTED = 0x00080000; - public static final int ATTRIB_HIDDEN = 0x00080000; - public static final int ATTRIB_FILESYSANCESTOR = 0x10000000; - public static final int ATTRIB_FOLDER = 0x20000000; - public static final int ATTRIB_FILESYSTEM = 0x40000000; - public static final int ATTRIB_HASSUBFOLDER = 0x80000000; - public static final int ATTRIB_VALIDATE = 0x01000000; - public static final int ATTRIB_REMOVABLE = 0x02000000; - public static final int ATTRIB_COMPRESSED = 0x04000000; - public static final int ATTRIB_BROWSABLE = 0x08000000; - public static final int ATTRIB_NONENUMERATED = 0x00100000; - public static final int ATTRIB_NEWCONTENT = 0x00200000; - - // IShellFolder::GetDisplayNameOf constants - public static final int SHGDN_NORMAL = 0; - public static final int SHGDN_INFOLDER = 1; - public static final int SHGDN_INCLUDE_NONFILESYS= 0x2000; - public static final int SHGDN_FORADDRESSBAR = 0x4000; - public static final int SHGDN_FORPARSING = 0x8000; - - // Values for system call LoadIcon() - public enum SystemIcon { - IDI_APPLICATION(32512), - IDI_HAND(32513), - IDI_ERROR(32513), - IDI_QUESTION(32514), - IDI_EXCLAMATION(32515), - IDI_WARNING(32515), - IDI_ASTERISK(32516), - IDI_INFORMATION(32516), - IDI_WINLOGO(32517); - - private final int iconID; - - SystemIcon(int iconID) { - this.iconID = iconID; - } - - public int getIconID() { - return iconID; - } - } - - static class FolderDisposer implements sun.java2d.DisposerRecord { - /* - * This is cached as a concession to getFolderType(), which needs - * an absolute PIDL. - */ - cli.System.IntPtr absolutePIDL; - /* - * We keep track of shell folders through the IShellFolder - * interface of their parents plus their relative PIDL. - */ - cli.System.Object pIShellFolder; - cli.System.IntPtr relativePIDL; - - boolean disposed; - - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public void dispose() { - if (disposed) - return; - if ( relativePIDL != null && !cli.System.IntPtr.Zero.Equals( relativePIDL ) ) { - releasePIDL(relativePIDL); - } - if ( absolutePIDL != null && !cli.System.IntPtr.Zero.Equals( absolutePIDL ) ) { - releasePIDL(absolutePIDL); - } - if ( pIShellFolder != null ) { - releaseIShellFolder(pIShellFolder); - } - disposed = true; - } - } - - FolderDisposer disposer = new FolderDisposer(); - - private void setIShellFolder( cli.System.Object iShellFolder ) { - disposer.pIShellFolder = iShellFolder; - } - - private void setRelativePIDL(cli.System.IntPtr relativePIDL) { - disposer.relativePIDL = relativePIDL; - } - - /* - * The following are for caching various shell folder properties. - */ - private cli.System.Object pIShellIcon = null; - private String folderType = null; - private String displayName = null; - private Image smallIcon = null; - private Image largeIcon = null; - private Boolean isDir = null; - - /* - * The following is to identify the My Documents folder as being special - */ - private boolean isPersonal; - - /** - * Create a system special shell folder, such as the - * desktop or Network Neighborhood. - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - Win32ShellFolder2(final int csidl) throws IOException, InterruptedException { - // Desktop is parent of DRIVES and NETWORK, not necessarily - // other special shell folders. - super ( null, (getFileSystemPath(csidl) == null) ? ("ShellFolder: 0x" + Integer.toHexString(csidl)) : getFileSystemPath(csidl)); - if (csidl == DESKTOP) { - // compared to the Java implementation we require two steps here since - // we don't have a callback from the native methods in to this instance - setIShellFolder( initDesktopFolder() ); - setRelativePIDL( initDesktopPIDL() ); - } else { - cli.System.Object desktopFolder = getDesktop().getIShellFolder(); - cli.System.IntPtr pidl = initSpecialPIDL( desktopFolder, csidl ); - setRelativePIDL( pidl ); - setIShellFolder( initSpecialFolder(desktopFolder, pidl) ); - // At this point, the native method initSpecial() has set our relativePIDL - // relative to the Desktop, which may not be our immediate parent. We need - // to traverse this ID list and break it into a chain of shell folders from - // the top, with each one having an immediate parent and a relativePIDL - // relative to that parent. - bindToDesktop(); - } - - sun.java2d.Disposer.addRecord(this , disposer); - } - - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - protected void bindToDesktop() { - cli.System.IntPtr pIDL = disposer.relativePIDL; - parent = getDesktop(); - while ( pIDL != null && !cli.System.IntPtr.Zero.Equals( pIDL ) ) { - // Get a child pidl relative to 'parent' - cli.System.IntPtr childPIDL = copyFirstPIDLEntry(pIDL); - if (childPIDL != null && !cli.System.IntPtr.Zero.Equals( childPIDL ) ) { - // Get a handle to the the rest of the ID list - // i,e, parent's grandchilren and down - pIDL = getNextPIDLEntry(pIDL); - if ( pIDL != null && !cli.System.IntPtr.Zero.Equals( pIDL ) ) { - // Now we know that parent isn't immediate to 'this' because it - // has a continued ID list. Create a shell folder for this child - // pidl and make it the new 'parent'. - parent = new Win32ShellFolder2( (Win32ShellFolder2) parent, childPIDL ); - } else { - // No grandchildren means we have arrived at the parent of 'this', - // and childPIDL is directly relative to parent. - disposer.relativePIDL = childPIDL; - } - } else { - break; - } - } - } - - /** - * Create a system shell folder - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - Win32ShellFolder2(Win32ShellFolder2 parent, cli.System.Object pIShellFolder, cli.System.IntPtr relativePIDL, String path) { - super(parent, (path != null) ? path : "ShellFolder: "); - this.disposer.pIShellFolder = pIShellFolder; - this.disposer.relativePIDL = relativePIDL; - sun.java2d.Disposer.addRecord(this, disposer); - } - - /** - * Creates a shell folder with a parent and relative PIDL - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - Win32ShellFolder2(Win32ShellFolder2 parent, cli.System.IntPtr relativePIDL) { - super (parent, getFileSystemPath(parent.getIShellFolder(), relativePIDL)); - this .disposer.relativePIDL = relativePIDL; - getAbsolutePath(); - sun.java2d.Disposer.addRecord(this , disposer); - } - - // Initializes the desktop shell folder - /** - * Returns the pIDL of the Desktop folder (pIDL root) - * @return the pIDL of the Desktop folder (pIDL root) - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.IntPtr initDesktopPIDL(); - /** - * Returns the IShellFolder pointer of the Desktop folder (pIDL root) - * @return the IShellFolder pointer of the Desktop folder (pIDL root) - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.Object initDesktopFolder(); - - // Initializes a special, non-file system shell folder - // from one of the above constants - /** - * initializes a special folder - * @param desktopIShellFolder the IShellFolder reference of the desktop folder - * @param csidl the CSIDL of the requested special folder - * @return the pIDL of the special folder relative to the desktop root - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.IntPtr initSpecialPIDL(cli.System.Object desktopIShellFolder, int csidl); - /** - * initializes a special folder - * @param desktopIShellFolder the IShellFolder reference of the desktop folder - * @param pidl the pIDL of the requested folder relative to the desktopIShellFolder - * @return the IShellFolder reference for the requested folder - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.Object initSpecialFolder(cli.System.Object desktopIShellFolder, cli.System.IntPtr pidl); - - /** Marks this folder as being the My Documents (Personal) folder */ - public void setIsPersonal() { - isPersonal = true; - } - - /** - * This method is implemented to make sure that no instances - * of <code>ShellFolder</code> are ever serialized. If <code>isFileSystem()</code> returns - * <code>true</code>, then the object is representable with an instance of - * <code>java.io.File</code> instead. If not, then the object depends - * on native PIDL state and should not be serialized. - * - * @returns a <code>java.io.File</code> replacement object. If the folder - * is a not a normal directory, then returns the first non-removable - * drive (normally "C:\"). - */ - protected Object writeReplace() - throws java.io.ObjectStreamException { - if (isFileSystem()) { - return new File(getPath()); - } else { - Win32ShellFolder2 drives = Win32ShellFolderManager2.getDrives(); - if (drives != null) { - File[] driveRoots = drives.listFiles(); - if (driveRoots != null) { - for (int i = 0; i < driveRoots.length; i++) { - if (driveRoots[i] instanceof Win32ShellFolder2) { - Win32ShellFolder2 sf = (Win32ShellFolder2) driveRoots[i]; - if (sf.isFileSystem() && !sf.hasAttribute(ATTRIB_REMOVABLE)) { - return new File(sf.getPath()); - } - } - } - } - } - // Ouch, we have no hard drives. Return something "valid" anyway. - return new File("C:\\"); - } - } - - /** - * Finalizer to clean up any COM objects or PIDLs used by this object. - */ - protected void dispose() { - disposer.dispose(); - } - - // Given a (possibly multi-level) relative PIDL (with respect to - // the desktop, at least in all of the usage cases in this code), - // return a pointer to the next entry. Does not mutate the PIDL in - // any way. Returns 0 if the null terminator is reached. - // Needs to be accessible to Win32ShellFolderManager2 - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native cli.System.IntPtr getNextPIDLEntry(cli.System.IntPtr pIDL); - - // Given a (possibly multi-level) relative PIDL (with respect to - // the desktop, at least in all of the usage cases in this code), - // copy the first entry into a newly-allocated PIDL. Returns 0 if - // the PIDL is at the end of the list. - // Needs to be accessible to Win32ShellFolderManager2 - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native cli.System.IntPtr copyFirstPIDLEntry(cli.System.IntPtr pIDL); - - // Given a parent's absolute PIDL and our relative PIDL, build an absolute PIDL - /** - * Combines a parent pIDL with a descendant pIDL. It doesn't matter whether the parent pIDL - * is relative or absolute since this is only a concatenation of the IDLs - * @param ppIDL the parent pIDL - * @param pIDL the pIDL relative to the ppIDL - * @return a pIDL for the item referenced by the original pIDL but relative to the parent of ppIDL - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.IntPtr combinePIDLs(cli.System.IntPtr ppIDL, cli.System.IntPtr pIDL); - - // Release a PIDL object - // Needs to be accessible to Win32ShellFolderManager2 - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native void releasePIDL(cli.System.IntPtr pIDL); - - // Release an IShellFolder object - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native void releaseIShellFolder( cli.System.Object iShellFolder ); - - /** - * Accessor for IShellFolder - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public cli.System.Object getIShellFolder() { - if (disposer.pIShellFolder == null ) { - assert (isDirectory()); - assert (parent != null); - cli.System.Object parentIShellFolder = getParentIShellFolder(); - if (parentIShellFolder == null) { - throw new InternalError( "Parent IShellFolder was null for " + getAbsolutePath() ); - } - // We are a directory with a parent and a relative PIDL. - // We want to bind to the parent so we get an IShellFolder instance associated with us. - disposer.pIShellFolder = bindToObject(parentIShellFolder, disposer.relativePIDL); - if (disposer.pIShellFolder == null ) { - throw new InternalError("Unable to bind " + getAbsolutePath() + " to parent"); - } - } - return disposer.pIShellFolder; - } - - /** - * Get the parent ShellFolder's IShellFolder interface - */ - public cli.System.Object getParentIShellFolder() { - Win32ShellFolder2 parent = (Win32ShellFolder2) getParentFile(); - cli.System.Object parentFolder; - if (parent == null) { - // Parent should only be null if this is the desktop, whose - // relativePIDL is relative to its own IShellFolder. - parentFolder = getIShellFolder(); - } else { - parentFolder = parent.getIShellFolder(); - } - return parentFolder; - } - - /** - * Accessor for relative PIDL - */ - public cli.System.IntPtr getRelativePIDL() { - if (disposer.relativePIDL == null) { - throw new InternalError( "Should always have a relative PIDL" ); - } - return disposer.relativePIDL; - } - - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - private cli.System.IntPtr getAbsolutePIDL() { - if (parent == null) { - // This is the desktop - return getRelativePIDL(); - } else { - if (disposer.absolutePIDL == null || disposer.absolutePIDL.Equals( IntPtr.Zero )) { - disposer.absolutePIDL = combinePIDLs( ((Win32ShellFolder2) parent).getAbsolutePIDL(), getRelativePIDL()); - } - - return disposer.absolutePIDL; - } - } - - /** - * Helper function to return the desktop - */ - public Win32ShellFolder2 getDesktop() { - return Win32ShellFolderManager2.getDesktop(); - } - - /** - * Helper function to return the desktop IShellFolder interface - */ - public cli.System.Object getDesktopIShellFolder() { - return getDesktop().getIShellFolder(); - } - - private static boolean pathsEqual(String path1, String path2) { - // Same effective implementation as Win32FileSystem - return path1.equalsIgnoreCase(path2); - } - - /** - * Check to see if two ShellFolder objects are the same - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public boolean equals(Object o) { - if (o == null || !(o instanceof Win32ShellFolder2)) { - // Short-circuit circuitous delegation path - if (!(o instanceof File)) { - return super.equals(o); - } - return pathsEqual(getPath(), ((File) o).getPath()); - } - Win32ShellFolder2 rhs = (Win32ShellFolder2) o; - if ((parent == null && rhs.parent != null) || - (parent != null && rhs.parent == null)) { - return false; - } - - if (isFileSystem() && rhs.isFileSystem()) { - // Only folders with identical parents can be equal - return (pathsEqual(getPath(), rhs.getPath()) && - (parent == rhs.parent || parent.equals(rhs.parent))); - } - - if (parent == rhs.parent || parent.equals(rhs.parent)) { - try { - return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL); - } catch (InterruptedException e) { - return false; - } - } - - return false; - } - - @cli.System.Security.SecurityCriticalAttribute.Annotation - static boolean pidlsEqual(final cli.System.Object pIShellFolder, final cli.System.IntPtr pidl1, final cli.System.IntPtr pidl2) - throws InterruptedException { - return invoke(new Callable<Boolean>() { - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public Boolean call() { - return compareIDs(pIShellFolder, pidl1, pidl2) == 0; - } - }, RuntimeException.class); - } - - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native int compareIDs(cli.System.Object pParentIShellFolder, cli.System.IntPtr pidl1, cli.System.IntPtr pidl2); - - private volatile Boolean cachedIsFileSystem; - - /** - * @return Whether this is a file system shell folder - */ - public boolean isFileSystem() { - if (cachedIsFileSystem == null) { - cachedIsFileSystem = hasAttribute(ATTRIB_FILESYSTEM); - } - - return cachedIsFileSystem; - } - - /** - * Return whether the given attribute flag is set for this object - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public boolean hasAttribute(int attribute) { - // Caching at this point doesn't seem to be cost efficient - return (getAttributes0(getParentIShellFolder(), getRelativePIDL(), attribute) & attribute) != 0; - } - - /** - * Returns the queried attributes specified in attrsMask. - * - * Could plausibly be used for attribute caching but have to be - * very careful not to touch network drives and file system roots - * with a full attrsMask - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native int getAttributes0(cli.System.Object pParentIShellFolder, cli.System.IntPtr pIDL, int attrsMask); - - // Return the path to the underlying file system object - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static String getFileSystemPath(cli.System.Object parentIShellFolder, cli.System.IntPtr relativePIDL) { - int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER; - if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() && - getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) { - - cli.System.Object desktopIShellFolder = Win32ShellFolderManager2.getDesktop().getIShellFolder(); - String path = getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING ); - String s = getFileSystemPath(desktopIShellFolder, getLinkLocation( path, false)); - if (s != null && s.startsWith("\\\\")) { - return s; - } - } - return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_NORMAL | SHGDN_FORPARSING); - } - - // Needs to be accessible to Win32ShellFolderManager2 - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native String getFileSystemPath(int csidl) throws IOException, InterruptedException; - - // Return whether the path is a network root. - // Path is assumed to be non-null - private static boolean isNetworkRoot(String path) { - return (path.equals("\\\\") || path.equals("\\") || path.equals("//") || path.equals("/")); - } - - /** - * @return The parent shell folder of this shell folder, null if - * there is no parent - */ - public File getParentFile() { - return parent; - } - - public boolean isDirectory() { - if (isDir == null) { - // Folders with SFGAO_BROWSABLE have "shell extension" handlers and are - // not traversable in JFileChooser. - if (hasAttribute(ATTRIB_FOLDER) && !hasAttribute(ATTRIB_BROWSABLE)) { - isDir = Boolean.TRUE; - } else if (isLink()) { - ShellFolder linkLocation = getLinkLocation(false); - isDir = Boolean.valueOf(linkLocation != null && linkLocation.isDirectory()); - } else { - isDir = Boolean.FALSE; - } - } - return isDir.booleanValue(); - } - - /* - * Functions for enumerating an IShellFolder's children - */ - // Returns an IEnumIDList interface for an IShellFolder. The value - // returned must be released using releaseEnumObjects(). - /** - * Returns an IEnumIDList interface for an IShellFolder. The value - * returned must be released using releaseEnumObjects(). - * @param pIShellFolder the IShellFolder instance of the parent shell folder - * @param includeHiddenFiles if true, hidden files will be included in the enumeration - * @return an instance of IEnumIDList - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - cli.System.Object getEnumObjects(cli.System.Object pIShellFolder, boolean includeHiddenFiles) { - boolean isDesktop = (disposer.pIShellFolder == getDesktopIShellFolder()); - return getEnumObjects(disposer.pIShellFolder, isDesktop, includeHiddenFiles); - } - - /** - * Returns an IEnumIDList interface for an IShellFolder. The value - * returned must be released using releaseEnumObjects(). - * @param pIShellFolder the IShellFolder instance of the parent shell folder - * @param isDesktop must be set to true, if the pIShellFolder is the desktop shell folder - * @param includeHiddenFiles if true, hidden files will be included in the enumeration - * @return an instance of IEnumIDList - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.Object getEnumObjects(cli.System.Object pIShellFolder, boolean isDesktop, boolean includeHiddenFiles); - - /** - * Returns the next sequential child as a relative PIDL - * from an IEnumIDList interface. The value returned must - * be released using releasePIDL(). - * @param pEnumObjects the IEnumIDList instance to get the next child from - * @return the next child or {@link IntPtr#Zero} if the end of the enumeration is reached - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native cli.System.IntPtr getNextChild(cli.System.Object pEnumObjects); - - /** - * Releases the IEnumIDList interface - * @param pEnumObjects an IEnumIDList instance - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native void releaseEnumObjects(cli.System.Object pEnumObjects); - - /** - * Returns the IShellFolder of a child from a parent IShellFolder and a relative pIDL. The pIDL - * may as well be any other descendant of the shell folder - at least this is, what the windows API - * documentation says. - * The value returned must be released using releaseIShellFolder(). - * @param parentIShellFolder an IShellFolder instance as root for the pIDL - * @param pIDL a pIDL relative to the parent shell folder - * @return a NEW instance of an IShellFolder for the path given by the pIDL, may be null if the path is invalid - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.Object bindToObject(cli.System.Object parentIShellFolder, cli.System.IntPtr pIDL); - - /** - * @return An array of shell folders that are children of this shell folder - * object. The array will be empty if the folder is empty. Returns - * <code>null</code> if this shellfolder does not denote a directory. - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public File[] listFiles(final boolean includeHiddenFiles) { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(getPath()); - } - - try { - return invoke(new Callable<File[]>() { - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public File[] call() throws InterruptedException { - if (!isDirectory()) { - return null; - } - // Links to directories are not directories and cannot be parents. - // This does not apply to folders in My Network Places (NetHood) - // because they are both links and real directories! - if (isLink() && !hasAttribute(ATTRIB_FOLDER)) { - return new File[0]; - } - - Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop(); - Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal(); - - // If we are a directory, we have a parent and (at least) a - // relative PIDL. We must first ensure we are bound to the - // parent so we have an IShellFolder to query. - cli.System.Object pIShellFolder = getIShellFolder(); - // Now we can enumerate the objects in this folder. - ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>(); - cli.System.Object pEnumObjects = getEnumObjects(pIShellFolder, includeHiddenFiles); - if (pEnumObjects != null) { - cli.System.IntPtr childPIDL = null; - int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR; - do { - if (Thread.currentThread().isInterrupted()) { - return new File[0]; - } - childPIDL = getNextChild(pEnumObjects); - boolean releasePIDL = true; - if ( childPIDL != null && !cli.System.IntPtr.Zero.Equals( childPIDL ) && (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) { - Win32ShellFolder2 childFolder = null; - if (this .equals(desktop) && personal != null - && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL) ) { - childFolder = personal; - } else { - childFolder = new Win32ShellFolder2(Win32ShellFolder2.this , childPIDL); - releasePIDL = false; - } - list.add(childFolder); - } - if (releasePIDL) { - releasePIDL(childPIDL); - } - } while (childPIDL != null && !childPIDL.Equals( cli.System.IntPtr.Zero )); - releaseEnumObjects(pEnumObjects); - } - return Thread.currentThread().isInterrupted() - ? new File[0] - : list.toArray(new ShellFolder[list.size()]); - } - }, InterruptedException.class); - } catch (InterruptedException e) { - return new File[0]; - } - } - - - /** - * Look for (possibly special) child folder by it's path. Note: this will not work an an ancestor(not child) - * of the current folder. - * @return The child shell folder, or null if not found. - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - Win32ShellFolder2 getChildByPath(String filePath) { - cli.System.Object pIShellFolder = getIShellFolder(); - cli.System.Object pEnumObjects = getEnumObjects(pIShellFolder, true); - Win32ShellFolder2 child = null; - cli.System.IntPtr childPIDL = null; - - childPIDL = getNextChild(pEnumObjects); - while ( childPIDL != null && !cli.System.IntPtr.Zero.Equals( childPIDL ) ) { - if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) { - String path = getFileSystemPath(pIShellFolder, childPIDL); - if (path != null && path.equalsIgnoreCase(filePath)) { - cli.System.Object childIShellFolder = bindToObject( pIShellFolder, childPIDL); - child = new Win32ShellFolder2(this, childIShellFolder, childPIDL, path); - break; - } - } - releasePIDL(childPIDL); - childPIDL = getNextChild(pEnumObjects); - } - releaseEnumObjects(pEnumObjects); - return child; - } - - private volatile Boolean cachedIsLink; - - /** - * @return Whether this shell folder is a link - */ - public boolean isLink() { - if (cachedIsLink == null) { - cachedIsLink = hasAttribute(ATTRIB_LINK); - } - - return cachedIsLink; - } - - /** - * @return Whether this shell folder is marked as hidden - */ - public boolean isHidden() { - return hasAttribute(ATTRIB_HIDDEN); - } - - // Return the link location of a shell folder - /** - * Resolves the link location of an item to an ABSOLUTE pIDL - * @param parentIShellFolder the pointer to the parent IShellFolder of the item - * @param relativePIDL a single-level pIDL to the item - * @param resolve - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native cli.System.IntPtr getLinkLocation( String path, boolean resolve); - - /** - * @return The shell folder linked to by this shell folder, or null - * if this shell folder is not a link or is a broken or invalid link - */ - public ShellFolder getLinkLocation() { - return getLinkLocation(true); - } - - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - private ShellFolder getLinkLocation(final boolean resolve) { - return invoke(new Callable<ShellFolder>() { - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public ShellFolder call() { - if (!isLink()) { - return null; - } - - ShellFolder location = null; - cli.System.IntPtr linkLocationPIDL = getLinkLocation( getAbsolutePath(), resolve); - if (linkLocationPIDL != null && !cli.System.IntPtr.Zero.Equals( linkLocationPIDL ) ) { - try { - location = - Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(), - linkLocationPIDL); - } catch (InterruptedException e) { - // Return null - } catch (InternalError e) { - // Could be a link to a non-bindable object, such as a network connection - // TODO: getIShellFolder() should throw FileNotFoundException instead - } - } - return location; - } - }); - } - - /** - * Parse a display name into a PIDL relative to the current IShellFolder. - * @param name the name or relative path - * @return a pIDL for the path, may be {@link IntPtr#Zero} if not found - * @throws FileNotFoundException - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - cli.System.IntPtr parseDisplayName(String name) throws FileNotFoundException { - try { - return parseDisplayName0(getIShellFolder(), name); - } catch (IOException e) { - throw new FileNotFoundException("Could not find file " + name); - } - } - - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.IntPtr parseDisplayName0(cli.System.Object pIShellFolder, String name) throws IOException; - - /** - * Returns the display name of an item in a folder - * @param parentIShellFolder the pointer to the IShellFolder interface of the parent folder - * @param relativePIDL single-level pIDL to the requested item within the parent folder - * @param attrs formatting attributes for the display name, refer to SHGDN in MSDN - * @return - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native String getDisplayNameOf( cli.System.Object parentIShellFolder, cli.System.IntPtr relativePIDL, int attrs); - - /** - * @return The name used to display this shell folder - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public String getDisplayName() { - if (displayName == null) { - displayName = getDisplayNameOf(getParentIShellFolder(), getRelativePIDL(), SHGDN_NORMAL); - } - return displayName; - } - - // Return the folder type of a shell folder - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native String getFolderType(cli.System.IntPtr pIDL); - - /** - * @return The type of shell folder as a string - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public String getFolderType() { - if (folderType == null) { - folderType = getFolderType(getAbsolutePIDL()); - } - return folderType; - } - - // Return the executable type of a file system shell folder - private static native String getExecutableType(String path); - - /** - * @return The executable type as a string - */ - public String getExecutableType() { - if (!isFileSystem()) { - return null; - } - return getExecutableType(getAbsolutePath()); - } - - // Icons - - private static Map smallSystemImages = new HashMap(); - private static Map largeSystemImages = new HashMap(); - private static Map smallLinkedSystemImages = new HashMap(); - private static Map largeLinkedSystemImages = new HashMap(); - - /** - * Returns the icon index in the system image list - * @param parentIShellIcon the the pointer to the IShellIcon instance of the parent folder - * @param relativePIDL the relative pIDL to the requested item - * @return the system image list index for the icon of the item or zero, if there is no entry - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native int getIconIndex(cli.System.Object parentIShellFolder, cli.System.IntPtr relativePIDL); - - // Return the icon of a file system shell folder in the form of an HICON - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.IntPtr getIcon(String absolutePath, boolean getLargeIcon); - - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.IntPtr extractIcon(cli.System.Object parentIShellFolder, cli.System.IntPtr relativePIDL, - boolean getLargeIcon); - - /** - * Returns the {@link Bitmap} for a HICON. - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native Bitmap getIconBits(cli.System.IntPtr hIcon, int size); - - /** - * Disposes a icon handle - * @param hIcon the handle to be disposed - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native void disposeIcon(cli.System.IntPtr hIcon); - - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native Bitmap getStandardViewButton0(int iconIndex); - - /** - * Creates a Java icon for a HICON pointer - * @param hIcon the handle for the icon - * @param getLargeIcon true for a large icon, false for a small icon - * @return the created image or null, if the handle is invalid - */ - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static Image makeIcon(cli.System.IntPtr hIcon, boolean getLargeIcon) { - if (hIcon != null ) { - // Get the bits. This has the side effect of setting the imageHash value for this object. - Bitmap bitmap = getIconBits(hIcon, getLargeIcon ? 32 : 16 ); - if (bitmap == null) { - return null; - } - return new BufferedImage(bitmap); - } - return null; - } - - - /** - * @return The icon image used to display this shell folder - */ - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public Image getIcon(boolean getLargeIcon) { - Image icon = getLargeIcon ? largeIcon : smallIcon; - if (icon == null) { - cli.System.IntPtr relativePIDL = getRelativePIDL(); - - if (isFileSystem() && parent != null) { - // These are cached per type (using the index in the system image list) - int index = getIconIndex( ((Win32ShellFolder2)parent).getIShellFolder(), relativePIDL); - if (index > 0) { - Map imageCache; - if (isLink()) { - imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages; - } else { - imageCache = getLargeIcon ? largeSystemImages : smallSystemImages; - } - icon = (Image) imageCache.get(Integer.valueOf(index)); - if (icon == null) { - cli.System.IntPtr hIcon = getIcon(getAbsolutePath(), getLargeIcon); - icon = makeIcon(hIcon, getLargeIcon); - disposeIcon(hIcon); - if (icon != null) { - imageCache.put(Integer.valueOf(index), icon); - } - } - } - } - - if (icon == null) { - // These are only cached per object - cli.System.IntPtr hIcon = extractIcon(getParentIShellFolder(), getRelativePIDL(), getLargeIcon); - icon = makeIcon(hIcon, getLargeIcon); - disposeIcon(hIcon); - } - - if (getLargeIcon) { - largeIcon = icon; - } else { - smallIcon = icon; - } - } - if (icon == null) { - icon = super .getIcon(getLargeIcon); - } - return icon; - } - - /** - * Gets an icon from the Windows system icon list as an <code>Image</code> - */ - static Image getShell32Icon(int iconID, boolean getLargeIcon) { - Bitmap bitmap = getShell32IconResourceAsBitmap(iconID, getLargeIcon); - if (bitmap == null) { - return null; - } - return new BufferedImage(bitmap); - } - - private static native Bitmap getShell32IconResourceAsBitmap(int iconID, boolean getLargeIcon); - - /** - * Returns the canonical form of this abstract pathname. Equivalent to - * <code>new Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>. - * - * @see java.io.File#getCanonicalFile - */ - public File getCanonicalFile() throws IOException { - return this; - } - - /* - * Indicates whether this is a special folder (includes My Documents) - */ - public boolean isSpecial() { - return isPersonal || !isFileSystem() || (this == getDesktop()); - } - - /** - * Compares this object with the specified object for order. - * - * @see sun.awt.shell.ShellFolder#compareTo(File) - */ - public int compareTo(File file2) { - if (!(file2 instanceof Win32ShellFolder2)) { - if (isFileSystem() && !isSpecial()) { - return super.compareTo(file2); - } else { - return -1; // Non-file shellfolders sort before files - } - } - return Win32ShellFolderManager2.compareShellFolders(this, (Win32ShellFolder2) file2); - } - - // native constants from commctrl.h - private static final int LVCFMT_LEFT = 0; - private static final int LVCFMT_RIGHT = 1; - private static final int LVCFMT_CENTER = 2; - - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public ShellFolderColumnInfo[] getFolderColumns() { - Object o = doGetColumnInfo(getIShellFolder()); - ShellFolderColumnInfo[] columns = (ShellFolderColumnInfo[]) o; - - if (columns != null) { - List<ShellFolderColumnInfo> notNullColumns = new ArrayList<ShellFolderColumnInfo>(); - for (int i = 0; i < columns.length; i++) { - ShellFolderColumnInfo column = columns[i]; - if (column != null) { - column.setAlignment(column.getAlignment() == LVCFMT_RIGHT ? SwingConstants.RIGHT - : column.getAlignment() == LVCFMT_CENTER ? SwingConstants.CENTER - : SwingConstants.LEADING); - - column.setComparator(new ColumnComparator(i)); - - notNullColumns.add(column); - } - } - columns = new ShellFolderColumnInfo[notNullColumns.size()]; - notNullColumns.toArray(columns); - } - return columns; - } - - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public Object getFolderColumnValue(int column) { - return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column); - } - - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native cli.System.Object /*ShellFolderColumnInfo[]*/ doGetColumnInfo( cli.System.Object iShellFolder2 ); - - @cli.System.Security.SecurityCriticalAttribute.Annotation - private static native Object doGetColumnValue(cli.System.Object parentIShellFolder2, cli.System.IntPtr childPIDL, int columnIdx); - - @cli.System.Security.SecurityCriticalAttribute.Annotation - static native int compareIDsByColumn(cli.System.Object pParentIShellFolder, cli.System.IntPtr pidl1, cli.System.IntPtr pidl2, int columnIdx); - - private class ColumnComparator implements Comparator { - private final int columnIdx; - - public ColumnComparator(int columnIdx) { - this.columnIdx = columnIdx; - } - - // compares 2 objects within this folder by the specified column - @cli.System.Security.SecuritySafeCriticalAttribute.Annotation - public int compare(Object o, Object o1) { - if (o instanceof Win32ShellFolder2 && o1 instanceof Win32ShellFolder2) { - // delegates comparison to native method - return compareIDsByColumn(getIShellFolder(), - ((Win32ShellFolder2) o).getRelativePIDL(), - ((Win32ShellFolder2) o1).getRelativePIDL(), - columnIdx); - } - return 0; - } - } -}
\ No newline at end of file |