2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package com
.intellij
.openapi
.vfs
.impl
.win32
;
19 import com
.sun
.jna
.win32
.StdCallLibrary
;
20 import com
.sun
.jna
.win32
.W32APIFunctionMapper
;
21 import com
.sun
.jna
.win32
.W32APITypeMapper
;
23 import java
.util
.ArrayList
;
24 import java
.util
.HashMap
;
25 import java
.util
.List
;
29 * @author Dmitry Avdeev
31 public class Win32Kernel
{
33 private static Kernel32 myKernel
= (Kernel32
)Native
.loadLibrary("kernel32", Kernel32
.class, new HashMap
<Object
, Object
>() {
35 put(Library
.OPTION_TYPE_MAPPER
, W32APITypeMapper
.UNICODE
);
36 put(Library
.OPTION_FUNCTION_MAPPER
, W32APIFunctionMapper
.UNICODE
);
39 private static final int MAX_PATH
= 0x00000104;
40 public static final int FILE_ATTRIBUTE_DIRECTORY
= 0x00000010;
41 public static final int FILE_ATTRIBUTE_READONLY
= 0x0001;
43 private static HANDLE INVALID_HANDLE_VALUE
= new HANDLE() {
45 super.setPointer(Pointer
.createConstant(-1));
48 public static class HANDLE
extends PointerType
{
49 public Object
fromNative(Object nativeValue
, FromNativeContext context
) {
50 Object o
= super.fromNative(nativeValue
, context
);
51 if (INVALID_HANDLE_VALUE
.equals(o
)) return INVALID_HANDLE_VALUE
;
56 private static int DATA_SIZE
= new WIN32_FIND_DATA().size();
58 private Map
<String
, WIN32_FIND_DATA
> myCache
= new HashMap
<String
, WIN32_FIND_DATA
>();
59 private List
<WIN32_FIND_DATA
> myDatas
= new ArrayList
<WIN32_FIND_DATA
>();
61 private WIN32_FIND_DATA
getData() {
62 if (myDatas
.isEmpty()) {
63 myDatas
.add(new WIN32_FIND_DATA());
65 return myDatas
.remove(0);
68 public String
[] list(String absolutePath
) {
70 myDatas
.addAll(myCache
.values());
73 ArrayList
<String
> list
= new ArrayList
<String
>();
74 WIN32_FIND_DATA data
= getData();
75 HANDLE hFind
= myKernel
.FindFirstFile(absolutePath
.replace('/', '\\') + "\\*", data
);
76 if (hFind
== INVALID_HANDLE_VALUE
) return new String
[0];
78 String name
= toString(data
.cFileName
);
79 if (name
.equals(".") || name
.equals("..")) {
82 myCache
.put(absolutePath
+ "/" + name
, data
);
86 while (myKernel
.FindNextFile(hFind
, data
));
87 myKernel
.FindClose(hFind
);
88 return list
.toArray(new String
[list
.size()]);
91 public boolean isDirectory(String path
) throws NotAvailableException
{
92 WIN32_FIND_DATA data
= getData(path
);
93 return (data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
) != 0;
96 public boolean isWritable(String path
) throws NotAvailableException
{
97 return (getData(path
).dwFileAttributes
& FILE_ATTRIBUTE_READONLY
) == 0;
101 public long getTimeStamp(String path
) throws NotAvailableException
{
102 return getData(path
).ftLastWriteTime
.toLong();
105 private WIN32_FIND_DATA
getData(String path
) throws NotAvailableException
{
106 WIN32_FIND_DATA data
= myCache
.get(path
);
108 throw new NotAvailableException(path
);
113 private static String
toString(char[] array
) {
114 for (int i
= 0; i
< array
.length
; i
++) {
115 if (array
[i
] == 0) return new String(array
, 0, i
);
117 return new String(array
);
120 public interface Kernel32
extends StdCallLibrary
{
122 HANDLE
FindFirstFile(String lpFileName
, WIN32_FIND_DATA lpFindFileData
);
124 boolean FindNextFile(HANDLE hFindFile
, WIN32_FIND_DATA lpFindFileData
);
126 boolean FindClose(HANDLE hFindFile
);
131 public static class FILETIME
extends Structure
implements Structure
.ByValue
{
133 public int dwLowDateTime
;
134 public int dwHighDateTime
;
136 private static long l(int i
) {
140 return ((long) i
& 0x7FFFFFFFl
) + 0x80000000l
;
144 public long toLong() {
145 long result
= dwHighDateTime
;
146 result
= result
<< 32;
147 result
= result
+ l(dwLowDateTime
);
148 result
= result
/ 10000;
149 result
= result
- 11644473600000l;
154 public static class WIN32_FIND_DATA
extends Structure
{
156 public int dwFileAttributes
;
158 public FILETIME ftCreationTime
;
160 public FILETIME ftLastAccessTime
;
162 public FILETIME ftLastWriteTime
;
164 public int nFileSizeHigh
;
166 public int nFileSizeLow
;
168 public int dwReserved0
;
170 public int dwReserved1
;
172 public char[] cFileName
= new char[MAX_PATH
];
174 public char[] cAlternateFileName
= new char[14];
178 public static class NotAvailableException
extends Exception
{
179 public NotAvailableException(String message
) {