Search
Write a publication
Pull to refresh

Comments 30

ох, жаба в своей красе.
>private static final byte[] Hexhars = {
>'0', '1', '2', '3', '4', '5',
>'6', '7', '8', '9', 'a', 'b',
>'c', 'd', 'e', 'f'
>};
всю это тягомотину можно заменить на
>private static byte[] Hexhars = «0123456abcdef».getBytes();
FFUU~
>private static byte[] Hexhars = «0123456789abcdef».getBytes();
Вместо того, чтобы отформатировать код, вы предлагаете объявить строку и дернуть её метод? Элегантно, ничего не скажешь :)
Если бы вы знали, какой байткод генерируется для создания таких вот массивов, то предпочли бы именно такую бы вот строку с метотом.
И? В чем конкретно проблема? Я лично не смотрю байткод без особой на то нужды, и как-то не чувствую себя ущемленным.
Тут можно почитать про cервисы, создающие html, содержащий подсвеченный код. Ну и переменные с большой буквы в Java смотрятся как-то… эм… необычно. А так, хорошая статья :)
спасибо, подправила и на будущее учту)
Посмотрел, выругался, отформатировал, назвал переменные, выделил места для асертов.

package upload;

import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.win32.StdCallLibrary;
import java.io.IOException;

/**
*
* @author samozvanka
*/
public class Win32GetFileInformation
{
  //+ declare before using
  private static byte[] Hexhars = "«0123456789abcdef".getBytes();
  
  public String FileVersion;
  private String LanguageCodePage;
  private PointerByReference InfoData;
  
  public interface Win32VersionDLL extends StdCallLibrary
  {
    Win32VersionDLL INSTANCE = (Win32VersionDLL) Native.loadLibrary(
        "Version", Win32VersionDLL.class);
    
    Integer GetFileVersionInfoSizeA(String FilePath, IntByReference Handle);

    Boolean GetFileVersionInfoA(String FilePath, int Handle, int InfoSize,
        PointerByReference InfoData);

    Boolean VerQueryValueA(PointerByReference InfoData,
        String VersionInformation, PointerByReference VersionData,
        IntByReference DataSize);
  }

  public void Win32GetFileInformation(String FilePath) throws IOException
  {
    IntByReference unusedParam = new IntByReference();
    
    int infoSize = Win32VersionDLL.INSTANCE.GetFileVersionInfoSizeA(FilePath, unusedParam);
    if (infoSize == 0)
    {
      throw new IOException("File does not exist or has no information.");
    }

    this.InfoData = new PointerByReference();
    
    Boolean success = Win32VersionDLL.INSTANCE.GetFileVersionInfoA
    (
        FilePath,
        unusedParam.getValue(),
        infoSize,
        this.InfoData
    );
    
    //+ Assert(success, "GetFileVersionInfoA in Win32GetFileInformation is failed")
    
    PointerByReference versionDataByRef = new PointerByReference();
    IntByReference dataSize = new IntByReference();
    Pointer versionDataPointer = null;
    
    // Retrieve the language information
    success = Win32VersionDLL.INSTANCE.VerQueryValueA
    (
        this.InfoData,
        "\\VarFileInfo\\Translation",
        versionDataByRef,
        dataSize
    );
    
    //+ Assert(success, "VerQueryValueA in Win32GetFileInformation is failed")
    
    System.out.println("DataSize.getValue() = " + dataSize.getValue());
    
    versionDataPointer = versionDataByRef.getValue();
    byte[] codePageBytes = versionDataPointer.getByteArray(0, dataSize.getValue());
    byte BSwap;
    // swap 0<->1 and 2<->3
    BSwap = codePageBytes[1];
    codePageBytes[1] = codePageBytes[0];
    codePageBytes[0] = BSwap;
    BSwap = codePageBytes[3];
    codePageBytes[3] = codePageBytes[2];
    codePageBytes[2] = BSwap;
    // got 1,0,3,2
    
    this.LanguageCodePage = decode(codePageBytes).toUpperCase();
    
    //// Retrieve file information
    this.FileVersion = QueryValue("FileVersion");
    
    System.out.println("FileVersion = " + this.FileVersion);

  }

  private String QueryValue(String ValueName)
  {
    IntByReference dataSize = new IntByReference();
    PointerByReference versionDataByRef = new PointerByReference();
    Pointer versionDataPointer = null;
    Boolean success = Win32VersionDLL.INSTANCE.VerQueryValueA
    (
        this.InfoData,
        "\\StringFileInfo\\" + this.LanguageCodePage + "\\" + ValueName, //"
        versionDataByRef,
        dataSize
    );
    
    //+ Assert(success, "VerQueryValueA in Win32GetFileInformation is failed")
    
    versionDataPointer = versionDataByRef.getValue();
    if (versionDataPointer == null)
    {
      return "";
    }
    else
    {
      versionDataPointer = versionDataByRef.getValue();
      return versionDataPointer.getString();
    }
  }

  private static String decode(byte[] encodedString)
  {
    StringBuilder result = new StringBuilder(2 * encodedString.length);
    
    for (int i = 0; i < encodedString.length; i++)
    {
      int v = encodedString[i] & 0xff;
    
      result.append((char) Hexhars[v >> 4]);
      result.append((char) Hexhars[v & 0xf]);
    }
    
    return result.toString();
  }
}

* This source code was highlighted with Source Code Highlighter.
UFO landed and left these words here
Если не ошибаюсь, то это поля MajorImageVersion и MinorImageVersion опционального заголовка PE-файла.
UFO landed and left these words here
А приведите, пожалуйста, пример, как это сделать таким способом?
По-моему как раз такие посты и стоит поощрять.
А удачным коментарием было бы написать эти 20 строк, чтоб поделиться опытом и показать как реализовать лучше, раз уж Вы «такой умный», г-н Дятлов.
UFO landed and left these words here
К сожалению, у меня слишком мало опыта побайтового чтения — C++ колупал буквально пару лет, а в джаве стараюсь по максимуму разбираться в стандартной библиотеке и ее возмоэжностях, потому зачастую довольствуюсь высокоуровневыми штучками-дрючками.
Но спасибо за информацию, по крайней мере в будущем (если что) буду знать в каком направлении «копать».
Пример на C++

#include "stdafx.h"
#include <windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
char* path = "C:\\windows\\explorer.exe";
HANDLE open = CreateFileA(path,GENERIC_READ,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_READONLY,0);
HANDLE mem = CreateFileMapping(open,0,PAGE_READONLY,0,0,0);
LPVOID mvof = MapViewOfFile(mem,FILE_MAP_READ,0,0,0);
PIMAGE_DOS_HEADER pidh = (PIMAGE_DOS_HEADER)mvof;
PIMAGE_NT_HEADERS pinth = (PIMAGE_NT_HEADERS)((PBYTE)pidh + pidh->e_lfanew);
printf("%d.%d",pinth->OptionalHeader.MajorImageVersion,
pinth->OptionalHeader.MinorImageVersion);
UnmapViewOfFile(mvof);
CloseHandle(mem);
CloseHandle(open);
return 0;
}
> а JNA сможет получить версию exe файла в ОС Linux?
В Linux нет exe-файлов.
А в линукс есть .exe файлы? :)
UFO landed and left these words here
Лично я предпочитаю использовать JNI и выделять платформо-зависимые куски в отдельные плагины, а использовать их через общие платформо-независимые интерфейсы.
Уж фиг с ними с отступами, с потерянными ноликами, с тем, что у вас метод называется как конструктор (и не понятно, это должен быть всё-таки метод или конструктор). Можно даже закрыть глаза на то, что у вас не проверяются возвращаемые значения (Boolean Success). Но скажите, какое оправдание есть тому, чтобы писать
private static final byte[] Hexhars = ... ;
result.append((char) Hexhars[...]);
вместо
private static final char[] Hexhars = ... ;
result.append(Hexhars[...]);
свои личные переживания сюда то не выноси, будь мужчиной
та да. я пожалел. какие-то тупые дегенераты меня уже минусаниули. кошмар, теперь не смогу никогда замутить крутой пост на хабре(((
Sign up to leave a comment.

Articles