All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sun.jna.platform.win32.Cfgmgr32Util Maven / Gradle / Ivy

The newest version!
/* Copyright (c) 2018, 2021 Daniel Widdis, All Rights Reserved
 *
 * The contents of this file is dual-licensed under 2
 * alternative Open Source/Free licenses: LGPL 2.1 or later and
 * Apache License 2.0. (starting with JNA version 4.0.0).
 *
 * You can freely decide which license you want to apply to
 * the project.
 *
 * You may obtain a copy of the LGPL License at:
 *
 * http://www.gnu.org/licenses/licenses.html
 *
 * A copy is also included in the downloadable source code package
 * containing JNA, in file "LGPL2.1".
 *
 * You may obtain a copy of the Apache License at:
 *
 * http://www.apache.org/licenses/
 *
 * A copy is also included in the downloadable source code package
 * containing JNA, in file "AL2.0".
 */
package com.sun.jna.platform.win32;

import com.sun.jna.Memory;
import com.sun.jna.Native;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.win32.W32APITypeMapper;

/**
 * Cfgmgr32 utility API.
 */
public abstract class Cfgmgr32Util {
    @SuppressWarnings("serial")
    public static class Cfgmgr32Exception extends RuntimeException {
        private final int errorCode;

        public Cfgmgr32Exception(int errorCode) {
            this.errorCode = errorCode;
        }

        public int getErrorCode() {
            return errorCode;
        }

        @Override
        public String toString() {
            return super.toString() + String.format(" [errorCode: 0x%08x]", errorCode);
        }
    }

    /**
     * Utility method to call Cfgmgr32's CM_Get_Device_ID_Size, allocates the
     * required memory for the Buffer parameter based on the type mapping used,
     * calls to CM_Get_Device_ID, and returns the received string.
     *
     * @param devInst
     *            Caller-supplied device instance handle that is bound to the local
     *            machine.
     * @return The device instance ID string.
     * @throws Cfgmgr32Exception
     */
    public static String CM_Get_Device_ID(int devInst) throws Cfgmgr32Exception {
        int charToBytes = Boolean.getBoolean("w32.ascii") ? 1 : Native.WCHAR_SIZE;

        // Get Device ID character count
        IntByReference pulLen = new IntByReference();
        int ret = Cfgmgr32.INSTANCE.CM_Get_Device_ID_Size(pulLen, devInst, 0);
        if (ret != Cfgmgr32.CR_SUCCESS) {
            throw new Cfgmgr32Exception(ret);
        }

        // Add one to length to allow null terminator
        Memory buffer = new Memory((pulLen.getValue() + 1) * charToBytes);
        // Zero the buffer (including the extra character)
        buffer.clear();
        // Fetch the buffer specifying only the current length
        ret = Cfgmgr32.INSTANCE.CM_Get_Device_ID(devInst, buffer, pulLen.getValue(), 0);
        // In the unlikely event the device id changes this might not be big
        // enough, try again. This happens rarely enough one retry should be
        // sufficient.
        if (ret == Cfgmgr32.CR_BUFFER_SMALL) {
            ret = Cfgmgr32.INSTANCE.CM_Get_Device_ID_Size(pulLen, devInst, 0);
            if (ret != Cfgmgr32.CR_SUCCESS) {
                throw new Cfgmgr32Exception(ret);
            }
            buffer = new Memory((pulLen.getValue() + 1) * charToBytes);
            buffer.clear();
            ret = Cfgmgr32.INSTANCE.CM_Get_Device_ID(devInst, buffer, pulLen.getValue(), 0);
        }
        // If we still aren't successful throw an exception
        if (ret != Cfgmgr32.CR_SUCCESS) {
            throw new Cfgmgr32Exception(ret);
        }
        // Convert buffer to Java String
        if (charToBytes == 1) {
            return buffer.getString(0);
        } else {
            return buffer.getWideString(0);
        }
    }

    /**
     * Utility method to call Cfgmgr32's CM_Get_DevNode_Registry_Property that
     * allocates the required memory for the Buffer parameter, and returns values of
     * the appropriate type.
     *
     * @param devInst
     *            Caller-supplied device instance handle that is bound to the local
     *            machine.
     * @param ulProperty
     *            A {@code CM_DRP_}-prefixed constant value that identifies the
     *            device property to be obtained from the registry. These constants
     *            are defined in Cfgmgr32.h.
     * @return An {@link Object} containing the specified registry property for the
     *         device.
     *         

* If the property is of type {@link WinNT#REG_SZ}, a * {@link java.lang.String} is returned. *

* If the property is of type {@link WinNT#REG_MULTI_SZ}, an array of * {@link java.lang.String} is returned. *

* If the property is of type {@link WinNT#REG_DWORD}, an * {@link java.lang.Integer} is returned. *

* If the property is of type {@link WinNT#REG_BINARY}, an array of * {@link java.lang.Byte} is returned. *

* If no value exists for this property (error * {@link Cfgmgr32#CR_NO_SUCH_VALUE}), returns {@code null}. * @throws Cfgmgr32Exception * on any errors other than {@link Cfgmgr32#CR_NO_SUCH_VALUE} */ public static Object CM_Get_DevNode_Registry_Property(int devInst, int ulProperty) throws Cfgmgr32Exception { // Get byte count and type IntByReference size = new IntByReference(); IntByReference type = new IntByReference(); int ret = Cfgmgr32.INSTANCE.CM_Get_DevNode_Registry_Property(devInst, ulProperty, type, null, size, 0); // If this property does not exist return null if (ret == Cfgmgr32.CR_NO_SUCH_VALUE) { return null; } // If successful in retrieving type and size, should fail with CR_BUFFER_SMALL, // otherwise throw an exception if (ret != Cfgmgr32.CR_BUFFER_SMALL) { throw new Cfgmgr32Exception(ret); } // It is possible to have a valid value with registry data type, but 0 size. // Leave the memory buffer null in that case Memory buffer = null; if (size.getValue() > 0) { buffer = new Memory(size.getValue()); ret = Cfgmgr32.INSTANCE.CM_Get_DevNode_Registry_Property(devInst, ulProperty, type, buffer, size, 0); if (ret != Cfgmgr32.CR_SUCCESS) { throw new Cfgmgr32Exception(ret); } } // Get the appropriate type of data from the buffer switch (type.getValue()) { case WinNT.REG_SZ: // Convert buffer to Java String if (buffer == null) { return ""; } return W32APITypeMapper.DEFAULT == W32APITypeMapper.UNICODE ? buffer.getWideString(0) : buffer.getString(0); case WinNT.REG_MULTI_SZ: // Convert buffer to String Array if (buffer == null) { return new String[0]; } return Advapi32Util.regMultiSzBufferToStringArray(buffer); case WinNT.REG_DWORD: // Convert buffer to int if (buffer == null) { return 0; } return buffer.getInt(0); case WinNT.REG_NONE: return null; default: // Intended for WinNT.REG_BINARY but safe default for any data if (buffer == null) { return new byte[0]; } // Convert buffer to array of bytes return buffer.getByteArray(0, (int) buffer.size()); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy