VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Installer/VBCoInst.cpp@ 34575

Last change on this file since 34575 was 31634, checked in by vboxsync, 14 years ago

Windows Additions: export shared folders and installer to OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.9 KB
Line 
1// 45678901234567890123456789012345678901234567890123456789012345678901234567890
2//+---------------------------------------------------------------------------
3//
4// Microsoft Windows
5// Copyright (C) Microsoft Corporation, 1999.
6//
7// File: COINST.C
8//
9// Contents: co-installer hook.
10//
11// Notes: For a complete description of CoInstallers, please see the
12// Microsoft Windows 2000 DDK Documentation
13//
14// Author: keithga 4 June 1999
15//
16// Revision History:
17// Added FriendlyName interface (Eliyas Yakub Aug 2, 1999)
18//
19//----------------------------------------------------------------------------
20
21#undef UNICODE
22#if !defined(_UNICODE) && defined(UNICODE)
23#define _UNICODE
24#endif
25
26#include <windows.h>
27#include <setupapi.h>
28#include <stdio.h>
29#include <tchar.h>
30
31// #define LOG_ENABLED
32
33#ifdef LOG_ENABLED
34#include <stdio.h>
35
36static VOID _dprintf(LPSTR String, ...)
37{
38 va_list va;
39
40 va_start(va, String);
41
42 CHAR Buffer[1024];
43 if (strlen(String) < 1000)
44 {
45 _vsntprintf (Buffer, sizeof(Buffer), String, va);
46
47 FILE *f = fopen ("\\coinst.log", "ab");
48 if (f)
49 {
50 fprintf (f, "%s", Buffer);
51 fclose (f);
52 }
53 }
54
55 va_end (va);
56}
57#define dprintf(a) _dprintf a
58#else
59#define dprintf(a) do {} while (0)
60#endif /* LOG_ENABLED */
61
62//+---------------------------------------------------------------------------
63//
64// WARNING!
65//
66// A Coinstaller must not generate any popup to the user.
67// it should provide appropriate defaults.
68//
69// OutputDebugString should be fine...
70//
71#if DBG
72#define DbgOut(Text) OutputDebugString(TEXT("CoInstaller: " Text "\n"))
73#else
74#define DbgOut(Text)
75#endif
76
77/** strip the filename and leave the slash. */
78void StripFilename (TCHAR *psz)
79{
80 TCHAR *pchSep = NULL;
81 TCHAR *pch = psz;
82
83 /* strip of the filename. */
84 for (; *pch; pch++)
85 {
86 if (*pch == '\\' || *pch == '/' || *pch == ':')
87 pchSep = pch + 1;
88 }
89 if (pchSep)
90 *pchSep = '\0';
91 else
92 {
93 psz[0] = '.';
94 psz[1] = '\0';
95 }
96}
97
98/**
99 Check the installation type.
100 This function checks if the currently used
101 INF file not OEMxx.inf. If yes, the user installs the guest additions by hand,
102 if no this is an automated installation.
103 */
104BOOL CheckForNormalInstall (TCHAR *psz)
105{
106 TCHAR *pchSep = NULL;
107 TCHAR *pch = psz;
108
109 /* strip of the filename. */
110 for (; *pch; pch++)
111 {
112 if (*pch == '\\' || *pch == '/' || *pch == ':')
113 pchSep = pch + 1;
114 }
115 if (pchSep)
116 {
117 if (*pchSep == 'o' || *pchSep == 'O')
118 return FALSE;
119 return TRUE;
120 }
121 return TRUE; /* We shouldn't end here... */
122}
123
124ULONG startMouseInstallation (TCHAR *pszVBoxGuestInfName)
125{
126 TCHAR szAppCmd[MAX_PATH];
127 STARTUPINFO sInfo = { 0 };
128 PROCESS_INFORMATION pInfo = { 0 };
129 BOOL fNotAutomated;
130
131 dprintf(("startMouseInstallation: filename = %s\n", pszVBoxGuestInfName));
132
133 /* Check if we do an automated install */
134 fNotAutomated = CheckForNormalInstall(pszVBoxGuestInfName);
135
136 StripFilename(pszVBoxGuestInfName);
137
138 dprintf(("startMouseInstallation: fNotAutomated = %d, filename = %s\n", fNotAutomated, pszVBoxGuestInfName));
139
140 if (fNotAutomated)
141 {
142 /* This is a normal guest installation done by inserting the ISO */
143 _sntprintf(szAppCmd, sizeof(szAppCmd), TEXT("rundll32.exe SETUPAPI.DLL,InstallHinfSection VBoxMouse 132 %sVBoxMouse.inf"), pszVBoxGuestInfName);
144
145 sInfo.cb = sizeof(STARTUPINFO);
146
147 if (CreateProcess(NULL, szAppCmd, NULL, //lpProcessAttributes
148 NULL, //lpThreadAttributes
149 FALSE, //bInheritHandles
150 0, //dwCreationFlags
151 NULL, //lpEnvironment
152 NULL, //lpCurrentDirectory,
153 &sInfo, //lpStartupInfo,
154 &pInfo)) //lpProcessInformation
155 {
156 DWORD dwExitCode = 0;
157
158 /* Wait for rundll32 to finish and then check the exit code; only then do we know if it succeeded or not! */
159 WaitForSingleObject(pInfo.hProcess, INFINITE);
160 if (GetExitCodeProcess(pInfo.hProcess, &dwExitCode) != 0 && dwExitCode == 0)
161 {
162 //
163 // hook the filter into the mouse class
164 //
165
166 dprintf(("startMouseInstallation: hooking\n"));
167
168 // first determine the GUID of the Mouse class
169 GUID guid;
170 DWORD numGuids;
171 if (SetupDiClassGuidsFromNameEx("Mouse", &guid, 1, &numGuids, NULL, NULL) || (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
172 {
173 // get the corresponding class registry key
174 HKEY hkey = SetupDiOpenClassRegKeyEx(&guid, KEY_READ | KEY_WRITE, DIOCR_INSTALLER, NULL, NULL);
175 if (hkey)
176 {
177 // hardcoded value, ours + the standard filter
178 RegSetValueEx(hkey, "UpperFilters", 0, REG_MULTI_SZ, (const BYTE*)"VBoxMouse\0mouclass\0\0", 20);
179 RegCloseKey(hkey);
180 }
181 }
182 CloseHandle(pInfo.hProcess);
183 CloseHandle(pInfo.hThread);
184 dprintf(("startMouseInstallation: return ok\n"));
185 return 0;
186 }
187 CloseHandle(pInfo.hProcess);
188 CloseHandle(pInfo.hThread);
189 } /* CreateProcess() */
190 } /* fNotAutomated */
191 else
192 {
193 /* This is an automated installation */
194
195 //
196 // hook the filter into the mouse class
197 //
198
199 dprintf(("startMouseInstallation: automated\n"));
200
201 // first determine the GUID of the Mouse class
202 GUID guid;
203 DWORD numGuids;
204 if (SetupDiClassGuidsFromNameEx("Mouse", &guid, 1, &numGuids, NULL, NULL) || (GetLastError() == ERROR_INSUFFICIENT_BUFFER))
205 {
206 // get the corresponding class registry key
207 HKEY hkey = SetupDiOpenClassRegKeyEx(&guid, KEY_READ | KEY_WRITE, DIOCR_INSTALLER, NULL, NULL);
208 if (hkey)
209 {
210 // hardcoded value, ours + the standard filter
211 RegSetValueEx(hkey, "UpperFilters", 0, REG_MULTI_SZ, (const BYTE*)"VBoxMouse\0mouclass\0\0", 20);
212 RegCloseKey(hkey);
213 }
214 }
215 return 0;
216 }
217
218 /* bitch to debug output */
219 return -1;
220}
221
222//+---------------------------------------------------------------------------
223//
224// Function: VBoxCoInstaller
225//
226// Purpose: Responds to co-installer messages
227//
228// Arguments:
229// InstallFunction [in]
230// DeviceInfoSet [in]
231// DeviceInfoData [in]
232// Context [inout]
233//
234// Returns: NO_ERROR, ERROR_DI_POSTPROCESSING_REQUIRED, or an error code.
235//
236// This co-installer is used to install the mouse filter after installation of
237// the VBoxGuest driver
238extern "C"
239HRESULT WINAPI
240VBoxCoInstaller (
241 IN DI_FUNCTION InstallFunction,
242 IN HDEVINFO DeviceInfoSet,
243 IN PSP_DEVINFO_DATA DeviceInfoData, OPTIONAL
244 IN OUT PCOINSTALLER_CONTEXT_DATA Context
245)
246{
247 dprintf((__DATE__ __TIME__ "VBoxCoInstaller InstallFunction 0x%02X\n", InstallFunction));
248
249 switch (InstallFunction)
250 {
251 case DIF_INSTALLDEVICE:
252 {
253 SP_DEVINSTALL_PARAMS DeviceInstallParams;
254 DeviceInstallParams.cbSize = sizeof (DeviceInstallParams);
255
256 if (!SetupDiGetDeviceInstallParams (DeviceInfoSet,
257 DeviceInfoData,
258 &DeviceInstallParams))
259 {
260 dprintf(("Failed to get DeviceInstallParams\n"));
261 return NO_ERROR;
262 }
263
264 /* Reboot the system and do not dynamically load the driver. */
265 DeviceInstallParams.Flags |= DI_NEEDREBOOT | DI_DONOTCALLCONFIGMG;
266
267 if (!SetupDiSetDeviceInstallParams (DeviceInfoSet,
268 DeviceInfoData,
269 &DeviceInstallParams))
270 {
271 dprintf(("Failed to set DeviceInstallParams\n"));
272 return NO_ERROR;
273 }
274
275 return NO_ERROR;
276 }
277
278 // case DIF_REMOVE:
279 // {
280 // return NO_ERROR;
281 // } break;
282#if 0
283 /* This request is only sent when the installation of the VBoxGuest
284 succeeded. Because VBoxMouse needs VBoxGuest to work this is
285 a nice installation prerequisite check, too. */
286 case DIF_NEWDEVICEWIZARD_FINISHINSTALL:
287 {
288 SP_DRVINFO_DATA DriverInfoData;
289 SP_DRVINFO_DETAIL_DATA DriverInfoDetailData;
290 HRESULT Status;
291
292 /* Get the path to the VBoxGuest INF. The VBoxMouse INF is in the same
293 directory. */
294 DriverInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
295 if (!SetupDiGetSelectedDriver(DeviceInfoSet,
296 DeviceInfoData,
297 &DriverInfoData))
298 {
299 return NO_ERROR; /* Should return an error here? */
300 }
301
302 DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
303 if (!SetupDiGetDriverInfoDetail(DeviceInfoSet,
304 DeviceInfoData,
305 &DriverInfoData,
306 &DriverInfoDetailData,
307 sizeof(SP_DRVINFO_DETAIL_DATA),
308 NULL))
309 {
310 if ((Status = GetLastError()) == ERROR_INSUFFICIENT_BUFFER)
311 {
312 // We don't need the extended information. Ignore.
313 }
314 else
315 {
316 return NO_ERROR; /* Should return an error here? */
317 }
318 }
319
320 startMouseInstallation(DriverInfoDetailData.InfFileName);
321 break;
322 }
323#endif
324
325 default:
326 break;
327 }
328
329 return NO_ERROR;
330}
331
Note: See TracBrowser for help on using the repository browser.

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