VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/Installer/VBoxGuestDrvInst.cpp@ 31634

最後變更 在這個檔案從31634是 31634,由 vboxsync 提交於 15 年 前

Windows Additions: export shared folders and installer to OSE

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 13.8 KB
 
1/** @file
2 *
3 * instdrvmain - Install guest drivers on NT4
4 *
5 * Copyright (C) 2006-2007 Oracle Corporation
6 *
7 * Oracle Corporation confidential
8 * All rights reserved
9 */
10
11/**
12 * @todo
13 * The spacing in this file is horrible! Here are some simple rules:
14 * - tabs are forbidden
15 * - indentation is 4 spaces
16 */
17
18
19#include <windows.h>
20#include <setupapi.h>
21#include <regstr.h>
22#include <DEVGUID.h>
23#include <stdio.h>
24
25#include "tchar.h"
26#include "string.h"
27
28
29/*******************************************************************************
30* Defined Constants And Macros *
31*******************************************************************************/
32
33/** The video service name. */
34#define VBOXGUEST_VIDEO_NAME "VBoxVideo"
35
36/** The video inf file name */
37#define VBOXGUEST_VIDEO_INF_NAME "VBoxVideo.inf"
38
39/////////////////////////////////////////////////////////////////////////////
40
41
42
43/**
44 * Do some cleanup of data we used. Called by installVideoDriver()
45 */
46void closeAndDestroy(HDEVINFO hDevInfo, HINF hInf)
47{
48 SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
49 SetupDiDestroyDeviceInfoList(hDevInfo);
50 SetupCloseInfFile(hInf);
51}
52
53
54/**
55 * Install the VBox video driver.
56 *
57 * @returns TRUE on success.
58 * @returns FALSE on failure.
59 * @param szDriverDir The base directory where we find the INF.
60 */
61BOOL installVideoDriver(TCHAR* szDriverDir)
62{
63 HDEVINFO hDevInfo;
64 SP_DEVINSTALL_PARAMS DeviceInstallParams={0};
65 SP_DRVINFO_DATA drvInfoData={0};
66 SP_DRVINFO_DETAIL_DATA DriverInfoDetailData={0};
67
68 DWORD cbReqSize;
69
70 /* Vars used for reading the INF */
71 HINF hInf;
72 TCHAR szServiceSection[LINE_LEN];
73 INFCONTEXT serviceContext;
74 TCHAR szServiceData[LINE_LEN];
75 TCHAR deviceRegStr[1000];//I'm lazy here. 1000 ought to be enough for everybody...
76
77 SP_DEVINFO_DATA deviceInfoData;
78 DWORD configFlags;
79
80 HKEY hkey;
81 DWORD disp;
82 TCHAR regKeyName[LINE_LEN];
83
84 BOOL rc;
85
86 /* Create an empty list */
87 hDevInfo = SetupDiCreateDeviceInfoList((LPGUID) &GUID_DEVCLASS_DISPLAY,
88 NULL);
89
90 if (hDevInfo == INVALID_HANDLE_VALUE)
91 return FALSE;
92
93 memset(&DeviceInstallParams, 0, sizeof(SP_DEVINSTALL_PARAMS));
94 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
95
96 rc=SetupDiGetDeviceInstallParams(hDevInfo,
97 NULL,
98 &DeviceInstallParams);
99
100 if(!rc)
101 return FALSE;
102
103 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
104 DeviceInstallParams.Flags |= DI_NOFILECOPY | /* We did our own file copying */
105 DI_DONOTCALLCONFIGMG |
106 DI_ENUMSINGLEINF; /* .DriverPath specifies an inf file */
107
108
109 /* Path to inf file */
110 wsprintf(DeviceInstallParams.DriverPath,
111 TEXT("%ws\\%ws"),
112 szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME));
113
114 rc=SetupDiSetDeviceInstallParams(hDevInfo,
115 NULL,
116 &DeviceInstallParams);
117 if(!rc)
118 return FALSE;
119
120 /* Read the drivers from the inf file */
121 if (!SetupDiBuildDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER))
122 {
123 SetupDiDestroyDeviceInfoList(hDevInfo);
124 return FALSE;
125 }
126
127 /* Get the first found driver.
128 Our Inf file only contains one so this is fine */
129 drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
130 if(FALSE==SetupDiEnumDriverInfo(hDevInfo, NULL, SPDIT_CLASSDRIVER,
131 0, &drvInfoData)){
132 SetupDiDestroyDeviceInfoList(hDevInfo);
133 return FALSE;
134 }
135
136 /* Get necessary driver details */
137 DriverInfoDetailData.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
138 if (!(!SetupDiGetDriverInfoDetail(hDevInfo,
139 NULL,
140 &drvInfoData,
141 &DriverInfoDetailData,
142 DriverInfoDetailData.cbSize,
143 &cbReqSize)
144 &&GetLastError()== ERROR_INSUFFICIENT_BUFFER) )
145 {
146 SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
147 SetupDiDestroyDeviceInfoList(hDevInfo);
148 return FALSE;
149 }
150
151 hInf = SetupOpenInfFile(DriverInfoDetailData.InfFileName,
152 NULL, INF_STYLE_WIN4, NULL);
153
154 if (hInf == INVALID_HANDLE_VALUE)
155 {
156 SetupDiDestroyDriverInfoList(hDevInfo, NULL, SPDIT_CLASSDRIVER);
157 SetupDiDestroyDeviceInfoList(hDevInfo);
158 return FALSE;
159 }
160
161 /* First install the service */
162 wsprintf(szServiceSection, TEXT("%ws.Services"),
163 DriverInfoDetailData.SectionName);
164
165 if(!SetupFindFirstLine(hInf, szServiceSection, NULL, &serviceContext))
166 {
167 /* No service line?? Can't be... */
168 closeAndDestroy(hDevInfo, hInf);
169 return FALSE;
170 }
171
172 /* Get the name */
173 SetupGetStringField(&serviceContext,
174 1,
175 szServiceData,
176 sizeof(szServiceData),
177 NULL);
178
179 wsprintf(deviceRegStr, TEXT("Root\\LEGACY_%ws\\0000"), szServiceData);
180
181 memset(&deviceInfoData, 0, sizeof(SP_DEVINFO_DATA));
182 deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
183
184 if (SetupDiOpenDeviceInfo(hDevInfo, deviceRegStr, NULL, 0, &deviceInfoData) //Check for existing
185 ||(SetupDiCreateDeviceInfo(hDevInfo, deviceRegStr, //Create new
186 (LPGUID) &GUID_DEVCLASS_DISPLAY,
187 NULL, //Do we need a description here?
188 NULL, //No user interface
189 0,
190 &deviceInfoData) &&
191 SetupDiRegisterDeviceInfo(hDevInfo,
192 &deviceInfoData,
193 0,
194 NULL,
195 NULL,
196 NULL)) )
197 {
198 /* We created a new key in the registry */
199
200 memset(&DeviceInstallParams, 0,sizeof(SP_DEVINSTALL_PARAMS));
201 DeviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
202
203 SetupDiGetDeviceInstallParams(hDevInfo,
204 &deviceInfoData,
205 &DeviceInstallParams);
206
207 DeviceInstallParams.Flags |= DI_NOFILECOPY | //We already copied the files
208 DI_DONOTCALLCONFIGMG |
209 DI_ENUMSINGLEINF; //Use our INF file only
210
211 /* Path to inf file */
212 wsprintf(DeviceInstallParams.DriverPath,
213 TEXT("%ws\\%ws"),
214 szDriverDir, TEXT(VBOXGUEST_VIDEO_INF_NAME));
215
216 SetupDiSetDeviceInstallParams(hDevInfo,
217 &deviceInfoData,
218 &DeviceInstallParams);
219
220
221 if(!SetupDiBuildDriverInfoList(hDevInfo,
222 &deviceInfoData,
223 SPDIT_CLASSDRIVER))
224 {
225 closeAndDestroy(hDevInfo, hInf);
226 return FALSE;
227 }
228
229 drvInfoData.cbSize = sizeof(SP_DRVINFO_DATA);
230 if (!SetupDiEnumDriverInfo(hDevInfo,
231 &deviceInfoData,
232 SPDIT_CLASSDRIVER,
233 0,
234 &drvInfoData))
235 {
236 closeAndDestroy(hDevInfo, hInf);
237 return FALSE;
238 }
239
240 if(!SetupDiSetSelectedDriver(hDevInfo,
241 &deviceInfoData,
242 &drvInfoData))
243 {
244 closeAndDestroy(hDevInfo, hInf);
245 return FALSE;
246 }
247
248 if(!SetupDiInstallDevice(hDevInfo,
249 &deviceInfoData))
250 {
251 closeAndDestroy(hDevInfo, hInf);
252 return FALSE;
253 }
254 }
255
256 /* Make sure the device is enabled */
257 if (SetupDiGetDeviceRegistryProperty(hDevInfo,
258 &deviceInfoData, SPDRP_CONFIGFLAGS,
259 NULL, (LPBYTE) &configFlags,
260 sizeof(DWORD),
261 NULL)
262 && (configFlags & CONFIGFLAG_DISABLED))
263 {
264 configFlags &= ~CONFIGFLAG_DISABLED;
265
266 SetupDiSetDeviceRegistryProperty(hDevInfo,
267 &deviceInfoData,
268 SPDRP_CONFIGFLAGS,
269 (LPBYTE) &configFlags,
270 sizeof(DWORD));
271 }
272
273 wsprintf(regKeyName,
274 TEXT("System\\CurrentControlSet\\Services\\%ws\\Device%d"),
275 szServiceData, 0); //We only have one device
276
277 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
278 regKeyName,
279 0,
280 NULL,
281 REG_OPTION_NON_VOLATILE,
282 KEY_READ | KEY_WRITE,
283 NULL,
284 &hkey,
285 &disp) == ERROR_SUCCESS)
286 {
287 /* Insert description */
288 RegSetValueEx(hkey,
289 TEXT("Device Description"),
290 0,
291 REG_SZ,
292 (LPBYTE) DriverInfoDetailData.DrvDescription,
293 (lstrlen(DriverInfoDetailData.DrvDescription) + 1) *
294 sizeof(TCHAR) );
295
296 TCHAR szSoftwareSection[LINE_LEN];
297
298 wsprintf(szSoftwareSection,
299 TEXT("%ws.SoftwareSettings"),
300 szServiceData);
301
302 if (!SetupInstallFromInfSection(NULL,
303 hInf,
304 szSoftwareSection,
305 SPINST_REGISTRY,
306 hkey,
307 NULL,
308 0,
309 NULL,
310 NULL,
311 NULL,
312 NULL))
313 {
314 RegCloseKey(hkey);
315 closeAndDestroy(hDevInfo, hInf);
316 return FALSE;
317 }
318
319 RegCloseKey(hkey);
320 }
321
322 /* Install OpenGL stuff */
323 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
324 TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\OpenGLDrivers"),
325 0,
326 NULL,
327 REG_OPTION_NON_VOLATILE,
328 KEY_READ | KEY_WRITE,
329 NULL,
330 &hkey,
331 &disp) == ERROR_SUCCESS)
332 {
333 /* Do installation here if ever necessary. Currently there is no OpenGL stuff */
334
335 RegCloseKey(hkey);
336 }
337
338
339 /* Cleanup */
340 closeAndDestroy(hDevInfo, hInf);
341
342#if 0
343 /* If this key is inserted into the registry, windows will show the desktop
344 applet on next boot. We decide in the installer if we want that so the code
345 is disabled here. */
346 /* Set registry keys so windows picks up the changes */
347 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
348 TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\NewDisplay"),
349 0,
350 NULL,
351 REG_OPTION_NON_VOLATILE,
352 KEY_READ | KEY_WRITE,
353 NULL,
354 &hkey,
355 &disp) == ERROR_SUCCESS)
356 {
357 RegCloseKey(hkey);
358 }
359#endif
360
361 /* We must reboot at some point */
362 if (RegCreateKeyEx(HKEY_LOCAL_MACHINE,
363 TEXT("SYSTEM\\CurrentControlSet\\Control\\GraphicsDrivers\\RebootNecessary"),
364 0,
365 NULL,
366 REG_OPTION_NON_VOLATILE,
367 KEY_READ | KEY_WRITE,
368 NULL,
369 &hkey,
370 &disp) == ERROR_SUCCESS)
371 {
372 RegCloseKey(hkey);
373 }
374
375 return TRUE;
376}
377
378
379void displayHelpAndExit(char *programName)
380{
381 printf("Installs VirtualBox Guest Additions for Windows NT 4.0\n\n");
382 printf("Syntax: %s [/i|/u]\n", programName);
383 printf("\n\t/i - perform Guest Additions installation\n");
384 printf("\t/u: - perform Guest Additions uninstallation\n");
385 exit(1);
386}
387
388/**
389 * Check if we are running on NT4.
390 *
391 * @returns TRUE if NT 4.
392 * @returns FALSE otherwise.
393 */
394BOOL isNT4(void)
395{
396 OSVERSIONINFO osVersion;
397
398 osVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
399 GetVersionEx(&osVersion);
400
401 switch (osVersion.dwPlatformId)
402 {
403 case VER_PLATFORM_WIN32s:
404 case VER_PLATFORM_WIN32_WINDOWS:
405 return FALSE;
406 case VER_PLATFORM_WIN32_NT:
407 if (osVersion.dwMajorVersion == 4)
408 return TRUE;
409 else
410 return FALSE;
411 default:
412 break;
413 }
414 return FALSE;
415}
416
417/**
418 * Video driver uninstallation will be added later if necessary.
419 */
420int uninstallDrivers(void)
421{
422 return 0;
423}
424
425
426int main(int argc, char **argv)
427{
428 BOOL rc=FALSE;
429 TCHAR szInstallDir[MAX_PATH];
430 HMODULE hExe = GetModuleHandle(NULL);
431
432 /** @todo r=bird:
433 * And by the way, we're only missing the coding style dmik uses now
434 * and this file would contain the complete set. */
435 if(2!=argc || (stricmp(argv[1], "/i") && stricmp(argv[1], "/u")))
436 displayHelpAndExit(argv[0]);
437
438 /* This program is only for installing drivers on NT4 */
439 if(!isNT4()){
440 printf("This program only runs on NT4\n");
441 return -1;
442 }
443
444 if (!GetModuleFileName(hExe, &szInstallDir[0], sizeof(szInstallDir)))
445 {
446 printf("GetModuleFileName failed! rc = %d\n", GetLastError());
447 return -1;
448 }
449
450 TCHAR *lastBackslash = wcsrchr(szInstallDir, L'\\');
451
452 if (!lastBackslash)
453 {
454 printf("Invalid path name!\n");
455 return -1;
456 }
457
458 *lastBackslash=L'\0';
459
460 /* Install video driver. Mouse driver installation is done by overwriting
461 the image path in the setup script. */
462 if(!stricmp(argv[1], "/i")){
463 rc=installVideoDriver(szInstallDir);
464 }
465 else{
466 /* No video driver uninstallation yet. Do we need it? */
467 }
468
469 if(FALSE==rc)
470 printf("Some failure occurred during driver installation.\n");
471 return !rc; /* Return != 0 on failure. */
472}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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