Coverage Report - org.seasar.uruma.util.win32.Win32API
 
Classes in this File Line Coverage Branch Coverage Complexity
Win32API
64%
78/122
52%
23/44
0
 
 1  
 /*
 2  
  * Copyright 2004-2008 the Seasar Foundation and the Others.
 3  
  *
 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
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 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, 
 13  
  * either express or implied. See the License for the specific language
 14  
  * governing permissions and limitations under the License.
 15  
  */
 16  
 package org.seasar.uruma.util.win32;
 17  
 
 18  
 import java.io.StringWriter;
 19  
 import java.nio.ByteBuffer;
 20  
 import java.nio.ByteOrder;
 21  
 
 22  
 import nlink.Holder;
 23  
 import nlink.win32.NLink;
 24  
 
 25  
 import org.eclipse.swt.SWT;
 26  
 import org.eclipse.swt.graphics.Image;
 27  
 import org.eclipse.swt.graphics.ImageData;
 28  
 import org.eclipse.swt.internal.win32.OS;
 29  
 import org.eclipse.swt.internal.win32.SHFILEINFO;
 30  
 import org.eclipse.swt.internal.win32.SHFILEINFOA;
 31  
 import org.eclipse.swt.internal.win32.SHFILEINFOW;
 32  
 import org.eclipse.swt.internal.win32.TCHAR;
 33  
 import org.seasar.uruma.exception.Win32ApiException;
 34  
 import org.seasar.uruma.util.AssertionUtil;
 35  
 
 36  
 /**
 37  
  * Java から Win32 API を呼び出すためのユーティリティクラスです。<br />
 38  
  * 
 39  
  * @author y-komori
 40  
  */
 41  
 public class Win32API {
 42  
     protected static final int MAX_COMPUTERNAME_LENGTH = 15;
 43  
 
 44  4
     private static Kernel32 kernel32 = NLink.create(Kernel32.class);
 45  
 
 46  0
     private Win32API() {
 47  
 
 48  0
     }
 49  
 
 50  
     private static final int SHGFI_TYPENAME = 1024;
 51  
 
 52  
     private static final int SHGFI_DISPLAYNAME = 512;
 53  
 
 54  
     /**
 55  
      * ローカルコンピュータの NetBIOS 名を取得します。<br />
 56  
      * 
 57  
      * @return ローカルコンピュータのNetBIOS名
 58  
      */
 59  
     public static String getComputerName() {
 60  4
         ByteBuffer buffer = ByteBuffer
 61  
                 .allocateDirect(MAX_COMPUTERNAME_LENGTH + 1);
 62  4
         Holder<Integer> holder = new Holder<Integer>(buffer.capacity());
 63  
 
 64  
         try {
 65  4
             kernel32.GetComputerName(buffer, holder);
 66  4
             return convertToJavaString(buffer);
 67  0
         } catch (Exception ex) {
 68  0
             throw new Win32ApiException(ex.getLocalizedMessage());
 69  
         }
 70  
     }
 71  
 
 72  
     /**
 73  
      * 現在利用可能なディスクドライブを取得します。<br />
 74  
      * 
 75  
      * @return 利用可能なディスクドライブ名の配列
 76  
      */
 77  
     public static String[] getLogicalDrives() {
 78  
         try {
 79  16
             int result = kernel32.GetLogicalDrives();
 80  
 
 81  16
             int mask = 0x01;
 82  16
             int cnt = 0;
 83  432
             for (int i = 0; i < 26; i++, mask = mask << 1) {
 84  416
                 if ((result & mask) != 0) {
 85  192
                     cnt++;
 86  
                 }
 87  
             }
 88  16
             String[] drives = new String[cnt];
 89  16
             char drive = 'A';
 90  16
             mask = 0x01;
 91  16
             cnt = 0;
 92  432
             for (int i = 0; i < 26; i++, drive++, mask = mask << 1) {
 93  416
                 if ((result & mask) != 0) {
 94  192
                     drives[cnt++] = drive + ":\\";
 95  
                 }
 96  
             }
 97  16
             return drives;
 98  
 
 99  0
         } catch (Exception ex) {
 100  0
             throw new Win32ApiException(ex.getLocalizedMessage());
 101  
         }
 102  
     }
 103  
 
 104  
     /**
 105  
      * ボリューム情報を取得します。<br />
 106  
      * 
 107  
      * @param rootPathName
 108  
      *            ボリュームのルートパス
 109  
      * @return ボリューム情報。取得できなかった場合は <code>null</code>
 110  
      */
 111  
     public static VolumeInformation getVolumeInformation(
 112  
             final String rootPathName) {
 113  4
         ByteBuffer volumeNameBuf = ByteBuffer.allocateDirect(128);
 114  4
         Holder<Integer> volumeSerialNum = new Holder<Integer>(new Integer(0));
 115  4
         Holder<Integer> maxComponentLength = new Holder<Integer>(new Integer(0));
 116  4
         Holder<Integer> fileSystemFlags = new Holder<Integer>(new Integer(0));
 117  4
         ByteBuffer fileSystemNameBuf = ByteBuffer.allocateDirect(128);
 118  
 
 119  
         try {
 120  4
             kernel32.SetErrorMode(Kernel32.SEM_FAILCRITICALERRORS);
 121  4
             int result = kernel32.GetVolumeInformation(rootPathName,
 122  
                     volumeNameBuf, volumeNameBuf.capacity(), volumeSerialNum,
 123  
                     maxComponentLength, fileSystemFlags, fileSystemNameBuf,
 124  
                     fileSystemNameBuf.capacity());
 125  4
             if (result != 0) {
 126  4
                 VolumeInformation info = new VolumeInformation();
 127  4
                 info.setRootPath(rootPathName);
 128  4
                 info.setVolumeLabel(convertToJavaString(volumeNameBuf));
 129  4
                 info.setSerialNumber(volumeSerialNum.value);
 130  4
                 info.setFileSystemName(convertToJavaString(fileSystemNameBuf));
 131  4
                 info.setMaxComponentLength(maxComponentLength.value);
 132  4
                 info.setFileSystemFlags(fileSystemFlags.value);
 133  4
                 return info;
 134  
             } else {
 135  0
                 return null;
 136  
             }
 137  0
         } catch (Exception ex) {
 138  0
             throw new Win32ApiException(ex.getLocalizedMessage());
 139  
         }
 140  
     }
 141  
 
 142  
     /**
 143  
      * 指定したルートパスのドライブの種類を調べます。<br />
 144  
      * 
 145  
      * @param rootPathName
 146  
      *            種類を調べるドライブのルートパス
 147  
      * @return ドライブの種類
 148  
      * @see DriveType
 149  
      */
 150  
     public static DriveType getDriveType(final String rootPathName) {
 151  
         try {
 152  48
             int result = kernel32.GetDriveType(rootPathName);
 153  
 
 154  48
             switch (result) {
 155  
             case Kernel32.DRIVE_UNKNOWN:
 156  0
                 return DriveType.DRIVE_UNKNOWN;
 157  
 
 158  
             case Kernel32.DRIVE_NO_ROOT_DIR:
 159  0
                 return DriveType.DRIVE_NO_ROOT_DIR;
 160  
 
 161  
             case Kernel32.DRIVE_REMOVABLE:
 162  24
                 return DriveType.DRIVE_REMOVABLE;
 163  
 
 164  
             case Kernel32.DRIVE_FIXED:
 165  12
                 return DriveType.DRIVE_FIXED;
 166  
 
 167  
             case Kernel32.DRIVE_REMOTE:
 168  0
                 return DriveType.DRIVE_REMOTE;
 169  
 
 170  
             case Kernel32.DRIVE_CDROM:
 171  12
                 return DriveType.DRIVE_CDROM;
 172  
 
 173  
             case Kernel32.DRIVE_RAMDISK:
 174  0
                 return DriveType.DRIVE_RAMDISK;
 175  
 
 176  
             default:
 177  0
                 return DriveType.DRIVE_UNKNOWN;
 178  
             }
 179  0
         } catch (Exception ex) {
 180  0
             throw new Win32ApiException(ex.getLocalizedMessage());
 181  
         }
 182  
     }
 183  
 
 184  
     /**
 185  
      * 指定されたファイルの種類を取得します。<br />
 186  
      * 
 187  
      * @param path
 188  
      *            種類を調べるファイルのパス
 189  
      * @return ファイルの種類
 190  
      */
 191  
     public static String getFileTypeName(final String path) {
 192  48
         int flags = SHGFI_TYPENAME | OS.SHGFI_USEFILEATTRIBUTES;
 193  48
         SHFILEINFO info = getFileInfo(path, flags);
 194  48
         if (info instanceof SHFILEINFOW) {
 195  48
             return convertToJavaString(((SHFILEINFOW) info).szTypeName);
 196  
         } else {
 197  0
             return convertToJavaString(((SHFILEINFOA) info).szTypeName);
 198  
         }
 199  
     }
 200  
 
 201  
     /**
 202  
      * 指定されたファイルの表示名称を取得します。<br />
 203  
      * 
 204  
      * @param path
 205  
      *            ファイルのパス
 206  
      * @return 表示名称
 207  
      */
 208  
     public static String getFileDisplayName(final String path) {
 209  48
         int flags = SHGFI_DISPLAYNAME | OS.SHGFI_USEFILEATTRIBUTES;
 210  48
         SHFILEINFO info = getFileInfo(path, flags);
 211  48
         if (info instanceof SHFILEINFOW) {
 212  48
             return convertToJavaString(((SHFILEINFOW) info).szDisplayName);
 213  
         } else {
 214  0
             return convertToJavaString(((SHFILEINFOA) info).szDisplayName);
 215  
         }
 216  
     }
 217  
 
 218  
     /**
 219  
      * 指定したパスのアイコンをを取得します。<br />
 220  
      * 
 221  
      * @param path
 222  
      *            パス
 223  
      * @return アイコンの {@link ImageData} オブジェクト
 224  
      */
 225  
     public static ImageData getFileIcon(final String path) {
 226  0
         int flags = OS.SHGFI_ICON | OS.SHGFI_SMALLICON
 227  
                 | OS.SHGFI_USEFILEATTRIBUTES;
 228  0
         SHFILEINFO info = getFileInfo(path, flags);
 229  0
         if (info.hIcon != 0) {
 230  0
             Image image = Image.win32_new(null, SWT.ICON, info.hIcon);
 231  0
             ImageData imageData = image.getImageData();
 232  0
             image.dispose();
 233  0
             return imageData;
 234  
         } else {
 235  0
             return null;
 236  
         }
 237  
     }
 238  
 
 239  
     private static SHFILEINFO getFileInfo(final String path, final int flags) {
 240  96
         AssertionUtil.assertNotNull("path", path);
 241  96
         SHFILEINFO info = OS.IsUnicode ? (SHFILEINFO) new SHFILEINFOW()
 242  
                 : new SHFILEINFOA();
 243  96
         TCHAR pszPath = new TCHAR(0, path, true);
 244  96
         int retCode = OS.SHGetFileInfo(pszPath, OS.FILE_ATTRIBUTE_NORMAL, info,
 245  
                 SHFILEINFO.sizeof, flags);
 246  96
         if (retCode != 0) {
 247  96
             return info;
 248  
         } else {
 249  0
             throw new Win32ApiException("SHGetFileInfo", retCode);
 250  
         }
 251  
     }
 252  
 
 253  
     /**
 254  
      * ファイルからインデックスで指定したアイコンを取得します。<br />
 255  
      * 
 256  
      * @param fileName
 257  
      *            ファイル名
 258  
      * @param index
 259  
      *            アイコンのインデックス番号
 260  
      * @return アイコンの {@link ImageData} オブジェクト
 261  
      */
 262  
     public static ImageData extractIcon(final String fileName, final int index) {
 263  0
         TCHAR lpszFile = new TCHAR(0, fileName, true);
 264  0
         int[] phiconSmall = new int[1];
 265  0
         int[] phiconLarge = null;
 266  0
         OS.ExtractIconEx(lpszFile, index, phiconLarge, phiconSmall, 1);
 267  0
         if (phiconSmall[0] == 0) {
 268  0
             return null;
 269  
         }
 270  0
         Image image = Image.win32_new(null, SWT.ICON, phiconSmall[0]);
 271  0
         ImageData imageData = image.getImageData();
 272  0
         image.dispose();
 273  0
         return imageData;
 274  
     }
 275  
 
 276  
     /**
 277  
      * 指定した文字列に含まれる環境変数を展開します。<br />
 278  
      * 
 279  
      * @param str
 280  
      *            対象文字列
 281  
      * @return 環境変数展開後の文字列
 282  
      */
 283  
     public static String expandEnvironmentStrings(final String str) {
 284  8
         TCHAR lpSrc = new TCHAR(OS.CP_INSTALLED, str, true);
 285  8
         String result = str;
 286  8
         int length = OS.ExpandEnvironmentStrings(lpSrc, null, 0);
 287  8
         if (length != 0) {
 288  8
             TCHAR lpDst = new TCHAR(0, length);
 289  8
             OS.ExpandEnvironmentStrings(lpSrc, lpDst, length);
 290  8
             result = lpDst.toString(0, Math.max(0, length - 1));
 291  
         }
 292  8
         return result;
 293  
     }
 294  
 
 295  
     static String convertToJavaString(final ByteBuffer buffer) {
 296  12
         buffer.order(ByteOrder.LITTLE_ENDIAN);
 297  12
         StringWriter writer = new StringWriter();
 298  76
         for (int i = 0; buffer.remaining() > 0; i++) {
 299  76
             short chr = buffer.getShort();
 300  76
             if (chr == 0x00) {
 301  12
                 break;
 302  
             } else {
 303  64
                 writer.write(chr);
 304  
             }
 305  
         }
 306  12
         writer.flush();
 307  12
         return writer.toString();
 308  
     }
 309  
 
 310  
     static String convertToJavaString(final char[] str) {
 311  96
         StringWriter writer = new StringWriter();
 312  1284
         for (int i = 0; i < str.length; i++) {
 313  1284
             if (str[i] == 0x00) {
 314  96
                 break;
 315  
             } else {
 316  1188
                 writer.write(str[i]);
 317  
             }
 318  
         }
 319  96
         writer.flush();
 320  96
         return writer.toString();
 321  
     }
 322  
 
 323  
     static String convertToJavaString(final byte[] bytes) {
 324  0
         byte[] result = null;
 325  0
         for (int i = 0; i < bytes.length; i++) {
 326  0
             if (bytes[i] == 0x00) {
 327  0
                 result = new byte[i];
 328  0
                 System.arraycopy(bytes, 0, result, 0, result.length);
 329  0
                 return new String(result);
 330  
             }
 331  
         }
 332  0
         return "";
 333  
     }
 334  
 }