VirtualBox

source: vbox/trunk/src/VBox/Main/VMMDevInterface.cpp@ 1011

Last change on this file since 1011 was 906, checked in by vboxsync, 18 years ago

Save and load state notifications for HGCM host services added.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.2 KB
Line 
1/** @file
2 *
3 * VirtualBox Driver Interface to VMM device
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
20 */
21
22#include "VMMDev.h"
23#include "ConsoleImpl.h"
24#include "DisplayImpl.h"
25#include "GuestImpl.h"
26
27#include "Logging.h"
28
29#include <VBox/pdm.h>
30#include <VBox/VBoxDev.h>
31#include <VBox/VBoxGuest.h>
32#include <VBox/cfgm.h>
33#include <VBox/err.h>
34#include <iprt/asm.h>
35
36#ifdef VBOX_HGCM
37#include "hgcm/HGCM.h"
38#endif
39
40//
41// defines
42//
43
44
45//
46// globals
47//
48
49
50/**
51 * VMMDev driver instance data.
52 */
53typedef struct DRVMAINVMMDEV
54{
55 /** Pointer to the VMMDev object. */
56 VMMDev *pVMMDev;
57 /** Pointer to the driver instance structure. */
58 PPDMDRVINS pDrvIns;
59 /** Pointer to the VMMDev port interface of the driver/device above us. */
60 PPDMIVMMDEVPORT pUpPort;
61 /** Our VMM device connector interface. */
62 PDMIVMMDEVCONNECTOR Connector;
63#ifdef VBOX_HGCM
64 /** Pointer to the HGCM port interface of the driver/device above us. */
65 PPDMIHGCMPORT pHGCMPort;
66 /** Our HGCM connector interface. */
67 PDMIHGCMCONNECTOR HGCMConnector;
68#endif
69} DRVMAINVMMDEV, *PDRVMAINVMMDEV;
70
71/** Converts PDMIVMMDEVCONNECTOR pointer to a DRVMAINVMMDEV pointer. */
72#define PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface) ( (PDRVMAINVMMDEV) ((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINVMMDEV, Connector)) )
73
74#ifdef VBOX_HGCM
75/** Converts PDMIHGCMCONNECTOR pointer to a DRVMAINVMMDEV pointer. */
76#define PDMIHGCMCONNECTOR_2_MAINVMMDEV(pInterface) ( (PDRVMAINVMMDEV) ((uintptr_t)pInterface - RT_OFFSETOF(DRVMAINVMMDEV, HGCMConnector)) )
77#endif
78
79//
80// constructor / destructor
81//
82VMMDev::VMMDev(Console *console) : mpDrv(NULL)
83{
84 mParent = console;
85 int rc = RTSemEventCreate(&mCredentialsEvent);
86 AssertRC(rc);
87#ifdef VBOX_HGCM
88 rc = hgcmInit ();
89 AssertRC(rc);
90#endif /* VBOX_HGCM */
91 mu32CredentialsFlags = 0;
92}
93
94VMMDev::~VMMDev()
95{
96 RTSemEventDestroy (mCredentialsEvent);
97 if (mpDrv)
98 mpDrv->pVMMDev = NULL;
99 mpDrv = NULL;
100}
101
102PPDMIVMMDEVPORT VMMDev::getVMMDevPort()
103{
104 Assert(mpDrv);
105 return mpDrv->pUpPort;
106}
107
108
109
110//
111// public methods
112//
113
114/**
115 * Wait on event semaphore for guest credential judgement result.
116 */
117int VMMDev::WaitCredentialsJudgement (uint32_t u32Timeout, uint32_t *pu32CredentialsFlags)
118{
119 if (u32Timeout == 0)
120 {
121 u32Timeout = 5000;
122 }
123
124 int rc = RTSemEventWait (mCredentialsEvent, u32Timeout);
125
126 if (VBOX_SUCCESS (rc))
127 {
128 *pu32CredentialsFlags = mu32CredentialsFlags;
129 }
130
131 return rc;
132}
133
134int VMMDev::SetCredentialsJudgementResult (uint32_t u32Flags)
135{
136 mu32CredentialsFlags = u32Flags;
137
138 int rc = RTSemEventSignal (mCredentialsEvent);
139 AssertRC(rc);
140
141 return rc;
142}
143
144
145/**
146 * Report guest OS version.
147 * Called whenever the Additions issue a guest version report request.
148 *
149 * @param pInterface Pointer to this interface.
150 * @param guestInfo Pointer to guest information structure
151 * @thread The emulation thread.
152 */
153DECLCALLBACK(void) vmmdevUpdateGuestVersion(PPDMIVMMDEVCONNECTOR pInterface, VBoxGuestInfo *guestInfo)
154{
155 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
156
157 Assert(guestInfo);
158 if (!guestInfo)
159 return;
160
161 /* store that information in IGuest */
162 Guest* guest = pDrv->pVMMDev->getParent()->getGuest();
163 Assert(guest);
164 if (!guest)
165 return;
166
167 char version[20];
168 sprintf(version, "%d", guestInfo->additionsVersion);
169 guest->setAdditionsVersion(Bstr(version));
170
171 /*
172 * Tell the console interface about the event
173 * so that it can notify its consumers.
174 */
175 pDrv->pVMMDev->getParent()->onAdditionsStateChange();
176
177 if (guestInfo->additionsVersion < VMMDEV_VERSION)
178 {
179 pDrv->pVMMDev->getParent()->onAdditionsOutdated();
180 }
181}
182
183/**
184 * Update the mouse capabilities.
185 * This is called when the mouse capabilities change. The new capabilities
186 * are given and the connector should update its internal state.
187 *
188 * @param pInterface Pointer to this interface.
189 * @param newCapabilities New capabilities.
190 * @thread The emulation thread.
191 */
192DECLCALLBACK(void) vmmdevUpdateMouseCapabilities(PPDMIVMMDEVCONNECTOR pInterface, uint32_t newCapabilities)
193{
194 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
195 /*
196 * Tell the console interface about the event
197 * so that it can notify its consumers.
198 */
199 pDrv->pVMMDev->getParent()->onMouseCapabilityChange(BOOL (newCapabilities & VMMDEV_MOUSEGUESTWANTSABS),
200 BOOL (newCapabilities & VMMDEV_MOUSEGUESTNEEDSHOSTCUR));
201}
202
203
204/**
205 * Update the pointer shape or visibility.
206 *
207 * This is called when the mouse pointer shape changes or pointer is hidden/displaying.
208 * The new shape is passed as a caller allocated buffer that will be freed after returning.
209 *
210 * @param pInterface Pointer to this interface.
211 * @param fVisible Whether the pointer is visible or not.
212 * @param fAlpha Alpha channel information is present.
213 * @param xHot Horizontal coordinate of the pointer hot spot.
214 * @param yHot Vertical coordinate of the pointer hot spot.
215 * @param width Pointer width in pixels.
216 * @param height Pointer height in pixels.
217 * @param pShape The shape buffer. If NULL, then only pointer visibility is being changed.
218 * @thread The emulation thread.
219 */
220DECLCALLBACK(void) vmmdevUpdatePointerShape(PPDMIVMMDEVCONNECTOR pInterface, bool fVisible, bool fAlpha,
221 uint32_t xHot, uint32_t yHot,
222 uint32_t width, uint32_t height,
223 void *pShape)
224{
225 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
226
227 /* tell the console about it */
228 pDrv->pVMMDev->getParent()->onMousePointerShapeChange(fVisible, fAlpha,
229 xHot, yHot, width, height, pShape);
230}
231
232DECLCALLBACK(int) iface_VideoAccelEnable(PPDMIVMMDEVCONNECTOR pInterface, bool fEnable, VBVAMEMORY *pVbvaMemory)
233{
234 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
235
236 Display *display = pDrv->pVMMDev->getParent()->getDisplay();
237
238 if (display)
239 {
240 LogFlow(("MAIN::VMMDevInterface::iface_VideoAccelEnable: %d, %p\n", fEnable, pVbvaMemory));
241 return display->VideoAccelEnable (fEnable, pVbvaMemory);
242 }
243
244 return VERR_NOT_SUPPORTED;
245}
246DECLCALLBACK(void) iface_VideoAccelFlush(PPDMIVMMDEVCONNECTOR pInterface)
247{
248 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
249
250 Display *display = pDrv->pVMMDev->getParent()->getDisplay();
251
252 if (display)
253 {
254 LogFlow(("MAIN::VMMDevInterface::iface_VideoAccelFlush\n"));
255 display->VideoAccelFlush ();
256 }
257}
258
259DECLCALLBACK(int) vmmdevVideoModeSupported(PPDMIVMMDEVCONNECTOR pInterface, uint32_t width, uint32_t height,
260 uint32_t bpp, bool *fSupported)
261{
262 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
263
264 if (!fSupported)
265 return VERR_INVALID_PARAMETER;
266 IFramebuffer *framebuffer = pDrv->pVMMDev->getParent()->getDisplay()->getFramebuffer();
267 Assert(framebuffer);
268 framebuffer->VideoModeSupported(width, height, bpp, (BOOL*)fSupported);
269 return VINF_SUCCESS;
270}
271
272DECLCALLBACK(int) vmmdevGetHeightReduction(PPDMIVMMDEVCONNECTOR pInterface, uint32_t *heightReduction)
273{
274 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
275
276 if (!heightReduction)
277 return VERR_INVALID_PARAMETER;
278 IFramebuffer *framebuffer = pDrv->pVMMDev->getParent()->getDisplay()->getFramebuffer();
279 Assert(framebuffer);
280 framebuffer->COMGETTER(HeightReduction)((ULONG*)heightReduction);
281 return VINF_SUCCESS;
282}
283
284DECLCALLBACK(int) vmmdevSetCredentialsJudgementResult(PPDMIVMMDEVCONNECTOR pInterface, uint32_t u32Flags)
285{
286 PDRVMAINVMMDEV pDrv = PDMIVMMDEVCONNECTOR_2_MAINVMMDEV(pInterface);
287
288 int rc = pDrv->pVMMDev->SetCredentialsJudgementResult (u32Flags);
289
290 return rc;
291}
292
293#ifdef VBOX_HGCM
294
295/* HGCM connector interface */
296
297static DECLCALLBACK(int) iface_hgcmConnect (PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, PHGCMSERVICELOCATION pServiceLocation, uint32_t *pu32ClientID)
298{
299 PDRVMAINVMMDEV pDrv = PDMIHGCMCONNECTOR_2_MAINVMMDEV(pInterface);
300
301 return hgcmConnectInternal (pDrv->pHGCMPort, pCmd, pServiceLocation, pu32ClientID, false);
302}
303
304static DECLCALLBACK(int) iface_hgcmDisconnect (PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, uint32_t u32ClientID)
305{
306 PDRVMAINVMMDEV pDrv = PDMIHGCMCONNECTOR_2_MAINVMMDEV(pInterface);
307
308 return hgcmDisconnectInternal (pDrv->pHGCMPort, pCmd, u32ClientID, false);
309}
310
311static DECLCALLBACK(int) iface_hgcmCall (PPDMIHGCMCONNECTOR pInterface, PVBOXHGCMCMD pCmd, uint32_t u32ClientID, uint32_t u32Function,
312 uint32_t cParms, PVBOXHGCMSVCPARM paParms)
313{
314 PDRVMAINVMMDEV pDrv = PDMIHGCMCONNECTOR_2_MAINVMMDEV(pInterface);
315
316 return hgcmGuestCallInternal (pDrv->pHGCMPort, pCmd, u32ClientID, u32Function, cParms, paParms, false);
317}
318
319/**
320 * Execute state save operation.
321 *
322 * @returns VBox status code.
323 * @param pDrvIns Driver instance of the driver which registered the data unit.
324 * @param pSSM SSM operation handle.
325 */
326static DECLCALLBACK(int) iface_hgcmSave(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM)
327{
328 PDRVMAINVMMDEV pDrv = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
329
330 return hgcmSaveStateInternal (pDrv->pHGCMPort, pDrv->pVMMDev->mSharedFolderClientId, pSSM);
331}
332
333
334/**
335 * Execute state load operation.
336 *
337 * @returns VBox status code.
338 * @param pDrvIns Driver instance of the driver which registered the data unit.
339 * @param pSSM SSM operation handle.
340 * @param u32Version Data layout version.
341 */
342static DECLCALLBACK(int) iface_hgcmLoad(PPDMDRVINS pDrvIns, PSSMHANDLE pSSM, uint32_t u32Version)
343{
344 PDRVMAINVMMDEV pDrv = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
345
346 if (u32Version != HGCM_SSM_VERSION)
347 return VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION;
348
349 return hgcmLoadStateInternal (pDrv->pHGCMPort, pDrv->pVMMDev->mSharedFolderClientId, pSSM);
350}
351
352int VMMDev::hgcmLoadService (const char *pszServiceName, const char *pszServiceLibrary)
353{
354 return hgcmLoadInternal (pszServiceName, pszServiceLibrary);
355}
356
357int VMMDev::hgcmConnect (PVBOXHGCMCMD pCmd, PHGCMSERVICELOCATION pServiceLocation, uint32_t *pu32ClientID)
358{
359 return hgcmConnectInternal (mpDrv->pHGCMPort, pCmd, pServiceLocation, pu32ClientID, true);
360}
361
362int VMMDev::hgcmDisconnect (PVBOXHGCMCMD pCmd, uint32_t u32ClientID)
363{
364 return hgcmDisconnectInternal (mpDrv->pHGCMPort, pCmd, u32ClientID, true);
365}
366
367int VMMDev::hgcmHostCall (const char *pszServiceName, uint32_t u32Function,
368 uint32_t cParms, PVBOXHGCMSVCPARM paParms)
369{
370 return hgcmHostCallInternal (pszServiceName, u32Function, cParms, paParms);
371}
372
373#endif
374
375
376/**
377 * Queries an interface to the driver.
378 *
379 * @returns Pointer to interface.
380 * @returns NULL if the interface was not supported by the driver.
381 * @param pInterface Pointer to this interface structure.
382 * @param enmInterface The requested interface identification.
383 */
384DECLCALLBACK(void *) VMMDev::drvQueryInterface(PPDMIBASE pInterface, PDMINTERFACE enmInterface)
385{
386 PPDMDRVINS pDrvIns = PDMIBASE_2_PDMDRV(pInterface);
387 PDRVMAINVMMDEV pDrv = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
388 switch (enmInterface)
389 {
390 case PDMINTERFACE_BASE:
391 return &pDrvIns->IBase;
392 case PDMINTERFACE_VMMDEV_CONNECTOR:
393 return &pDrv->Connector;
394#ifdef VBOX_HGCM
395 case PDMINTERFACE_HGCM_CONNECTOR:
396 return &pDrv->HGCMConnector;
397#endif
398 default:
399 return NULL;
400 }
401}
402
403
404/**
405 * Destruct a VMMDev driver instance.
406 *
407 * @returns VBox status.
408 * @param pDrvIns The driver instance data.
409 */
410DECLCALLBACK(void) VMMDev::drvDestruct(PPDMDRVINS pDrvIns)
411{
412 PDRVMAINVMMDEV pData = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
413 LogFlow(("VMMDev::drvDestruct: iInstance=%d\n", pDrvIns->iInstance));
414#ifdef VBOX_HGCM
415 /* Unload Shared Folder HGCM service */
416 if (pData->pVMMDev->mSharedFolderClientId)
417 {
418 uint64_t dummy = 0;
419 PVBOXHGCMCMD cmd = (PVBOXHGCMCMD)&dummy;
420
421 pData->pVMMDev->hgcmDisconnect(cmd, pData->pVMMDev->getShFlClientId());
422 }
423
424 /// @todo hgcmShutdown
425#endif
426 if (pData->pVMMDev)
427 {
428 pData->pVMMDev->mpDrv = NULL;
429 }
430}
431
432/**
433 * Reset notification.
434 *
435 * @returns VBox status.
436 * @param pDrvIns The driver instance data.
437 */
438DECLCALLBACK(void) VMMDev::drvReset(PPDMDRVINS pDrvIns)
439{
440 PDRVMAINVMMDEV pData = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
441 LogFlow(("VMMDev::drvReset: iInstance=%d\n", pDrvIns->iInstance));
442#ifdef VBOX_HGCM
443 /* Unload Shared Folder HGCM service */
444 if (pData->pVMMDev->mSharedFolderClientId)
445 {
446 uint64_t dummy = 0;
447 PVBOXHGCMCMD cmd = (PVBOXHGCMCMD)&dummy;
448
449 pData->pVMMDev->hgcmDisconnect(cmd, pData->pVMMDev->getShFlClientId());
450
451 /* Reload Shared Folder HGCM service */
452 HGCMSERVICELOCATION loc;
453
454 cmd = (PVBOXHGCMCMD)&dummy;
455
456 Log(("Connect to Shared Folders service\n"));
457 pData->pVMMDev->mSharedFolderClientId = 0;
458 loc.type = VMMDevHGCMLoc_LocalHost;
459 strcpy(loc.u.host.achName, "VBoxSharedFolders");
460 int rc = pData->pVMMDev->hgcmConnect(cmd, &loc, &pData->pVMMDev->mSharedFolderClientId);
461 if (rc != VINF_SUCCESS)
462 {
463 AssertMsgFailed(("hgcmConnect returned %Vrc\n", rc));
464 }
465 }
466#endif
467}
468
469/**
470 * Construct a VMMDev driver instance.
471 *
472 * @returns VBox status.
473 * @param pDrvIns The driver instance data.
474 * If the registration structure is needed, pDrvIns->pDrvReg points to it.
475 * @param pCfgHandle Configuration node handle for the driver. Use this to obtain the configuration
476 * of the driver instance. It's also found in pDrvIns->pCfgHandle, but like
477 * iInstance it's expected to be used a bit in this function.
478 */
479DECLCALLBACK(int) VMMDev::drvConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfgHandle)
480{
481 PDRVMAINVMMDEV pData = PDMINS2DATA(pDrvIns, PDRVMAINVMMDEV);
482 LogFlow(("Keyboard::drvConstruct: iInstance=%d\n", pDrvIns->iInstance));
483
484 /*
485 * Validate configuration.
486 */
487 if (!CFGMR3AreValuesValid(pCfgHandle, "Object\0"))
488 return VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
489 PPDMIBASE pBaseIgnore;
490 int rc = pDrvIns->pDrvHlp->pfnAttach(pDrvIns, &pBaseIgnore);
491 if (rc != VERR_PDM_NO_ATTACHED_DRIVER)
492 {
493 AssertMsgFailed(("Configuration error: Not possible to attach anything to this driver!\n"));
494 return VERR_PDM_DRVINS_NO_ATTACH;
495 }
496
497 /*
498 * IBase.
499 */
500 pDrvIns->IBase.pfnQueryInterface = VMMDev::drvQueryInterface;
501
502 pData->Connector.pfnUpdateGuestVersion = vmmdevUpdateGuestVersion;
503 pData->Connector.pfnUpdateMouseCapabilities = vmmdevUpdateMouseCapabilities;
504 pData->Connector.pfnUpdatePointerShape = vmmdevUpdatePointerShape;
505 pData->Connector.pfnVideoAccelEnable = iface_VideoAccelEnable;
506 pData->Connector.pfnVideoAccelFlush = iface_VideoAccelFlush;
507 pData->Connector.pfnVideoModeSupported = vmmdevVideoModeSupported;
508 pData->Connector.pfnGetHeightReduction = vmmdevGetHeightReduction;
509 pData->Connector.pfnSetCredentialsJudgementResult = vmmdevSetCredentialsJudgementResult;
510
511#ifdef VBOX_HGCM
512 pData->HGCMConnector.pfnConnect = iface_hgcmConnect;
513 pData->HGCMConnector.pfnDisconnect = iface_hgcmDisconnect;
514 pData->HGCMConnector.pfnCall = iface_hgcmCall;
515#endif
516
517 /*
518 * Get the IVMMDevPort interface of the above driver/device.
519 */
520 pData->pUpPort = (PPDMIVMMDEVPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_VMMDEV_PORT);
521 if (!pData->pUpPort)
522 {
523 AssertMsgFailed(("Configuration error: No VMMDev port interface above!\n"));
524 return VERR_PDM_MISSING_INTERFACE_ABOVE;
525 }
526
527#ifdef VBOX_HGCM
528 pData->pHGCMPort = (PPDMIHGCMPORT)pDrvIns->pUpBase->pfnQueryInterface(pDrvIns->pUpBase, PDMINTERFACE_HGCM_PORT);
529 if (!pData->pHGCMPort)
530 {
531 AssertMsgFailed(("Configuration error: No HGCM port interface above!\n"));
532 return VERR_PDM_MISSING_INTERFACE_ABOVE;
533 }
534#endif
535
536 /*
537 * Get the Console object pointer and update the mpDrv member.
538 */
539 void *pv;
540 rc = CFGMR3QueryPtr(pCfgHandle, "Object", &pv);
541 if (VBOX_FAILURE(rc))
542 {
543 AssertMsgFailed(("Configuration error: No/bad \"Object\" value! rc=%Vrc\n", rc));
544 return rc;
545 }
546
547 pData->pVMMDev = (VMMDev*)pv; /** @todo Check this cast! */
548 pData->pVMMDev->mpDrv = pData;
549
550#ifdef VBOX_HGCM
551
552 /* Load Shared Folder HGCM service */
553 HGCMSERVICELOCATION loc;
554 uint64_t dummy = 0;
555 PVBOXHGCMCMD pCmd = (PVBOXHGCMCMD)&dummy;
556
557 Log(("Connect to Shared Folders service\n"));
558 pData->pVMMDev->mSharedFolderClientId = 0;
559
560 rc = pData->pVMMDev->hgcmLoadService ("VBoxSharedFolders", "VBoxSharedFolders");
561
562 if (rc == VINF_SUCCESS)
563 {
564 loc.type = VMMDevHGCMLoc_LocalHost;
565 strcpy(loc.u.host.achName, "VBoxSharedFolders");
566 rc = pData->pVMMDev->hgcmConnect(pCmd, &loc, &pData->pVMMDev->mSharedFolderClientId);
567 }
568
569 if (rc != VINF_SUCCESS)
570 {
571 Log(("hgcmConnect returned %Vrc, shared folders are unavailable!!!\n", rc));
572
573 /* This is not a fatal error; the shared folder dll can e.g. be missing */
574 rc = VINF_SUCCESS;
575 pData->pVMMDev->mSharedFolderClientId = 0;
576 }
577#if 0 /* enable later */
578 pDrvIns->pDrvHlp->pfnSSMRegister(pDrvIns, "HGCM", 0, HGCM_SSM_VERSION, 4096/* bad guess */, NULL, iface_hgcmSave, NULL, NULL, iface_hgcmLoad, NULL);
579#endif
580#endif
581
582 return VINF_SUCCESS;
583}
584
585
586/**
587 * VMMDevice driver registration record.
588 */
589const PDMDRVREG VMMDev::DrvReg =
590{
591 /* u32Version */
592 PDM_DRVREG_VERSION,
593 /* szDriverName */
594 "MainVMMDev",
595 /* pszDescription */
596 "Main VMMDev driver (Main as in the API).",
597 /* fFlags */
598 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
599 /* fClass. */
600 PDM_DRVREG_CLASS_VMMDEV,
601 /* cMaxInstances */
602 ~0,
603 /* cbInstance */
604 sizeof(DRVMAINVMMDEV),
605 /* pfnConstruct */
606 VMMDev::drvConstruct,
607 /* pfnDestruct */
608 VMMDev::drvDestruct,
609 /* pfnIOCtl */
610 NULL,
611 /* pfnPowerOn */
612 NULL,
613 /* pfnReset */
614 VMMDev::drvReset,
615 /* pfnSuspend */
616 NULL,
617 /* pfnResume */
618 NULL,
619 /* pfnDetach */
620 NULL
621};
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