[USB-BRINGUP-TRUNK]
[reactos.git] / dll / win32 / fusion / assembly.c
index 75ca048..a3abc4e 100644 (file)
@@ -52,7 +52,7 @@ typedef struct tagCLRTABLE
 
 struct tagASSEMBLY
 {
-    LPSTR path;
+    LPWSTR path;
 
     HANDLE hfile;
     HANDLE hmap;
@@ -76,22 +76,6 @@ struct tagASSEMBLY
     BYTE *blobs;
 };
 
-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;
@@ -153,7 +137,7 @@ static BYTE *GetData(BYTE *pData, ULONG *pLength)
 
 static VOID *assembly_data_offset(ASSEMBLY *assembly, ULONG offset)
 {
-    return (VOID *)&assembly->data[offset];
+    return &assembly->data[offset];
 }
 
 #define MAX_TABLES_WORD 0xFFFF
@@ -162,7 +146,7 @@ static VOID *assembly_data_offset(ASSEMBLY *assembly, ULONG offset)
 #define MAX_TABLES_3BIT_ENCODE 8191
 #define MAX_TABLES_5BIT_ENCODE 2047
 
-static inline ULONG get_table_size(ASSEMBLY *assembly, DWORD index)
+static inline ULONG get_table_size(const ASSEMBLY *assembly, DWORD index)
 {
     DWORD size;
     INT tables;
@@ -502,7 +486,7 @@ static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
     ULONG currofs;
 
     currofs = offset;
-    assembly->tableshdr = (METADATATABLESHDR *)assembly_data_offset(assembly, currofs);
+    assembly->tableshdr = assembly_data_offset(assembly, currofs);
     if (!assembly->tableshdr)
         return E_FAIL;
 
@@ -514,7 +498,7 @@ static HRESULT parse_clr_tables(ASSEMBLY *assembly, ULONG offset)
                        sizeof(DWORD) : sizeof(WORD);
 
     currofs += sizeof(METADATATABLESHDR);
-    assembly->numrows = (DWORD *)assembly_data_offset(assembly, currofs);
+    assembly->numrows = assembly_data_offset(assembly, currofs);
     if (!assembly->numrows)
         return E_FAIL;
 
@@ -628,9 +612,9 @@ static HRESULT parse_clr_metadata(ASSEMBLY *assembly)
                 return hr;
         }
         else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings"))
-            assembly->strings = (BYTE *)assembly_data_offset(assembly, ofs);
+            assembly->strings = assembly_data_offset(assembly, ofs);
         else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob"))
-            assembly->blobs = (BYTE *)assembly_data_offset(assembly, ofs);
+            assembly->blobs = assembly_data_offset(assembly, ofs);
 
         ptr += lstrlenA(stream) + 1;
         ptr = (BYTE *)(((UINT_PTR)ptr + 3) & ~3); /* align on DWORD boundary */
@@ -647,14 +631,18 @@ static HRESULT parse_pe_header(ASSEMBLY *assembly)
     if (!assembly->nthdr)
         return E_FAIL;
 
-    if (assembly->nthdr->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64)
+    if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
     {
         IMAGE_OPTIONAL_HEADER64 *opthdr =
                 (IMAGE_OPTIONAL_HEADER64 *)&assembly->nthdr->OptionalHeader;
         datadirs = opthdr->DataDirectory;
     }
     else
-        datadirs = assembly->nthdr->OptionalHeader.DataDirectory;
+    {
+        IMAGE_OPTIONAL_HEADER32 *opthdr =
+                (IMAGE_OPTIONAL_HEADER32 *)&assembly->nthdr->OptionalHeader;
+        datadirs = opthdr->DataDirectory;
+    }
 
     if (!datadirs)
         return E_FAIL;
@@ -684,7 +672,7 @@ HRESULT assembly_create(ASSEMBLY **out, LPCWSTR file)
     if (!assembly)
         return E_OUTOFMEMORY;
 
-    assembly->path = strdupWtoA(file);
+    assembly->path = strdupW(file);
     if (!assembly->path)
     {
         hr = E_OUTOFMEMORY;
@@ -743,16 +731,21 @@ HRESULT assembly_release(ASSEMBLY *assembly)
     return S_OK;
 }
 
-static LPSTR assembly_dup_str(ASSEMBLY *assembly, DWORD index)
+static LPWSTR assembly_dup_str(const ASSEMBLY *assembly, DWORD index)
 {
-    LPSTR str = (LPSTR)&assembly->strings[index];
-    LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(str)+1);
-    if (cpy)
-       strcpy(cpy, str);
+    int len;
+    LPWSTR cpy;
+    LPCSTR str = (LPCSTR)&assembly->strings[index];
+
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+
+    if ((cpy = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR))))
+       MultiByteToWideChar(CP_ACP, 0, str, -1, cpy, len);
+
     return cpy;
 }
 
-HRESULT assembly_get_name(ASSEMBLY *assembly, LPSTR *name)
+HRESULT assembly_get_name(ASSEMBLY *assembly, LPWSTR *name)
 {
     BYTE *ptr;
     LONG offset;
@@ -779,92 +772,65 @@ HRESULT assembly_get_name(ASSEMBLY *assembly, LPSTR *name)
     return S_OK;
 }
 
-HRESULT assembly_get_path(ASSEMBLY *assembly, LPSTR *path)
+HRESULT assembly_get_path(const ASSEMBLY *assembly, LPWSTR *path)
 {
-    LPSTR cpy = HeapAlloc(GetProcessHeap(), 0, strlen(assembly->path)+1);
+    LPWSTR cpy = HeapAlloc(GetProcessHeap(), 0, (strlenW(assembly->path) + 1) * sizeof(WCHAR));
     *path = cpy;
     if (cpy)
-        strcpy(cpy, assembly->path);
+        strcpyW(cpy, assembly->path);
     else
         return E_OUTOFMEMORY;
 
     return S_OK;
 }
 
-HRESULT assembly_get_version(ASSEMBLY *assembly, LPSTR *version)
+HRESULT assembly_get_version(ASSEMBLY *assembly, LPWSTR *version)
 {
-    LPSTR verdata;
-    VS_FIXEDFILEINFO *ffi;
-    HRESULT hr = S_OK;
-    DWORD size;
+    static const WCHAR format[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
 
-    size = GetFileVersionInfoSizeA(assembly->path, NULL);
-    if (!size)
-        return HRESULT_FROM_WIN32(GetLastError());
+    ASSEMBLYTABLE *asmtbl;
+    LONG offset;
 
-    verdata = HeapAlloc(GetProcessHeap(), 0, size);
-    if (!verdata)
-        return E_OUTOFMEMORY;
+    *version = NULL;
 
-    if (!GetFileVersionInfoA(assembly->path, 0, size, verdata))
-    {
-        hr = HRESULT_FROM_WIN32(GetLastError());
-        goto done;
-    }
+    offset = assembly->tables[TableFromToken(mdtAssembly)].offset;
+    if (offset == -1)
+        return E_FAIL;
 
-    if (!VerQueryValueA(verdata, "\\", (LPVOID *)&ffi, &size))
-    {
-        hr = HRESULT_FROM_WIN32(GetLastError());
-        goto done;
-    }
+    asmtbl = assembly_data_offset(assembly, offset);
+    if (!asmtbl)
+        return E_FAIL;
 
-    *version = HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
+    *version = HeapAlloc(GetProcessHeap(), 0, sizeof(format) + 4 * strlen("65535") * sizeof(WCHAR));
     if (!*version)
-    {
-        hr = E_OUTOFMEMORY;
-        goto done;
-    }
+        return E_OUTOFMEMORY;
 
-    sprintf(*version, "%d.%d.%d.%d", HIWORD(ffi->dwFileVersionMS),
-            LOWORD(ffi->dwFileVersionMS), HIWORD(ffi->dwFileVersionLS),
-            LOWORD(ffi->dwFileVersionLS));
+    sprintfW(*version, format, asmtbl->MajorVersion, asmtbl->MinorVersion,
+             asmtbl->BuildNumber, asmtbl->RevisionNumber);
 
-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)
+BYTE assembly_get_architecture(ASSEMBLY *assembly)
 {
-    return GetData(&assembly->blobs[index], size);
-}
+    if ((assembly->corhdr->MajorRuntimeVersion == 2) && (assembly->corhdr->MinorRuntimeVersion == 0))
+        return 0; /* .NET 1.x assembly */
 
-static void bytes_to_str(BYTE *bytes, DWORD len, LPSTR str)
-{
-    DWORD i;
+    if (assembly->nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
+        return peAMD64; /* AMD64/IA64 assembly */
 
-    static const char hexval[16] = {
-        '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'
-    };
+    if ((assembly->corhdr->Flags & COMIMAGE_FLAGS_ILONLY) && !(assembly->corhdr->Flags & COMIMAGE_FLAGS_32BITREQUIRED))
+        return peMSIL; /* MSIL assembly */
 
-    for(i = 0; i < len; i++)
-    {
-        str[i * 2] = hexval[((bytes[i] >> 4) & 0xF)];
-        str[i * 2 + 1] = hexval[(bytes[i]) & 0x0F];
-    }
+    return peI386; /* x86 assembly */
 }
 
-#define BYTES_PER_TOKEN 8
-#define CHARS_PER_BYTE 2
-#define TOKEN_LENGTH (BYTES_PER_TOKEN * CHARS_PER_BYTE + 1)
+static BYTE *assembly_get_blob(ASSEMBLY *assembly, WORD index, ULONG *size)
+{
+    return GetData(&assembly->blobs[index], size);
+}
 
-HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token)
+HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPWSTR *token)
 {
     ASSEMBLYTABLE *asmtbl;
     ULONG i, size;
@@ -875,7 +841,7 @@ HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token)
     BYTE *pubkey;
     BYTE tokbytes[BYTES_PER_TOKEN];
     HRESULT hr = E_FAIL;
-    LPSTR tok;
+    LPWSTR tok;
 
     *token = NULL;
 
@@ -883,7 +849,7 @@ HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token)
     if (offset == -1)
         return E_FAIL;
 
-    asmtbl = (ASSEMBLYTABLE *)assembly_data_offset(assembly, offset);
+    asmtbl = assembly_data_offset(assembly, offset);
     if (!asmtbl)
         return E_FAIL;
 
@@ -916,15 +882,14 @@ HRESULT assembly_get_pubkey_token(ASSEMBLY *assembly, LPSTR *token)
     for (i = size - 1; i >= size - 8; i--)
         tokbytes[size - i - 1] = hashdata[i];
 
-    tok = HeapAlloc(GetProcessHeap(), 0, TOKEN_LENGTH);
+    tok = HeapAlloc(GetProcessHeap(), 0, (TOKEN_LENGTH + 1) * sizeof(WCHAR));
     if (!tok)
     {
         hr = E_OUTOFMEMORY;
         goto done;
     }
 
-    bytes_to_str(tokbytes, BYTES_PER_TOKEN, tok);
-    tok[TOKEN_LENGTH - 1] = '\0';
+    token_to_str(tokbytes, tok);
 
     *token = tok;
     hr = S_OK;