提交 26b463b3 编写于 作者: R rupashka

6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp

Reviewed-by: peterz, loneid
上级 5f55e0e8
...@@ -27,6 +27,7 @@ package javax.swing.plaf.basic; ...@@ -27,6 +27,7 @@ package javax.swing.plaf.basic;
import java.io.File; import java.io.File;
import java.util.*; import java.util.*;
import java.util.concurrent.Callable;
import javax.swing.*; import javax.swing.*;
import javax.swing.filechooser.*; import javax.swing.filechooser.*;
import javax.swing.event.*; import javax.swing.event.*;
...@@ -223,113 +224,115 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh ...@@ -223,113 +224,115 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
this.fid = fid; this.fid = fid;
} }
private void invokeLater(DoChangeContents runnable) {
runnables.addElement(runnable);
SwingUtilities.invokeLater(runnable);
}
public void run() { public void run() {
run0(); run0();
setBusy(false, fid); setBusy(false, fid);
} }
public void run0() { public void run0() {
FileSystemView fileSystem = filechooser.getFileSystemView(); DoChangeContents doChangeContents = ShellFolder.getInvoker().invoke(new Callable<DoChangeContents>() {
public DoChangeContents call() throws Exception {
FileSystemView fileSystem = filechooser.getFileSystemView();
File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled()); File[] list = fileSystem.getFiles(currentDirectory, filechooser.isFileHidingEnabled());
Vector<File> acceptsList = new Vector<File>(); Vector<File> acceptsList = new Vector<File>();
if (isInterrupted()) { if (isInterrupted()) {
return; return null;
} }
// run through the file list, add directories and selectable files to fileCache // run through the file list, add directories and selectable files to fileCache
for (File file : list) { for (File file : list) {
if (filechooser.accept(file)) { if (filechooser.accept(file)) {
acceptsList.addElement(file); acceptsList.addElement(file);
} }
} }
if (isInterrupted()) { if (isInterrupted()) {
return; return null;
} }
// First sort alphabetically by filename // First sort alphabetically by filename
sort(acceptsList); sort(acceptsList);
Vector<File> newDirectories = new Vector<File>(50); Vector<File> newDirectories = new Vector<File>(50);
Vector<File> newFiles = new Vector<File>(); Vector<File> newFiles = new Vector<File>();
// run through list grabbing directories in chunks of ten // run through list grabbing directories in chunks of ten
for(int i = 0; i < acceptsList.size(); i++) { for (int i = 0; i < acceptsList.size(); i++) {
File f = acceptsList.elementAt(i); File f = acceptsList.elementAt(i);
boolean isTraversable = filechooser.isTraversable(f); boolean isTraversable = filechooser.isTraversable(f);
if (isTraversable) { if (isTraversable) {
newDirectories.addElement(f); newDirectories.addElement(f);
} else if (!isTraversable && filechooser.isFileSelectionEnabled()) { } else if (!isTraversable && filechooser.isFileSelectionEnabled()) {
newFiles.addElement(f); newFiles.addElement(f);
} }
if(isInterrupted()) { if (isInterrupted()) {
return; return null;
} }
} }
Vector<File> newFileCache = new Vector<File>(newDirectories); Vector<File> newFileCache = new Vector<File>(newDirectories);
newFileCache.addAll(newFiles); newFileCache.addAll(newFiles);
int newSize = newFileCache.size(); int newSize = newFileCache.size();
int oldSize = fileCache.size(); int oldSize = fileCache.size();
if (newSize > oldSize) { if (newSize > oldSize) {
//see if interval is added //see if interval is added
int start = oldSize; int start = oldSize;
int end = newSize; int end = newSize;
for (int i = 0; i < oldSize; i++) { for (int i = 0; i < oldSize; i++) {
if (!newFileCache.get(i).equals(fileCache.get(i))) { if (!newFileCache.get(i).equals(fileCache.get(i))) {
start = i; start = i;
for (int j = i; j < newSize; j++) { for (int j = i; j < newSize; j++) {
if (newFileCache.get(j).equals(fileCache.get(i))) { if (newFileCache.get(j).equals(fileCache.get(i))) {
end = j; end = j;
break;
}
}
break; break;
} }
} }
break; if (start >= 0 && end > start
} && newFileCache.subList(end, newSize).equals(fileCache.subList(start, oldSize))) {
} if (isInterrupted()) {
if (start >= 0 && end > start return null;
&& newFileCache.subList(end, newSize).equals(fileCache.subList(start, oldSize))) { }
if(isInterrupted()) { return new DoChangeContents(newFileCache.subList(start, end), start, null, 0, fid);
return; }
} } else if (newSize < oldSize) {
invokeLater(new DoChangeContents(newFileCache.subList(start, end), start, null, 0, fid)); //see if interval is removed
newFileCache = null; int start = -1;
} int end = -1;
} else if (newSize < oldSize) { for (int i = 0; i < newSize; i++) {
//see if interval is removed if (!newFileCache.get(i).equals(fileCache.get(i))) {
int start = -1; start = i;
int end = -1; end = i + oldSize - newSize;
for (int i = 0; i < newSize; i++) { break;
if (!newFileCache.get(i).equals(fileCache.get(i))) { }
start = i; }
end = i + oldSize - newSize; if (start >= 0 && end > start
break; && fileCache.subList(end, oldSize).equals(newFileCache.subList(start, newSize))) {
if (isInterrupted()) {
return null;
}
return new DoChangeContents(null, 0, new Vector(fileCache.subList(start, end)), start, fid);
}
} }
} if (!fileCache.equals(newFileCache)) {
if (start >= 0 && end > start if (isInterrupted()) {
&& fileCache.subList(end, oldSize).equals(newFileCache.subList(start, newSize))) { cancelRunnables(runnables);
if(isInterrupted()) { }
return; return new DoChangeContents(newFileCache, 0, fileCache, 0, fid);
} }
invokeLater(new DoChangeContents(null, 0, new Vector<File>(fileCache.subList(start, end)), return null;
start, fid));
newFileCache = null;
}
}
if (newFileCache != null && !fileCache.equals(newFileCache)) {
if (isInterrupted()) {
cancelRunnables(runnables);
} }
invokeLater(new DoChangeContents(newFileCache, 0, fileCache, 0, fid)); });
if (doChangeContents != null) {
runnables.addElement(doChangeContents);
SwingUtilities.invokeLater(doChangeContents);
} }
} }
......
...@@ -31,6 +31,7 @@ import java.awt.Toolkit; ...@@ -31,6 +31,7 @@ import java.awt.Toolkit;
import java.io.*; import java.io.*;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.*; import java.util.*;
import java.util.concurrent.Callable;
/** /**
* @author Michael Martak * @author Michael Martak
...@@ -461,6 +462,35 @@ public abstract class ShellFolder extends File { ...@@ -461,6 +462,35 @@ public abstract class ShellFolder extends File {
return null; return null;
} }
private static Invoker invoker;
/**
* Provides the single access point to the {@link Invoker}. It is guaranteed that the value
* returned by this method will be always the same.
*
* @return the singleton instance of {@link Invoker}
*/
public static Invoker getInvoker() {
if (invoker == null) {
invoker = shellFolderManager.createInvoker();
}
return invoker;
}
/**
* Interface allowing to invoke tasks in different environments on different platforms.
*/
public static interface Invoker {
/**
* Invokes a callable task. If the {@code task} throws a checked exception,
* it will be wrapped into a {@link RuntimeException}
*
* @param task a task to invoke
* @return the result of {@code task}'s invokation
*/
<T> T invoke(Callable<T> task);
}
/** /**
* Provides a default comparator for the default column set * Provides a default comparator for the default column set
*/ */
......
...@@ -27,6 +27,7 @@ package sun.awt.shell; ...@@ -27,6 +27,7 @@ package sun.awt.shell;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.util.concurrent.Callable;
/** /**
* @author Michael Martak * @author Michael Martak
...@@ -96,9 +97,23 @@ class ShellFolderManager { ...@@ -96,9 +97,23 @@ class ShellFolderManager {
} }
public boolean isFileSystemRoot(File dir) { public boolean isFileSystemRoot(File dir) {
if (dir instanceof ShellFolder && !((ShellFolder)dir).isFileSystem()) { if (dir instanceof ShellFolder && !((ShellFolder) dir).isFileSystem()) {
return false; return false;
} }
return (dir.getParentFile() == null); return (dir.getParentFile() == null);
} }
protected ShellFolder.Invoker createInvoker() {
return new DirectInvoker();
}
private static class DirectInvoker implements ShellFolder.Invoker {
public <T> T invoke(Callable<T> task) {
try {
return task.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
} }
...@@ -34,6 +34,7 @@ import java.text.DateFormat; ...@@ -34,6 +34,7 @@ import java.text.DateFormat;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.*; import java.util.*;
import java.util.List; import java.util.List;
import java.util.concurrent.Callable;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.*; import javax.swing.border.*;
...@@ -900,6 +901,16 @@ public class FilePane extends JPanel implements PropertyChangeListener { ...@@ -900,6 +901,16 @@ public class FilePane extends JPanel implements PropertyChangeListener {
} }
} }
@Override
public void sort() {
ShellFolder.getInvoker().invoke(new Callable<Void>() {
public Void call() throws Exception {
DetailsTableRowSorter.super.sort();
return null;
}
});
}
public void modelStructureChanged() { public void modelStructureChanged() {
super.modelStructureChanged(); super.modelStructureChanged();
updateComparators(detailsTableModel.getColumns()); updateComparators(detailsTableModel.getColumns());
......
...@@ -31,7 +31,10 @@ import java.io.File; ...@@ -31,7 +31,10 @@ import java.io.File;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.security.AccessController; import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.*; import java.util.*;
import java.util.concurrent.*;
import sun.security.action.LoadLibraryAction; import sun.security.action.LoadLibraryAction;
import static sun.awt.shell.Win32ShellFolder2.*; import static sun.awt.shell.Win32ShellFolder2.*;
...@@ -408,4 +411,102 @@ public class Win32ShellFolderManager2 extends ShellFolderManager { ...@@ -408,4 +411,102 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
return name1.compareTo(name2); return name1.compareTo(name2);
} }
} }
@Override
protected Invoker createInvoker() {
return new ComInvoker();
}
private static class ComInvoker extends ThreadPoolExecutor implements ThreadFactory, ShellFolder.Invoker {
private static Thread comThread;
private ComInvoker() {
super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<Runnable>());
allowCoreThreadTimeOut(false);
setThreadFactory(this);
final Runnable shutdownHook = new Runnable() {
public void run() {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
shutdownNow();
return null;
}
});
}
};
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
Runtime.getRuntime().addShutdownHook(
new Thread(shutdownHook)
);
return null;
}
});
}
public synchronized Thread newThread(final Runnable task) {
final Runnable comRun = new Runnable() {
public void run() {
try {
initializeCom();
task.run();
} finally {
uninitializeCom();
}
}
};
comThread =
AccessController.doPrivileged(
new PrivilegedAction<Thread>() {
public Thread run() {
/* The thread must be a member of a thread group
* which will not get GCed before VM exit.
* Make its parent the top-level thread group.
*/
ThreadGroup tg = Thread.currentThread().getThreadGroup();
for (ThreadGroup tgn = tg;
tgn != null;
tg = tgn, tgn = tg.getParent());
Thread thread = new Thread(tg, comRun, "Swing-Shell");
thread.setDaemon(true);
return thread;
}
}
);
return comThread;
}
public <T> T invoke(Callable<T> task) {
try {
T result;
if (Thread.currentThread() == comThread) {
// if it's already called from the COM
// thread, we don't need to delegate the task
result = task.call();
} else {
Future<T> future = submit(task);
try {
result = future.get();
} catch (InterruptedException e) {
result = null;
future.cancel(true);
}
}
return result;
} catch (Exception e) {
Throwable cause = (e instanceof ExecutionException) ? e.getCause() : e;
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
}
if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(cause);
}
}
}
static native void initializeCom();
static native void uninitializeCom();
} }
...@@ -225,6 +225,34 @@ JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initIDs ...@@ -225,6 +225,34 @@ JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initIDs
FID_folderType = env->GetFieldID(cls, "folderType", "Ljava/lang/String;"); FID_folderType = env->GetFieldID(cls, "folderType", "Ljava/lang/String;");
} }
/*
* Class: sun_awt_shell_Win32ShellFolderManager2
* Method: initializeCom
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolderManager2_initializeCom
(JNIEnv* env, jclass cls)
{
HRESULT hr = ::CoInitialize(NULL);
if (FAILED(hr)) {
char c[64];
sprintf(c, "Could not initialize COM: HRESULT=0x%08X", hr);
JNU_ThrowInternalError(env, c);
}
}
/*
* Class: sun_awt_shell_Win32ShellFolderManager2
* Method: uninitializeCom
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolderManager2_uninitializeCom
(JNIEnv* env, jclass cls)
{
::CoUninitialize();
}
static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) { static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) {
// http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp // http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp
HRESULT hres; HRESULT hres;
...@@ -239,29 +267,6 @@ static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) { ...@@ -239,29 +267,6 @@ static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) {
return (IShellIcon*)NULL; return (IShellIcon*)NULL;
} }
// Fixed 6263669
//
// CoInitialize wrapper
// call CoInitialize to initialize COM in STA mode and check result
// RPC_E_CHANGED_MODE means COM has already been initialized in MTA mode,
// so don't set the flag to call CoUninitialize later
BOOL CoInit(BOOL& doCoUninit) { // returns TRUE if initialized successfully
switch(::CoInitialize(NULL)) {
case S_OK:
case S_FALSE:
doCoUninit = TRUE;
return TRUE;
break;
case RPC_E_CHANGED_MODE:
doCoUninit = FALSE;
return TRUE;
break;
default:
return FALSE;
}
}
/* /*
* Class: sun_awt_shell_Win32ShellFolder2 * Class: sun_awt_shell_Win32ShellFolder2
...@@ -507,10 +512,10 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getAttributes0 ...@@ -507,10 +512,10 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getAttributes0
/* /*
* Class: sun_awt_shell_Win32ShellFolder2 * Class: sun_awt_shell_Win32ShellFolder2
* Method: getFileSystemPath * Method: getFileSystemPath0
* Signature: (I)Ljava/lang/String; * Signature: (I)Ljava/lang/String;
*/ */
JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileSystemPath__I JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileSystemPath0
(JNIEnv* env, jclass cls, jint csidl) (JNIEnv* env, jclass cls, jint csidl)
{ {
LPITEMIDLIST relPIDL; LPITEMIDLIST relPIDL;
...@@ -611,18 +616,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_bindToObject ...@@ -611,18 +616,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_bindToObject
if (SUCCEEDED (hr)) { if (SUCCEEDED (hr)) {
return (jlong)pFolder; return (jlong)pFolder;
} }
if (IS_WINVISTA) {
BOOL doCoUninit;
if (CoInit(doCoUninit)) {
hr = pParent->BindToObject(pidl, NULL, IID_IShellFolder, (void**)&pFolder);
if (doCoUninit) {
::CoUninitialize();
}
if (SUCCEEDED (hr)) {
return (jlong)pFolder;
}
}
}
return 0; return 0;
} }
...@@ -650,7 +643,10 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation ...@@ -650,7 +643,10 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
return NULL; return NULL;
} }
pParent->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret); hres = pParent->GetDisplayNameOf(pidl, SHGDN_NORMAL | SHGDN_FORPARSING, &strret);
if (FAILED(hres)) {
return NULL;
}
switch (strret.uType) { switch (strret.uType) {
case STRRET_CSTR : case STRRET_CSTR :
...@@ -669,10 +665,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation ...@@ -669,10 +665,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
break; break;
} }
BOOL doCoUninit;
if (!CoInit(doCoUninit)) {
return 0;
}
IShellLinkW* psl; IShellLinkW* psl;
hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID *)&psl); hres = ::CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLinkW, (LPVOID *)&psl);
if (SUCCEEDED(hres)) { if (SUCCEEDED(hres)) {
...@@ -692,9 +684,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation ...@@ -692,9 +684,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
} }
psl->Release(); psl->Release();
} }
if (doCoUninit) {
::CoUninitialize();
}
if (SUCCEEDED(hres)) { if (SUCCEEDED(hres)) {
return (jlong)pidl; return (jlong)pidl;
...@@ -741,7 +730,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_parseDisplayName0 ...@@ -741,7 +730,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_parseDisplayName0
/* /*
* Class: sun_awt_shell_Win32ShellFolder2 * Class: sun_awt_shell_Win32ShellFolder2
* Method: getDisplayNameOf * Method: getDisplayNameOf
* Signature: (JJ)Ljava/lang/String; * Signature: (JJI)Ljava/lang/String;
*/ */
JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getDisplayNameOf JNIEXPORT jstring JNICALL Java_sun_awt_shell_Win32ShellFolder2_getDisplayNameOf
(JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL, jint attrs) (JNIEnv* env, jclass cls, jlong parentIShellFolder, jlong relativePIDL, jint attrs)
...@@ -833,10 +822,6 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex ...@@ -833,10 +822,6 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex
} }
INT index = -1; INT index = -1;
BOOL doCoUninit;
if (!CoInit(doCoUninit)) {
return (jint)index;
}
HRESULT hres; HRESULT hres;
// http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp // http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp
...@@ -844,9 +829,6 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex ...@@ -844,9 +829,6 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex
hres = pIShellIcon->GetIconOf(pidl, GIL_FORSHELL, &index); hres = pIShellIcon->GetIconOf(pidl, GIL_FORSHELL, &index);
} }
if (doCoUninit) {
::CoUninitialize();
}
return (jint)index; return (jint)index;
} }
...@@ -866,10 +848,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon ...@@ -866,10 +848,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
} }
HICON hIcon = NULL; HICON hIcon = NULL;
BOOL doCoUninit;
if (!CoInit(doCoUninit)) {
return (jlong)hIcon;
}
HRESULT hres; HRESULT hres;
IExtractIconW* pIcon; IExtractIconW* pIcon;
...@@ -894,9 +872,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon ...@@ -894,9 +872,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
} }
pIcon->Release(); pIcon->Release();
} }
if (doCoUninit) {
::CoUninitialize();
}
return (jlong)hIcon; return (jlong)hIcon;
} }
...@@ -994,14 +969,10 @@ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileChooserB ...@@ -994,14 +969,10 @@ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileChooserB
HINSTANCE libComCtl32; HINSTANCE libComCtl32;
HINSTANCE libShell32; HINSTANCE libShell32;
libShell32 = LoadLibrary(TEXT("shell32.dll")); libShell32 = LoadLibrary(TEXT("shell32.dll"));
if (libShell32 != NULL) { if (libShell32 != NULL) {
long osVersion = GetVersion();
BOOL isVista = (!(osVersion & 0x80000000) && (LOBYTE(LOWORD(osVersion)) >= 6));
hBitmap = (HBITMAP)LoadImage(libShell32, hBitmap = (HBITMAP)LoadImage(libShell32,
isVista ? TEXT("IDB_TB_SH_DEF_16") : MAKEINTRESOURCE(216), IS_WINVISTA ? TEXT("IDB_TB_SH_DEF_16") : MAKEINTRESOURCE(216),
IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION); IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
} }
if (hBitmap == NULL) { if (hBitmap == NULL) {
...@@ -1095,46 +1066,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconResource ...@@ -1095,46 +1066,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconResource
} }
// Helper functions for workaround COM initialization:
static HRESULT GetDetailsOfFolder(
IShellFolder2 *folder,
LPCITEMIDLIST pidl,
UINT column,
SHELLDETAILS *psd)
{
HRESULT hr = folder->GetDetailsOf(pidl, column, psd);
if (IS_WINVISTA && FAILED (hr)) {
BOOL doCoUninit;
if (CoInit(doCoUninit)) {
hr = folder->GetDetailsOf(pidl, column, psd);
if (doCoUninit) {
::CoUninitialize();
}
}
}
return hr;
}
static HRESULT GetDetailsOf(
IShellDetails *details,
LPCITEMIDLIST pidl,
UINT column,
SHELLDETAILS *psd)
{
HRESULT hr = details->GetDetailsOf(pidl, column, psd);
if (IS_WINVISTA && FAILED (hr)) {
BOOL doCoUninit;
if (CoInit(doCoUninit)) {
hr = details->GetDetailsOf(pidl, column, psd);
if (doCoUninit) {
::CoUninitialize();
}
}
}
return hr;
}
/* /*
* Helper function for creating Java column info object * Helper function for creating Java column info object
*/ */
...@@ -1187,7 +1118,7 @@ JNIEXPORT jobjectArray JNICALL ...@@ -1187,7 +1118,7 @@ JNIEXPORT jobjectArray JNICALL
int colNum = -1; int colNum = -1;
hr = S_OK; hr = S_OK;
do{ do{
hr = GetDetailsOfFolder(pIShellFolder2, NULL, ++colNum, &sd); hr = pIShellFolder2->GetDetailsOf(NULL, ++colNum, &sd);
} while (SUCCEEDED (hr)); } while (SUCCEEDED (hr));
jobjectArray columns = jobjectArray columns =
...@@ -1202,7 +1133,7 @@ JNIEXPORT jobjectArray JNICALL ...@@ -1202,7 +1133,7 @@ JNIEXPORT jobjectArray JNICALL
colNum = 0; colNum = 0;
hr = S_OK; hr = S_OK;
while (SUCCEEDED (hr)) { while (SUCCEEDED (hr)) {
hr = GetDetailsOfFolder(pIShellFolder2, NULL, colNum, &sd); hr = pIShellFolder2->GetDetailsOf(NULL, colNum, &sd);
if (SUCCEEDED (hr)) { if (SUCCEEDED (hr)) {
hr = pIShellFolder2->GetDefaultColumnState(colNum, &csFlags); hr = pIShellFolder2->GetDefaultColumnState(colNum, &csFlags);
...@@ -1232,7 +1163,7 @@ JNIEXPORT jobjectArray JNICALL ...@@ -1232,7 +1163,7 @@ JNIEXPORT jobjectArray JNICALL
int colNum = -1; int colNum = -1;
hr = S_OK; hr = S_OK;
do{ do{
hr = GetDetailsOf(pIShellDetails, NULL, ++colNum, &sd); hr = pIShellDetails->GetDetailsOf(NULL, ++colNum, &sd);
} while (SUCCEEDED (hr)); } while (SUCCEEDED (hr));
jobjectArray columns = jobjectArray columns =
...@@ -1246,7 +1177,7 @@ JNIEXPORT jobjectArray JNICALL ...@@ -1246,7 +1177,7 @@ JNIEXPORT jobjectArray JNICALL
colNum = 0; colNum = 0;
hr = S_OK; hr = S_OK;
while (SUCCEEDED (hr)) { while (SUCCEEDED (hr)) {
hr = GetDetailsOf(pIShellDetails, NULL, colNum, &sd); hr = pIShellDetails->GetDetailsOf(NULL, colNum, &sd);
if (SUCCEEDED (hr)) { if (SUCCEEDED (hr)) {
jobject column = CreateColumnInfo(env, jobject column = CreateColumnInfo(env,
&columnClass, &columnConstructor, &columnClass, &columnConstructor,
...@@ -1288,7 +1219,7 @@ JNIEXPORT jobject JNICALL ...@@ -1288,7 +1219,7 @@ JNIEXPORT jobject JNICALL
if(SUCCEEDED (hr)) { if(SUCCEEDED (hr)) {
// The folder exposes IShellFolder2 interface // The folder exposes IShellFolder2 interface
IShellFolder2 *pIShellFolder2 = (IShellFolder2*) pIUnknown; IShellFolder2 *pIShellFolder2 = (IShellFolder2*) pIUnknown;
hr = GetDetailsOfFolder(pIShellFolder2, pidl, (UINT)columnIdx, &sd); hr = pIShellFolder2->GetDetailsOf(pidl, (UINT)columnIdx, &sd);
pIShellFolder2->Release(); pIShellFolder2->Release();
if (SUCCEEDED (hr)) { if (SUCCEEDED (hr)) {
STRRET strRet = sd.str; STRRET strRet = sd.str;
...@@ -1300,7 +1231,7 @@ JNIEXPORT jobject JNICALL ...@@ -1300,7 +1231,7 @@ JNIEXPORT jobject JNICALL
if(SUCCEEDED (hr)) { if(SUCCEEDED (hr)) {
// The folder exposes IShellDetails interface // The folder exposes IShellDetails interface
IShellDetails *pIShellDetails = (IShellDetails*) pIUnknown; IShellDetails *pIShellDetails = (IShellDetails*) pIUnknown;
hr = GetDetailsOf(pIShellDetails, pidl, (UINT)columnIdx, &sd); hr = pIShellDetails->GetDetailsOf(pidl, (UINT)columnIdx, &sd);
pIShellDetails->Release(); pIShellDetails->Release();
if (SUCCEEDED (hr)) { if (SUCCEEDED (hr)) {
STRRET strRet = sd.str; STRRET strRet = sd.str;
......
/*
* @test
* @bug 6570445
* @summary Checks if Win32ShellFolder2's COM-using methods work under a security manager
* @author Leonid Popov
*/
import javax.swing.filechooser.FileSystemView;
public class bug6570445 {
public static void main(String[] args) {
System.setSecurityManager(new SecurityManager());
// The next line of code forces FileSystemView to request data from Win32ShellFolder2,
// what causes an exception if a security manager installed (see the bug 6570445 description)
FileSystemView.getFileSystemView().getRoots();
System.out.println("Passed.");
}
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册