/*
 * assembly parser
 *
 * Copyright 2008 James Hawkins
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include <stdarg.h>
#include <stdio.h>

#include "windef.h"
#include "winbase.h"
#include "winuser.h"
#include "winver.h"
#include "wincrypt.h"
#include "dbghelp.h"
#include "ole2.h"
#include "fusion.h"

#include "fusionpriv.h"
#include "wine/debug.h"
#include "wine/unicode.h"

#define MAX_CLR_TABLES  64

typedef struct tagCLRTABLE
{
    DWORD rows;
    DWORD offset;
} CLRTABLE;

struct tagASSEMBLY
{
    LPSTR path;

    HANDLE hfile;
    HANDLE hmap;
    BYTE *data;

    IMAGE_NT_HEADERS32 *nthdr;
    IMAGE_COR20_HEADER *corhdr;

    METADATAHDR *metadatahdr;

    METADATATABLESHDR *tableshdr;
    DWORD numtables;
    DWORD *numrows;
    CLRTABLE tables[MAX_CLR_TABLES];

    BYTE *strings;
    BYTE *blobs;
};

const DWORD COR_TABLE_SIZES[64] =
{
    sizeof(MODULETABLE),
    sizeof(TYPEREFTABLE),
    sizeof(TYPEDEFTABLE),
    0,
    sizeof(FIELDTABLE),
    0,
    sizeof(METHODDEFTABLE),
    0,
    sizeof(PARAMTABLE),
    sizeof(INTERFACEIMPLTABLE),
    sizeof(MEMBERREFTABLE),
    sizeof(CONSTANTTABLE),
    sizeof(CUSTOMATTRIBUTETABLE),
    sizeof(FIELDMARSHALTABLE),
    sizeof(DECLSECURITYTABLE),
    sizeof(CLASSLAYOUTTABLE),
    sizeof(FIELDLAYOUTTABLE),
    sizeof(STANDALONESIGTABLE),
    sizeof(EVENTMAPTABLE),
    0,
    sizeof(EVENTTABLE),
    sizeof(PROPERTYMAPTABLE),
    0,
    sizeof(PROPERTYTABLE),
    sizeof(METHODSEMANTICSTABLE),
    sizeof(METHODIMPLTABLE),
    sizeof(MODULEREFTABLE),
    sizeof(TYPESPECTABLE),
    sizeof(IMPLMAPTABLE),
    sizeof(FIELDRVATABLE),
    0,
    0,
    sizeof(ASSEMBLYTABLE),
    sizeof(ASSEMBLYPROCESSORTABLE),
    sizeof(ASSEMBLYOSTABLE),
    sizeof(ASSEMBLYREFTABLE),
    sizeof(ASSEMBLYREFPROCESSORTABLE),
    sizeof(ASSEMBLYREFOSTABLE),
    sizeof(FILETABLE),
    sizeof(EXPORTEDTYPETABLE),
    sizeof(MANIFESTRESTABLE),
    sizeof(NESTEDCLASSTABLE),
    sizeof(GENERICPARAMTABLE),
    sizeof(METHODSPECTABLE),
    sizeof(GENERICPARAMCONSTRAINTTABLE),
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0,
    0
};

static LPSTR strdupWtoA(LPCWSTR str)
{
    LPSTR ret = NULL;
    DWORD len;

    if (!str)
        return ret;

    len = WideCharToMultiByte(CP_ACP, 0, str, -1, NULL, 0, NULL, NULL);
    ret = HeapAlloc(GetProcessHeap(), 0, len);
    if (ret)
        WideCharToMultiByte(CP_ACP, 0, str, -1, ret, len, NULL, NULL);

    return ret;
}

static DWORD rva_to_offset(IMAGE_NT_HEADERS *nthdrs, DWORD rva)
{
    DWORD offset = rva, limit;
    IMAGE_SECTION_HEADER *img;
    WORD i;

    img = IMAGE_FIRST_SECTION(nthdrs);

    if (rva < img->PointerToRawData)
        return rva;

    for (i = 0; i < nthdrs->FileHeader.NumberOfSections; i++)
    {
        if (img[i].SizeOfRawData)
            limit = img[i].SizeOfRawData;
        else
            limit = img[i].Misc.VirtualSize;

        if (rva >= img[i].VirtualAddress &&
            rva < (img[i].VirtualAddress + limit))
        {
            if (img[i].PointerToRawData != 0)
            {
                offset -= img[i].VirtualAddress;
                offset += img[i].PointerToRawData;
            }

            return offset;
        }
    }

    return 0;
}

static BYTE *GetData(BYTE *pData, ULONG *pLength)
{
    if ((*pData & 0x80) == 0x00)
    {
        *pLength = (*pData & 0x7f);
        return pData + 1;
    }

    if ((*pData & 0xC0) == 0x80)
    {
        *pLength = ((*pData & 0x3f) << 8 | *(pData + 1));
        return pData + 2;
    }

    if ((*pData & 0xE0) == 0xC0)
    {
        *pLength = ((*pData & 0x1f) << 24 | *(pData + 1) << 16 |
                    *(pData + 2) << 8 | *(pData + 3));
        return pData + 4;
    }

    *pLength = (ULONG)-1;
    return 0;
}

static VOID *assembly_data_offset(ASSEMBLY *assembly, ULONG offset)
{
    return (VOID *)&assembly->data[offset];
}

static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
{
    DWORD i, previ, offidx;
    ULONG currofs;

    currofs = offset;
    assembly->tableshdr = (METADATATABLESHDR *)assembly_data_offset(assembly, currofs);
    if (!assembly->tableshdr)
        return E_FAIL;

    currofs += sizeof(METADATATABLESHDR);
    assembly->numrows = (DWORD *)assembly_data_offset(assembly, currofs);
    if (!assembly->numrows)
        return E_FAIL;

    assembly->numtables = 0;
    for (i = 0; i < MAX_CLR_TABLES; i++)
    {
        if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) ||
            (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1))
        {
            assembly->numtables++;
        }
    }

    currofs += assembly->numtables * sizeof(DWORD);
    memset(assembly->tables, -1, MAX_CLR_TABLES * sizeof(CLRTABLE));

    if (assembly->tableshdr->MaskValid.u.LowPart & 1)
    {
        assembly->tables[0].offset = currofs;
        assembly->tables[0].rows = assembly->numrows[0];
    }

    previ = 0;
    offidx = 1;
    for (i = 1; i < MAX_CLR_TABLES; i++)
    {
        if ((i < 32 && (assembly->tableshdr->MaskValid.u.LowPart >> i) & 1) ||
            (i >= 32 && (assembly->tableshdr->MaskValid.u.HighPart >> i) & 1))
        {
            currofs += COR_TABLE_SIZES[previ] * assembly->numrows[offidx - 1];
            assembly->tables[i].offset = currofs;
            assembly->tables[i].rows = assembly->numrows[offidx];
            offidx++;
            previ = i;
        }
    }

    return S_OK;
}

static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
{
    METADATASTREAMHDR *streamhdr;
    ULONG rva, i, ofs;
    LPSTR stream;
    HRESULT hr;
    BYTE *ptr;

    rva = assembly->corhdr->MetaData.VirtualAddress;
    assembly->metadatahdr = ImageRvaToVa(assembly->nthdr, assembly->data,
                                         rva, NULL);
    if (!assembly->metadatahdr)
        return E_FAIL;

    ptr = ImageRvaToVa(assembly->nthdr, assembly->data,
                       rva + sizeof(METADATAHDR), NULL);
    if (!ptr)
        return E_FAIL;

    for (i = 0; i < assembly->metadatahdr->Streams; i++)
    {
        streamhdr = (METADATASTREAMHDR *)ptr;
        ofs = rva_to_offset(assembly->nthdr, rva + streamhdr->Offset);

        ptr += sizeof(METADATASTREAMHDR);
        stream = (LPSTR)ptr;

        if (!lstrcmpA(stream, "#~"))
        {
            hr = parse_clr_tables(assembly, ofs);
            if (FAILED(hr))
                return hr;
        }
        else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings"))
            assembly->strings = (BYTE *)assembly_data_offset(assembly, ofs);
        else if (!lstrcmpA(stream, "#Blob"))
            assembly->blobs = (BYTE *)assembly_data_offset(assembly, ofs);

        ptr += lstrlenA(stream);
        while (!*ptr) ptr++;
    }

    return S_OK;
}

static HRESULT parse_pe_header(ASSEMBLY *assembly)
{
    IMAGE_DATA_DIRECTORY *datadirs;

    assembly->nthdr = ImageNtHeader(assembly->data);
    if (!assembly->nthdr)
        return E_FAIL;

    datadirs = assembly->nthdr->OptionalHeader.DataDirectory;
    if (!datadirs)
        return E_FAIL;

    if (!datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress ||
        !datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].Size)
    {
        return E_FAIL;
    }

    assembly->corhdr = ImageRvaToVa(assembly->nthdr, assembly->data,
        datadirs[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR].VirtualAddress, NULL);
    if (!assembly->corhdr)
        return E_FAIL;

    return S_OK;
}

HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
{
    ASSEMBLY *assembly;
    HRESULT hr;

    *out = NULL;

    assembly = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ASSEMBLY));
    if (!assembly)
        return E_OUTOFMEMORY;

    assembly->path = strdupWtoA(file);
    if (!assembly->path)
    {
        hr = E_OUTOFMEMORY;
        goto failed;
    }

    assembly->hfile = CreateFileW(file, GENERIC_READ, FILE_SHARE_READ,
                                  NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
    if (assembly->hfile == INVALID_HANDLE_VALUE)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto failed;
    }

    assembly->hmap = CreateFileMappingW(assembly->hfile, NULL, PAGE_READONLY,
                                        0, 0, NULL);
    if (!assembly->hmap)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto failed;
    }

    assembly->data = MapViewOfFile(assembly->hmap, FILE_MAP_READ, 0, 0, 0);
    if (!assembly->data)
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto failed;
    }

    hr = parse_pe_header(assembly);
    if (FAILED(hr)) goto failed;

    hr = parse_clr_metadata(assembly);
    if (FAILED(hr)) goto failed;

    *out = assembly;
    return S_OK;

failed:
    assembly_release( assembly );
    return hr;
}

HRESULT assembly_release(ASSEMBLY *assembly)
{
    if (!assembly)
        return S_OK;

    HeapFree(GetProcessHeap(), 0, assembly->path);
    UnmapViewOfFile(assembly->data);
    CloseHandle(assembly->hmap);
    CloseHandle(assembly->hfile);
    HeapFree(GetProcessHeap(), 0, assembly);

    return S_OK;
}

static LPSTR assembly_dup_str(ASSEMBLY *assembly, WORD index)
{
    LPSTR str = (LPSTR)&assembly->strings[index];
    LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(str)+1);
    if (cpy)
       strcpy(cpy, str);
    return cpy;
}

HRESULT assembly_get_name(ASSEMBLY *assembly, LPSTR *name)
{
    ASSEMBLYTABLE *asmtbl;
    ULONG offset;

    offset = assembly->tables[0x20].offset; /* FIXME: add constants */
    if (offset == -1)
        return E_FAIL;

    asmtbl = (ASSEMBLYTABLE *)assembly_data_offset(assembly, offset);
    if (!asmtbl)
        return E_FAIL;

    *name = assembly_dup_str(assembly, asmtbl->Name);
    if (!*name)
        return E_OUTOFMEMORY;

    return S_OK;
}

HRESULT assembly_get_path(ASSEMBLY *assembly, LPSTR *path)
{
    LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(assembly->path)+1);
    *path = cpy;
    if (cpy)
        strcpy(cpy, assembly->path);
    else
        return E_OUTOFMEMORY;

    return S_OK;
}

HRESULT assembly_get_version(ASSEMBLY *assembly, LPSTR *version)
{
    LPSTR verdata;
    VS_FIXEDFILEINFO *ffi;
    HRESULT hr = S_OK;
    DWORD size;

    size = GetFileVersionInfoSizeA(assembly->path, NULL);
    if (!size)
        return HRESULT_FROM_WIN32(GetLastError());

    verdata = HeapAlloc(GetProcessHeap(), 0, size);
    if (!verdata)
        return E_OUTOFMEMORY;

    if (!GetFileVersionInfoA(assembly->path, 0, size, verdata))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto done;
    }

    if (!VerQueryValueA(verdata, "\\", (LPVOID *)&ffi, &size))
    {
        hr = HRESULT_FROM_WIN32(GetLastError());
        goto done;
    }

    *version = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
    if (!*version)
    {
        hr = E_OUTOFMEMORY;
        goto done;
    }

    sprintf(*version, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
            LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
            LOWORD(ffi->dwFileVersionLS));

done:
    HeapFree(GetProcessHeap(), 0, verdata);
    return hr;
}

HRESULT assembly_get_architecture(ASSEMBLY *assembly, DWORD fixme)
{
    /* FIXME */
    return S_OK;
}

static BYTE *assembly_get_blob(ASSEMBLY *assembly, WORD index, ULONG *size)
{
    return GetData(&assembly->blobs[index], size);
}

static void bytes_to_str(BYTE *bytes, DWORD len, LPSTR str)
{
    int i;

    static const char hexval[16] = {
        '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
    };

    for(i = 0; i < len; i++)
    {
        str[i * 2] = hexval[((bytes[i] >> 4) & 0xF)];
        str[i * 2 + 1] = hexval[(bytes[i]) & 0x0F];
    }
}

#define BYTES_PER_TOKEN 8
#define CHARS_PER_BYTE 2
#define TOKEN_LENGTH (BYTES_PER_TOKEN * CHARS_PER_BYTE + 1)

HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token)
{
    ASSEMBLYTABLE *asmtbl;
    ULONG i, offset, size;
    BYTE *hashdata;
    HCRYPTPROV crypt;
    HCRYPTHASH hash;
    BYTE *pubkey;
    BYTE tokbytes[BYTES_PER_TOKEN];
    HRESULT hr = E_FAIL;
    LPSTR tok;

    *token = NULL;

    offset = assembly->tables[0x20].offset; /* FIXME: add constants */
    if (offset == -1)
        return E_FAIL;

    asmtbl = (ASSEMBLYTABLE *)assembly_data_offset(assembly, offset);
    if (!asmtbl)
        return E_FAIL;

    pubkey = assembly_get_blob(assembly, asmtbl->PublicKey, &size);

    if (!CryptAcquireContextA(&crypt, NULL, NULL, PROV_RSA_FULL,
                              CRYPT_VERIFYCONTEXT))
        return E_FAIL;

    if (!CryptCreateHash(crypt, CALG_SHA1, 0, 0, &hash))
        return E_FAIL;

    if (!CryptHashData(hash, pubkey, size, 0))
        return E_FAIL;

    size = 0;
    if (!CryptGetHashParam(hash, HP_HASHVAL, NULL, &size, 0))
        return E_FAIL;

    hashdata = HeapAlloc(GetProcessHeap(), 0, size);
    if (!hashdata)
    {
        hr = E_OUTOFMEMORY;
        goto done;
    }

    if (!CryptGetHashParam(hash, HP_HASHVAL, hashdata, &size, 0))
        goto done;

    for (i = size - 1; i >= size - 8; i--)
        tokbytes[size - i - 1] = hashdata[i];

    tok = HeapAlloc(GetProcessHeap(), 0, TOKEN_LENGTH);
    if (!tok)
    {
        hr = E_OUTOFMEMORY;
        goto done;
    }

    bytes_to_str(tokbytes, BYTES_PER_TOKEN, tok);
    tok[TOKEN_LENGTH - 1] = '\0';

    *token = tok;
    hr = S_OK;

done:
    HeapFree(GetProcessHeap(), 0, hashdata);
    CryptDestroyHash(hash);
    CryptReleaseContext(crypt, 0);

    return hr;
}
