VirtualBox

source: vbox/trunk/src/VBox/HostDrivers/Support/os2/SUPDrv-os2.cpp@ 97883

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

SUPDrv: OS/2 build fix.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 16.7 KB
 
1/* $Id: SUPDrv-os2.cpp 97883 2022-12-28 01:27:35Z vboxsync $ */
2/** @file
3 * VBoxDrv - The VirtualBox Support Driver - OS/2 specifics.
4 */
5
6/*
7 * Copyright (c) 2007 knut st. osmundsen <[email protected]>
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31
32/*********************************************************************************************************************************
33* Header Files *
34*********************************************************************************************************************************/
35#define LOG_GROUP LOG_GROUP_SUP_DRV
36#define __STDC_CONSTANT_MACROS
37#define __STDC_LIMIT_MACROS
38
39#include <os2ddk/bsekee.h>
40#undef RT_MAX
41
42#include "SUPDrvInternal.h"
43#include <VBox/version.h>
44#include <iprt/initterm.h>
45#include <iprt/string.h>
46#include <iprt/spinlock.h>
47#include <iprt/process.h>
48#include <iprt/assert.h>
49#include <VBox/log.h>
50#include <iprt/param.h>
51
52
53/*********************************************************************************************************************************
54* Global Variables *
55*********************************************************************************************************************************/
56/**
57 * Device extention & session data association structure.
58 */
59static SUPDRVDEVEXT g_DevExt;
60/** Spinlock protecting g_apSessionHashTab. */
61static RTSPINLOCK g_Spinlock = NIL_RTSPINLOCK;
62/** Hash table */
63static PSUPDRVSESSION g_apSessionHashTab[19];
64/** Calculates the index into g_apSessionHashTab.*/
65#define SESSION_HASH(sfn) ((sfn) % RT_ELEMENTS(g_apSessionHashTab))
66
67RT_C_DECLS_BEGIN
68/* Defined in SUPDrvA-os2.asm */
69extern uint16_t g_offLogHead;
70extern uint16_t volatile g_offLogTail;
71extern uint16_t const g_cchLogMax;
72extern char g_szLog[];
73/* (init only:) */
74extern char g_szInitText[];
75extern uint16_t g_cchInitText;
76extern uint16_t g_cchInitTextMax;
77RT_C_DECLS_END
78
79
80/*********************************************************************************************************************************
81* Internal Functions *
82*********************************************************************************************************************************/
83
84
85
86/**
87 * 32-bit Ring-0 initialization.
88 *
89 * @returns 0 on success, non-zero on failure.
90 * @param pszArgs Pointer to the device arguments.
91 */
92DECLASM(int) VBoxDrvInit(const char *pszArgs)
93{
94 /*
95 * Initialize the runtime.
96 */
97 int rc = RTR0Init(0);
98 if (RT_SUCCESS(rc))
99 {
100 Log(("VBoxDrvInit: pszArgs=%s\n", pszArgs));
101
102 /*
103 * Initialize the device extension.
104 */
105 rc = supdrvInitDevExt(&g_DevExt, sizeof(SUPDRVSESSION));
106 if (RT_SUCCESS(rc))
107 {
108 /*
109 * Initialize the session hash table.
110 */
111 rc = RTSpinlockCreate(&g_Spinlock, RTSPINLOCK_FLAGS_INTERRUPT_SAFE, "VBoxDrvOS2");
112 if (RT_SUCCESS(rc))
113 {
114 /*
115 * Process the commandline. Later.
116 */
117 bool fVerbose = true;
118
119 /*
120 * Success
121 */
122 if (fVerbose)
123 {
124 strcpy(&g_szInitText[0],
125 "\r\n"
126 "VirtualBox.org Support Driver for OS/2 version " VBOX_VERSION_STRING "\r\n"
127 "Copyright (C) 2007 Knut St. Osmundsen\r\n"
128 "Copyright (C) 2007-2020 Oracle Corporation\r\n");
129 g_cchInitText = strlen(&g_szInitText[0]);
130 }
131 return VINF_SUCCESS;
132 }
133 g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTSpinlockCreate failed, rc=%Rrc\n", rc);
134 supdrvDeleteDevExt(&g_DevExt);
135 }
136 else
137 g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: supdrvInitDevExt failed, rc=%Rrc\n", rc);
138 RTR0Term();
139 }
140 else
141 g_cchInitText = RTStrPrintf(&g_szInitText[0], g_cchInitTextMax, "VBoxDrv.sys: RTR0Init failed, rc=%Rrc\n", rc);
142 return rc;
143}
144
145
146DECLASM(int) VBoxDrvOpen(uint16_t sfn)
147{
148 int rc;
149 PSUPDRVSESSION pSession;
150
151 /*
152 * Create a new session.
153 */
154 rc = supdrvCreateSession(&g_DevExt, true /* fUser */, true /*fUnrestricted*/, &pSession);
155 if (RT_SUCCESS(rc))
156 {
157 pSession->sfn = sfn;
158
159 /*
160 * Insert it into the hash table.
161 */
162 unsigned iHash = SESSION_HASH(sfn);
163 RTSpinlockAcquire(g_Spinlock);
164 pSession->pNextHash = g_apSessionHashTab[iHash];
165 g_apSessionHashTab[iHash] = pSession;
166 RTSpinlockRelease(g_Spinlock);
167 }
168
169 Log(("VBoxDrvOpen: g_DevExt=%p pSession=%p rc=%d pid=%d\n", &g_DevExt, pSession, rc, (int)RTProcSelf()));
170 return rc;
171}
172
173
174DECLASM(int) VBoxDrvClose(uint16_t sfn)
175{
176 Log(("VBoxDrvClose: pid=%d sfn=%d\n", (int)RTProcSelf(), sfn));
177
178 /*
179 * Remove from the hash table.
180 */
181 PSUPDRVSESSION pSession;
182 const RTPROCESS Process = RTProcSelf();
183 const unsigned iHash = SESSION_HASH(sfn);
184 RTSpinlockAcquire(g_Spinlock);
185
186 pSession = g_apSessionHashTab[iHash];
187 if (pSession)
188 {
189 if ( pSession->sfn == sfn
190 && pSession->Process == Process)
191 {
192 g_apSessionHashTab[iHash] = pSession->pNextHash;
193 pSession->pNextHash = NULL;
194 }
195 else
196 {
197 PSUPDRVSESSION pPrev = pSession;
198 pSession = pSession->pNextHash;
199 while (pSession)
200 {
201 if ( pSession->sfn == sfn
202 && pSession->Process == Process)
203 {
204 pPrev->pNextHash = pSession->pNextHash;
205 pSession->pNextHash = NULL;
206 break;
207 }
208
209 /* next */
210 pPrev = pSession;
211 pSession = pSession->pNextHash;
212 }
213 }
214 }
215 RTSpinlockRelease(g_Spinlock);
216 if (!pSession)
217 {
218 OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d sfn=%d\n", (int)Process, sfn));
219 return VERR_INVALID_PARAMETER;
220 }
221
222 /*
223 * Close the session.
224 */
225 supdrvSessionRelease(pSession);
226 return 0;
227}
228
229
230DECLASM(int) VBoxDrvIOCtlFast(uint16_t sfn, uint8_t iFunction)
231{
232 /*
233 * Find the session.
234 */
235 const RTPROCESS Process = RTProcSelf();
236 const unsigned iHash = SESSION_HASH(sfn);
237 PSUPDRVSESSION pSession;
238
239 RTSpinlockAcquire(g_Spinlock);
240 pSession = g_apSessionHashTab[iHash];
241 if (pSession && pSession->Process != Process)
242 {
243 do pSession = pSession->pNextHash;
244 while ( pSession
245 && ( pSession->sfn != sfn
246 || pSession->Process != Process));
247
248 if (RT_LIKELY(pSession))
249 supdrvSessionRetain(pSession);
250 }
251 RTSpinlockRelease(g_Spinlock);
252 if (RT_UNLIKELY(!pSession))
253 {
254 OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d\n", (int)Process));
255 return VERR_INVALID_PARAMETER;
256 }
257
258 /*
259 * Dispatch the fast IOCtl.
260 */
261 int rc;
262 if ((unsigned)(iFunction - SUP_IOCTL_FAST_DO_FIRST) < (unsigned)32)
263 rc = supdrvIOCtlFast(iFunction, 0, &g_DevExt, pSession);
264 else
265 rc = VERR_INVALID_FUNCTION;
266 supdrvSessionRelease(pSession);
267 return rc;
268}
269
270
271DECLASM(int) VBoxDrvIOCtl(uint16_t sfn, uint8_t iCat, uint8_t iFunction, void *pvParm, void *pvData, uint16_t *pcbParm, uint16_t *pcbData)
272{
273 /*
274 * Find the session.
275 */
276 const RTPROCESS Process = RTProcSelf();
277 const unsigned iHash = SESSION_HASH(sfn);
278 PSUPDRVSESSION pSession;
279
280 RTSpinlockAcquire(g_Spinlock);
281 pSession = g_apSessionHashTab[iHash];
282 if (pSession && pSession->Process != Process)
283 {
284 do pSession = pSession->pNextHash;
285 while ( pSession
286 && ( pSession->sfn != sfn
287 || pSession->Process != Process));
288
289 if (RT_LIKELY(pSession))
290 supdrvSessionRetain(pSession);
291 }
292 RTSpinlockRelease(g_Spinlock);
293 if (!pSession)
294 {
295 OSDBGPRINT(("VBoxDrvIoctl: WHUT?!? pSession == NULL! This must be a mistake... pid=%d\n", (int)Process));
296 return VERR_INVALID_PARAMETER;
297 }
298
299 /*
300 * Verify the category and dispatch the IOCtl.
301 */
302 int rc;
303 if (RT_LIKELY(iCat == SUP_CTL_CATEGORY))
304 {
305 Log(("VBoxDrvIOCtl: pSession=%p iFunction=%#x pvParm=%p pvData=%p *pcbParm=%d *pcbData=%d\n", pSession, iFunction, pvParm, pvData, *pcbParm, *pcbData));
306 Assert(pvParm);
307 Assert(!pvData);
308
309 /*
310 * Lock the header.
311 */
312 PSUPREQHDR pHdr = (PSUPREQHDR)pvParm;
313 AssertReturn(*pcbParm == sizeof(*pHdr), VERR_INVALID_PARAMETER);
314 KernVMLock_t Lock;
315 rc = KernVMLock(VMDHL_WRITE, pHdr, *pcbParm, &Lock, (KernPageList_t *)-1, NULL);
316 AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, *pcbParm, &Lock, rc), VERR_LOCK_FAILED);
317
318 /*
319 * Validate the header.
320 */
321 if (RT_LIKELY((pHdr->fFlags & SUPREQHDR_FLAGS_MAGIC_MASK) == SUPREQHDR_FLAGS_MAGIC))
322 {
323 uint32_t cbReq = RT_MAX(pHdr->cbIn, pHdr->cbOut);
324 if (RT_LIKELY( pHdr->cbIn >= sizeof(*pHdr)
325 && pHdr->cbOut >= sizeof(*pHdr)
326 && cbReq <= _1M*16))
327 {
328 /*
329 * Lock the rest of the buffer if necessary.
330 */
331 if (((uintptr_t)pHdr & PAGE_OFFSET_MASK) + cbReq > PAGE_SIZE)
332 {
333 rc = KernVMUnlock(&Lock);
334 AssertMsgReturn(!rc, ("KernVMUnlock(Lock) -> %#x\n", rc), VERR_LOCK_FAILED);
335
336 rc = KernVMLock(VMDHL_WRITE, pHdr, cbReq, &Lock, (KernPageList_t *)-1, NULL);
337 AssertMsgReturn(!rc, ("KernVMLock(VMDHL_WRITE, %p, %#x, &p, NULL, NULL) -> %d\n", pHdr, cbReq, &Lock, rc), VERR_LOCK_FAILED);
338 }
339
340 /*
341 * Process the IOCtl.
342 */
343 rc = supdrvIOCtl(iFunction, &g_DevExt, pSession, pHdr, cbReq);
344 }
345 else
346 {
347 OSDBGPRINT(("VBoxDrvIOCtl: max(%#x,%#x); iCmd=%#x\n", pHdr->cbIn, pHdr->cbOut, iFunction));
348 rc = VERR_INVALID_PARAMETER;
349 }
350 }
351 else
352 {
353 OSDBGPRINT(("VBoxDrvIOCtl: bad magic fFlags=%#x; iCmd=%#x\n", pHdr->fFlags, iFunction));
354 rc = VERR_INVALID_PARAMETER;
355 }
356
357 /*
358 * Unlock and return.
359 */
360 int rc2 = KernVMUnlock(&Lock);
361 AssertMsg(!rc2, ("rc2=%d\n", rc2)); NOREF(rc2);
362 }
363 else
364 rc = VERR_NOT_SUPPORTED;
365
366 supdrvSessionRelease(pSession);
367 Log2(("VBoxDrvIOCtl: returns %d\n", rc));
368 return rc;
369}
370
371
372void VBOXCALL supdrvOSCleanupSession(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession)
373{
374 NOREF(pDevExt);
375 NOREF(pSession);
376}
377
378
379void VBOXCALL supdrvOSSessionHashTabInserted(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
380{
381 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
382}
383
384
385void VBOXCALL supdrvOSSessionHashTabRemoved(PSUPDRVDEVEXT pDevExt, PSUPDRVSESSION pSession, void *pvUser)
386{
387 NOREF(pDevExt); NOREF(pSession); NOREF(pvUser);
388}
389
390
391void VBOXCALL supdrvOSObjInitCreator(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession)
392{
393 NOREF(pObj);
394 NOREF(pSession);
395}
396
397
398bool VBOXCALL supdrvOSObjCanAccess(PSUPDRVOBJ pObj, PSUPDRVSESSION pSession, const char *pszObjName, int *prc)
399{
400 NOREF(pObj);
401 NOREF(pSession);
402 NOREF(pszObjName);
403 NOREF(prc);
404 return false;
405}
406
407
408bool VBOXCALL supdrvOSGetForcedAsyncTscMode(PSUPDRVDEVEXT pDevExt)
409{
410 NOREF(pDevExt);
411 return false;
412}
413
414
415bool VBOXCALL supdrvOSAreCpusOfflinedOnSuspend(void)
416{
417 return false;
418}
419
420
421bool VBOXCALL supdrvOSAreTscDeltasInSync(void)
422{
423 return false;
424}
425
426
427int VBOXCALL supdrvOSLdrOpen(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
428{
429 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
430 return VERR_NOT_SUPPORTED;
431}
432
433
434int VBOXCALL supdrvOSLdrValidatePointer(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, void *pv,
435 const uint8_t *pbImageBits, const char *pszSymbol)
436{
437 NOREF(pDevExt); NOREF(pImage); NOREF(pv); NOREF(pbImageBits); NOREF(pszSymbol);
438 return VERR_NOT_SUPPORTED;
439}
440
441
442int VBOXCALL supdrvOSLdrLoad(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const uint8_t *pbImageBits, PSUPLDRLOAD pReq)
443{
444 NOREF(pDevExt); NOREF(pImage); NOREF(pbImageBits); NOREF(pReq);
445 return VERR_NOT_SUPPORTED;
446}
447
448
449void VBOXCALL supdrvOSLdrUnload(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
450{
451 NOREF(pDevExt); NOREF(pImage);
452}
453
454
455void VBOXCALL supdrvOSLdrNotifyOpened(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage, const char *pszFilename)
456{
457 NOREF(pDevExt); NOREF(pImage); NOREF(pszFilename);
458}
459
460
461void VBOXCALL supdrvOSLdrNotifyUnloaded(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
462{
463 NOREF(pDevExt); NOREF(pImage);
464}
465
466
467int VBOXCALL supdrvOSLdrQuerySymbol(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage,
468 const char *pszSymbol, size_t cchSymbol, void **ppvSymbol)
469{
470 RT_NOREF(pDevExt, pImage, pszSymbol, cchSymbol, ppvSymbol);
471 return VERR_WRONG_ORDER;
472}
473
474
475void VBOXCALL supdrvOSLdrRetainWrapperModule(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
476{
477 RT_NOREF(pDevExt, pImage);
478 AssertFailed();
479}
480
481
482void VBOXCALL supdrvOSLdrReleaseWrapperModule(PSUPDRVDEVEXT pDevExt, PSUPDRVLDRIMAGE pImage)
483{
484 RT_NOREF(pDevExt, pImage);
485 AssertFailed();
486}
487
488#ifdef SUPDRV_WITH_MSR_PROBER
489
490int VBOXCALL supdrvOSMsrProberRead(uint32_t uMsr, RTCPUID idCpu, uint64_t *puValue)
491{
492 NOREF(uMsr); NOREF(idCpu); NOREF(puValue);
493 return VERR_NOT_SUPPORTED;
494}
495
496
497int VBOXCALL supdrvOSMsrProberWrite(uint32_t uMsr, RTCPUID idCpu, uint64_t uValue)
498{
499 NOREF(uMsr); NOREF(idCpu); NOREF(uValue);
500 return VERR_NOT_SUPPORTED;
501}
502
503
504int VBOXCALL supdrvOSMsrProberModify(RTCPUID idCpu, PSUPMSRPROBER pReq)
505{
506 NOREF(idCpu); NOREF(pReq);
507 return VERR_NOT_SUPPORTED;
508}
509
510#endif /* SUPDRV_WITH_MSR_PROBER */
511
512
513/**
514 * Callback for writing to the log buffer.
515 *
516 * @returns number of bytes written.
517 * @param pvArg Unused.
518 * @param pachChars Pointer to an array of utf-8 characters.
519 * @param cbChars Number of bytes in the character array pointed to by pachChars.
520 */
521static DECLCALLBACK(size_t) VBoxDrvLogOutput(void *pvArg, const char *pachChars, size_t cbChars)
522{
523 size_t cchWritten = 0;
524 while (cbChars-- > 0)
525 {
526 const uint16_t offLogHead = g_offLogHead;
527 const uint16_t offLogHeadNext = (offLogHead + 1) & (g_cchLogMax - 1);
528 if (offLogHeadNext == g_offLogTail)
529 break; /* no */
530 g_szLog[offLogHead] = *pachChars++;
531 g_offLogHead = offLogHeadNext;
532 cchWritten++;
533 }
534 return cchWritten;
535}
536
537
538SUPR0DECL(int) SUPR0PrintfV(const char *pszFormat, va_list va)
539{
540#if 0 //def DEBUG_bird
541 va_list va2;
542 va_copy(va2, va);
543 RTLogComPrintfV(pszFormat, va2);
544 va_end(va2);
545#endif
546
547 RTLogFormatV(VBoxDrvLogOutput, NULL, pszFormat, va);
548 return 0;
549}
550
551
552SUPR0DECL(uint32_t) SUPR0GetKernelFeatures(void)
553{
554 return 0;
555}
556
557
558SUPR0DECL(bool) SUPR0FpuBegin(bool fCtxHook)
559{
560 RT_NOREF(fCtxHook);
561 return false;
562}
563
564
565SUPR0DECL(void) SUPR0FpuEnd(bool fCtxHook)
566{
567 RT_NOREF(fCtxHook);
568}
569
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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