VirtualBox

source: vbox/trunk/src/VBox/Devices/Storage/DrvHostFloppy.cpp@ 63942

Last change on this file since 63942 was 62928, checked in by vboxsync, 8 years ago

Devices: warnings

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 KB
Line 
1/* $Id: DrvHostFloppy.cpp 62928 2016-08-03 15:31:34Z vboxsync $ */
2/** @file
3 *
4 * VBox storage devices:
5 * Host floppy block driver
6 */
7
8/*
9 * Copyright (C) 2006-2016 Oracle Corporation
10 *
11 * This file is part of VirtualBox Open Source Edition (OSE), as
12 * available from http://www.virtualbox.org. This file is free software;
13 * you can redistribute it and/or modify it under the terms of the GNU
14 * General Public License (GPL) as published by the Free Software
15 * Foundation, in version 2 as it comes in the "COPYING" file of the
16 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
17 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
18 */
19
20
21/*********************************************************************************************************************************
22* Header Files *
23*********************************************************************************************************************************/
24#define LOG_GROUP LOG_GROUP_DRV_HOST_FLOPPY
25#ifdef RT_OS_LINUX
26# include <sys/ioctl.h>
27# include <linux/fd.h>
28# include <sys/fcntl.h>
29# include <errno.h>
30
31# elif defined(RT_OS_WINDOWS)
32# include <iprt/win/windows.h>
33# include <dbt.h>
34
35#elif defined(RT_OS_L4)
36
37#else /* !RT_OS_WINDOWS nor RT_OS_LINUX nor RT_OS_L4 */
38# error "Unsupported Platform."
39#endif /* !RT_OS_WINDOWS nor RT_OS_LINUX nor RT_OS_L4 */
40
41#include <VBox/vmm/pdmdrv.h>
42#include <VBox/vmm/pdmstorageifs.h>
43#include <iprt/assert.h>
44#include <iprt/file.h>
45#include <iprt/string.h>
46#include <iprt/thread.h>
47#include <iprt/semaphore.h>
48#include <iprt/uuid.h>
49#include <iprt/asm.h>
50#include <iprt/critsect.h>
51
52#include "VBoxDD.h"
53#include "DrvHostBase.h"
54
55
56/**
57 * Floppy driver instance data.
58 */
59typedef struct DRVHOSTFLOPPY
60{
61 DRVHOSTBASE Base;
62 /** Previous poll status. */
63 bool fPrevDiskIn;
64
65} DRVHOSTFLOPPY, *PDRVHOSTFLOPPY;
66
67
68
69#ifdef RT_OS_WINDOWS
70/**
71 * Get media size - needs a special IOCTL.
72 *
73 * @param pThis The instance data.
74 */
75static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
76{
77 DISK_GEOMETRY geom;
78 DWORD cbBytesReturned;
79 int rc;
80 int cbSectors;
81
82 memset(&geom, 0, sizeof(geom));
83 rc = DeviceIoControl((HANDLE)RTFileToNative(pThis->hFileDevice), IOCTL_DISK_GET_DRIVE_GEOMETRY,
84 NULL, 0, &geom, sizeof(geom), &cbBytesReturned, NULL);
85 if (rc) {
86 cbSectors = geom.Cylinders.QuadPart * geom.TracksPerCylinder * geom.SectorsPerTrack;
87 *pcb = cbSectors * geom.BytesPerSector;
88 rc = VINF_SUCCESS;
89 }
90 else
91 {
92 DWORD dwLastError;
93
94 dwLastError = GetLastError();
95 rc = RTErrConvertFromWin32(dwLastError);
96 Log(("DrvHostFloppy: IOCTL_DISK_GET_DRIVE_GEOMETRY(%s) failed, LastError=%d rc=%Rrc\n",
97 pThis->pszDevice, dwLastError, rc));
98 return rc;
99 }
100
101 return rc;
102}
103#endif /* RT_OS_WINDOWS */
104
105#ifdef RT_OS_LINUX
106/**
107 * Get media size and do change processing.
108 *
109 * @param pThis The instance data.
110 */
111static DECLCALLBACK(int) drvHostFloppyGetMediaSize(PDRVHOSTBASE pThis, uint64_t *pcb)
112{
113 int rc = ioctl(RTFileToNative(pThis->hFileDevice), FDFLUSH);
114 if (rc)
115 {
116 rc = RTErrConvertFromErrno (errno);
117 Log(("DrvHostFloppy: FDFLUSH ioctl(%s) failed, errno=%d rc=%Rrc\n", pThis->pszDevice, errno, rc));
118 return rc;
119 }
120
121 floppy_drive_struct DrvStat;
122 rc = ioctl(RTFileToNative(pThis->hFileDevice), FDGETDRVSTAT, &DrvStat);
123 if (rc)
124 {
125 rc = RTErrConvertFromErrno(errno);
126 Log(("DrvHostFloppy: FDGETDRVSTAT ioctl(%s) failed, errno=%d rc=%Rrc\n", pThis->pszDevice, errno, rc));
127 return rc;
128 }
129 pThis->fReadOnly = !(DrvStat.flags & FD_DISK_WRITABLE);
130
131 return RTFileSeek(pThis->hFileDevice, 0, RTFILE_SEEK_END, pcb);
132}
133#endif /* RT_OS_LINUX */
134
135
136#ifdef RT_OS_LINUX
137/**
138 * This thread will periodically poll the Floppy for media presence.
139 *
140 * @returns Ignored.
141 * @param ThreadSelf Handle of this thread. Ignored.
142 * @param pvUser Pointer to the driver instance structure.
143 */
144static DECLCALLBACK(int) drvHostFloppyPoll(PDRVHOSTBASE pThis)
145{
146 PDRVHOSTFLOPPY pThisFloppy = (PDRVHOSTFLOPPY)pThis;
147 floppy_drive_struct DrvStat;
148 int rc = ioctl(RTFileToNative(pThis->hFileDevice), FDPOLLDRVSTAT, &DrvStat);
149 if (rc)
150 return RTErrConvertFromErrno(errno);
151
152 RTCritSectEnter(&pThis->CritSect);
153 bool fDiskIn = !(DrvStat.flags & (FD_VERIFY | FD_DISK_NEWCHANGE));
154 if ( fDiskIn
155 && !pThisFloppy->fPrevDiskIn)
156 {
157 if (pThis->fMediaPresent)
158 DRVHostBaseMediaNotPresent(pThis);
159 rc = DRVHostBaseMediaPresent(pThis);
160 if (RT_FAILURE(rc))
161 {
162 pThisFloppy->fPrevDiskIn = fDiskIn;
163 RTCritSectLeave(&pThis->CritSect);
164 return rc;
165 }
166 }
167
168 if ( !fDiskIn
169 && pThisFloppy->fPrevDiskIn
170 && pThis->fMediaPresent)
171 DRVHostBaseMediaNotPresent(pThis);
172 pThisFloppy->fPrevDiskIn = fDiskIn;
173
174 RTCritSectLeave(&pThis->CritSect);
175 return VINF_SUCCESS;
176}
177#endif /* RT_OS_LINUX */
178
179
180/**
181 * @copydoc FNPDMDRVCONSTRUCT
182 */
183static DECLCALLBACK(int) drvHostFloppyConstruct(PPDMDRVINS pDrvIns, PCFGMNODE pCfg, uint32_t fFlags)
184{
185 RT_NOREF(fFlags);
186 PDRVHOSTFLOPPY pThis = PDMINS_2_DATA(pDrvIns, PDRVHOSTFLOPPY);
187 LogFlow(("drvHostFloppyConstruct: iInstance=%d\n", pDrvIns->iInstance));
188
189 /*
190 * Init instance data.
191 */
192 int rc = DRVHostBaseInitData(pDrvIns, pCfg, PDMMEDIATYPE_FLOPPY_1_44);
193 if (RT_SUCCESS(rc))
194 {
195 /*
196 * Validate configuration.
197 */
198 if (CFGMR3AreValuesValid(pCfg, "Path\0ReadOnly\0Interval\0Locked\0BIOSVisible\0"))
199 {
200 /*
201 * Override stuff.
202 */
203#ifdef RT_OS_WINDOWS
204 pThis->Base.pfnGetMediaSize = drvHostFloppyGetMediaSize;
205#endif
206#ifdef RT_OS_LINUX
207 pThis->Base.pfnPoll = drvHostFloppyPoll;
208 pThis->Base.pfnGetMediaSize = drvHostFloppyGetMediaSize;
209#endif
210
211 /*
212 * 2nd init part.
213 */
214 rc = DRVHostBaseInitFinish(&pThis->Base);
215 }
216 else
217 {
218 pThis->Base.fAttachFailError = true;
219 rc = VERR_PDM_DRVINS_UNKNOWN_CFG_VALUES;
220 }
221 }
222 if (RT_FAILURE(rc))
223 {
224 if (!pThis->Base.fAttachFailError)
225 {
226 /* Suppressing the attach failure error must not affect the normal
227 * DRVHostBaseDestruct, so reset this flag below before leaving. */
228 pThis->Base.fKeepInstance = true;
229 rc = VINF_SUCCESS;
230 }
231 DRVHostBaseDestruct(pDrvIns);
232 pThis->Base.fKeepInstance = false;
233 }
234
235 LogFlow(("drvHostFloppyConstruct: returns %Rrc\n", rc));
236 return rc;
237}
238
239
240/**
241 * Block driver registration record.
242 */
243const PDMDRVREG g_DrvHostFloppy =
244{
245 /* u32Version */
246 PDM_DRVREG_VERSION,
247 /* szName */
248 "HostFloppy",
249 /* szRCMod */
250 "",
251 /* szR0Mod */
252 "",
253 /* pszDescription */
254 "Host Floppy Block Driver.",
255 /* fFlags */
256 PDM_DRVREG_FLAGS_HOST_BITS_DEFAULT,
257 /* fClass. */
258 PDM_DRVREG_CLASS_BLOCK,
259 /* cMaxInstances */
260 ~0U,
261 /* cbInstance */
262 sizeof(DRVHOSTFLOPPY),
263 /* pfnConstruct */
264 drvHostFloppyConstruct,
265 /* pfnDestruct */
266 DRVHostBaseDestruct,
267 /* pfnRelocate */
268 NULL,
269 /* pfnIOCtl */
270 NULL,
271 /* pfnPowerOn */
272 NULL,
273 /* pfnReset */
274 NULL,
275 /* pfnSuspend */
276 NULL,
277 /* pfnResume */
278 NULL,
279 /* pfnAttach */
280 NULL,
281 /* pfnDetach */
282 NULL,
283 /* pfnPowerOff */
284 NULL,
285 /* pfnSoftReset */
286 NULL,
287 /* u32EndVersion */
288 PDM_DRVREG_VERSION
289};
290
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