diff options
author | Lorry Tar Creator <lorry-tar-importer@baserock.org> | 2014-03-26 19:21:20 +0000 |
---|---|---|
committer | <> | 2014-05-08 15:03:54 +0000 |
commit | fb123f93f9f5ce42c8e5785d2f8e0edaf951740e (patch) | |
tree | c2103d76aec5f1f10892cd1d3a38e24f665ae5db /src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp | |
parent | 58ed4748338f9466599adfc8a9171280ed99e23f (diff) | |
download | VirtualBox-master.tar.gz |
Imported from /home/lorry/working-area/delta_VirtualBox/VirtualBox-4.3.10.tar.bz2.HEADVirtualBox-4.3.10master
Diffstat (limited to 'src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp')
-rw-r--r-- | src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp | 185 |
1 files changed, 116 insertions, 69 deletions
diff --git a/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp b/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp index 5a27edf4..61492be0 100644 --- a/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp +++ b/src/VBox/Additions/WINNT/Installer/InstallHelper/VBoxGuestInstallHelper.cpp @@ -4,7 +4,7 @@ */ /* - * Copyright (C) 2011 Oracle Corporation + * Copyright (C) 2011-2013 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; @@ -25,6 +25,12 @@ #include <strsafe.h> #include "exdll.h" +#include <iprt/err.h> +#include <iprt/initterm.h> +#include <iprt/localipc.h> +#include <iprt/mem.h> +#include <iprt/string.h> + /* Required structures/defines of VBoxTray. */ #include "../../VBoxTray/VBoxTrayMsg.h" @@ -48,6 +54,9 @@ HINSTANCE g_hInstance; HWND g_hwndParent; PFNSFCFILEEXCEPTION g_pfnSfcFileException = NULL; +/** + * @todo Clean up this DLL, use more IPRT in here! + */ /** * Pops (gets) a value from the internal NSIS stack. @@ -62,7 +71,7 @@ static HRESULT vboxPopString(TCHAR *pszDest, size_t cchDest) { HRESULT hr = S_OK; if (!g_stacktop || !*g_stacktop) - hr = __HRESULT_FROM_WIN32(ERROR_EMPTY); + hr = __HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE); else { stack_t *pStack = (*g_stacktop); @@ -75,6 +84,8 @@ static HRESULT vboxPopString(TCHAR *pszDest, size_t cchDest) GlobalFree((HGLOBAL)pStack); } } + else + hr = __HRESULT_FROM_WIN32(ERROR_INVALID_HANDLE); } return hr; } @@ -114,6 +125,45 @@ static void vboxPushResultAsString(HRESULT hr) pushstring(szErr); } +/** + * Connects to VBoxTray IPC under the behalf of the user running + * in the current thread context. + * + * @return IPRT status code. + * @param phSession Where to store the IPC session. + */ +static int vboxConnectToVBoxTray(RTLOCALIPCSESSION *phSession) +{ + int rc = VINF_SUCCESS; + + RTUTF16 wszUserName[255]; + DWORD cchUserName = sizeof(wszUserName) / sizeof(RTUTF16); + BOOL fRc = GetUserNameW(wszUserName, &cchUserName); + if (!fRc) + rc = RTErrConvertFromWin32(GetLastError()); + + if (RT_SUCCESS(rc)) + { + char *pszUserName; + rc = RTUtf16ToUtf8(wszUserName, &pszUserName); + if (RT_SUCCESS(rc)) + { + char szPipeName[255]; + if (RTStrPrintf(szPipeName, sizeof(szPipeName), "%s%s", + VBOXTRAY_IPC_PIPE_PREFIX, pszUserName)) + { + rc = RTLocalIpcSessionConnect(phSession, szPipeName, 0 /* Flags */); + } + else + rc = VERR_NO_MEMORY; + + RTStrFree(pszUserName); + } + } + + return rc; +} + static void vboxChar2WCharFree(PWCHAR pwString) { if (pwString) @@ -143,56 +193,22 @@ static HRESULT vboxChar2WCharAlloc(const char *pszString, PWCHAR *ppwString) return hr; } -static HANDLE vboxIPCConnect(void) +/** + * Loads a system DLL. + * + * @returns Module handle or NULL + * @param pszName The DLL name. + */ +static HMODULE loadSystemDll(const char *pszName) { - HANDLE hPipe = NULL; - while (1) - { - hPipe = CreateFile(VBOXTRAY_PIPE_IPC, /* Pipe name. */ - GENERIC_READ | /* Read and write access. */ - GENERIC_WRITE, - 0, /* No sharing. */ - NULL, /* Default security attributes. */ - OPEN_EXISTING, /* Opens existing pipe. */ - 0, /* Default attributes. */ - NULL); /* No template file. */ - - /* Break if the pipe handle is valid. */ - if (hPipe != INVALID_HANDLE_VALUE) - break; - - /* Exit if an error other than ERROR_PIPE_BUSY occurs. */ - if (GetLastError() != ERROR_PIPE_BUSY) - return NULL; - - /* All pipe instances are busy, so wait for 20 seconds. */ - if (!WaitNamedPipe(VBOXTRAY_PIPE_IPC, 20000)) - return NULL; - } - - /* The pipe connected; change to message-read mode. */ - DWORD dwMode = PIPE_READMODE_MESSAGE; - BOOL fSuccess = SetNamedPipeHandleState(hPipe, /* Pipe handle. */ - &dwMode, /* New pipe mode. */ - NULL, /* Don't set maximum bytes. */ - NULL); /* Don't set maximum time. */ - if (!fSuccess) + char szPath[MAX_PATH]; + UINT cchPath = GetSystemDirectoryA(szPath, sizeof(szPath)); + size_t cbName = strlen(pszName) + 1; + if (cchPath + 1 + cbName > sizeof(szPath)) return NULL; - return hPipe; -} - -static void vboxIPCDisconnect(HANDLE hPipe) -{ - CloseHandle(hPipe); -} - -static HRESULT vboxIPCWriteMessage(HANDLE hPipe, BYTE *pMessage, DWORD cbMessage) -{ - HRESULT hr = S_OK; - DWORD cbWritten = 0; - if (!WriteFile(hPipe, pMessage, cbMessage - cbWritten, &cbWritten, 0)) - hr = HRESULT_FROM_WIN32(GetLastError()); - return hr; + szPath[cchPath] = '\\'; + memcpy(&szPath[cchPath + 1], pszName, cbName); + return LoadLibraryA(szPath); } /** @@ -213,7 +229,7 @@ VBOXINSTALLHELPER_EXPORT DisableWFP(HWND hwndParent, int string_size, HRESULT hr = vboxPopString(szFile, sizeof(szFile) / sizeof(TCHAR)); if (SUCCEEDED(hr)) { - HMODULE hSFC = LoadLibrary("sfc_os.dll"); + HMODULE hSFC = loadSystemDll("sfc_os.dll"); /** @todo Replace this by RTLdr APIs. */ if (NULL != hSFC) { g_pfnSfcFileException = (PFNSFCFILEEXCEPTION)GetProcAddress(hSFC, "SfcFileException"); @@ -426,31 +442,62 @@ VBOXINSTALLHELPER_EXPORT VBoxTrayShowBallonMsg(HWND hwndParent, int string_size, { EXDLL_INIT(); - VBOXTRAYIPCHEADER hdr; - hdr.ulMsg = VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG; - hdr.cbBody = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG); - - VBOXTRAYIPCMSG_SHOWBALLOONMSG msg; - HRESULT hr = vboxPopString(msg.szContent, sizeof(msg.szContent) / sizeof(TCHAR)); - if (SUCCEEDED(hr)) - hr = vboxPopString(msg.szTitle, sizeof(msg.szTitle) / sizeof(TCHAR)); + char szMsg[256]; + char szTitle[128]; + HRESULT hr = vboxPopString(szMsg, sizeof(szMsg) / sizeof(char)); if (SUCCEEDED(hr)) - hr = vboxPopULong(&msg.ulType); - if (SUCCEEDED(hr)) - hr = vboxPopULong(&msg.ulShowMS); + hr = vboxPopString(szTitle, sizeof(szTitle) / sizeof(char)); + + /** @todo Do we need to restore the stack on failure? */ if (SUCCEEDED(hr)) { - msg.ulFlags = 0; - - HANDLE hPipe = vboxIPCConnect(); - if (hPipe) + RTR3InitDll(0); + + uint32_t cbMsg = sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG) + + strlen(szMsg) + 1 /* Include terminating zero */ + + strlen(szTitle) + 1; /* Dito. */ + Assert(cbMsg); + PVBOXTRAYIPCMSG_SHOWBALLOONMSG pIpcMsg = + (PVBOXTRAYIPCMSG_SHOWBALLOONMSG)RTMemAlloc(cbMsg); + if (pIpcMsg) { - hr = vboxIPCWriteMessage(hPipe, (BYTE*)&hdr, sizeof(VBOXTRAYIPCHEADER)); + /* Stuff in the strings. */ + memcpy(pIpcMsg->szMsgContent, szMsg, strlen(szMsg) + 1); + memcpy(pIpcMsg->szMsgTitle, szTitle, strlen(szTitle) + 1); + + /* Pop off the values in reverse order from the stack. */ + if (SUCCEEDED(hr)) + hr = vboxPopULong((ULONG*)&pIpcMsg->uType); + if (SUCCEEDED(hr)) + hr = vboxPopULong((ULONG*)&pIpcMsg->uShowMS); + if (SUCCEEDED(hr)) - hr = vboxIPCWriteMessage(hPipe, (BYTE*)&msg, sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG)); - vboxIPCDisconnect(hPipe); + { + RTLOCALIPCSESSION hSession = 0; + int rc = vboxConnectToVBoxTray(&hSession); + if (RT_SUCCESS(rc)) + { + VBOXTRAYIPCHEADER ipcHdr = { VBOXTRAY_IPC_HDR_MAGIC, 0 /* Header version */, + VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG, cbMsg }; + + rc = RTLocalIpcSessionWrite(hSession, &ipcHdr, sizeof(ipcHdr)); + if (RT_SUCCESS(rc)) + rc = RTLocalIpcSessionWrite(hSession, pIpcMsg, cbMsg); + + int rc2 = RTLocalIpcSessionClose(hSession); + if (RT_SUCCESS(rc)) + rc = rc2; + } + + if (RT_FAILURE(rc)) + hr = __HRESULT_FROM_WIN32(ERROR_BROKEN_PIPE); + } + + RTMemFree(pIpcMsg); } + else + hr = __HRESULT_FROM_WIN32(ERROR_NOT_ENOUGH_MEMORY); } /* Push simple return value on stack. */ |