FileDocCategorySizeDatePackage
LnkParser.javaAPI DocExample4536Mon Jan 09 11:01:58 GMT 2006None

LnkParser.java

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;

public class LnkParser {
    
    public LnkParser(File f) throws Exception {
        parse(f);
    }
    
    private boolean is_dir;
    public boolean isDirectory() {
        return is_dir;
    }
    
    private String real_file;
    public String getRealFilename() {
        return real_file;
    }
    
    public void parse(File f) throws Exception {
        // read the entire file into a byte buffer
        FileInputStream fin = new FileInputStream(f);
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        byte[] buff = new byte[256];
        while(true) {
            int n = fin.read(buff);
            if(n == -1) { break; }
            bout.write(buff,0,n);
        }
        fin.close();
        byte[] link = bout.toByteArray();
        
        
        // get the flags byte
        byte flags = link[0x14];
        
        // get the file attributes byte
        final int file_atts_offset = 0x18;
        byte fileatts = link[file_atts_offset];
        byte is_dir_mask = (byte)0x10;
        if((fileatts & is_dir_mask) > 0) {
            is_dir = true;
        } else {
            is_dir = false;
        }
        
        // if the shell settings are present, skip them
        final int shell_offset = 0x4c;
        int shell_len = 0;
        if((flags & 0x1) > 0) {
            // the plus 2 accounts for the length marker itself
            shell_len = bytes2short(link,shell_offset) + 2;
        }
        
        // get to the file settings
        int file_start = 0x4c + shell_len;
        
        // get the local volume and local system values
        int local_sys_off = link[file_start+0x10] + file_start;
        real_file = getNullDelimitedString(link,local_sys_off);
        p("real filename = " + real_file);
    }
    
    static String getNullDelimitedString(byte[] bytes, int off) {
        int len = 0;
        // count bytes until the null character (0)
        while(true) {
            if(bytes[off+len] == 0) {
                break;
            }
            len++;
        }
        return new String(bytes,off,len);
    }
    
    // convert two bytes into a short
    // note, this is little endian because it's for an
    // Intel only OS.
    static int bytes2short(byte[] bytes, int off) {
        return bytes[off] | (bytes[off+1]<<8);
    }
    
    /*
    static int norm(byte b) {
        if(b < 0) {
            b+=128;
        }
        return b;
    }
    static int bytes2int(byte[] arr, int off) {
        int b1 = norm(arr[off]);
        int b2 = norm(arr[off+1]);
        int b3 = norm(arr[off+2]);
        int b4 = norm(arr[off+3]);
        int val =  (
                    (b1 << 0) |
                    (b2 << 8) |
                    (b3 << 16) |
                    (b4 << 24)
                    );
        //p("bytes2int: " + b1 + " " + b2 + " " + b3 + " " + b4);
        return val;
    }
                    
    
    static NumberFormat num_format = new DecimalFormat(" 000;-000");

    public static String padd(String str, int len) {
        while(str.length() < len) {
            str = " " + str;
        }
        return str;
    }
    
    public static void pw(byte[] arr, int off) {
        StringBuffer top = new StringBuffer();
        StringBuffer mid = new StringBuffer();
        StringBuffer bot = new StringBuffer();
        top.append("--");
        mid.append("  ");
        bot.append("  ");
        
        for(int i=0; i<16; i++) {
            int val = arr[off+i];
            String str = Integer.toHexString(off+i);
            top.append(padd(str,5));
            mid.append(padd(""+val,5));
            if(val < 0) {
                val += 128;
            }
            if(val >= ' ' && val <= '~') {
                str = "" + (char)val;
            } else {
                str = Integer.toHexString(val);
            }
            str = padd(str,5);
            bot.append(str);
            if(i%4==3) {
                top.append("    ");
                mid.append("    ");
                bot.append("    ");
            }
        }
        p(top.toString());
        p(mid.toString());
        p(bot.toString());
    }
    public static void pbits(byte bt) {
        p("byte = " + bt + " " + Integer.toHexString(bt) + " " + Integer.toBinaryString(bt));
    }*/
    
    public static void p(String str) {
        System.out.println(str);
    }
}