/*
 * [Volser.java]
 *
 * Summary: Access Windows 32-bit volume serial number of a drive.
 *
 * Copyright: (c) 2007-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2007-12-17 initial release
 *  1.1 2008-09-23 fix problem with Microsoft C++ runtime library
 *  1.2 2010-11-07 fix delete[] bug in C++ that could cause heap corruption.
 *  1.3 2012-12-11 add 64-bit support.
 */
package com.mindprod.volser;

import static java.lang.System.*;

/**
 * Access Windows 32-bit volume serial number of a drive.
 * <p/>
 * Uses JNI native C++/ASM code that only works on Vista, XP, Windows 2000.
 * Do not confuse this with the case-sensitive volume label.
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.3 2012-12-11 add 64-bit support.
 * @since 2007-12-17
 */
public final class Volser
    {
    /**
     * true if you want to include the debugging harness code.
     */
    private static final boolean DEBUGGING = false;

    private static final int FIRST_COPYRIGHT_YEAR = 2007;

    /**
     * undisplayed embedded copyright notice
     */
    private static final String EMBEDDED_COPYRIGHT =
            "Copyright: (c) 2007-2017 Roedy Green, Canadian Mind Products, http://mindprod.com";

    /**
     * undisplayed embedded release date
     */
    private static final String RELEASE_DATE = "2012-12-11";

    /**
     * undisplayed embedded version string.
     */
    private static final String VERSION_STRING = "1.3";

    static
        {
        // get DLL loaded from somewhere on java.library path.
        String dll = "volser.32";
        try
            {
            // load nativepcclock.dll on path, set up by Java Web Start
            // arch is x86 or amd64
            if ( System.getProperty( "os.arch" ).equals( "amd64" ) )
                {
                dll = "volser.64";
                }
            // without .dll suffix
            System.loadLibrary( dll );
            // if have troubles change this code to use load(
            // "E:\\com\\mindprod\\volser\\volser.32.dll" );
            }
        catch ( Exception e )
            {
            out.println( "Unable to load " + dll );
            out.println( e.getMessage() );
            }
        }

    /**
     * Get the volume serial number.
     *
     * @param rootPath drive with trailing colon and backslash e.g. "C:\\". Can also be a network drive.
     *
     * @return 32-bit volume serial number as an int. Normally displayed in hex in two pieces separated by a colon or
     * dash.
     */
    public static native int getVolser( String rootPath );

    /**
     * test debug harness
     *
     * @param args not used
     */
    public static void main( String[] args )
        {
        if ( DEBUGGING )
            {
            final int volser = Volser.getVolser( "C:\\" );
            out.println( Integer.toHexString( volser ) );
            final int high = volser >>> 16;
            final int low = volser & 0xffff;
            // This code does not apply lead zeros on each half.
            // See http://mindprod.com/jgloss/hex.html for how to add that refinement.
            final String hexVolser = Integer.toHexString( high ) + ":" + Integer.toHexString( low );
            out.println( "4-byte volume serial number for drive C: is " + hexVolser );
            }
        }
    }