/* Copyright (c) 2007 Timothy Wall, All Rights Reserved * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. */ package com.sun.jna.platform.win32; import java.io.File; import java.util.Collection; import java.util.List; import org.junit.Test; import com.sun.jna.Native; import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; public class Kernel32VolumeManagementFunctionsTest extends AbstractWin32TestSupport { public Kernel32VolumeManagementFunctionsTest() { super(); } @Test public void testQueryDosDevice() { Collection<String> logicalDrives = Kernel32Util.getLogicalDriveStrings(); for (String lpszDeviceName : logicalDrives) { // the documentation states that the device name cannot have a trailing backslash if (lpszDeviceName.charAt(lpszDeviceName.length() - 1) == File.separatorChar) { lpszDeviceName = lpszDeviceName.substring(0, lpszDeviceName.length() - 1); } Collection<String> devices = Kernel32Util.queryDosDevice(lpszDeviceName, WinBase.MAX_PATH); assertTrue("No devices for " + lpszDeviceName, devices.size() > 0); for (String name : devices) { assertTrue("Empty device name for " + lpszDeviceName, name.length() > 0); // System.out.append(getCurrentTestName()).append('[').append(lpszDeviceName).append(']').append(" - ").println(name); } } } @Test public void testGetVolumePathName() { char[] lpszVolumePathName = new char[WinDef.MAX_PATH + 1]; for (String propName : new String[] { "java.home", "java.io.tmpdir", "user.dir", "user.home" }) { String lpszFileName = System.getProperty(propName); assertCallSucceeded("GetVolumePathName(" + lpszFileName + ")", Kernel32.INSTANCE.GetVolumePathName(lpszFileName, lpszVolumePathName, lpszVolumePathName.length)); String path = Native.toString(lpszVolumePathName); // System.out.append(getCurrentTestName()).append('[').append(lpszFileName).append(']').append(" - ").println(path); assertTrue("No volume path for " + lpszFileName, path.length() > 0); } } @Test public void testGetVolumeNameForVolumeMountPoint() { Collection<String> logicalDrives = Kernel32Util.getLogicalDriveStrings(); char[] lpVolumeNameBuffer = new char[WinDef.MAX_PATH + 1]; for (String lpszVolumeMountPoint : logicalDrives) { // according to documentation path MUST end in backslash if (lpszVolumeMountPoint.charAt(lpszVolumeMountPoint.length() - 1) != File.separatorChar) { lpszVolumeMountPoint += File.separator; } int driveType = Kernel32.INSTANCE.GetDriveType(lpszVolumeMountPoint); // network mapped drives fail GetVolumeNameForVolumeMountPoint call if (driveType != WinBase.DRIVE_FIXED) { // System.out.append('\t').append('[').append(lpszVolumeMountPoint).append(']').println(" - skipped: non-fixed drive"); continue; } if (Kernel32.INSTANCE.GetVolumeNameForVolumeMountPoint(lpszVolumeMountPoint, lpVolumeNameBuffer, lpVolumeNameBuffer.length)) { String volumeGUID = Native.toString(lpVolumeNameBuffer); // System.out.append(getCurrentTestName()).append('[').append(lpszVolumeMountPoint).append(']').append(" - ").println(volumeGUID); assertTrue("Empty GUID for " + lpszVolumeMountPoint, volumeGUID.length() > 0); } else { int hr = Kernel32.INSTANCE.GetLastError(); if ((hr == WinError.ERROR_ACCESS_DENIED) // e.g., hidden volumes || (hr == WinError.ERROR_NOT_READY)) { // e.g., DVD drive // System.out.append('\t').append('[').append(lpszVolumeMountPoint).append(']').append(" - skipped: reason=").println(hr); continue; } fail("Cannot (error=" + hr + ") get volume information mount point " + lpszVolumeMountPoint); } } } @Test public void testGetVolumeInformation() { List<String> logicalDrives = Kernel32Util.getLogicalDriveStrings(); char[] lpVolumeNameBuffer = new char[WinDef.MAX_PATH + 1]; char[] lpFileSystemNameBuffer = new char[WinDef.MAX_PATH + 1]; IntByReference lpVolumeSerialNumber = new IntByReference(); IntByReference lpMaximumComponentLength = new IntByReference(); IntByReference lpFileSystemFlags = new IntByReference(); for (int index=(-1); index < logicalDrives.size(); index++) { String lpRootPathName = (index < 0) ? null /* curdir */ : logicalDrives.get(index); // according to documentation path MUST end in backslash if ((lpRootPathName != null) && (lpRootPathName.charAt(lpRootPathName.length() - 1) != File.separatorChar)) { lpRootPathName += File.separator; } if (!Kernel32.INSTANCE.GetVolumeInformation(lpRootPathName, lpVolumeNameBuffer, lpVolumeNameBuffer.length, lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags, lpFileSystemNameBuffer, lpFileSystemNameBuffer.length)) { int hr = Kernel32.INSTANCE.GetLastError(); if ((hr == WinError.ERROR_ACCESS_DENIED) // e.g., network or hidden volumes || (hr == WinError.ERROR_NOT_READY)) { // e.g., DVD drive // System.out.append('\t').append('[').append(lpRootPathName).append(']').append(" - skipped: reason=").println(hr); continue; } fail("Cannot (error=" + hr + ") get volume information for " + lpRootPathName); } // System.out.append(getCurrentTestName()).append('[').append(lpRootPathName).println(']'); // System.out.append('\t').append("Volume name: ").println(Native.toString(lpVolumeNameBuffer)); // System.out.append('\t').append("File system name: ").println(Native.toString(lpFileSystemNameBuffer)); // System.out.append('\t').append("Serial number: ").println(lpVolumeSerialNumber.getValue()); // System.out.append('\t').append("Max. component: ").println(lpMaximumComponentLength.getValue()); // System.out.append('\t').append("File system flags: 0x").println(Integer.toHexString(lpFileSystemFlags.getValue())); } } @Test public void testEnumVolumes() { char[] lpszVolumeName = new char[WinDef.MAX_PATH + 1]; HANDLE hFindVolume = assertValidHandle("FindFirstVolume", Kernel32.INSTANCE.FindFirstVolume(lpszVolumeName, lpszVolumeName.length)); try { int foundPaths = 0; do { String volumeGUID = Native.toString(lpszVolumeName); testEnumVolumeMountMoints(volumeGUID); foundPaths += testGetVolumePathNamesForVolumeName(volumeGUID); } while(Kernel32.INSTANCE.FindNextVolume(hFindVolume, lpszVolumeName, lpszVolumeName.length)); assertTrue("No paths were found", foundPaths > 0); int hr = Kernel32.INSTANCE.GetLastError(); assertEquals("Bad volumes enum termination reason", WinError.ERROR_NO_MORE_FILES, hr); } finally { assertCallSucceeded("FindVolumeClose", Kernel32.INSTANCE.FindVolumeClose(hFindVolume)); } } private int testGetVolumePathNamesForVolumeName(String lpszVolumeName) { Collection<String> paths = Kernel32Util.getVolumePathNamesForVolumeName(lpszVolumeName); for (String p : paths) { // System.out.append('\t').append("testGetVolumePathNamesForVolumeName").append('[').append(lpszVolumeName).append(']').append(" - ").println(p); assertTrue("Empty path for volume " + lpszVolumeName, p.length() > 0); } return paths.size(); } private void testEnumVolumeMountMoints(String volumeGUID) { char[] lpszVolumeMountPoint = new char[WinDef.MAX_PATH + 1]; HANDLE hFindVolumeMountPoint = Kernel32.INSTANCE.FindFirstVolumeMountPoint(volumeGUID, lpszVolumeMountPoint, lpszVolumeMountPoint.length); if (WinNT.INVALID_HANDLE_VALUE.equals(hFindVolumeMountPoint)) { int hr = Kernel32.INSTANCE.GetLastError(); if ((hr == WinError.ERROR_ACCESS_DENIED) // e.g., network or hidden volumes || (hr == WinError.ERROR_NOT_READY) // e.g., DVD drive || (hr == WinError.ERROR_NO_MORE_FILES) // No folders found || (hr == WinError.ERROR_PATH_NOT_FOUND)) { // System.out.append('\t').append('[').append(volumeGUID).append(']').append(" - skipped: reason=").println(hr); return; } fail("Cannot (error=" + hr + ") open mount point search handle for " + volumeGUID); } try { do { String name = Native.toString(lpszVolumeMountPoint); assertTrue("Empty mount point for " + volumeGUID, name.length() > 0); // System.out.append('\t').append("testEnumVolumeMountMoints").append('[').append(volumeGUID).append(']').append(" - ").println(name); } while(Kernel32.INSTANCE.FindNextVolumeMountPoint(hFindVolumeMountPoint, lpszVolumeMountPoint, lpszVolumeMountPoint.length)); int hr = Kernel32.INSTANCE.GetLastError(); assertEquals("Mount points enum termination reason for " + volumeGUID, WinError.ERROR_NO_MORE_FILES, hr); } finally { assertCallSucceeded("FindVolumeMountPointClose(" + volumeGUID + ")", Kernel32.INSTANCE.FindVolumeMountPointClose(hFindVolumeMountPoint)); } } }