Package net.pms.io

Source Code of net.pms.io.WinUtils$Kernel32

/*
* PS3 Media Server, for streaming any medias to your PS3.
* Copyright (C) 2008  A.Brochard
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; version 2
* of the License only.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/
package net.pms.io;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.WString;
import com.sun.jna.ptr.LongByReference;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.CharBuffer;
import java.util.prefs.Preferences;
import net.pms.PMS;
import net.pms.configuration.PmsConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* Contains the Windows specific native functionality. Do not try to instantiate on Linux/MacOS X !
*
* @author zsombor
*/
public class WinUtils extends BasicSystemUtils implements SystemUtils {
  private static final Logger LOGGER = LoggerFactory.getLogger(WinUtils.class);
  private static final PmsConfiguration configuration = PMS.getConfiguration();

  public interface Kernel32 extends Library {
    Kernel32 INSTANCE = (Kernel32) Native.loadLibrary("kernel32", Kernel32.class);
    Kernel32 SYNC_INSTANCE = (Kernel32) Native.synchronizedLibrary(INSTANCE);

    int GetShortPathNameW(WString lpszLongPath, char[] lpdzShortPath, int cchBuffer);

    int GetWindowsDirectoryW(char[] lpdzShortPath, int uSize);

    boolean GetVolumeInformationW(
      char[] lpRootPathName,
      CharBuffer lpVolumeNameBuffer,
      int nVolumeNameSize,
      LongByReference lpVolumeSerialNumber,
      LongByReference lpMaximumComponentLength,
      LongByReference lpFileSystemFlags,
      CharBuffer lpFileSystemNameBuffer,
      int nFileSystemNameSize
    );

    int SetThreadExecutionState(int EXECUTION_STATE);
    int ES_DISPLAY_REQUIRED = 0x00000002;
    int ES_SYSTEM_REQUIRED = 0x00000001;
    int ES_CONTINUOUS = 0x80000000;
  }

  private static final int KEY_READ = 0x20019;
  private boolean kerio;
  private String avsPluginsDir;
  private String kLiteFiltersDir;
  public long lastDontSleepCall = 0;
  public long lastGoToSleepCall = 0;

  /* (non-Javadoc)
   * @see net.pms.io.SystemUtils#disableGoToSleep()
   */
  @Override
  public void disableGoToSleep() {
    // Disable go to sleep (every 40s)
    if (configuration.isPreventsSleep() && System.currentTimeMillis() - lastDontSleepCall > 40000) {
      LOGGER.trace("Calling SetThreadExecutionState ES_SYSTEM_REQUIRED");
      Kernel32.INSTANCE.SetThreadExecutionState(Kernel32.ES_SYSTEM_REQUIRED | Kernel32.ES_CONTINUOUS);
      lastDontSleepCall = System.currentTimeMillis();
    }
  }

  /* (non-Javadoc)
   * @see net.pms.io.SystemUtils#reenableGoToSleep()
   */
  @Override
  public void reenableGoToSleep() {
    // Reenable go to sleep
    if (configuration.isPreventsSleep() && System.currentTimeMillis() - lastGoToSleepCall > 40000) {
      LOGGER.trace("Calling SetThreadExecutionState ES_CONTINUOUS");
      Kernel32.INSTANCE.SetThreadExecutionState(Kernel32.ES_CONTINUOUS);
      lastGoToSleepCall = System.currentTimeMillis();
    }
  }

  /* (non-Javadoc)
   * @see net.pms.io.SystemUtils#getAvsPluginsDir()
   */
  @Override
  public File getAvsPluginsDir() {
    if (avsPluginsDir == null) {
      return null;
    }
    File pluginsDir = new File(avsPluginsDir);
    if (!pluginsDir.exists()) {
      pluginsDir = null;
    }
    return pluginsDir;
  }

  /**
   * The Filters directory for K-Lite Codec Pack, which contains vsfilter.dll
   */
  @Override
  public File getKLiteFiltersDir() {
    if (kLiteFiltersDir == null) {
      return null;
    }
    File filtersDir = new File(kLiteFiltersDir + "\\Filters");
    if (!filtersDir.exists()) {
      filtersDir = null;
    }
    return filtersDir;
  }

  /* (non-Javadoc)
   * @see net.pms.io.SystemUtils#getShortPathNameW(java.lang.String)
   */
  @Override
  public String getShortPathNameW(String longPathName) {
    boolean unicodeChars;
    try {
      byte b1[] = longPathName.getBytes("UTF-8");
      byte b2[] = longPathName.getBytes("cp1252");
      unicodeChars = b1.length != b2.length;
    } catch (Exception e) {
      return longPathName;
    }

    if (unicodeChars) {
      try {
        WString pathname = new WString(longPathName);

        char test[] = new char[2 + pathname.length() * 2];
        int r = Kernel32.INSTANCE.GetShortPathNameW(pathname, test, test.length);
        if (r > 0) {
          LOGGER.debug("Forcing short path name on " + pathname);
          return Native.toString(test);
        } else {
          LOGGER.info("File does not exist? " + pathname);
          return null;
        }

      } catch (Exception e) {
        return longPathName;
      }
    }
    return longPathName;
  }

  /* (non-Javadoc)
   * @see net.pms.io.SystemUtils#getWindowsDirectory()
   */
  @Override
  public String getWindowsDirectory() {
    char test[] = new char[2 + 256 * 2];
    int r = Kernel32.INSTANCE.GetWindowsDirectoryW(test, 256);
    if (r > 0) {
      return Native.toString(test);
    }
    return null;
  }

  /* (non-Javadoc)
   * @see net.pms.io.SystemUtils#getDiskLabel(java.io.File)
   */
  @Override
  public String getDiskLabel(File f) {
    String driveName;
    try {
      driveName = f.getCanonicalPath().substring(0, 2) + "\\";

      char[] lpRootPathName_chars = new char[4];
      for (int i = 0; i < 3; i++) {
        lpRootPathName_chars[i] = driveName.charAt(i);
      }
      lpRootPathName_chars[3] = '\0';
      int nVolumeNameSize = 256;
      CharBuffer lpVolumeNameBuffer_char = CharBuffer.allocate(nVolumeNameSize);
      LongByReference lpVolumeSerialNumber = new LongByReference();
      LongByReference lpMaximumComponentLength = new LongByReference();
      LongByReference lpFileSystemFlags = new LongByReference();
      int nFileSystemNameSize = 256;
      CharBuffer lpFileSystemNameBuffer_char = CharBuffer.allocate(nFileSystemNameSize);

      boolean result2 = Kernel32.INSTANCE.GetVolumeInformationW(
        lpRootPathName_chars,
        lpVolumeNameBuffer_char,
        nVolumeNameSize,
        lpVolumeSerialNumber,
        lpMaximumComponentLength,
        lpFileSystemFlags,
        lpFileSystemNameBuffer_char,
        nFileSystemNameSize);
      if (!result2) {
        return null;
      }
      String diskLabel = charString2String(lpVolumeNameBuffer_char);
      return diskLabel;
    } catch (Exception e) {
      return null;
    }
  }

  private String charString2String(CharBuffer buf) {
    char[] chars = buf.array();
    int i;
    for (i = 0; i < chars.length; i++) {
      if (chars[i] == '\0') {
        break;
      }
    }
    return new String(chars, 0, i);
  }

  public WinUtils() {
    start();
  }

  private void start() {
    final Preferences userRoot = Preferences.userRoot();
    final Preferences systemRoot = Preferences.systemRoot();
    final Class<? extends Preferences> clz = userRoot.getClass();
    try {
      if (clz.getName().endsWith("WindowsPreferences")) {
        final Method openKey = clz.getDeclaredMethod("WindowsRegOpenKey", int.class, byte[].class, int.class);
        openKey.setAccessible(true);

        final Method closeKey = clz.getDeclaredMethod("WindowsRegCloseKey", int.class);
        closeKey.setAccessible(true);

        final Method winRegQueryValue = clz.getDeclaredMethod("WindowsRegQueryValueEx", int.class, byte[].class);
        winRegQueryValue.setAccessible(true);

        byte[] valb;
        String key;

        // Check if VLC is installed
        key = "SOFTWARE\\VideoLAN\\VLC";
        int handles[] = (int[]) openKey.invoke(systemRoot, -2147483646, toCstr(key), KEY_READ);
        if (!(handles.length == 2 && handles[0] != 0 && handles[1] == 0)) {
          key = "SOFTWARE\\Wow6432Node\\VideoLAN\\VLC";
          handles = (int[]) openKey.invoke(systemRoot, -2147483646, toCstr(key), KEY_READ);
        }
        if (handles.length == 2 && handles[0] != 0 && handles[1] == 0) {
          valb = (byte[]) winRegQueryValue.invoke(systemRoot, handles[0], toCstr(""));
          vlcp = (valb != null ? new String(valb).trim() : null);
          valb = (byte[]) winRegQueryValue.invoke(systemRoot, handles[0], toCstr("Version"));
          vlcv = (valb != null ? new String(valb).trim() : null);
          closeKey.invoke(systemRoot, handles[0]);
        }

        // Check if AviSynth is installed
        key = "SOFTWARE\\AviSynth";
        handles = (int[]) openKey.invoke(systemRoot, -2147483646, toCstr(key), KEY_READ);
        if (!(handles.length == 2 && handles[0] != 0 && handles[1] == 0)) {
          key = "SOFTWARE\\Wow6432Node\\AviSynth";
          handles = (int[]) openKey.invoke(systemRoot, -2147483646, toCstr(key), KEY_READ);
        }
        if (handles.length == 2 && handles[0] != 0 && handles[1] == 0) {
          avis = true;
          valb = (byte[]) winRegQueryValue.invoke(systemRoot, handles[0], toCstr("plugindir2_5"));
          avsPluginsDir = (valb != null ? new String(valb).trim() : null);
          closeKey.invoke(systemRoot, handles[0]);
        }

        // Check if K-Lite Codec Pack is installed
        key = "SOFTWARE\\Wow6432Node\\KLCodecPack";
        handles = (int[]) openKey.invoke(systemRoot, -2147483646, toCstr(key), KEY_READ);
        if (!(handles.length == 2 && handles[0] != 0 && handles[1] == 0)) {
          key = "SOFTWARE\\KLCodecPack";
          handles = (int[]) openKey.invoke(systemRoot, -2147483646, toCstr(key), KEY_READ);
        }
        if (handles.length == 2 && handles[0] != 0 && handles[1] == 0) {
          valb = (byte[]) winRegQueryValue.invoke(systemRoot, handles[0], toCstr("installdir"));
          kLiteFiltersDir = (valb != null ? new String(valb).trim() : null);
          closeKey.invoke(systemRoot, handles[0]);
        }

        // Check if Kerio is installed
        key = "SOFTWARE\\Kerio";
        handles = (int[]) openKey.invoke(systemRoot, -2147483646, toCstr(key), KEY_READ);
        if (handles.length == 2 && handles[0] != 0 && handles[1] == 0) {
          kerio = true;
        }
      }
    } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
      LOGGER.debug("Caught exception", e);
    }
  }

  /* (non-Javadoc)
   * @see net.pms.io.SystemUtils#isKerioFirewall()
   */
  @Override
  public boolean isKerioFirewall() {
    return kerio;
  }

  private static byte[] toCstr(String str) {
    byte[] result = new byte[str.length() + 1];
    for (int i = 0; i < str.length(); i++) {
      result[i] = (byte) str.charAt(i);
    }
    result[str.length()] = 0;
    return result;
  }

  @Override
  public String[] getPingCommand(String hostAddress, int count, int packetSize) {
    String cmd = PMS.getConfiguration().pingPath();
    if (cmd == null) {
      return new String[]{"ping", /* count */ "-n", Integer.toString(count), /* size */ "-l", Integer.toString(packetSize), hostAddress};
    } else {
      return new String[]{cmd, /*warmup */ "-w", "0", "-i", "0", /* count */ "-n", Integer.toString(count), /* size */ "-l", Integer.toString(packetSize), hostAddress};
    }

  }

  @Override
  public String parsePingLine(String line) {
    if (PMS.getConfiguration().pingPath() == null) {
      return super.parsePingLine(line);
    }
    int msPos = line.indexOf("ms");

    if (msPos == -1) {
      return null;
    }
    return line.substring(line.lastIndexOf(':', msPos) + 1, msPos).trim();
  }
}
TOP

Related Classes of net.pms.io.WinUtils$Kernel32

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.