VirtualBox

Changeset 39548 in vbox for trunk/src/VBox/Additions/WINNT


Ignore:
Timestamp:
Dec 7, 2011 3:34:34 PM (13 years ago)
Author:
vboxsync
Message:

VBoxGuestInstallHelper: Added routines for looking up a file's vendor and target architecture (PE/COFF).

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp

    r37421 r39548  
    2323#include <stdlib.h>
    2424#include <Strsafe.h>
     25#include <tchar.h>
    2526#include "exdll.h"
    2627
     
    6263    HRESULT hr = S_OK;
    6364    if (!g_stacktop || !*g_stacktop)
    64         hr = ERROR_EMPTY;
     65        hr = __HRESULT_FROM_WIN32(ERROR_EMPTY);
    6566    else
    6667    {
     
    8384    HRESULT hr = S_OK;
    8485    if (!g_stacktop || !*g_stacktop)
    85         hr = ERROR_EMPTY;
     86        hr = __HRESULT_FROM_WIN32(ERROR_EMPTY);
    8687    else
    8788    {
     
    9697    }
    9798    return hr;
     99}
     100
     101static void vboxPushResultAsString(HRESULT hr)
     102{
     103    TCHAR szErr[MAX_PATH + 1];
     104    if (FAILED(hr))
     105    {
     106        if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, szErr, MAX_PATH, NULL))
     107            szErr[MAX_PATH] = '\0';
     108        else
     109            StringCchPrintf(szErr, sizeof(szErr),
     110                            "FormatMessage failed! Error = %ld", GetLastError());
     111    }
     112    else
     113        StringCchPrintf(szErr, sizeof(szErr), "0");
     114    pushstring(szErr);
    98115}
    99116
     
    110127    WCHAR *pwString = (WCHAR*)HeapAlloc(GetProcessHeap(), 0, iLen * sizeof(WCHAR));
    111128    if (!pwString)
    112         hr = ERROR_NOT_ENOUGH_MEMORY;
     129        hr = __HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY);
    113130    else
    114131    {
     
    180197
    181198/**
    182  * Shows a balloon message using VBoxTray's notification area in the
    183  * Windows task bar.
    184  *
    185  * @param   hwndParent          Window handle of parent.
    186  * @param   string_size         Size of variable string.
    187  * @param   variables           The actual variable string.
    188  * @param   stacktop            Pointer to a pointer to the current stack.
    189  */
    190 VBOXINSTALLHELPER_EXPORT VBoxTrayShowBallonMsg(HWND hwndParent, int string_size,
    191                                                TCHAR *variables, stack_t **stacktop)
    192 {
    193     EXDLL_INIT();
    194 
    195     VBOXTRAYIPCHEADER hdr;
    196     hdr.ulMsg = VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG;
    197     hdr.cbBody = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG);
    198 
    199     VBOXTRAYIPCMSG_SHOWBALLOONMSG msg;
    200     HRESULT hr = vboxPopString(msg.szContent, sizeof(msg.szContent) / sizeof(TCHAR));
    201     if (SUCCEEDED(hr))
    202         hr = vboxPopString(msg.szTitle, sizeof(msg.szTitle) / sizeof(TCHAR));
    203     if (SUCCEEDED(hr))
    204         hr = vboxPopULong(&msg.ulType);
    205     if (SUCCEEDED(hr))
    206         hr = vboxPopULong(&msg.ulShowMS);
    207 
    208     if (SUCCEEDED(hr))
    209     {
    210         msg.ulFlags = 0;
    211 
    212         HANDLE hPipe = vboxIPCConnect();
    213         if (hPipe)
    214         {
    215             hr = vboxIPCWriteMessage(hPipe, (BYTE*)&hdr, sizeof(VBOXTRAYIPCHEADER));
    216             if (SUCCEEDED(hr))
    217                 hr = vboxIPCWriteMessage(hPipe, (BYTE*)&msg, sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG));
    218             vboxIPCDisconnect(hPipe);
    219         }
    220     }
    221 
    222     /* Push simple return value on stack. */
    223     SUCCEEDED(hr) ? pushstring("0") : pushstring("1");
    224 }
    225 
    226 BOOL WINAPI DllMain(HANDLE hInst, ULONG uReason, LPVOID lpReserved)
    227 {
    228     g_hInstance = (HINSTANCE)hInst;
    229     return TRUE;
    230 }
    231 
    232 /**
    233199 * Disables the Windows File Protection for a specified file
    234200 * using an undocumented SFC API call. Don't try this at home!
     
    280246    }
    281247
    282     TCHAR szErr[MAX_PATH + 1];
     248    vboxPushResultAsString(hr);
     249}
     250
     251/**
     252 * Retrieves a file's architecture (x86 or amd64).
     253 * Outputs "x86", "amd64" or an error message (if not found/invalid) on stack.
     254 *
     255 * @param   hwndParent          Window handle of parent.
     256 * @param   string_size         Size of variable string.
     257 * @param   variables           The actual variable string.
     258 * @param   stacktop            Pointer to a pointer to the current stack.
     259 */
     260VBOXINSTALLHELPER_EXPORT FileGetArchitecture(HWND hwndParent, int string_size,
     261                                             TCHAR *variables, stack_t **stacktop)
     262{
     263    EXDLL_INIT();
     264
     265    TCHAR szFile[MAX_PATH + 1];
     266    HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
     267    if (SUCCEEDED(hr))
     268    {
     269        /* See: http://www.microsoft.com/whdc/system/platform/firmware/PECOFF.mspx */
     270        FILE *pFh = fopen(szFile, "rb");
     271        if (pFh)
     272        {
     273            /* Assume the file is invalid. */
     274            hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
     275
     276            BYTE byOffsetPE; /* Absolute offset of PE signature. */
     277
     278            /* Do some basic validation. */
     279            /* Check for "MZ" header (DOS stub). */
     280            BYTE byBuf[255];
     281            if (   fread(&byBuf, sizeof(BYTE), 2, pFh) == 2
     282                && !memcmp(&byBuf, "MZ", 2))
     283            {
     284                /* Seek to 0x3C to get the PE offset. */
     285                if (!fseek(pFh, 60L /*0x3C*/, SEEK_SET))
     286                {
     287                    /* Read actual offset of PE signature. */
     288                    if (fread(&byOffsetPE, sizeof(BYTE), 1, pFh) == 1)
     289                    {
     290                        /* ... and seek to it. */
     291                        if (!fseek(pFh, byOffsetPE, SEEK_SET))
     292                        {
     293                            /* Validate PE signature. */
     294                            if (fread(byBuf, sizeof(BYTE), 4, pFh) == 4)
     295                            {
     296                                if (!memcmp(byBuf, "PE\0\0", 4))
     297                                    hr = S_OK;
     298                            }
     299                        }
     300                    }
     301                }
     302            }
     303
     304            /* Validation successful? */
     305            if (SUCCEEDED(hr))
     306            {
     307                BYTE byOffsetCOFF = byOffsetPE + 0x4; /* Skip PE signature. */
     308
     309                /** @todo When we need to do more stuff here, we probably should
     310                 *        mmap the file w/ a struct so that we easily could access
     311                 *        all the fixed size stuff. Later. */
     312
     313                /* Jump to machine type (first entry, 2 bytes):
     314                 * Use absolute PE offset retrieved above. */
     315                if (!fseek(pFh, byOffsetCOFF, SEEK_SET))
     316                {
     317                    WORD wMachineType;
     318                    if (fread(&wMachineType, 1,
     319                              sizeof(wMachineType), pFh) == 2)
     320                    {
     321                        switch (wMachineType)
     322                        {
     323                            case 0x14C: /* Intel 86 */
     324                                pushstring("x86");
     325                                break;
     326
     327                            case 0x8664: /* AMD64 / x64 */
     328                                pushstring("amd64");
     329                                break;
     330
     331                            default:
     332                                hr = __HRESULT_FROM_WIN32(ERROR_NOT_SUPPORTED);
     333                                break;
     334                        }
     335                    }
     336                    else
     337                        hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
     338                }
     339                else
     340                    hr = __HRESULT_FROM_WIN32(ERROR_FILE_INVALID);
     341            }
     342
     343            fclose(pFh);
     344        }
     345        else
     346            hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
     347    }
     348
    283349    if (FAILED(hr))
    284     {
    285         if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hr, 0, szErr, MAX_PATH, NULL))
    286             szErr[MAX_PATH] = '\0';
     350        vboxPushResultAsString(hr);
     351}
     352
     353/**
     354 * Retrieves a file's vendor.
     355 * Outputs the vendor's name or an error message (if not found/invalid) on stack.
     356 *
     357 * @param   hwndParent          Window handle of parent.
     358 * @param   string_size         Size of variable string.
     359 * @param   variables           The actual variable string.
     360 * @param   stacktop            Pointer to a pointer to the current stack.
     361 */
     362VBOXINSTALLHELPER_EXPORT FileGetVendor(HWND hwndParent, int string_size,
     363                                       TCHAR *variables, stack_t **stacktop)
     364{
     365    EXDLL_INIT();
     366
     367    TCHAR szFile[MAX_PATH + 1];
     368    HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR));
     369    if (SUCCEEDED(hr))
     370    {
     371        DWORD dwInfoSize = GetFileVersionInfoSize(szFile, NULL /* lpdwHandle */);
     372        if (dwInfoSize)
     373        {
     374            void *pFileInfo = GlobalAlloc(GMEM_FIXED, dwInfoSize);
     375            if (pFileInfo)
     376            {
     377                if (GetFileVersionInfo(szFile, 0, dwInfoSize, pFileInfo))
     378                {
     379                    LPVOID pvInfo;
     380                    UINT puInfoLen;
     381                    if (VerQueryValue(pFileInfo, _T("\\VarFileInfo\\Translation"),
     382                                      &pvInfo, &puInfoLen))
     383                    {
     384                        WORD wCodePage = LOWORD(*(DWORD*)pvInfo);
     385                        WORD wLanguageID = HIWORD(*(DWORD*)pvInfo);
     386
     387                        TCHAR szQuery[MAX_PATH];
     388                        _sntprintf(szQuery, sizeof(szQuery), _T("StringFileInfo\\%04X%04X\\CompanyName"),
     389                                   wCodePage,wLanguageID);
     390
     391                        LPCTSTR pcData;
     392                        if (VerQueryValue(pFileInfo, szQuery,(void**)&pcData, &puInfoLen))
     393                        {
     394                            pushstring(pcData);
     395                        }
     396                        else
     397                            hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
     398                    }
     399                    else
     400                        hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
     401                }
     402                GlobalFree(pFileInfo);
     403            }
     404            else
     405                hr = __HRESULT_FROM_WIN32(ERROR_OUTOFMEMORY);
     406        }
    287407        else
    288             StringCchPrintf(szErr, sizeof(szErr),
    289                             "FormatMessage failed! Error = %ld", GetLastError());
    290     }
    291     else
    292         StringCchPrintf(szErr, sizeof(szErr), "0");
    293     pushstring(szErr);
    294 }
    295 
     408            hr = __HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
     409    }
     410
     411    if (FAILED(hr))
     412        vboxPushResultAsString(hr);
     413}
     414
     415/**
     416 * Shows a balloon message using VBoxTray's notification area in the
     417 * Windows task bar.
     418 *
     419 * @param   hwndParent          Window handle of parent.
     420 * @param   string_size         Size of variable string.
     421 * @param   variables           The actual variable string.
     422 * @param   stacktop            Pointer to a pointer to the current stack.
     423 */
     424VBOXINSTALLHELPER_EXPORT VBoxTrayShowBallonMsg(HWND hwndParent, int string_size,
     425                                               TCHAR *variables, stack_t **stacktop)
     426{
     427    EXDLL_INIT();
     428
     429    VBOXTRAYIPCHEADER hdr;
     430    hdr.ulMsg = VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG;
     431    hdr.cbBody = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG);
     432
     433    VBOXTRAYIPCMSG_SHOWBALLOONMSG msg;
     434    HRESULT hr = vboxPopString(msg.szContent, sizeof(msg.szContent) / sizeof(TCHAR));
     435    if (SUCCEEDED(hr))
     436        hr = vboxPopString(msg.szTitle, sizeof(msg.szTitle) / sizeof(TCHAR));
     437    if (SUCCEEDED(hr))
     438        hr = vboxPopULong(&msg.ulType);
     439    if (SUCCEEDED(hr))
     440        hr = vboxPopULong(&msg.ulShowMS);
     441
     442    if (SUCCEEDED(hr))
     443    {
     444        msg.ulFlags = 0;
     445
     446        HANDLE hPipe = vboxIPCConnect();
     447        if (hPipe)
     448        {
     449            hr = vboxIPCWriteMessage(hPipe, (BYTE*)&hdr, sizeof(VBOXTRAYIPCHEADER));
     450            if (SUCCEEDED(hr))
     451                hr = vboxIPCWriteMessage(hPipe, (BYTE*)&msg, sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG));
     452            vboxIPCDisconnect(hPipe);
     453        }
     454    }
     455
     456    /* Push simple return value on stack. */
     457    SUCCEEDED(hr) ? pushstring("0") : pushstring("1");
     458}
     459
     460BOOL WINAPI DllMain(HANDLE hInst, ULONG uReason, LPVOID lpReserved)
     461{
     462    g_hInstance = (HINSTANCE)hInst;
     463    return TRUE;
     464}
     465
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette