/** * Initializes the global variables related to windows version. */ static void rtR3InitWindowsVersion(void) { Assert(g_hModNtDll != NULL); /* * ASSUMES OSVERSIONINFOEX starts with the exact same layout as OSVERSIONINFO (safe). */ AssertCompileMembersSameSizeAndOffset(OSVERSIONINFOEX, szCSDVersion, OSVERSIONINFO, szCSDVersion); AssertCompileMemberOffset(OSVERSIONINFOEX, wServicePackMajor, sizeof(OSVERSIONINFO)); /* * Use the NT version of GetVersionExW so we don't get fooled by * compatability shims. */ RT_ZERO(g_WinOsInfoEx); g_WinOsInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); LONG (__stdcall *pfnRtlGetVersion)(OSVERSIONINFOEXW *); *(FARPROC *)&pfnRtlGetVersion = GetProcAddress(g_hModNtDll, "RtlGetVersion"); LONG rcNt = -1; if (pfnRtlGetVersion) rcNt = pfnRtlGetVersion(&g_WinOsInfoEx); if (rcNt != 0) { /* * Couldn't find it or it failed, try the windows version of the API. */ RT_ZERO(g_WinOsInfoEx); g_WinOsInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); if (!GetVersionExW((POSVERSIONINFOW)&g_WinOsInfoEx)) { /* * If that didn't work either, just get the basic version bits. */ RT_ZERO(g_WinOsInfoEx); g_WinOsInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOW); if (GetVersionExW((POSVERSIONINFOW)&g_WinOsInfoEx)) Assert(g_WinOsInfoEx.dwPlatformId != VER_PLATFORM_WIN32_NT || g_WinOsInfoEx.dwMajorVersion < 5); else { AssertBreakpoint(); RT_ZERO(g_WinOsInfoEx); } } } if (g_WinOsInfoEx.dwOSVersionInfoSize) g_enmWinVer = rtR3InitWinSimplifiedVersion(&g_WinOsInfoEx); }
RTDECL(int) RTPathSplit(const char *pszPath, PRTPATHSPLIT pSplit, size_t cbSplit, uint32_t fFlags) { /* * Input validation. */ AssertReturn(cbSplit >= RT_UOFFSETOF(RTPATHSPLIT, apszComps), VERR_INVALID_PARAMETER); AssertPtrReturn(pSplit, VERR_INVALID_POINTER); AssertPtrReturn(pszPath, VERR_INVALID_POINTER); AssertReturn(*pszPath, VERR_PATH_ZERO_LENGTH); AssertReturn(RTPATH_STR_F_IS_VALID(fFlags, 0), VERR_INVALID_FLAGS); /* * Use RTPathParse to do the parsing. * - This makes the ASSUMPTION that the output of this function is greater * or equal to that of RTPathParsed. * - We're aliasing the buffer here, so use volatile to avoid issues due to * compiler optimizations. */ RTPATHPARSED volatile *pParsedVolatile = (RTPATHPARSED volatile *)pSplit; RTPATHSPLIT volatile *pSplitVolatile = (RTPATHSPLIT volatile *)pSplit; AssertCompile(sizeof(*pParsedVolatile) <= sizeof(*pSplitVolatile)); AssertCompile(sizeof(pParsedVolatile->aComps[0]) <= sizeof(pSplitVolatile->apszComps[0])); int rc = RTPathParse(pszPath, (PRTPATHPARSED)pParsedVolatile, cbSplit, fFlags); if (RT_FAILURE(rc) && rc != VERR_BUFFER_OVERFLOW) return rc; /* * Calculate the required buffer space. */ uint16_t const cComps = pParsedVolatile->cComps; uint16_t const fProps = pParsedVolatile->fProps; uint16_t const cchPath = pParsedVolatile->cchPath; uint16_t const offSuffix = pParsedVolatile->offSuffix; uint32_t cbNeeded = RT_OFFSETOF(RTPATHSPLIT, apszComps[cComps]) + cchPath + RTPATH_PROP_FIRST_NEEDS_NO_SLASH(fProps) /* zero terminator for root spec. */ - RT_BOOL(fProps & RTPATH_PROP_DIR_SLASH) /* counted by cchPath, not included in the comp str. */ + 1; /* zero terminator. */ if (cbNeeded > cbSplit) { pSplitVolatile->cbNeeded = cbNeeded; return VERR_BUFFER_OVERFLOW; } Assert(RT_SUCCESS(rc)); /* * Convert the array and copy the strings, both backwards. */ char *psz = (char *)pSplit + cbNeeded; uint32_t idxComp = cComps - 1; /* the final component first (because of suffix handling). */ uint16_t offComp = pParsedVolatile->aComps[idxComp].off; uint16_t cchComp = pParsedVolatile->aComps[idxComp].cch; *--psz = '\0'; psz -= cchComp; memcpy(psz, &pszPath[offComp], cchComp); pSplitVolatile->apszComps[idxComp] = psz; char *pszSuffix; if (offSuffix >= offComp + cchComp) pszSuffix = &psz[cchComp]; else pszSuffix = &psz[offSuffix - offComp]; /* the remainder */ while (idxComp-- > 0) { offComp = pParsedVolatile->aComps[idxComp].off; cchComp = pParsedVolatile->aComps[idxComp].cch; *--psz = '\0'; psz -= cchComp; memcpy(psz, &pszPath[offComp], cchComp); pSplitVolatile->apszComps[idxComp] = psz; } /* * Store / reshuffle the non-array bits. This MUST be done after finishing * the array processing because there may be members in RTPATHSPLIT * overlapping the array of RTPATHPARSED. */ AssertCompileMembersSameSizeAndOffset(RTPATHPARSED, cComps, RTPATHSPLIT, cComps); Assert(pSplitVolatile->cComps == cComps); AssertCompileMembersSameSizeAndOffset(RTPATHPARSED, fProps, RTPATHSPLIT, fProps); Assert(pSplitVolatile->fProps == fProps); AssertCompileMembersSameSizeAndOffset(RTPATHPARSED, cchPath, RTPATHSPLIT, cchPath); Assert(pSplitVolatile->cchPath == cchPath); pSplitVolatile->u16Reserved = 0; pSplitVolatile->cbNeeded = cbNeeded; pSplitVolatile->pszSuffix = pszSuffix; return rc; }
ULONG APIENTRY VBoxDispDrvEscape(SURFOBJ *pso, ULONG iEsc, ULONG cjIn, PVOID pvIn, ULONG cjOut, PVOID pvOut) { PVBOXDISPDEV pDev = (PVBOXDISPDEV)pso->dhpdev; LOGF_ENTER(); switch (iEsc) { #ifdef VBOX_WITH_CROGL case OPENGL_GETINFO: { if (pvOut && cjOut >= sizeof(OPENGL_INFO)) { POPENGL_INFO pInfo = (POPENGL_INFO)pvOut; pInfo->dwVersion = 2; pInfo->dwDriverVersion = 1; pInfo->szDriverName[0] = 'V'; pInfo->szDriverName[1] = 'B'; pInfo->szDriverName[2] = 'o'; pInfo->szDriverName[3] = 'x'; pInfo->szDriverName[4] = 'O'; pInfo->szDriverName[5] = 'G'; pInfo->szDriverName[6] = 'L'; pInfo->szDriverName[7] = 0; LOG(("OPENGL_GETINFO ok")); return cjOut; } else { WARN(("OPENGL_GETINFO invalid parms")); return 0; } } case QUERYESCSUPPORT: { if (pvIn && cjIn == sizeof(DWORD)) { DWORD nEscapeQuery = *(DWORD *)pvIn; if (nEscapeQuery==OPENGL_GETINFO) { LOG(("QUERYESCSUPPORT OPENGL_GETINFO")); return 1; } else { LOG(("QUERYESCSUPPORT unsupported query %d", nEscapeQuery)); return 0; } } else { WARN(("QUERYESCSUPPORT invalid parms")); return 0; } } #endif case VBOXESC_ISVRDPACTIVE: { if (pDev && pDev->vbvaCtx.pVBVA && pDev->vbvaCtx.pVBVA->hostFlags.u32HostEvents&VBVA_F_MODE_VRDP) { LOGF(("VBOXESC_ISVRDPACTIVE: 1")); return 1; } LOGF(("VBOXESC_ISVRDPACTIVE: 0")); return 0; } case VBOXESC_SETVISIBLEREGION: { LOGF(("VBOXESC_SETVISIBLEREGION")); LPRGNDATA lpRgnData = (LPRGNDATA)pvIn; DWORD cRects; if ( cjIn >= sizeof(RGNDATAHEADER) && pvIn && lpRgnData->rdh.dwSize == sizeof(RGNDATAHEADER) && lpRgnData->rdh.iType == RDH_RECTANGLES && (cRects = lpRgnData->rdh.nCount) <= _1M && cjIn == cRects * (uint64_t)sizeof(RECT) + sizeof(RGNDATAHEADER)) { /** @todo this whole conversion thing could maybe be skipped * since RTRECT matches the RECT layout. */ #if 0 AssertCompile(sizeof(RTRECT) == sizeof(RECT)); AssertCompileMembersSameSizeAndOffset(RTRECT, xLeft, RECT, left); AssertCompileMembersSameSizeAndOffset(RTRECT, xBottom, RECT, bottom); AssertCompileMembersSameSizeAndOffset(RTRECT, xRight, RECT, right); AssertCompileMembersSameSizeAndOffset(RTRECT, xTop, RECT, top); rc = VBoxDispMPSetVisibleRegion(pDev->hDriver, (PRTRECT)&lpRgnData->Buffer[0], cRects); VBOX_WARNRC(rc); #else DWORD i; PRTRECT pRTRect; int rc; RECT *pRect = (RECT *)&lpRgnData->Buffer; pRTRect = (PRTRECT) EngAllocMem(0, cRects*sizeof(RTRECT), MEM_ALLOC_TAG); if (!pRTRect) { WARN(("failed to allocate %d bytes", cRects*sizeof(RTRECT))); break; } for (i = 0; i < cRects; ++i) { LOG(("New visible rectangle (%d,%d) (%d,%d)", pRect[i].left, pRect[i].bottom, pRect[i].right, pRect[i].top)); pRTRect[i].xLeft = pRect[i].left; pRTRect[i].yBottom = pRect[i].bottom; pRTRect[i].xRight = pRect[i].right; pRTRect[i].yTop = pRect[i].top; } rc = VBoxDispMPSetVisibleRegion(pDev->hDriver, pRTRect, cRects); VBOX_WARNRC(rc); EngFreeMem(pRTRect); #endif if (RT_SUCCESS(rc)) { LOGF_LEAVE(); return 1; } } else { if (pvIn) { WARN(("check failed rdh.dwSize=%x iType=%d size=%d expected size=%d", lpRgnData->rdh.dwSize, lpRgnData->rdh.iType, cjIn, lpRgnData->rdh.nCount * sizeof(RECT) + sizeof(RGNDATAHEADER))); } } break; } default: { LOG(("unsupported iEsc %#x", iEsc)); } } LOGF_LEAVE(); return 0; }
int main(int argc, char **argv) { /* Only positive tests here. */ NOREF(argc); NOREF(argv); AssertCompile(true); AssertCompile(1); AssertCompile(2); AssertCompile(99); uint8_t u8; NOREF( u8); uint16_t u16; NOREF(u16); uint32_t u32; NOREF(u32); uint64_t u64; NOREF(u64); AssertCompileSize( u8, 1); AssertCompileSize(u16, 2); AssertCompileSize(u32, 4); AssertCompileSize(u64, 8); AssertCompileSizeAlignment( u8, 1); AssertCompileSizeAlignment(u16, 1); AssertCompileSizeAlignment(u16, 2); AssertCompileSizeAlignment(u32, 1); AssertCompileSizeAlignment(u32, 2); AssertCompileSizeAlignment(u32, 4); AssertCompileSizeAlignment(u64, 1); AssertCompileSizeAlignment(u64, 2); AssertCompileSizeAlignment(u64, 4); AssertCompileSizeAlignment(u64, 8); typedef struct STRUCT12S { uint8_t u8; uint8_t au8[8]; uint64_t u64; uint8_t u8UnalignmentFiller1; uint32_t u32; uint8_t u8UnalignmentFiller2; uint16_t u16; const char *psz; uint32_t u32A; uint32_t u32B; } STRUCT1, STRUCT2; AssertCompileMemberSize(STRUCT1, u8, 1); AssertCompileMemberSize(STRUCT1, u16, 2); AssertCompileMemberSize(STRUCT1, u32, 4); AssertCompileMemberSize(STRUCT1, u64, 8); AssertCompileMemberSizeAlignment(STRUCT1, u8, 1); AssertCompileMemberSizeAlignment(STRUCT1, u16, 1); AssertCompileMemberSizeAlignment(STRUCT1, u16, 2); AssertCompileMemberSizeAlignment(STRUCT1, u32, 1); AssertCompileMemberSizeAlignment(STRUCT1, u32, 2); AssertCompileMemberSizeAlignment(STRUCT1, u32, 4); AssertCompileMemberSizeAlignment(STRUCT1, u64, 1); AssertCompileMemberSizeAlignment(STRUCT1, u64, 2); AssertCompileMemberSizeAlignment(STRUCT1, u64, 4); AssertCompileMemberSizeAlignment(STRUCT1, u64, 8); AssertCompileMemberSizeAlignment(STRUCT1, psz, sizeof(void *)); AssertCompileMemberAlignment(STRUCT1, u8, 1); AssertCompileMemberAlignment(STRUCT1, u16, 1); AssertCompileMemberAlignment(STRUCT1, u16, 2); AssertCompileMemberAlignment(STRUCT1, u32, 1); AssertCompileMemberAlignment(STRUCT1, u32, 2); AssertCompileMemberAlignment(STRUCT1, u32, 4); AssertCompileMemberAlignment(STRUCT1, u64, 1); AssertCompileMemberAlignment(STRUCT1, u64, 2); AssertCompileMemberAlignment(STRUCT1, u64, 4); #if defined(__GNUC__) && ARCH_BITS >= 64 AssertCompileMemberAlignment(STRUCT1, u64, 8); #endif AssertCompileMemberAlignment(STRUCT1, psz, sizeof(void *)); AssertCompileMemberOffset(STRUCT1, u8, 0); AssertCompileMemberOffset(STRUCT1, au8, 1); #ifndef _MSC_VER /** @todo figure out why MSC has trouble with these expressions */ AssertCompileMemberOffset(STRUCT1, au8[0], 1); AssertCompileMemberOffset(STRUCT1, au8[8], 9); #endif typedef union UNION1U { STRUCT1 s1; STRUCT2 s2; } UNION1; AssertCompile2MemberOffsets(UNION1, s1.u8, s2.u8); AssertCompile2MemberOffsets(UNION1, s1.u16, s2.u16); AssertCompile2MemberOffsets(UNION1, s1.u32, s2.u32); AssertCompile2MemberOffsets(UNION1, s1.u64, s2.u64); AssertCompile2MemberOffsets(UNION1, s1.psz, s2.psz); AssertCompileAdjacentMembers(STRUCT1, u32A, u32B); AssertCompileAdjacentMembers(STRUCT1, u8, au8); #ifndef _MSC_VER /** @todo figure out why MSC has trouble with these expressions */ AssertCompileAdjacentMembers(STRUCT1, u8, au8[0]); AssertCompileAdjacentMembers(STRUCT1, au8[0], au8[1]); #endif AssertCompileMembersAtSameOffset(STRUCT1, u8, STRUCT2, u8); AssertCompileMembersAtSameOffset(STRUCT1, au8, STRUCT2, au8); AssertCompileMembersAtSameOffset(STRUCT1, u16, STRUCT2, u16); AssertCompileMembersAtSameOffset(STRUCT1, u32, STRUCT2, u32); AssertCompileMembersAtSameOffset(STRUCT1, u64, STRUCT2, u64); AssertCompileMembersSameSize(STRUCT1, u8, STRUCT2, u8); AssertCompileMembersSameSize(STRUCT1, au8, STRUCT2, au8); AssertCompileMembersSameSize(STRUCT1, u16, STRUCT2, u16); AssertCompileMembersSameSize(STRUCT1, u32, STRUCT2, u32); AssertCompileMembersSameSize(STRUCT1, u64, STRUCT2, u64); AssertCompileMembersSameSizeAndOffset(STRUCT1, u8, STRUCT2, u8); AssertCompileMembersSameSizeAndOffset(STRUCT1, au8, STRUCT2, au8); AssertCompileMembersSameSizeAndOffset(STRUCT1, u16, STRUCT2, u16); AssertCompileMembersSameSizeAndOffset(STRUCT1, u32, STRUCT2, u32); AssertCompileMembersSameSizeAndOffset(STRUCT1, u64, STRUCT2, u64); /* * Check some cdefs.h macros while where here, we'll be using * AssertCompile so it's kind of related. */ #ifdef RT_COMPILER_SUPPORTS_VA_ARGS AssertCompile(RT_COUNT_VA_ARGS() == 0); AssertCompile(RT_COUNT_VA_ARGS(asdf) == 1); AssertCompile(RT_COUNT_VA_ARGS(yyyy) == 1); AssertCompile(RT_COUNT_VA_ARGS(_) == 1); AssertCompile(RT_COUNT_VA_ARGS(1, 2, 3, 4, 5, 6, 7, 8, 9, 0) == 10); #endif return 0; }