jdk/src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
author rupashka
Wed, 21 Oct 2009 14:25:25 +0400
changeset 4269 0283fbab043c
parent 3978 b024e01b947a
child 4275 4c3444f1b9d8
permissions -rw-r--r--
6892340: Part of the CR 6741890 should be forwardported Reviewed-by: malenkov
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
     2
 * Copyright 2003-2009 Sun Microsystems, Inc.  All Rights Reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
90ce3da70b43 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.  Sun designates this
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
90ce3da70b43 Initial load
duke
parents:
diff changeset
     9
 * by Sun in the LICENSE file that accompanied this code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    21
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    22
 * CA 95054 USA or visit www.sun.com if you need additional information or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    23
 * have any questions.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.awt.shell;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.awt.Image;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.awt.Toolkit;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
import java.awt.image.BufferedImage;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
import java.io.File;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
import java.io.IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
import java.util.*;
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
    34
import java.util.concurrent.*;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
import javax.swing.SwingConstants;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
// NOTE: This class supersedes Win32ShellFolder, which was removed from
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
//       distribution after version 1.4.2.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * Win32 Shell Folders
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 * <P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * There are two fundamental types of shell folders : file system folders
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 * and non-file system folders.  File system folders are relatively easy
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * to deal with.  Non-file system folders are items such as My Computer,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * Network Neighborhood, and the desktop.  Some of these non-file system
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * folders have special values and properties.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * <P>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * Win32 keeps two basic data structures for shell folders.  The first
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * of these is called an ITEMIDLIST.  Usually a pointer, called an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * LPITEMIDLIST, or more frequently just "PIDL".  This structure holds
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 * a series of identifiers and can be either relative to the desktop
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 * (an absolute PIDL), or relative to the shell folder that contains them.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 * Some Win32 functions can take absolute or relative PIDL values, and
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 * others can only accept relative values.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 * The second data structure is an IShellFolder COM interface.  Using
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 * this interface, one can enumerate the relative PIDLs in a shell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 * folder, get attributes, etc.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 * <BR>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 * All Win32ShellFolder2 objects which are folder types (even non-file
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 * system folders) contain an IShellFolder object. Files are named in
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 * directories via relative PIDLs.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * @author Michael Martak
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 * @author Leif Samuelsson
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 * @author Kenneth Russell
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
 * @since 1.4 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
final class Win32ShellFolder2 extends ShellFolder {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    private static native void initIDs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    static {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
        initIDs();
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    // Win32 Shell Folder Constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    public static final int DESKTOP = 0x0000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    public static final int INTERNET = 0x0001;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    public static final int PROGRAMS = 0x0002;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    public static final int CONTROLS = 0x0003;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    public static final int PRINTERS = 0x0004;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    public static final int PERSONAL = 0x0005;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    public static final int FAVORITES = 0x0006;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    public static final int STARTUP = 0x0007;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    public static final int RECENT = 0x0008;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    public static final int SENDTO = 0x0009;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    public static final int BITBUCKET = 0x000a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    public static final int STARTMENU = 0x000b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    public static final int DESKTOPDIRECTORY = 0x0010;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    public static final int DRIVES = 0x0011;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    public static final int NETWORK = 0x0012;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    public static final int NETHOOD = 0x0013;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
    public static final int FONTS = 0x0014;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    public static final int TEMPLATES = 0x0015;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
    public static final int COMMON_STARTMENU = 0x0016;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
    public static final int COMMON_PROGRAMS = 0X0017;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    public static final int COMMON_STARTUP = 0x0018;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
    public static final int COMMON_DESKTOPDIRECTORY = 0x0019;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
    public static final int APPDATA = 0x001a;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
    public static final int PRINTHOOD = 0x001b;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    public static final int ALTSTARTUP = 0x001d;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
    public static final int COMMON_ALTSTARTUP = 0x001e;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    public static final int COMMON_FAVORITES = 0x001f;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
    public static final int INTERNET_CACHE = 0x0020;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
    public static final int COOKIES = 0x0021;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    public static final int HISTORY = 0x0022;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    // Win32 shell folder attributes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
    public static final int ATTRIB_CANCOPY          = 0x00000001;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    public static final int ATTRIB_CANMOVE          = 0x00000002;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
    public static final int ATTRIB_CANLINK          = 0x00000004;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
    public static final int ATTRIB_CANRENAME        = 0x00000010;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    public static final int ATTRIB_CANDELETE        = 0x00000020;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
    public static final int ATTRIB_HASPROPSHEET     = 0x00000040;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    public static final int ATTRIB_DROPTARGET       = 0x00000100;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
    public static final int ATTRIB_LINK             = 0x00010000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    public static final int ATTRIB_SHARE            = 0x00020000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
    public static final int ATTRIB_READONLY         = 0x00040000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
    public static final int ATTRIB_GHOSTED          = 0x00080000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
    public static final int ATTRIB_HIDDEN           = 0x00080000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
    public static final int ATTRIB_FILESYSANCESTOR  = 0x10000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    public static final int ATTRIB_FOLDER           = 0x20000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    public static final int ATTRIB_FILESYSTEM       = 0x40000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    public static final int ATTRIB_HASSUBFOLDER     = 0x80000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    public static final int ATTRIB_VALIDATE         = 0x01000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
    public static final int ATTRIB_REMOVABLE        = 0x02000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    public static final int ATTRIB_COMPRESSED       = 0x04000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
    public static final int ATTRIB_BROWSABLE        = 0x08000000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
    public static final int ATTRIB_NONENUMERATED    = 0x00100000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    public static final int ATTRIB_NEWCONTENT       = 0x00200000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    // IShellFolder::GetDisplayNameOf constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
    public static final int SHGDN_NORMAL            = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    public static final int SHGDN_INFOLDER          = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
    public static final int SHGDN_INCLUDE_NONFILESYS= 0x2000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
    public static final int SHGDN_FORADDRESSBAR     = 0x4000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    public static final int SHGDN_FORPARSING        = 0x8000;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
    // Values for system call LoadIcon()
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
    public enum SystemIcon {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
        IDI_APPLICATION(32512),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
        IDI_HAND(32513),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        IDI_ERROR(32513),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        IDI_QUESTION(32514),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
        IDI_EXCLAMATION(32515),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        IDI_WARNING(32515),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        IDI_ASTERISK(32516),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        IDI_INFORMATION(32516),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        IDI_WINLOGO(32517);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
        private final int iconID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
        SystemIcon(int iconID) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            this.iconID = iconID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        public int getIconID() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
            return iconID;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
    static class FolderDisposer implements sun.java2d.DisposerRecord {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
         * This is cached as a concession to getFolderType(), which needs
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
         * an absolute PIDL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        long absolutePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
         * We keep track of shell folders through the IShellFolder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
         * interface of their parents plus their relative PIDL.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
         */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        long pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        long relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        boolean disposed;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        public void dispose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
            if (disposed) return;
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   182
            invoke(new Callable<Void>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   183
                public Void call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   184
                    if (relativePIDL != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   185
                        releasePIDL(relativePIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   186
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   187
                    if (absolutePIDL != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   188
                        releasePIDL(absolutePIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   189
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   190
                    if (pIShellFolder != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   191
                        releaseIShellFolder(pIShellFolder);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   192
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   193
                    return null;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   194
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   195
            });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
            disposed = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    FolderDisposer disposer = new FolderDisposer();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
    private void setIShellFolder(long pIShellFolder) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
        disposer.pIShellFolder = pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
    private void setRelativePIDL(long relativePIDL) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        disposer.relativePIDL = relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
     * The following are for caching various shell folder properties.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
    private long pIShellIcon = -1L;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
    private String folderType = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
    private String displayName = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
    private Image smallIcon = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
    private Image largeIcon = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
    private Boolean isDir = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
     * The following is to identify the My Documents folder as being special
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
    private boolean isPersonal;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   221
    private static String composePathForCsidl(int csidl) throws IOException, InterruptedException {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   222
        String path = getFileSystemPath(csidl);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   223
        return path == null
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   224
                ? ("ShellFolder: 0x" + Integer.toHexString(csidl))
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   225
                : path;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   226
    }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * Create a system special shell folder, such as the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     * desktop or Network Neighborhood.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     */
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   232
    Win32ShellFolder2(final int csidl) throws IOException, InterruptedException {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
        // Desktop is parent of DRIVES and NETWORK, not necessarily
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
        // other special shell folders.
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   235
        super(null, composePathForCsidl(csidl));
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   236
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   237
        invoke(new Callable<Void>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   238
            public Void call() throws InterruptedException {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   239
                if (csidl == DESKTOP) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   240
                    initDesktop();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   241
                } else {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   242
                    initSpecial(getDesktop().getIShellFolder(), csidl);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   243
                    // At this point, the native method initSpecial() has set our relativePIDL
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   244
                    // relative to the Desktop, which may not be our immediate parent. We need
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   245
                    // to traverse this ID list and break it into a chain of shell folders from
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   246
                    // the top, with each one having an immediate parent and a relativePIDL
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   247
                    // relative to that parent.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   248
                    long pIDL = disposer.relativePIDL;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   249
                    parent = getDesktop();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   250
                    while (pIDL != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   251
                        // Get a child pidl relative to 'parent'
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   252
                        long childPIDL = copyFirstPIDLEntry(pIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   253
                        if (childPIDL != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   254
                            // Get a handle to the the rest of the ID list
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   255
                            // i,e, parent's grandchilren and down
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   256
                            pIDL = getNextPIDLEntry(pIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   257
                            if (pIDL != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   258
                                // Now we know that parent isn't immediate to 'this' because it
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   259
                                // has a continued ID list. Create a shell folder for this child
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   260
                                // pidl and make it the new 'parent'.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   261
                                parent = new Win32ShellFolder2((Win32ShellFolder2) parent, childPIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   262
                            } else {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   263
                                // No grandchildren means we have arrived at the parent of 'this',
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   264
                                // and childPIDL is directly relative to parent.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   265
                                disposer.relativePIDL = childPIDL;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   266
                            }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   267
                        } else {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   268
                            break;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   269
                        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
                }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   272
                return null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   274
        }, InterruptedException.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
        sun.java2d.Disposer.addRecord(this, disposer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
     * Create a system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    Win32ShellFolder2(Win32ShellFolder2 parent, long pIShellFolder, long relativePIDL, String path) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
        super(parent, (path != null) ? path : "ShellFolder: ");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
        this.disposer.pIShellFolder = pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        this.disposer.relativePIDL = relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        sun.java2d.Disposer.addRecord(this, disposer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     * Creates a shell folder with a parent and relative PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     */
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   294
    Win32ShellFolder2(final Win32ShellFolder2 parent, final long relativePIDL) throws InterruptedException {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   295
        super(parent,
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   296
            invoke(new Callable<String>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   297
                public String call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   298
                    return getFileSystemPath(parent.getIShellFolder(), relativePIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   299
                }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   300
            }, RuntimeException.class)
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   301
        );
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        this.disposer.relativePIDL = relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
        sun.java2d.Disposer.addRecord(this, disposer);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
    // Initializes the desktop shell folder
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   307
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
    private native void initDesktop();
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   309
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
    // Initializes a special, non-file system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    // from one of the above constants
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   312
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
    private native void initSpecial(long desktopIShellFolder, int csidl);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
    /** Marks this folder as being the My Documents (Personal) folder */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
    public void setIsPersonal() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        isPersonal = true;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
     * This method is implemented to make sure that no instances
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
     * of <code>ShellFolder</code> are ever serialized. If <code>isFileSystem()</code> returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
     * <code>true</code>, then the object is representable with an instance of
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
     * <code>java.io.File</code> instead. If not, then the object depends
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
     * on native PIDL state and should not be serialized.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
     *
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
   327
     * @return a <code>java.io.File</code> replacement object. If the folder
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
     * is a not a normal directory, then returns the first non-removable
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
     * drive (normally "C:\").
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
    protected Object writeReplace() throws java.io.ObjectStreamException {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   332
        return invoke(new Callable<File>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   333
            public File call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   334
                if (isFileSystem()) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   335
                    return new File(getPath());
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   336
                } else {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   337
                    Win32ShellFolder2 drives = Win32ShellFolderManager2.getDrives();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   338
                    if (drives != null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   339
                        File[] driveRoots = drives.listFiles();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   340
                        if (driveRoots != null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   341
                            for (int i = 0; i < driveRoots.length; i++) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   342
                                if (driveRoots[i] instanceof Win32ShellFolder2) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   343
                                    Win32ShellFolder2 sf = (Win32ShellFolder2) driveRoots[i];
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   344
                                    if (sf.isFileSystem() && !sf.hasAttribute(ATTRIB_REMOVABLE)) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   345
                                        return new File(sf.getPath());
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   346
                                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   347
                                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
                            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
                        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
                    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   351
                    // Ouch, we have no hard drives. Return something "valid" anyway.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   352
                    return new File("C:\\");
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
            }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   355
        });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
     * Finalizer to clean up any COM objects or PIDLs used by this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
    protected void dispose() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
        disposer.dispose();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
    // Given a (possibly multi-level) relative PIDL (with respect to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
    // the desktop, at least in all of the usage cases in this code),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
    // return a pointer to the next entry. Does not mutate the PIDL in
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
    // any way. Returns 0 if the null terminator is reached.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
    // Needs to be accessible to Win32ShellFolderManager2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
    static native long getNextPIDLEntry(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
    // Given a (possibly multi-level) relative PIDL (with respect to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
    // the desktop, at least in all of the usage cases in this code),
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
    // copy the first entry into a newly-allocated PIDL. Returns 0 if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
    // the PIDL is at the end of the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
    // Needs to be accessible to Win32ShellFolderManager2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
    static native long copyFirstPIDLEntry(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
    // Given a parent's absolute PIDL and our relative PIDL, build an absolute PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
    private static native long combinePIDLs(long ppIDL, long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    // Release a PIDL object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
    // Needs to be accessible to Win32ShellFolderManager2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    static native void releasePIDL(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
    // Release an IShellFolder object
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   389
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
    private static native void releaseIShellFolder(long pIShellFolder);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
     * Accessor for IShellFolder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
     */
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   395
    private long getIShellFolder() {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
        if (disposer.pIShellFolder == 0) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   397
            try {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   398
                disposer.pIShellFolder = invoke(new Callable<Long>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   399
                    public Long call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   400
                        assert(isDirectory());
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   401
                        assert(parent != null);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   402
                        long parentIShellFolder = getParentIShellFolder();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   403
                        if (parentIShellFolder == 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   404
                            throw new InternalError("Parent IShellFolder was null for "
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   405
                                    + getAbsolutePath());
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   406
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   407
                        // We are a directory with a parent and a relative PIDL.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   408
                        // We want to bind to the parent so we get an
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   409
                        // IShellFolder instance associated with us.
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   410
                        long pIShellFolder = bindToObject(parentIShellFolder,
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   411
                                disposer.relativePIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   412
                        if (pIShellFolder == 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   413
                            throw new InternalError("Unable to bind "
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   414
                                    + getAbsolutePath() + " to parent");
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   415
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   416
                        return pIShellFolder;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   417
                    }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   418
                }, RuntimeException.class);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   419
            } catch (InterruptedException e) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   420
                // Ignore error
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   421
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
        return disposer.pIShellFolder;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
     * Get the parent ShellFolder's IShellFolder interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
    public long getParentIShellFolder() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
        Win32ShellFolder2 parent = (Win32ShellFolder2)getParentFile();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
        if (parent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
            // Parent should only be null if this is the desktop, whose
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
            // relativePIDL is relative to its own IShellFolder.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
            return getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
        return parent.getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
     * Accessor for relative PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    public long getRelativePIDL() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
        if (disposer.relativePIDL == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
            throw new InternalError("Should always have a relative PIDL");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        return disposer.relativePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    private long getAbsolutePIDL() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
        if (parent == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
            // This is the desktop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
            return getRelativePIDL();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
            if (disposer.absolutePIDL == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
                disposer.absolutePIDL = combinePIDLs(((Win32ShellFolder2)parent).getAbsolutePIDL(), getRelativePIDL());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   456
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   457
90ce3da70b43 Initial load
duke
parents:
diff changeset
   458
            return disposer.absolutePIDL;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   459
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   460
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   461
90ce3da70b43 Initial load
duke
parents:
diff changeset
   462
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   463
     * Helper function to return the desktop
90ce3da70b43 Initial load
duke
parents:
diff changeset
   464
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   465
    public Win32ShellFolder2 getDesktop() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   466
        return Win32ShellFolderManager2.getDesktop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   467
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   468
90ce3da70b43 Initial load
duke
parents:
diff changeset
   469
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   470
     * Helper function to return the desktop IShellFolder interface
90ce3da70b43 Initial load
duke
parents:
diff changeset
   471
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   472
    public long getDesktopIShellFolder() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   473
        return getDesktop().getIShellFolder();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   474
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   475
90ce3da70b43 Initial load
duke
parents:
diff changeset
   476
    private static boolean pathsEqual(String path1, String path2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   477
        // Same effective implementation as Win32FileSystem
90ce3da70b43 Initial load
duke
parents:
diff changeset
   478
        return path1.equalsIgnoreCase(path2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   479
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   480
90ce3da70b43 Initial load
duke
parents:
diff changeset
   481
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   482
     * Check to see if two ShellFolder objects are the same
90ce3da70b43 Initial load
duke
parents:
diff changeset
   483
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   484
    public boolean equals(Object o) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   485
        if (o == null || !(o instanceof Win32ShellFolder2)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   486
            // Short-circuit circuitous delegation path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   487
            if (!(o instanceof File)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   488
                return super.equals(o);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   489
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   490
            return pathsEqual(getPath(), ((File) o).getPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   491
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   492
        Win32ShellFolder2 rhs = (Win32ShellFolder2) o;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   493
        if ((parent == null && rhs.parent != null) ||
90ce3da70b43 Initial load
duke
parents:
diff changeset
   494
            (parent != null && rhs.parent == null)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   495
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   496
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   497
90ce3da70b43 Initial load
duke
parents:
diff changeset
   498
        if (isFileSystem() && rhs.isFileSystem()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   499
            // Only folders with identical parents can be equal
90ce3da70b43 Initial load
duke
parents:
diff changeset
   500
            return (pathsEqual(getPath(), rhs.getPath()) &&
90ce3da70b43 Initial load
duke
parents:
diff changeset
   501
                    (parent == rhs.parent || parent.equals(rhs.parent)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   502
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   503
90ce3da70b43 Initial load
duke
parents:
diff changeset
   504
        if (parent == rhs.parent || parent.equals(rhs.parent)) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   505
            try {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   506
                return pidlsEqual(getParentIShellFolder(), disposer.relativePIDL, rhs.disposer.relativePIDL);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   507
            } catch (InterruptedException e) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   508
                return false;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   509
            }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   510
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   511
90ce3da70b43 Initial load
duke
parents:
diff changeset
   512
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   513
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   514
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   515
    private static boolean pidlsEqual(final long pIShellFolder, final long pidl1, final long pidl2)
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   516
            throws InterruptedException {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   517
        return invoke(new Callable<Boolean>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   518
            public Boolean call() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   519
                return compareIDs(pIShellFolder, pidl1, pidl2) == 0;
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   520
            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   521
        }, RuntimeException.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   522
    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   523
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   524
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   525
    private static native int compareIDs(long pParentIShellFolder, long pidl1, long pidl2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   526
4269
0283fbab043c 6892340: Part of the CR 6741890 should be forwardported
rupashka
parents: 3978
diff changeset
   527
    private volatile Boolean cachedIsFileSystem;
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   528
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   529
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   530
     * @return Whether this is a file system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   531
     */
2817
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   532
    public boolean isFileSystem() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   533
        if (cachedIsFileSystem == null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   534
            cachedIsFileSystem = hasAttribute(ATTRIB_FILESYSTEM);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   535
        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   536
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   537
        return cachedIsFileSystem;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   538
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   539
90ce3da70b43 Initial load
duke
parents:
diff changeset
   540
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   541
     * Return whether the given attribute flag is set for this object
90ce3da70b43 Initial load
duke
parents:
diff changeset
   542
     */
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   543
    public boolean hasAttribute(final int attribute) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   544
        Boolean result = invoke(new Callable<Boolean>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   545
            public Boolean call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   546
                // Caching at this point doesn't seem to be cost efficient
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   547
                return (getAttributes0(getParentIShellFolder(),
2817
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   548
                    getRelativePIDL(), attribute)
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   549
                    & attribute) != 0;
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   550
            }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   551
        });
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   552
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   553
        return result != null && result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   554
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   555
90ce3da70b43 Initial load
duke
parents:
diff changeset
   556
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   557
     * Returns the queried attributes specified in attrsMask.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   558
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   559
     * Could plausibly be used for attribute caching but have to be
90ce3da70b43 Initial load
duke
parents:
diff changeset
   560
     * very careful not to touch network drives and file system roots
90ce3da70b43 Initial load
duke
parents:
diff changeset
   561
     * with a full attrsMask
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   562
     * NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   563
     */
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   564
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   565
    private static native int getAttributes0(long pParentIShellFolder, long pIDL, int attrsMask);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   566
90ce3da70b43 Initial load
duke
parents:
diff changeset
   567
    // Return the path to the underlying file system object
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   568
    // Should be called from the COM thread
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   569
    private static String getFileSystemPath(final long parentIShellFolder, final long relativePIDL) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   570
        int linkedFolder = ATTRIB_LINK | ATTRIB_FOLDER;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   571
        if (parentIShellFolder == Win32ShellFolderManager2.getNetwork().getIShellFolder() &&
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   572
                getAttributes0(parentIShellFolder, relativePIDL, linkedFolder) == linkedFolder) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   573
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   574
            String s =
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   575
                    getFileSystemPath(Win32ShellFolderManager2.getDesktop().getIShellFolder(),
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   576
                            getLinkLocation(parentIShellFolder, relativePIDL, false));
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   577
            if (s != null && s.startsWith("\\\\")) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   578
                return s;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   579
            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   580
        }
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   581
        return getDisplayNameOf(parentIShellFolder, relativePIDL, SHGDN_FORPARSING);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   582
    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   583
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   584
    // Needs to be accessible to Win32ShellFolderManager2
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   585
    static String getFileSystemPath(final int csidl) throws IOException, InterruptedException {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   586
        return invoke(new Callable<String>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   587
            public String call() throws IOException {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   588
                return getFileSystemPath0(csidl);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   589
            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   590
        }, IOException.class);
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   591
    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   592
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   593
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   594
    private static native String getFileSystemPath0(int csidl) throws IOException;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   595
90ce3da70b43 Initial load
duke
parents:
diff changeset
   596
    // Return whether the path is a network root.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   597
    // Path is assumed to be non-null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   598
    private static boolean isNetworkRoot(String path) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   599
        return (path.equals("\\\\") || path.equals("\\") || path.equals("//") || path.equals("/"));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   600
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   601
90ce3da70b43 Initial load
duke
parents:
diff changeset
   602
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   603
     * @return The parent shell folder of this shell folder, null if
90ce3da70b43 Initial load
duke
parents:
diff changeset
   604
     * there is no parent
90ce3da70b43 Initial load
duke
parents:
diff changeset
   605
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   606
    public File getParentFile() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   607
        return parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   608
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   609
90ce3da70b43 Initial load
duke
parents:
diff changeset
   610
    public boolean isDirectory() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   611
        if (isDir == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   612
            // Folders with SFGAO_BROWSABLE have "shell extension" handlers and are
3507
1610d6f5a0e3 6461173: One JCK test([NewFolderAction0001]) failed on Windows due to lack of PropertyPermission(s)
rupashka
parents: 3346
diff changeset
   613
            // not traversable in JFileChooser.
1610d6f5a0e3 6461173: One JCK test([NewFolderAction0001]) failed on Windows due to lack of PropertyPermission(s)
rupashka
parents: 3346
diff changeset
   614
            if (hasAttribute(ATTRIB_FOLDER) && !hasAttribute(ATTRIB_BROWSABLE)) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   615
                isDir = Boolean.TRUE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   616
            } else if (isLink()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   617
                ShellFolder linkLocation = getLinkLocation(false);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   618
                isDir = Boolean.valueOf(linkLocation != null && linkLocation.isDirectory());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   619
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   620
                isDir = Boolean.FALSE;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   621
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   622
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   623
        return isDir.booleanValue();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   624
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   625
90ce3da70b43 Initial load
duke
parents:
diff changeset
   626
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   627
     * Functions for enumerating an IShellFolder's children
90ce3da70b43 Initial load
duke
parents:
diff changeset
   628
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   629
    // Returns an IEnumIDList interface for an IShellFolder.  The value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   630
    // returned must be released using releaseEnumObjects().
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   631
    private long getEnumObjects(final boolean includeHiddenFiles) throws InterruptedException {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   632
        return invoke(new Callable<Long>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   633
            public Long call() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   634
                boolean isDesktop = disposer.pIShellFolder == getDesktopIShellFolder();
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   635
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   636
                return getEnumObjects(disposer.pIShellFolder, isDesktop, includeHiddenFiles);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   637
            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   638
        }, RuntimeException.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   639
    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   640
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   641
    // Returns an IEnumIDList interface for an IShellFolder.  The value
90ce3da70b43 Initial load
duke
parents:
diff changeset
   642
    // returned must be released using releaseEnumObjects().
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   643
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   644
    private native long getEnumObjects(long pIShellFolder, boolean isDesktop,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   645
                                       boolean includeHiddenFiles);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   646
    // Returns the next sequential child as a relative PIDL
90ce3da70b43 Initial load
duke
parents:
diff changeset
   647
    // from an IEnumIDList interface.  The value returned must
90ce3da70b43 Initial load
duke
parents:
diff changeset
   648
    // be released using releasePIDL().
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   649
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   650
    private native long getNextChild(long pEnumObjects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   651
    // Releases the IEnumIDList interface
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   652
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   653
    private native void releaseEnumObjects(long pEnumObjects);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   654
90ce3da70b43 Initial load
duke
parents:
diff changeset
   655
    // Returns the IShellFolder of a child from a parent IShellFolder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   656
    // and a relative PIDL.  The value returned must be released
90ce3da70b43 Initial load
duke
parents:
diff changeset
   657
    // using releaseIShellFolder().
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   658
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   659
    private static native long bindToObject(long parentIShellFolder, long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   660
90ce3da70b43 Initial load
duke
parents:
diff changeset
   661
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   662
     * @return An array of shell folders that are children of this shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   663
     *         object. The array will be empty if the folder is empty.  Returns
90ce3da70b43 Initial load
duke
parents:
diff changeset
   664
     *         <code>null</code> if this shellfolder does not denote a directory.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   665
     */
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   666
    public File[] listFiles(final boolean includeHiddenFiles) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   667
        SecurityManager security = System.getSecurityManager();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   668
        if (security != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   669
            security.checkRead(getPath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   670
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   671
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   672
        try {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   673
            return invoke(new Callable<File[]>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   674
                public File[] call() throws InterruptedException {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   675
                    if (!isDirectory()) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   676
                        return null;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   677
                    }
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   678
                    // Links to directories are not directories and cannot be parents.
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   679
                    // This does not apply to folders in My Network Places (NetHood)
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   680
                    // because they are both links and real directories!
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   681
                    if (isLink() && !hasAttribute(ATTRIB_FOLDER)) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   682
                        return new File[0];
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   683
                    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   684
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   685
                    Win32ShellFolder2 desktop = Win32ShellFolderManager2.getDesktop();
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   686
                    Win32ShellFolder2 personal = Win32ShellFolderManager2.getPersonal();
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   687
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   688
                    // If we are a directory, we have a parent and (at least) a
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   689
                    // relative PIDL. We must first ensure we are bound to the
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   690
                    // parent so we have an IShellFolder to query.
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   691
                    long pIShellFolder = getIShellFolder();
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   692
                    // Now we can enumerate the objects in this folder.
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   693
                    ArrayList<Win32ShellFolder2> list = new ArrayList<Win32ShellFolder2>();
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   694
                    long pEnumObjects = getEnumObjects(includeHiddenFiles);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   695
                    if (pEnumObjects != 0) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   696
                        long childPIDL;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   697
                        int testedAttrs = ATTRIB_FILESYSTEM | ATTRIB_FILESYSANCESTOR;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   698
                        do {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   699
                            childPIDL = getNextChild(pEnumObjects);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   700
                            boolean releasePIDL = true;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   701
                            if (childPIDL != 0 &&
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   702
                                    (getAttributes0(pIShellFolder, childPIDL, testedAttrs) & testedAttrs) != 0) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   703
                                Win32ShellFolder2 childFolder;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   704
                                if (Win32ShellFolder2.this.equals(desktop)
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   705
                                        && personal != null
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   706
                                        && pidlsEqual(pIShellFolder, childPIDL, personal.disposer.relativePIDL)) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   707
                                    childFolder = personal;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   708
                                } else {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   709
                                    childFolder = new Win32ShellFolder2(Win32ShellFolder2.this, childPIDL);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   710
                                    releasePIDL = false;
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   711
                                }
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   712
                                list.add(childFolder);
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   713
                            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   714
                            if (releasePIDL) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   715
                                releasePIDL(childPIDL);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   716
                            }
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   717
                        } while (childPIDL != 0 && !Thread.currentThread().isInterrupted());
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   718
                        releaseEnumObjects(pEnumObjects);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   719
                    }
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   720
                    return Thread.currentThread().isInterrupted()
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   721
                        ? new File[0]
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   722
                        : list.toArray(new ShellFolder[list.size()]);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   723
                }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   724
            }, InterruptedException.class);
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   725
        } catch (InterruptedException e) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   726
            return new File[0];
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   727
        }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   728
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   729
90ce3da70b43 Initial load
duke
parents:
diff changeset
   730
90ce3da70b43 Initial load
duke
parents:
diff changeset
   731
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   732
     * Look for (possibly special) child folder by it's path
90ce3da70b43 Initial load
duke
parents:
diff changeset
   733
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   734
     * @return The child shellfolder, or null if not found.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   735
     */
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   736
    Win32ShellFolder2 getChildByPath(final String filePath) throws InterruptedException {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   737
        return invoke(new Callable<Win32ShellFolder2>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   738
            public Win32ShellFolder2 call() throws InterruptedException {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   739
                long pIShellFolder = getIShellFolder();
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   740
                long pEnumObjects = getEnumObjects(true);
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   741
                Win32ShellFolder2 child = null;
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   742
                long childPIDL;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   743
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   744
                while ((childPIDL = getNextChild(pEnumObjects)) != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   745
                    if (getAttributes0(pIShellFolder, childPIDL, ATTRIB_FILESYSTEM) != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   746
                        String path = getFileSystemPath(pIShellFolder, childPIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   747
                        if (path != null && path.equalsIgnoreCase(filePath)) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   748
                            long childIShellFolder = bindToObject(pIShellFolder, childPIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   749
                            child = new Win32ShellFolder2(Win32ShellFolder2.this,
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   750
                                    childIShellFolder, childPIDL, path);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   751
                            break;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   752
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   753
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   754
                    releasePIDL(childPIDL);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   755
                }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   756
                releaseEnumObjects(pEnumObjects);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   757
                return child;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   758
            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   759
        }, InterruptedException.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   760
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   761
4269
0283fbab043c 6892340: Part of the CR 6741890 should be forwardported
rupashka
parents: 3978
diff changeset
   762
    private volatile Boolean cachedIsLink;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   763
90ce3da70b43 Initial load
duke
parents:
diff changeset
   764
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   765
     * @return Whether this shell folder is a link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   766
     */
2817
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
   767
    public boolean isLink() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   768
        if (cachedIsLink == null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   769
            cachedIsLink = hasAttribute(ATTRIB_LINK);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   770
        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   771
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   772
        return cachedIsLink;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   773
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   774
90ce3da70b43 Initial load
duke
parents:
diff changeset
   775
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   776
     * @return Whether this shell folder is marked as hidden
90ce3da70b43 Initial load
duke
parents:
diff changeset
   777
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   778
    public boolean isHidden() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   779
        return hasAttribute(ATTRIB_HIDDEN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   780
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   781
90ce3da70b43 Initial load
duke
parents:
diff changeset
   782
90ce3da70b43 Initial load
duke
parents:
diff changeset
   783
    // Return the link location of a shell folder
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   784
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   785
    private static native long getLinkLocation(long parentIShellFolder,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   786
                                        long relativePIDL, boolean resolve);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   787
90ce3da70b43 Initial load
duke
parents:
diff changeset
   788
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   789
     * @return The shell folder linked to by this shell folder, or null
90ce3da70b43 Initial load
duke
parents:
diff changeset
   790
     * if this shell folder is not a link or is a broken or invalid link
90ce3da70b43 Initial load
duke
parents:
diff changeset
   791
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   792
    public ShellFolder getLinkLocation()  {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   793
        return getLinkLocation(true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   794
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   795
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   796
    private ShellFolder getLinkLocation(final boolean resolve) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   797
        return invoke(new Callable<ShellFolder>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   798
            public ShellFolder call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   799
                if (!isLink()) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   800
                    return null;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   801
                }
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   802
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   803
                ShellFolder location = null;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   804
                long linkLocationPIDL = getLinkLocation(getParentIShellFolder(),
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   805
                        getRelativePIDL(), resolve);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   806
                if (linkLocationPIDL != 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   807
                    try {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   808
                        location =
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   809
                                Win32ShellFolderManager2.createShellFolderFromRelativePIDL(getDesktop(),
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   810
                                        linkLocationPIDL);
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   811
                    } catch (InterruptedException e) {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   812
                        // Return null
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   813
                    } catch (InternalError e) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   814
                        // Could be a link to a non-bindable object, such as a network connection
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   815
                        // TODO: getIShellFolder() should throw FileNotFoundException instead
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   816
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   817
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   818
                return location;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   819
            }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   820
        });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   821
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   822
90ce3da70b43 Initial load
duke
parents:
diff changeset
   823
    // Parse a display name into a PIDL relative to the current IShellFolder.
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   824
    long parseDisplayName(final String name) throws IOException, InterruptedException {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   825
        return invoke(new Callable<Long>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   826
            public Long call() throws IOException {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   827
                return parseDisplayName0(getIShellFolder(), name);
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   828
            }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   829
        }, IOException.class);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   830
    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   831
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   832
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   833
    private static native long parseDisplayName0(long pIShellFolder, String name) throws IOException;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   834
90ce3da70b43 Initial load
duke
parents:
diff changeset
   835
    // Return the display name of a shell folder
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   836
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   837
    private static native String getDisplayNameOf(long parentIShellFolder,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   838
                                                  long relativePIDL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   839
                                                  int attrs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   840
90ce3da70b43 Initial load
duke
parents:
diff changeset
   841
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   842
     * @return The name used to display this shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   843
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   844
    public String getDisplayName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   845
        if (displayName == null) {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   846
            displayName =
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   847
                invoke(new Callable<String>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   848
                    public String call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   849
                        return getDisplayNameOf(getParentIShellFolder(),
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   850
                                getRelativePIDL(), SHGDN_NORMAL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   851
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   852
                });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   853
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   854
        return displayName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   855
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   856
90ce3da70b43 Initial load
duke
parents:
diff changeset
   857
    // Return the folder type of a shell folder
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   858
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   859
    private static native String getFolderType(long pIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   860
90ce3da70b43 Initial load
duke
parents:
diff changeset
   861
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   862
     * @return The type of shell folder as a string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   863
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   864
    public String getFolderType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   865
        if (folderType == null) {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   866
            final long absolutePIDL = getAbsolutePIDL();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   867
            folderType =
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   868
                invoke(new Callable<String>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   869
                    public String call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   870
                        return getFolderType(absolutePIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   871
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   872
                });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   873
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   874
        return folderType;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   875
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   876
90ce3da70b43 Initial load
duke
parents:
diff changeset
   877
    // Return the executable type of a file system shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   878
    private native String getExecutableType(String path);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   879
90ce3da70b43 Initial load
duke
parents:
diff changeset
   880
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   881
     * @return The executable type as a string
90ce3da70b43 Initial load
duke
parents:
diff changeset
   882
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   883
    public String getExecutableType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   884
        if (!isFileSystem()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   885
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   886
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   887
        return getExecutableType(getAbsolutePath());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   888
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   889
90ce3da70b43 Initial load
duke
parents:
diff changeset
   890
90ce3da70b43 Initial load
duke
parents:
diff changeset
   891
90ce3da70b43 Initial load
duke
parents:
diff changeset
   892
    // Icons
90ce3da70b43 Initial load
duke
parents:
diff changeset
   893
90ce3da70b43 Initial load
duke
parents:
diff changeset
   894
    private static Map smallSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   895
    private static Map largeSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   896
    private static Map smallLinkedSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   897
    private static Map largeLinkedSystemImages = new HashMap();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   898
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   899
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   900
    private static native long getIShellIcon(long pIShellFolder);
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   901
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   902
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   903
    private static native int getIconIndex(long parentIShellIcon, long relativePIDL);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   904
90ce3da70b43 Initial load
duke
parents:
diff changeset
   905
    // Return the icon of a file system shell folder in the form of an HICON
90ce3da70b43 Initial load
duke
parents:
diff changeset
   906
    private static native long getIcon(String absolutePath, boolean getLargeIcon);
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   907
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   908
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   909
    private static native long extractIcon(long parentIShellFolder, long relativePIDL,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   910
                                           boolean getLargeIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   911
90ce3da70b43 Initial load
duke
parents:
diff changeset
   912
    // Returns an icon from the Windows system icon list in the form of an HICON
90ce3da70b43 Initial load
duke
parents:
diff changeset
   913
    private static native long getSystemIcon(int iconID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   914
    private static native long getIconResource(String libName, int iconID,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   915
                                               int cxDesired, int cyDesired,
90ce3da70b43 Initial load
duke
parents:
diff changeset
   916
                                               boolean useVGAColors);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   917
                                               // Note: useVGAColors is ignored on XP and later
90ce3da70b43 Initial load
duke
parents:
diff changeset
   918
90ce3da70b43 Initial load
duke
parents:
diff changeset
   919
    // Return the bits from an HICON.  This has a side effect of setting
90ce3da70b43 Initial load
duke
parents:
diff changeset
   920
    // the imageHash variable for efficient caching / comparing.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   921
    private static native int[] getIconBits(long hIcon, int iconSize);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   922
    // Dispose the HICON
90ce3da70b43 Initial load
duke
parents:
diff changeset
   923
    private static native void disposeIcon(long hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   924
3978
b024e01b947a 6840086: JFileChooser lacks icons on top right when running on Windows 7
rupashka
parents: 3507
diff changeset
   925
    static native int[] getStandardViewButton0(int iconIndex);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   926
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   927
    // Should be called from the COM thread
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   928
    private long getIShellIcon() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   929
        if (pIShellIcon == -1L) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   930
            pIShellIcon = getIShellIcon(getIShellFolder());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   931
        }
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   932
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   933
        return pIShellIcon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   934
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   935
90ce3da70b43 Initial load
duke
parents:
diff changeset
   936
    private static Image makeIcon(long hIcon, boolean getLargeIcon) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   937
        if (hIcon != 0L && hIcon != -1L) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   938
            // Get the bits.  This has the side effect of setting the imageHash value for this object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   939
            int size = getLargeIcon ? 32 : 16;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   940
            int[] iconBits = getIconBits(hIcon, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   941
            if (iconBits != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   942
                BufferedImage img = new BufferedImage(size, size, BufferedImage.TYPE_INT_ARGB);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   943
                img.setRGB(0, 0, size, size, iconBits, 0, size);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   944
                return img;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   945
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   946
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   947
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   948
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   949
90ce3da70b43 Initial load
duke
parents:
diff changeset
   950
90ce3da70b43 Initial load
duke
parents:
diff changeset
   951
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   952
     * @return The icon image used to display this shell folder
90ce3da70b43 Initial load
duke
parents:
diff changeset
   953
     */
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   954
    public Image getIcon(final boolean getLargeIcon) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   955
        Image icon = getLargeIcon ? largeIcon : smallIcon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   956
        if (icon == null) {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   957
            icon =
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   958
                invoke(new Callable<Image>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
   959
                    public Image call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   960
                        Image newIcon = null;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   961
                        if (isFileSystem()) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   962
                            long parentIShellIcon = (parent != null)
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   963
                                ? ((Win32ShellFolder2) parent).getIShellIcon()
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   964
                                : 0L;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   965
                            long relativePIDL = getRelativePIDL();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   966
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   967
                            // These are cached per type (using the index in the system image list)
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   968
                            int index = getIconIndex(parentIShellIcon, relativePIDL);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   969
                            if (index > 0) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   970
                                Map imageCache;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   971
                                if (isLink()) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   972
                                    imageCache = getLargeIcon ? largeLinkedSystemImages : smallLinkedSystemImages;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   973
                                } else {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   974
                                    imageCache = getLargeIcon ? largeSystemImages : smallSystemImages;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   975
                                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   976
                                newIcon = (Image) imageCache.get(Integer.valueOf(index));
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   977
                                if (newIcon == null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   978
                                    long hIcon = getIcon(getAbsolutePath(), getLargeIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   979
                                    newIcon = makeIcon(hIcon, getLargeIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   980
                                    disposeIcon(hIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   981
                                    if (newIcon != null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   982
                                        imageCache.put(Integer.valueOf(index), newIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   983
                                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   984
                                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   985
                            }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   986
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   987
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   988
                        if (newIcon == null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   989
                            // These are only cached per object
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   990
                            long hIcon = extractIcon(getParentIShellFolder(),
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   991
                                getRelativePIDL(), getLargeIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   992
                            newIcon = makeIcon(hIcon, getLargeIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   993
                            disposeIcon(hIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   994
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   995
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   996
                        if (newIcon == null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   997
                            newIcon = Win32ShellFolder2.super.getIcon(getLargeIcon);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   998
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
   999
                        return newIcon;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1000
                    }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1001
                });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1002
            if (getLargeIcon) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1003
                largeIcon = icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1004
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1005
                smallIcon = icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1006
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1007
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1008
        return icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1009
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1010
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1011
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1012
     * Gets an icon from the Windows system icon list as an <code>Image</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1013
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1014
    static Image getSystemIcon(SystemIcon iconType) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1015
        long hIcon = getSystemIcon(iconType.getIconID());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1016
        Image icon = makeIcon(hIcon, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1017
        disposeIcon(hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1018
        return icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1019
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1020
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1021
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1022
     * Gets an icon from the Windows system icon list as an <code>Image</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1023
     */
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
  1024
    static Image getShell32Icon(int iconID, boolean getLargeIcon) {
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1025
        boolean useVGAColors = true; // Will be ignored on XP and later
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1026
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
  1027
        int size = getLargeIcon ? 32 : 16;
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
  1028
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1029
        Toolkit toolkit = Toolkit.getDefaultToolkit();
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1030
        String shellIconBPP = (String)toolkit.getDesktopProperty("win.icon.shellIconBPP");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1031
        if (shellIconBPP != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1032
            useVGAColors = shellIconBPP.equals("4");
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1033
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1034
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
  1035
        long hIcon = getIconResource("shell32.dll", iconID, size, size, useVGAColors);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1036
        if (hIcon != 0) {
454
2f4f4fef8880 6210674: FileChooser fails to load custom harddrive icon and gets NullPointerException
rupashka
parents: 2
diff changeset
  1037
            Image icon = makeIcon(hIcon, getLargeIcon);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1038
            disposeIcon(hIcon);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1039
            return icon;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1040
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1041
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1042
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1043
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1044
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1045
     * Returns the canonical form of this abstract pathname.  Equivalent to
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1046
     * <code>new&nbsp;Win32ShellFolder2(getParentFile(), this.{@link java.io.File#getCanonicalPath}())</code>.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1047
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1048
     * @see java.io.File#getCanonicalFile
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1049
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1050
    public File getCanonicalFile() throws IOException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1051
        return this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1052
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1053
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1054
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1055
     * Indicates whether this is a special folder (includes My Documents)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1056
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1057
    public boolean isSpecial() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1058
        return isPersonal || !isFileSystem() || (this == getDesktop());
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1059
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1060
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1061
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1062
     * Compares this object with the specified object for order.
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1063
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1064
     * @see sun.awt.shell.ShellFolder#compareTo(File)
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1065
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1066
    public int compareTo(File file2) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1067
        if (!(file2 instanceof Win32ShellFolder2)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1068
            if (isFileSystem() && !isSpecial()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1069
                return super.compareTo(file2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1070
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1071
                return -1; // Non-file shellfolders sort before files
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1072
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1073
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1074
        return Win32ShellFolderManager2.compareShellFolders(this, (Win32ShellFolder2) file2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1075
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1076
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1077
    // native constants from commctrl.h
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1078
    private static final int LVCFMT_LEFT = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1079
    private static final int LVCFMT_RIGHT = 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1080
    private static final int LVCFMT_CENTER = 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1081
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1082
    public ShellFolderColumnInfo[] getFolderColumns() {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1083
        return invoke(new Callable<ShellFolderColumnInfo[]>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1084
            public ShellFolderColumnInfo[] call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1085
                ShellFolderColumnInfo[] columns = doGetColumnInfo(getIShellFolder());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1086
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1087
                if (columns != null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1088
                    List<ShellFolderColumnInfo> notNullColumns =
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1089
                            new ArrayList<ShellFolderColumnInfo>();
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1090
                    for (int i = 0; i < columns.length; i++) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1091
                        ShellFolderColumnInfo column = columns[i];
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1092
                        if (column != null) {
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1093
                            column.setAlignment(column.getAlignment() == LVCFMT_RIGHT
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1094
                                    ? SwingConstants.RIGHT
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1095
                                    : column.getAlignment() == LVCFMT_CENTER
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1096
                                    ? SwingConstants.CENTER
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1097
                                    : SwingConstants.LEADING);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1098
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1099
                            column.setComparator(new ColumnComparator(getIShellFolder(), i));
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1100
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1101
                            notNullColumns.add(column);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1102
                        }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1103
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1104
                    columns = new ShellFolderColumnInfo[notNullColumns.size()];
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1105
                    notNullColumns.toArray(columns);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1106
                }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1107
                return columns;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1108
            }
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1109
        });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1110
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1111
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1112
    public Object getFolderColumnValue(final int column) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1113
        return invoke(new Callable<Object>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1114
            public Object call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1115
                return doGetColumnValue(getParentIShellFolder(), getRelativePIDL(), column);
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1116
            }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1117
        });
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1118
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1119
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1120
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1121
    private native ShellFolderColumnInfo[] doGetColumnInfo(long iShellFolder2);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1122
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1123
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1124
    private native Object doGetColumnValue(long parentIShellFolder2, long childPIDL, int columnIdx);
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1125
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1126
    // NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1127
    private static native int compareIDsByColumn(long pParentIShellFolder, long pidl1, long pidl2, int columnIdx);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1128
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1129
2817
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1130
    public void sortChildren(final List<? extends File> files) {
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1131
        // To avoid loads of synchronizations with Invoker and improve performance we
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1132
        // synchronize the whole code of the sort method once
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1133
        invoke(new Callable<Void>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1134
            public Void call() {
2817
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1135
                Collections.sort(files, new ColumnComparator(getIShellFolder(), 0));
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1136
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1137
                return null;
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1138
            }
f171f2417978 6713352: Deadlock in JFileChooser with synchronized custom FileSystemView
rupashka
parents: 2489
diff changeset
  1139
        });
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1140
    }
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1141
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1142
    private static class ColumnComparator implements Comparator<File> {
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1143
        private final long parentIShellFolder;
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1144
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1145
        private final int columnIdx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1146
678
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1147
        public ColumnComparator(long parentIShellFolder, int columnIdx) {
7d331a53a753 6571802: 'Shared Documents' listed in-between C,D drives in the JFileChooser, does not match with native
rupashka
parents: 454
diff changeset
  1148
            this.parentIShellFolder = parentIShellFolder;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1149
            this.columnIdx = columnIdx;
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1150
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1151
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1152
        // compares 2 objects within this folder by the specified column
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1153
        public int compare(final File o, final File o1) {
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1154
            Integer result = invoke(new Callable<Integer>() {
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1155
                public Integer call() {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1156
                    if (o instanceof Win32ShellFolder2
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1157
                        && o1 instanceof Win32ShellFolder2) {
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1158
                        // delegates comparison to native method
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1159
                        return compareIDsByColumn(parentIShellFolder,
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1160
                            ((Win32ShellFolder2) o).getRelativePIDL(),
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1161
                            ((Win32ShellFolder2) o1).getRelativePIDL(),
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1162
                            columnIdx);
2489
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1163
                    }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1164
                    return 0;
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1165
                }
5052722686e2 6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
rupashka
parents: 715
diff changeset
  1166
            });
3346
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1167
1c65be97eaa2 6460525: javax/swing/JFileChooser/6396844/TwentyThousandTest.java times out
rupashka
parents: 2817
diff changeset
  1168
            return result == null ? 0 : result;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1169
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1170
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
  1171
}