Win32 filesystem
[fedora-idea.git] / platform / platform-impl / src / com / intellij / openapi / vfs / impl / win32 / Win32Kernel.java
blobbd452b825773626fce1eee6bf5a3f654221d253e
1 /*
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;
18 import com.sun.jna.*;
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;
26 import java.util.Map;
28 /**
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);
37 }});
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));
46 }};
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;
52 return o;
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());
71 myCache.clear();
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];
77 do {
78 String name = toString(data.cFileName);
79 if (name.equals(".") || name.equals("..")) {
80 continue;
82 myCache.put(absolutePath + "/" + name, data);
83 list.add(name);
84 data = getData();
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);
107 if (data == null) {
108 throw new NotAvailableException(path);
110 return data;
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);
128 int GetLastError();
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) {
137 if (i >= 0) {
138 return i;
139 } else {
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;
150 return result;
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) {
180 super(message);