1 | /* $Id: VBoxGuestInstallHelper.cpp 34098 2010-11-16 10:40:59Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * VBoxGuestInstallHelper - Various helper routines for Windows guest installer.
|
---|
4 | */
|
---|
5 |
|
---|
6 | /*
|
---|
7 | * Copyright (C) 2010 Oracle Corporation
|
---|
8 | *
|
---|
9 | * This file is part of VirtualBox Open Source Edition (OSE), as
|
---|
10 | * available from http://www.virtualbox.org. This file is free software;
|
---|
11 | * you can redistribute it and/or modify it under the terms of the GNU
|
---|
12 | * General Public License (GPL) as published by the Free Software
|
---|
13 | * Foundation, in version 2 as it comes in the "COPYING" file of the
|
---|
14 | * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
|
---|
15 | * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
|
---|
16 | */
|
---|
17 |
|
---|
18 | #include <windows.h>
|
---|
19 | #include <stdlib.h>
|
---|
20 | #include <Strsafe.h>
|
---|
21 | #include "exdll.h"
|
---|
22 |
|
---|
23 | /* Required structures/defines of VBoxTray. */
|
---|
24 | #include "../../VBoxTray/VBoxTrayMsg.h"
|
---|
25 |
|
---|
26 | HINSTANCE g_hInstance;
|
---|
27 | HWND g_hwndParent;
|
---|
28 |
|
---|
29 | #define VBOXINSTALLHELPER_EXPORT extern "C" void __declspec(dllexport)
|
---|
30 |
|
---|
31 | /**
|
---|
32 | * Pops (gets) a value from the internal NSIS stack.
|
---|
33 | * Since the supplied popstring() method easily can cause buffer
|
---|
34 | * overflows, use VBoxPopString() instead!
|
---|
35 | *
|
---|
36 | * @return HRESULT
|
---|
37 | * @param pszDest Pointer to pre-allocated string to store result.
|
---|
38 | * @param cchDest Size (in characters) of pre-allocated string.
|
---|
39 | */
|
---|
40 | static HRESULT VBoxPopString(TCHAR *pszDest, size_t cchDest)
|
---|
41 | {
|
---|
42 | HRESULT hr = S_OK;
|
---|
43 | if (!g_stacktop || !*g_stacktop)
|
---|
44 | hr = ERROR_EMPTY;
|
---|
45 | else
|
---|
46 | {
|
---|
47 | stack_t *pStack = (*g_stacktop);
|
---|
48 | if (pStack)
|
---|
49 | {
|
---|
50 | hr = StringCchCopy(pszDest, cchDest, pStack->text);
|
---|
51 | if (SUCCEEDED(hr))
|
---|
52 | {
|
---|
53 | *g_stacktop = pStack->next;
|
---|
54 | GlobalFree((HGLOBAL)pStack);
|
---|
55 | }
|
---|
56 | }
|
---|
57 | }
|
---|
58 | return hr;
|
---|
59 | }
|
---|
60 |
|
---|
61 | static HRESULT VBoxPopULong(ULONG *pulValue)
|
---|
62 | {
|
---|
63 | HRESULT hr = S_OK;
|
---|
64 | if (!g_stacktop || !*g_stacktop)
|
---|
65 | hr = ERROR_EMPTY;
|
---|
66 | else
|
---|
67 | {
|
---|
68 | stack_t *pStack = (*g_stacktop);
|
---|
69 | if (pStack)
|
---|
70 | {
|
---|
71 | *pulValue = strtoul(pStack->text, NULL, 10 /* Base */);
|
---|
72 |
|
---|
73 | *g_stacktop = pStack->next;
|
---|
74 | GlobalFree((HGLOBAL)pStack);
|
---|
75 | }
|
---|
76 | }
|
---|
77 | return hr;
|
---|
78 | }
|
---|
79 |
|
---|
80 | HANDLE VBoIPCConnect()
|
---|
81 | {
|
---|
82 | HANDLE hPipe = NULL;
|
---|
83 | while (1)
|
---|
84 | {
|
---|
85 | hPipe = CreateFile(VBOXTRAY_PIPE_IPC, /* Pipe name. */
|
---|
86 | GENERIC_READ | /* Read and write access. */
|
---|
87 | GENERIC_WRITE,
|
---|
88 | 0, /* No sharing. */
|
---|
89 | NULL, /* Default security attributes. */
|
---|
90 | OPEN_EXISTING, /* Opens existing pipe. */
|
---|
91 | 0, /* Default attributes. */
|
---|
92 | NULL); /* No template file. */
|
---|
93 |
|
---|
94 | /* Break if the pipe handle is valid. */
|
---|
95 | if (hPipe != INVALID_HANDLE_VALUE)
|
---|
96 | break;
|
---|
97 |
|
---|
98 | /* Exit if an error other than ERROR_PIPE_BUSY occurs. */
|
---|
99 | if (GetLastError() != ERROR_PIPE_BUSY)
|
---|
100 | return NULL;
|
---|
101 |
|
---|
102 | /* All pipe instances are busy, so wait for 20 seconds. */
|
---|
103 | if (!WaitNamedPipe(VBOXTRAY_PIPE_IPC, 20000))
|
---|
104 | return NULL;
|
---|
105 | }
|
---|
106 |
|
---|
107 | /* The pipe connected; change to message-read mode. */
|
---|
108 | DWORD dwMode = PIPE_READMODE_MESSAGE;
|
---|
109 | BOOL fSuccess = SetNamedPipeHandleState(hPipe, /* Pipe handle. */
|
---|
110 | &dwMode, /* New pipe mode. */
|
---|
111 | NULL, /* Don't set maximum bytes. */
|
---|
112 | NULL); /* Don't set maximum time. */
|
---|
113 | if (!fSuccess)
|
---|
114 | return NULL;
|
---|
115 | return hPipe;
|
---|
116 | }
|
---|
117 |
|
---|
118 | void VBoxIPCDisconnect(HANDLE hPipe)
|
---|
119 | {
|
---|
120 | CloseHandle(hPipe);
|
---|
121 | }
|
---|
122 |
|
---|
123 | HRESULT VBoxIPCWriteMessage(HANDLE hPipe, BYTE *pMessage, DWORD cbMessage)
|
---|
124 | {
|
---|
125 | HRESULT hr = S_OK;
|
---|
126 | DWORD cbWritten = 0;
|
---|
127 | if (!WriteFile(hPipe, pMessage, cbMessage - cbWritten, &cbWritten, 0))
|
---|
128 | hr = HRESULT_FROM_WIN32(GetLastError());
|
---|
129 | return hr;
|
---|
130 | }
|
---|
131 |
|
---|
132 | /**
|
---|
133 | * Shows a balloon message using VBoxTray's notification area in the
|
---|
134 | * Windows task bar.
|
---|
135 | *
|
---|
136 | * @param hwndParent Window handle of parent.
|
---|
137 | * @param string_size Size of variable string.
|
---|
138 | * @param variables The actual variable string.
|
---|
139 | * @param stacktop Pointer to a pointer to the current stack.
|
---|
140 | */
|
---|
141 | VBOXINSTALLHELPER_EXPORT VBoxTrayShowBallonMsg(HWND hwndParent, int string_size,
|
---|
142 | TCHAR *variables, stack_t **stacktop)
|
---|
143 | {
|
---|
144 | EXDLL_INIT();
|
---|
145 |
|
---|
146 | VBOXTRAYIPCHEADER hdr;
|
---|
147 | hdr.ulMsg = VBOXTRAYIPCMSGTYPE_SHOWBALLOONMSG;
|
---|
148 | hdr.ulVer = 1;
|
---|
149 |
|
---|
150 | VBOXTRAYIPCMSG_SHOWBALLOONMSG msg;
|
---|
151 | HRESULT hr = VBoxPopString(msg.szBody, sizeof(msg.szBody) / sizeof(TCHAR));
|
---|
152 | if (SUCCEEDED(hr))
|
---|
153 | hr = VBoxPopString(msg.szTitle, sizeof(msg.szTitle) / sizeof(TCHAR));
|
---|
154 | if (SUCCEEDED(hr))
|
---|
155 | hr = VBoxPopULong(&msg.ulType);
|
---|
156 | if (SUCCEEDED(hr))
|
---|
157 | hr = VBoxPopULong(&msg.ulShowMS);
|
---|
158 |
|
---|
159 | if (SUCCEEDED(hr))
|
---|
160 | {
|
---|
161 | msg.ulFlags = 0;
|
---|
162 |
|
---|
163 | HANDLE hPipe = VBoIPCConnect();
|
---|
164 | if (hPipe)
|
---|
165 | {
|
---|
166 | hr = VBoxIPCWriteMessage(hPipe, (BYTE*)&hdr, sizeof(VBOXTRAYIPCHEADER));
|
---|
167 | if (SUCCEEDED(hr))
|
---|
168 | hr = VBoxIPCWriteMessage(hPipe, (BYTE*)&msg, sizeof(VBOXTRAYIPCMSG_SHOWBALLOONMSG));
|
---|
169 | VBoxIPCDisconnect(hPipe);
|
---|
170 | }
|
---|
171 | }
|
---|
172 |
|
---|
173 | /* Push simple return value on stack. */
|
---|
174 | SUCCEEDED(hr) ? pushstring("0") : pushstring("1");
|
---|
175 | }
|
---|
176 |
|
---|
177 | BOOL WINAPI DllMain(HANDLE hInst, ULONG uReason, LPVOID lpReserved)
|
---|
178 | {
|
---|
179 | g_hInstance = (HINSTANCE)hInst;
|
---|
180 | return TRUE;
|
---|
181 | }
|
---|
182 |
|
---|