Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openanolis
dragonwell8_jdk
提交
26b463b3
D
dragonwell8_jdk
项目概览
openanolis
/
dragonwell8_jdk
通知
4
Star
2
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
dragonwell8_jdk
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
26b463b3
编写于
3月 12, 2009
作者:
R
rupashka
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
6491795: COM should be initialized for Shell API calls in ShellFolder2.cpp
Reviewed-by: peterz, loneid
上级
5f55e0e8
变更
8
显示空白变更内容
内联
并排
Showing
8 changed file
with
720 addition
and
451 deletion
+720
-451
src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java
...e/classes/javax/swing/plaf/basic/BasicDirectoryModel.java
+91
-88
src/share/classes/sun/awt/shell/ShellFolder.java
src/share/classes/sun/awt/shell/ShellFolder.java
+30
-0
src/share/classes/sun/awt/shell/ShellFolderManager.java
src/share/classes/sun/awt/shell/ShellFolderManager.java
+16
-1
src/share/classes/sun/swing/FilePane.java
src/share/classes/sun/swing/FilePane.java
+11
-0
src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
+409
-251
src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
...ndows/classes/sun/awt/shell/Win32ShellFolderManager2.java
+101
-0
src/windows/native/sun/windows/ShellFolder2.cpp
src/windows/native/sun/windows/ShellFolder2.cpp
+42
-111
test/javax/swing/JFileChooser/6570445/bug6570445.java
test/javax/swing/JFileChooser/6570445/bug6570445.java
+20
-0
未找到文件。
src/share/classes/javax/swing/plaf/basic/BasicDirectoryModel.java
浏览文件 @
26b463b3
...
...
@@ -27,6 +27,7 @@ package javax.swing.plaf.basic;
import
java.io.File
;
import
java.util.*
;
import
java.util.concurrent.Callable
;
import
javax.swing.*
;
import
javax.swing.filechooser.*
;
import
javax.swing.event.*
;
...
...
@@ -223,17 +224,14 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
this
.
fid
=
fid
;
}
private
void
invokeLater
(
DoChangeContents
runnable
)
{
runnables
.
addElement
(
runnable
);
SwingUtilities
.
invokeLater
(
runnable
);
}
public
void
run
()
{
run0
();
setBusy
(
false
,
fid
);
}
public
void
run0
()
{
DoChangeContents
doChangeContents
=
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
DoChangeContents
>()
{
public
DoChangeContents
call
()
throws
Exception
{
FileSystemView
fileSystem
=
filechooser
.
getFileSystemView
();
File
[]
list
=
fileSystem
.
getFiles
(
currentDirectory
,
filechooser
.
isFileHidingEnabled
());
...
...
@@ -241,7 +239,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
Vector
<
File
>
acceptsList
=
new
Vector
<
File
>();
if
(
isInterrupted
())
{
return
;
return
null
;
}
// run through the file list, add directories and selectable files to fileCache
...
...
@@ -252,7 +250,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
}
if
(
isInterrupted
())
{
return
;
return
null
;
}
// First sort alphabetically by filename
...
...
@@ -261,7 +259,7 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
Vector
<
File
>
newDirectories
=
new
Vector
<
File
>(
50
);
Vector
<
File
>
newFiles
=
new
Vector
<
File
>();
// 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
);
boolean
isTraversable
=
filechooser
.
isTraversable
(
f
);
if
(
isTraversable
)
{
...
...
@@ -269,8 +267,8 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
}
else
if
(!
isTraversable
&&
filechooser
.
isFileSelectionEnabled
())
{
newFiles
.
addElement
(
f
);
}
if
(
isInterrupted
())
{
return
;
if
(
isInterrupted
())
{
return
null
;
}
}
...
...
@@ -298,11 +296,10 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
}
if
(
start
>=
0
&&
end
>
start
&&
newFileCache
.
subList
(
end
,
newSize
).
equals
(
fileCache
.
subList
(
start
,
oldSize
)))
{
if
(
isInterrupted
())
{
return
;
if
(
isInterrupted
())
{
return
null
;
}
invokeLater
(
new
DoChangeContents
(
newFileCache
.
subList
(
start
,
end
),
start
,
null
,
0
,
fid
));
newFileCache
=
null
;
return
new
DoChangeContents
(
newFileCache
.
subList
(
start
,
end
),
start
,
null
,
0
,
fid
);
}
}
else
if
(
newSize
<
oldSize
)
{
//see if interval is removed
...
...
@@ -317,19 +314,25 @@ public class BasicDirectoryModel extends AbstractListModel implements PropertyCh
}
if
(
start
>=
0
&&
end
>
start
&&
fileCache
.
subList
(
end
,
oldSize
).
equals
(
newFileCache
.
subList
(
start
,
newSize
)))
{
if
(
isInterrupted
())
{
return
;
if
(
isInterrupted
())
{
return
null
;
}
invokeLater
(
new
DoChangeContents
(
null
,
0
,
new
Vector
<
File
>(
fileCache
.
subList
(
start
,
end
)),
start
,
fid
));
newFileCache
=
null
;
return
new
DoChangeContents
(
null
,
0
,
new
Vector
(
fileCache
.
subList
(
start
,
end
)),
start
,
fid
);
}
}
if
(
newFileCache
!=
null
&&
!
fileCache
.
equals
(
newFileCache
))
{
if
(
!
fileCache
.
equals
(
newFileCache
))
{
if
(
isInterrupted
())
{
cancelRunnables
(
runnables
);
}
invokeLater
(
new
DoChangeContents
(
newFileCache
,
0
,
fileCache
,
0
,
fid
));
return
new
DoChangeContents
(
newFileCache
,
0
,
fileCache
,
0
,
fid
);
}
return
null
;
}
});
if
(
doChangeContents
!=
null
)
{
runnables
.
addElement
(
doChangeContents
);
SwingUtilities
.
invokeLater
(
doChangeContents
);
}
}
...
...
src/share/classes/sun/awt/shell/ShellFolder.java
浏览文件 @
26b463b3
...
...
@@ -31,6 +31,7 @@ import java.awt.Toolkit;
import
java.io.*
;
import
java.io.FileNotFoundException
;
import
java.util.*
;
import
java.util.concurrent.Callable
;
/**
* @author Michael Martak
...
...
@@ -461,6 +462,35 @@ public abstract class ShellFolder extends File {
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
*/
...
...
src/share/classes/sun/awt/shell/ShellFolderManager.java
浏览文件 @
26b463b3
...
...
@@ -27,6 +27,7 @@ package sun.awt.shell;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.util.concurrent.Callable
;
/**
* @author Michael Martak
...
...
@@ -96,9 +97,23 @@ class ShellFolderManager {
}
public
boolean
isFileSystemRoot
(
File
dir
)
{
if
(
dir
instanceof
ShellFolder
&&
!((
ShellFolder
)
dir
).
isFileSystem
())
{
if
(
dir
instanceof
ShellFolder
&&
!((
ShellFolder
)
dir
).
isFileSystem
())
{
return
false
;
}
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
);
}
}
}
}
src/share/classes/sun/swing/FilePane.java
浏览文件 @
26b463b3
...
...
@@ -34,6 +34,7 @@ import java.text.DateFormat;
import
java.text.MessageFormat
;
import
java.util.*
;
import
java.util.List
;
import
java.util.concurrent.Callable
;
import
javax.swing.*
;
import
javax.swing.border.*
;
...
...
@@ -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
()
{
super
.
modelStructureChanged
();
updateComparators
(
detailsTableModel
.
getColumns
());
...
...
src/windows/classes/sun/awt/shell/Win32ShellFolder2.java
浏览文件 @
26b463b3
...
...
@@ -32,6 +32,7 @@ import java.io.File;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.util.*
;
import
java.util.concurrent.*
;
import
javax.swing.SwingConstants
;
// NOTE: This class supersedes Win32ShellFolder, which was removed from
...
...
@@ -184,6 +185,8 @@ final class Win32ShellFolder2 extends ShellFolder {
boolean
disposed
;
public
void
dispose
()
{
if
(
disposed
)
return
;
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Void
>()
{
public
Void
call
()
throws
Exception
{
if
(
relativePIDL
!=
0
)
{
releasePIDL
(
relativePIDL
);
}
...
...
@@ -193,6 +196,9 @@ final class Win32ShellFolder2 extends ShellFolder {
if
(
pIShellFolder
!=
0
)
{
releaseIShellFolder
(
pIShellFolder
);
}
return
null
;
}
});
disposed
=
true
;
}
}
...
...
@@ -218,17 +224,23 @@ final class Win32ShellFolder2 extends ShellFolder {
*/
private
boolean
isPersonal
;
private
static
String
composePathForCsidl
(
int
csidl
)
throws
IOException
{
String
path
=
getFileSystemPath
(
csidl
);
return
path
==
null
?
(
"ShellFolder: 0x"
+
Integer
.
toHexString
(
csidl
))
:
path
;
}
/**
* Create a system special shell folder, such as the
* desktop or Network Neighborhood.
*/
Win32ShellFolder2
(
int
csidl
)
throws
IOException
{
Win32ShellFolder2
(
final
int
csidl
)
throws
IOException
{
// Desktop is parent of DRIVES and NETWORK, not necessarily
// other special shell folders.
super
(
null
,
(
getFileSystemPath
(
csidl
)
==
null
)
?
(
"ShellFolder: 0x"
+
Integer
.
toHexString
(
csidl
))
:
getFileSystemPath
(
csidl
));
super
(
null
,
composePathForCsidl
(
csidl
));
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Void
>()
{
public
Void
call
()
throws
Exception
{
if
(
csidl
==
DESKTOP
)
{
initDesktop
();
}
else
{
...
...
@@ -251,7 +263,7 @@ final class Win32ShellFolder2 extends ShellFolder {
// Now we know that parent isn't immediate to 'this' because it
// has a continued ID list. Create a shell folder for this child
// pidl and make it the new 'parent'.
parent
=
new
Win32ShellFolder2
((
Win32ShellFolder2
)
parent
,
childPIDL
);
parent
=
new
Win32ShellFolder2
((
Win32ShellFolder2
)
parent
,
childPIDL
);
}
else
{
// No grandchildren means we have arrived at the parent of 'this',
// and childPIDL is directly relative to parent.
...
...
@@ -262,6 +274,9 @@ final class Win32ShellFolder2 extends ShellFolder {
}
}
}
return
null
;
}
});
sun
.
java2d
.
Disposer
.
addRecord
(
this
,
disposer
);
}
...
...
@@ -281,17 +296,26 @@ final class Win32ShellFolder2 extends ShellFolder {
/**
* Creates a shell folder with a parent and relative PIDL
*/
Win32ShellFolder2
(
Win32ShellFolder2
parent
,
long
relativePIDL
)
{
super
(
parent
,
getFileSystemPath
(
parent
.
getIShellFolder
(),
relativePIDL
));
Win32ShellFolder2
(
final
Win32ShellFolder2
parent
,
final
long
relativePIDL
)
{
super
(
parent
,
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
String
>()
{
public
String
call
()
throws
Exception
{
return
getFileSystemPath
(
parent
.
getIShellFolder
(),
relativePIDL
);
}
})
);
this
.
disposer
.
relativePIDL
=
relativePIDL
;
getAbsolutePath
();
sun
.
java2d
.
Disposer
.
addRecord
(
this
,
disposer
);
}
// Initializes the desktop shell folder
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
native
void
initDesktop
();
// Initializes a special, non-file system shell folder
// from one of the above constants
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
native
void
initSpecial
(
long
desktopIShellFolder
,
int
csidl
);
/** Marks this folder as being the My Documents (Personal) folder */
...
...
@@ -311,6 +335,8 @@ final class Win32ShellFolder2 extends ShellFolder {
* drive (normally "C:\").
*/
protected
Object
writeReplace
()
throws
java
.
io
.
ObjectStreamException
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
File
>()
{
public
File
call
()
throws
Exception
{
if
(
isFileSystem
())
{
return
new
File
(
getPath
());
}
else
{
...
...
@@ -320,7 +346,7 @@ final class Win32ShellFolder2 extends ShellFolder {
if
(
driveRoots
!=
null
)
{
for
(
int
i
=
0
;
i
<
driveRoots
.
length
;
i
++)
{
if
(
driveRoots
[
i
]
instanceof
Win32ShellFolder2
)
{
Win32ShellFolder2
sf
=
(
Win32ShellFolder2
)
driveRoots
[
i
];
Win32ShellFolder2
sf
=
(
Win32ShellFolder2
)
driveRoots
[
i
];
if
(
sf
.
isFileSystem
()
&&
!
sf
.
hasAttribute
(
ATTRIB_REMOVABLE
))
{
return
new
File
(
sf
.
getPath
());
}
...
...
@@ -332,6 +358,8 @@ final class Win32ShellFolder2 extends ShellFolder {
return
new
File
(
"C:\\"
);
}
}
});
}
/**
...
...
@@ -364,6 +392,7 @@ final class Win32ShellFolder2 extends ShellFolder {
static
native
void
releasePIDL
(
long
pIDL
);
// Release an IShellFolder object
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
void
releaseIShellFolder
(
long
pIShellFolder
);
/**
...
...
@@ -371,18 +400,28 @@ final class Win32ShellFolder2 extends ShellFolder {
*/
public
long
getIShellFolder
()
{
if
(
disposer
.
pIShellFolder
==
0
)
{
disposer
.
pIShellFolder
=
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Long
>()
{
public
Long
call
()
throws
Exception
{
assert
(
isDirectory
());
assert
(
parent
!=
null
);
long
parentIShellFolder
=
getParentIShellFolder
();
if
(
parentIShellFolder
==
0
)
{
throw
new
InternalError
(
"Parent IShellFolder was null for "
+
getAbsolutePath
());
throw
new
InternalError
(
"Parent IShellFolder was null for "
+
getAbsolutePath
());
}
// We are a directory with a parent and a relative PIDL.
// We want to bind to the parent so we get an IShellFolder instance associated with us.
disposer
.
pIShellFolder
=
bindToObject
(
parentIShellFolder
,
disposer
.
relativePIDL
);
if
(
disposer
.
pIShellFolder
==
0
)
{
throw
new
InternalError
(
"Unable to bind "
+
getAbsolutePath
()
+
" to parent"
);
// We want to bind to the parent so we get an
// IShellFolder instance associated with us.
long
pIShellFolder
=
bindToObject
(
parentIShellFolder
,
disposer
.
relativePIDL
);
if
(
pIShellFolder
==
0
)
{
throw
new
InternalError
(
"Unable to bind "
+
getAbsolutePath
()
+
" to parent"
);
}
return
pIShellFolder
;
}
});
}
return
disposer
.
pIShellFolder
;
}
...
...
@@ -472,24 +511,42 @@ final class Win32ShellFolder2 extends ShellFolder {
return
false
;
}
private
static
boolean
pidlsEqual
(
long
pIShellFolder
,
long
pidl1
,
long
pidl2
)
{
private
static
boolean
pidlsEqual
(
final
long
pIShellFolder
,
final
long
pidl1
,
final
long
pidl2
)
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Boolean
>()
{
public
Boolean
call
()
throws
Exception
{
return
(
compareIDs
(
pIShellFolder
,
pidl1
,
pidl2
)
==
0
);
}
});
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
int
compareIDs
(
long
pParentIShellFolder
,
long
pidl1
,
long
pidl2
);
private
Boolean
cachedIsFileSystem
;
/**
* @return Whether this is a file system shell folder
*/
public
boolean
isFileSystem
()
{
return
hasAttribute
(
ATTRIB_FILESYSTEM
);
public
synchronized
boolean
isFileSystem
()
{
if
(
cachedIsFileSystem
==
null
)
{
cachedIsFileSystem
=
hasAttribute
(
ATTRIB_FILESYSTEM
);
}
return
cachedIsFileSystem
;
}
/**
* Return whether the given attribute flag is set for this object
*/
public
boolean
hasAttribute
(
int
attribute
)
{
public
boolean
hasAttribute
(
final
int
attribute
)
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Boolean
>()
{
public
Boolean
call
()
throws
Exception
{
// Caching at this point doesn't seem to be cost efficient
return
(
getAttributes0
(
getParentIShellFolder
(),
getRelativePIDL
(),
attribute
)
&
attribute
)
!=
0
;
return
(
getAttributes0
(
getParentIShellFolder
(),
getRelativePIDL
(),
attribute
)
&
attribute
)
!=
0
;
}
});
}
/**
...
...
@@ -498,11 +555,15 @@ final class Win32ShellFolder2 extends ShellFolder {
* Could plausibly be used for attribute caching but have to be
* very careful not to touch network drives and file system roots
* with a full attrsMask
* NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
*/
private
static
native
int
getAttributes0
(
long
pParentIShellFolder
,
long
pIDL
,
int
attrsMask
);
// Return the path to the underlying file system object
private
static
String
getFileSystemPath
(
long
parentIShellFolder
,
long
relativePIDL
)
{
private
static
String
getFileSystemPath
(
final
long
parentIShellFolder
,
final
long
relativePIDL
)
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
String
>()
{
public
String
call
()
throws
Exception
{
int
linkedFolder
=
ATTRIB_LINK
|
ATTRIB_FOLDER
;
if
(
parentIShellFolder
==
Win32ShellFolderManager2
.
getNetwork
().
getIShellFolder
()
&&
getAttributes0
(
parentIShellFolder
,
relativePIDL
,
linkedFolder
)
==
linkedFolder
)
{
...
...
@@ -514,10 +575,22 @@ final class Win32ShellFolder2 extends ShellFolder {
return
s
;
}
}
return
getDisplayNameOf
(
parentIShellFolder
,
relativePIDL
,
SHGDN_NORMAL
|
SHGDN_FORPARSING
);
return
getDisplayNameOf
(
parentIShellFolder
,
relativePIDL
,
SHGDN_FORPARSING
);
}
});
}
// Needs to be accessible to Win32ShellFolderManager2
static
native
String
getFileSystemPath
(
int
csidl
)
throws
IOException
;
static
String
getFileSystemPath
(
final
int
csidl
)
throws
IOException
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
String
>()
{
public
String
call
()
throws
Exception
{
return
getFileSystemPath0
(
csidl
);
}
});
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
String
getFileSystemPath0
(
int
csidl
)
throws
IOException
;
// Return whether the path is a network root.
// Path is assumed to be non-null
...
...
@@ -557,24 +630,33 @@ final class Win32ShellFolder2 extends ShellFolder {
*/
// Returns an IEnumIDList interface for an IShellFolder. The value
// returned must be released using releaseEnumObjects().
private
long
getEnumObjects
(
long
pIShellFolder
,
boolean
includeHiddenFiles
)
{
boolean
isDesktop
=
(
disposer
.
pIShellFolder
==
getDesktopIShellFolder
());
private
long
getEnumObjects
(
long
pIShellFolder
,
final
boolean
includeHiddenFiles
)
{
final
boolean
isDesktop
=
(
disposer
.
pIShellFolder
==
getDesktopIShellFolder
());
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Long
>()
{
public
Long
call
()
throws
Exception
{
return
getEnumObjects
(
disposer
.
pIShellFolder
,
isDesktop
,
includeHiddenFiles
);
}
});
}
// Returns an IEnumIDList interface for an IShellFolder. The value
// returned must be released using releaseEnumObjects().
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
native
long
getEnumObjects
(
long
pIShellFolder
,
boolean
isDesktop
,
boolean
includeHiddenFiles
);
// Returns the next sequential child as a relative PIDL
// from an IEnumIDList interface. The value returned must
// be released using releasePIDL().
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
native
long
getNextChild
(
long
pEnumObjects
);
// Releases the IEnumIDList interface
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
native
void
releaseEnumObjects
(
long
pEnumObjects
);
// Returns the IShellFolder of a child from a parent IShellFolder
// and a relative PIDL. The value returned must be released
// using releaseIShellFolder().
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
long
bindToObject
(
long
parentIShellFolder
,
long
pIDL
);
/**
...
...
@@ -582,11 +664,14 @@ final class Win32ShellFolder2 extends ShellFolder {
* object. The array will be empty if the folder is empty. Returns
* <code>null</code> if this shellfolder does not denote a directory.
*/
public
File
[]
listFiles
(
boolean
includeHiddenFiles
)
{
public
File
[]
listFiles
(
final
boolean
includeHiddenFiles
)
{
SecurityManager
security
=
System
.
getSecurityManager
();
if
(
security
!=
null
)
{
security
.
checkRead
(
getPath
());
}
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
File
[]>()
{
public
File
[]
call
()
throws
Exception
{
if
(!
isDirectory
())
{
return
null
;
}
...
...
@@ -611,20 +696,17 @@ final class Win32ShellFolder2 extends ShellFolder {
long
childPIDL
;
int
testedAttrs
=
ATTRIB_FILESYSTEM
|
ATTRIB_FILESYSANCESTOR
;
do
{
if
(
Thread
.
currentThread
().
isInterrupted
())
{
return
new
File
[
0
];
}
childPIDL
=
getNextChild
(
pEnumObjects
);
boolean
releasePIDL
=
true
;
if
(
childPIDL
!=
0
&&
(
getAttributes0
(
pIShellFolder
,
childPIDL
,
testedAttrs
)
&
testedAttrs
)
!=
0
)
{
Win32ShellFolder2
childFolder
=
null
;
if
(
this
.
equals
(
desktop
)
Win32ShellFolder2
childFolder
;
if
(
Win32ShellFolder2
.
this
.
equals
(
desktop
)
&&
personal
!=
null
&&
pidlsEqual
(
pIShellFolder
,
childPIDL
,
personal
.
disposer
.
relativePIDL
))
{
childFolder
=
personal
;
}
else
{
childFolder
=
new
Win32ShellFolder2
(
this
,
childPIDL
);
childFolder
=
new
Win32ShellFolder2
(
Win32ShellFolder2
.
this
,
childPIDL
);
releasePIDL
=
false
;
}
list
.
add
(
childFolder
);
...
...
@@ -632,10 +714,14 @@ final class Win32ShellFolder2 extends ShellFolder {
if
(
releasePIDL
)
{
releasePIDL
(
childPIDL
);
}
}
while
(
childPIDL
!=
0
);
}
while
(
childPIDL
!=
0
&&
!
Thread
.
currentThread
().
isInterrupted
()
);
releaseEnumObjects
(
pEnumObjects
);
}
return
list
.
toArray
(
new
ShellFolder
[
list
.
size
()]);
return
Thread
.
currentThread
().
isInterrupted
()
?
new
File
[
0
]
:
list
.
toArray
(
new
ShellFolder
[
list
.
size
()]);
}
});
}
...
...
@@ -644,18 +730,21 @@ final class Win32ShellFolder2 extends ShellFolder {
*
* @return The child shellfolder, or null if not found.
*/
Win32ShellFolder2
getChildByPath
(
String
filePath
)
{
Win32ShellFolder2
getChildByPath
(
final
String
filePath
)
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Win32ShellFolder2
>()
{
public
Win32ShellFolder2
call
()
throws
Exception
{
long
pIShellFolder
=
getIShellFolder
();
long
pEnumObjects
=
getEnumObjects
(
pIShellFolder
,
true
);
Win32ShellFolder2
child
=
null
;
long
childPIDL
;
long
childPIDL
=
0
;
while
((
childPIDL
=
getNextChild
(
pEnumObjects
))
!=
0
)
{
if
(
getAttributes0
(
pIShellFolder
,
childPIDL
,
ATTRIB_FILESYSTEM
)
!=
0
)
{
String
path
=
getFileSystemPath
(
pIShellFolder
,
childPIDL
);
if
(
path
!=
null
&&
path
.
equalsIgnoreCase
(
filePath
))
{
long
childIShellFolder
=
bindToObject
(
pIShellFolder
,
childPIDL
);
child
=
new
Win32ShellFolder2
(
this
,
childIShellFolder
,
childPIDL
,
path
);
child
=
new
Win32ShellFolder2
(
Win32ShellFolder2
.
this
,
childIShellFolder
,
childPIDL
,
path
);
break
;
}
}
...
...
@@ -664,13 +753,20 @@ final class Win32ShellFolder2 extends ShellFolder {
releaseEnumObjects
(
pEnumObjects
);
return
child
;
}
});
}
private
Boolean
cachedIsLink
;
/**
* @return Whether this shell folder is a link
*/
public
boolean
isLink
()
{
return
hasAttribute
(
ATTRIB_LINK
);
public
synchronized
boolean
isLink
()
{
if
(
cachedIsLink
==
null
)
{
cachedIsLink
=
hasAttribute
(
ATTRIB_LINK
);
}
return
cachedIsLink
;
}
/**
...
...
@@ -682,6 +778,7 @@ final class Win32ShellFolder2 extends ShellFolder {
// Return the link location of a shell folder
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
long
getLinkLocation
(
long
parentIShellFolder
,
long
relativePIDL
,
boolean
resolve
);
...
...
@@ -693,7 +790,9 @@ final class Win32ShellFolder2 extends ShellFolder {
return
getLinkLocation
(
true
);
}
private
ShellFolder
getLinkLocation
(
boolean
resolve
)
{
private
ShellFolder
getLinkLocation
(
final
boolean
resolve
)
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
ShellFolder
>()
{
public
ShellFolder
call
()
throws
Exception
{
if
(!
isLink
())
{
return
null
;
}
...
...
@@ -713,18 +812,30 @@ final class Win32ShellFolder2 extends ShellFolder {
}
return
location
;
}
});
}
// Parse a display name into a PIDL relative to the current IShellFolder.
long
parseDisplayName
(
String
name
)
throws
FileNotFoundException
{
long
parseDisplayName
(
final
String
name
)
throws
FileNotFoundException
{
try
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Long
>()
{
public
Long
call
()
throws
Exception
{
return
parseDisplayName0
(
getIShellFolder
(),
name
);
}
catch
(
IOException
e
)
{
}
});
}
catch
(
RuntimeException
e
)
{
if
(
e
.
getCause
()
instanceof
IOException
)
{
throw
new
FileNotFoundException
(
"Could not find file "
+
name
);
}
throw
e
;
}
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
long
parseDisplayName0
(
long
pIShellFolder
,
String
name
)
throws
IOException
;
// Return the display name of a shell folder
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
String
getDisplayNameOf
(
long
parentIShellFolder
,
long
relativePIDL
,
int
attrs
);
...
...
@@ -734,12 +845,19 @@ final class Win32ShellFolder2 extends ShellFolder {
*/
public
String
getDisplayName
()
{
if
(
displayName
==
null
)
{
displayName
=
getDisplayNameOf
(
getParentIShellFolder
(),
getRelativePIDL
(),
SHGDN_NORMAL
);
displayName
=
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
String
>()
{
public
String
call
()
throws
Exception
{
return
getDisplayNameOf
(
getParentIShellFolder
(),
getRelativePIDL
(),
SHGDN_NORMAL
);
}
});
}
return
displayName
;
}
// Return the folder type of a shell folder
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
String
getFolderType
(
long
pIDL
);
/**
...
...
@@ -747,7 +865,13 @@ final class Win32ShellFolder2 extends ShellFolder {
*/
public
String
getFolderType
()
{
if
(
folderType
==
null
)
{
folderType
=
getFolderType
(
getAbsolutePIDL
());
final
long
absolutePIDL
=
getAbsolutePIDL
();
folderType
=
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
String
>()
{
public
String
call
()
throws
Exception
{
return
getFolderType
(
absolutePIDL
);
}
});
}
return
folderType
;
}
...
...
@@ -774,11 +898,16 @@ final class Win32ShellFolder2 extends ShellFolder {
private
static
Map
smallLinkedSystemImages
=
new
HashMap
();
private
static
Map
largeLinkedSystemImages
=
new
HashMap
();
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
long
getIShellIcon
(
long
pIShellFolder
);
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
int
getIconIndex
(
long
parentIShellIcon
,
long
relativePIDL
);
// Return the icon of a file system shell folder in the form of an HICON
private
static
native
long
getIcon
(
String
absolutePath
,
boolean
getLargeIcon
);
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
long
extractIcon
(
long
parentIShellFolder
,
long
relativePIDL
,
boolean
getLargeIcon
);
...
...
@@ -799,7 +928,12 @@ final class Win32ShellFolder2 extends ShellFolder {
private
long
getIShellIcon
()
{
if
(
pIShellIcon
==
-
1L
)
{
pIShellIcon
=
getIShellIcon
(
getIShellFolder
());
pIShellIcon
=
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Long
>()
{
public
Long
call
()
throws
Exception
{
return
getIShellIcon
(
getIShellFolder
());
}
});
}
return
pIShellIcon
;
}
...
...
@@ -850,13 +984,19 @@ final class Win32ShellFolder2 extends ShellFolder {
/**
* @return The icon image used to display this shell folder
*/
public
Image
getIcon
(
boolean
getLargeIcon
)
{
public
Image
getIcon
(
final
boolean
getLargeIcon
)
{
Image
icon
=
getLargeIcon
?
largeIcon
:
smallIcon
;
if
(
icon
==
null
)
{
long
parentIShellIcon
=
(
parent
!=
null
)
?
((
Win32ShellFolder2
)
parent
).
getIShellIcon
()
:
0L
;
icon
=
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Image
>()
{
public
Image
call
()
throws
Exception
{
Image
newIcon
=
null
;
if
(
isFileSystem
())
{
long
parentIShellIcon
=
(
parent
!=
null
)
?
((
Win32ShellFolder2
)
parent
).
getIShellIcon
()
:
0L
;
long
relativePIDL
=
getRelativePIDL
();
if
(
isFileSystem
())
{
// These are cached per type (using the index in the system image list)
int
index
=
getIconIndex
(
parentIShellIcon
,
relativePIDL
);
if
(
index
>
0
)
{
...
...
@@ -866,34 +1006,38 @@ final class Win32ShellFolder2 extends ShellFolder {
}
else
{
imageCache
=
getLargeIcon
?
largeSystemImages
:
smallSystemImages
;
}
icon
=
(
Image
)
imageCache
.
get
(
Integer
.
valueOf
(
index
));
if
(
i
con
==
null
)
{
newIcon
=
(
Image
)
imageCache
.
get
(
Integer
.
valueOf
(
index
));
if
(
newI
con
==
null
)
{
long
hIcon
=
getIcon
(
getAbsolutePath
(),
getLargeIcon
);
i
con
=
makeIcon
(
hIcon
,
getLargeIcon
);
newI
con
=
makeIcon
(
hIcon
,
getLargeIcon
);
disposeIcon
(
hIcon
);
if
(
i
con
!=
null
)
{
imageCache
.
put
(
Integer
.
valueOf
(
index
),
i
con
);
if
(
newI
con
!=
null
)
{
imageCache
.
put
(
Integer
.
valueOf
(
index
),
newI
con
);
}
}
}
}
if
(
i
con
==
null
)
{
if
(
newI
con
==
null
)
{
// These are only cached per object
long
hIcon
=
extractIcon
(
getParentIShellFolder
(),
getRelativePIDL
(),
getLargeIcon
);
icon
=
makeIcon
(
hIcon
,
getLargeIcon
);
long
hIcon
=
extractIcon
(
getParentIShellFolder
(),
getRelativePIDL
(),
getLargeIcon
);
newIcon
=
makeIcon
(
hIcon
,
getLargeIcon
);
disposeIcon
(
hIcon
);
}
if
(
newIcon
==
null
)
{
newIcon
=
Win32ShellFolder2
.
super
.
getIcon
(
getLargeIcon
);
}
return
newIcon
;
}
});
if
(
getLargeIcon
)
{
largeIcon
=
icon
;
}
else
{
smallIcon
=
icon
;
}
}
if
(
icon
==
null
)
{
icon
=
super
.
getIcon
(
getLargeIcon
);
}
return
icon
;
}
...
...
@@ -969,6 +1113,8 @@ final class Win32ShellFolder2 extends ShellFolder {
private
static
final
int
LVCFMT_CENTER
=
2
;
public
ShellFolderColumnInfo
[]
getFolderColumns
()
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
ShellFolderColumnInfo
[]>()
{
public
ShellFolderColumnInfo
[]
call
()
throws
Exception
{
ShellFolderColumnInfo
[]
columns
=
doGetColumnInfo
(
getIShellFolder
());
if
(
columns
!=
null
)
{
...
...
@@ -993,15 +1139,24 @@ final class Win32ShellFolder2 extends ShellFolder {
}
return
columns
;
}
});
}
public
Object
getFolderColumnValue
(
int
column
)
{
public
Object
getFolderColumnValue
(
final
int
column
)
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Object
>()
{
public
Object
call
()
throws
Exception
{
return
doGetColumnValue
(
getParentIShellFolder
(),
getRelativePIDL
(),
column
);
}
});
}
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
native
ShellFolderColumnInfo
[]
doGetColumnInfo
(
long
iShellFolder2
);
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
native
Object
doGetColumnValue
(
long
parentIShellFolder2
,
long
childPIDL
,
int
columnIdx
);
// NOTE: this method uses COM and must be called on the 'COM thread'. See ComInvoker for the details
private
static
native
int
compareIDsByColumn
(
long
pParentIShellFolder
,
long
pidl1
,
long
pidl2
,
int
columnIdx
);
...
...
@@ -1020,7 +1175,9 @@ final class Win32ShellFolder2 extends ShellFolder {
}
// compares 2 objects within this folder by the specified column
public
int
compare
(
File
o
,
File
o1
)
{
public
int
compare
(
final
File
o
,
final
File
o1
)
{
return
ShellFolder
.
getInvoker
().
invoke
(
new
Callable
<
Integer
>()
{
public
Integer
call
()
throws
Exception
{
if
(
o
instanceof
Win32ShellFolder2
&&
o1
instanceof
Win32ShellFolder2
)
{
// delegates comparison to native method
...
...
@@ -1031,6 +1188,7 @@ final class Win32ShellFolder2 extends ShellFolder {
}
return
0
;
}
});
}
}
}
src/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java
浏览文件 @
26b463b3
...
...
@@ -31,7 +31,10 @@ import java.io.File;
import
java.io.FileNotFoundException
;
import
java.io.IOException
;
import
java.security.AccessController
;
import
java.security.PrivilegedAction
;
import
java.util.*
;
import
java.util.concurrent.*
;
import
sun.security.action.LoadLibraryAction
;
import
static
sun
.
awt
.
shell
.
Win32ShellFolder2
.*;
...
...
@@ -408,4 +411,102 @@ public class Win32ShellFolderManager2 extends ShellFolderManager {
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
();
}
src/windows/native/sun/windows/ShellFolder2.cpp
浏览文件 @
26b463b3
...
...
@@ -225,6 +225,34 @@ JNIEXPORT void JNICALL Java_sun_awt_shell_Win32ShellFolder2_initIDs
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
)
{
// http://msdn.microsoft.com/library/en-us/shellcc/platform/Shell/programmersguide/shell_int/shell_int_programming/std_ifaces.asp
HRESULT
hres
;
...
...
@@ -239,29 +267,6 @@ static IShellIcon* getIShellIcon(IShellFolder* pIShellFolder) {
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
...
...
@@ -507,10 +512,10 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getAttributes0
/*
* Class: sun_awt_shell_Win32ShellFolder2
* Method: getFileSystemPath
* Method: getFileSystemPath
0
* Signature: (I)Ljava/lang/String;
*/
JNIEXPORT
jstring
JNICALL
Java_sun_awt_shell_Win32ShellFolder2_getFileSystemPath
__I
JNIEXPORT
jstring
JNICALL
Java_sun_awt_shell_Win32ShellFolder2_getFileSystemPath
0
(
JNIEnv
*
env
,
jclass
cls
,
jint
csidl
)
{
LPITEMIDLIST
relPIDL
;
...
...
@@ -611,18 +616,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_bindToObject
if
(
SUCCEEDED
(
hr
))
{
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
;
}
...
...
@@ -650,7 +643,10 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
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
)
{
case
STRRET_CSTR
:
...
...
@@ -669,10 +665,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
break
;
}
BOOL
doCoUninit
;
if
(
!
CoInit
(
doCoUninit
))
{
return
0
;
}
IShellLinkW
*
psl
;
hres
=
::
CoCreateInstance
(
CLSID_ShellLink
,
NULL
,
CLSCTX_INPROC_SERVER
,
IID_IShellLinkW
,
(
LPVOID
*
)
&
psl
);
if
(
SUCCEEDED
(
hres
))
{
...
...
@@ -692,9 +684,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
}
psl
->
Release
();
}
if
(
doCoUninit
)
{
::
CoUninitialize
();
}
if
(
SUCCEEDED
(
hres
))
{
return
(
jlong
)
pidl
;
...
...
@@ -741,7 +730,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_parseDisplayName0
/*
* Class: sun_awt_shell_Win32ShellFolder2
* Method: getDisplayNameOf
* Signature: (JJ)Ljava/lang/String;
* Signature: (JJ
I
)Ljava/lang/String;
*/
JNIEXPORT
jstring
JNICALL
Java_sun_awt_shell_Win32ShellFolder2_getDisplayNameOf
(
JNIEnv
*
env
,
jclass
cls
,
jlong
parentIShellFolder
,
jlong
relativePIDL
,
jint
attrs
)
...
...
@@ -833,10 +822,6 @@ JNIEXPORT jint JNICALL Java_sun_awt_shell_Win32ShellFolder2_getIconIndex
}
INT
index
=
-
1
;
BOOL
doCoUninit
;
if
(
!
CoInit
(
doCoUninit
))
{
return
(
jint
)
index
;
}
HRESULT
hres
;
// 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
hres
=
pIShellIcon
->
GetIconOf
(
pidl
,
GIL_FORSHELL
,
&
index
);
}
if
(
doCoUninit
)
{
::
CoUninitialize
();
}
return
(
jint
)
index
;
}
...
...
@@ -866,10 +848,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
}
HICON
hIcon
=
NULL
;
BOOL
doCoUninit
;
if
(
!
CoInit
(
doCoUninit
))
{
return
(
jlong
)
hIcon
;
}
HRESULT
hres
;
IExtractIconW
*
pIcon
;
...
...
@@ -894,9 +872,6 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_extractIcon
}
pIcon
->
Release
();
}
if
(
doCoUninit
)
{
::
CoUninitialize
();
}
return
(
jlong
)
hIcon
;
}
...
...
@@ -994,14 +969,10 @@ JNIEXPORT jintArray JNICALL Java_sun_awt_shell_Win32ShellFolder2_getFileChooserB
HINSTANCE
libComCtl32
;
HINSTANCE
libShell32
;
libShell32
=
LoadLibrary
(
TEXT
(
"shell32.dll"
));
if
(
libShell32
!=
NULL
)
{
long
osVersion
=
GetVersion
();
BOOL
isVista
=
(
!
(
osVersion
&
0x80000000
)
&&
(
LOBYTE
(
LOWORD
(
osVersion
))
>=
6
));
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
);
}
if
(
hBitmap
==
NULL
)
{
...
...
@@ -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
*/
...
...
@@ -1187,7 +1118,7 @@ JNIEXPORT jobjectArray JNICALL
int
colNum
=
-
1
;
hr
=
S_OK
;
do
{
hr
=
GetDetailsOfFolder
(
pIShellFolder2
,
NULL
,
++
colNum
,
&
sd
);
hr
=
pIShellFolder2
->
GetDetailsOf
(
NULL
,
++
colNum
,
&
sd
);
}
while
(
SUCCEEDED
(
hr
));
jobjectArray
columns
=
...
...
@@ -1202,7 +1133,7 @@ JNIEXPORT jobjectArray JNICALL
colNum
=
0
;
hr
=
S_OK
;
while
(
SUCCEEDED
(
hr
))
{
hr
=
GetDetailsOfFolder
(
pIShellFolder2
,
NULL
,
colNum
,
&
sd
);
hr
=
pIShellFolder2
->
GetDetailsOf
(
NULL
,
colNum
,
&
sd
);
if
(
SUCCEEDED
(
hr
))
{
hr
=
pIShellFolder2
->
GetDefaultColumnState
(
colNum
,
&
csFlags
);
...
...
@@ -1232,7 +1163,7 @@ JNIEXPORT jobjectArray JNICALL
int
colNum
=
-
1
;
hr
=
S_OK
;
do
{
hr
=
GetDetailsOf
(
pIShellDetails
,
NULL
,
++
colNum
,
&
sd
);
hr
=
pIShellDetails
->
GetDetailsOf
(
NULL
,
++
colNum
,
&
sd
);
}
while
(
SUCCEEDED
(
hr
));
jobjectArray
columns
=
...
...
@@ -1246,7 +1177,7 @@ JNIEXPORT jobjectArray JNICALL
colNum
=
0
;
hr
=
S_OK
;
while
(
SUCCEEDED
(
hr
))
{
hr
=
GetDetailsOf
(
pIShellDetails
,
NULL
,
colNum
,
&
sd
);
hr
=
pIShellDetails
->
GetDetailsOf
(
NULL
,
colNum
,
&
sd
);
if
(
SUCCEEDED
(
hr
))
{
jobject
column
=
CreateColumnInfo
(
env
,
&
columnClass
,
&
columnConstructor
,
...
...
@@ -1288,7 +1219,7 @@ JNIEXPORT jobject JNICALL
if
(
SUCCEEDED
(
hr
))
{
// The folder exposes IShellFolder2 interface
IShellFolder2
*
pIShellFolder2
=
(
IShellFolder2
*
)
pIUnknown
;
hr
=
GetDetailsOfFolder
(
pIShellFolder2
,
pidl
,
(
UINT
)
columnIdx
,
&
sd
);
hr
=
pIShellFolder2
->
GetDetailsOf
(
pidl
,
(
UINT
)
columnIdx
,
&
sd
);
pIShellFolder2
->
Release
();
if
(
SUCCEEDED
(
hr
))
{
STRRET
strRet
=
sd
.
str
;
...
...
@@ -1300,7 +1231,7 @@ JNIEXPORT jobject JNICALL
if
(
SUCCEEDED
(
hr
))
{
// The folder exposes IShellDetails interface
IShellDetails
*
pIShellDetails
=
(
IShellDetails
*
)
pIUnknown
;
hr
=
GetDetailsOf
(
pIShellDetails
,
pidl
,
(
UINT
)
columnIdx
,
&
sd
);
hr
=
pIShellDetails
->
GetDetailsOf
(
pidl
,
(
UINT
)
columnIdx
,
&
sd
);
pIShellDetails
->
Release
();
if
(
SUCCEEDED
(
hr
))
{
STRRET
strRet
=
sd
.
str
;
...
...
test/javax/swing/JFileChooser/6570445/bug6570445.java
0 → 100644
浏览文件 @
26b463b3
/*
* @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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录