Changeset 81062 in vbox for trunk/src/VBox/Runtime/r3/win/RTSystemFirmware-win.cpp
- Timestamp:
- Sep 27, 2019 8:53:09 PM (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/RTSystemFirmware-win.cpp
r80860 r81062 29 29 * Header Files * 30 30 *********************************************************************************************************************************/ 31 #include "internal/iprt.h" 32 #include <iprt/system.h> 31 33 32 34 #include <iprt/nt/nt-and-windows.h> 33 35 #include <WinSDKVer.h> 36 37 #include <iprt/asm.h> 34 38 #include <iprt/assert.h> 35 #include <iprt/err core.h>39 #include <iprt/err.h> 36 40 #include <iprt/mem.h> 37 41 #include <iprt/ldr.h> 38 42 #include <iprt/string.h> 39 #include <iprt/system.h>40 43 #include <iprt/utf16.h> 41 44 45 #include "internal-r3-win.h" 46 42 47 43 48 /********************************************************************************************************************************* 44 49 * Structures and Typedefs * 45 50 *********************************************************************************************************************************/ 46 /** 47 * These are the FirmwareType* defines found in the Vista Platform SDK and returned 48 * by GetProductInfo(). 49 * 50 * We define them ourselves because we don't necessarily have any Vista PSDK around. 51 */ 52 typedef enum RTWINFWTYPE 53 { 54 kRTWinFirmwareTypeUnknown = 0, 55 kRTWinFirmwareTypeBios = 1, 56 kRTWinFirmwareTypeUefi = 2, 57 kRTWinFirmwareTypeMax = 3 58 } RTWINFWTYPE; 59 60 /** Function pointer for dynamic import of GetFirmwareType(). */ 61 typedef BOOL (WINAPI *PFNGETFIRMWARETYPE)(RTWINFWTYPE *); 62 51 #if _WIN32_MAXVER < 0x0602 /* Windows 7 or older, supply missing GetFirmwareType bits. */ 52 typedef enum _FIRMWARE_TYPE 53 { 54 FirmwareTypeUnknown, 55 FirmwareTypeBios, 56 FirmwareTypeUefi, 57 FirmwareTypeMax 58 } FIRMWARE_TYPE; 59 typedef FIRMWARE_TYPE *PFIRMWARE_TYPE; 60 WINBASEAPI BOOL WINAPI GetFirmwareType(PFIRMWARE_TYPE); 61 #endif 62 63 64 /********************************************************************************************************************************* 65 * Defined Constants And Macros * 66 *********************************************************************************************************************************/ 63 67 /** Defines the UEFI Globals UUID. */ 64 68 #define VBOX_UEFI_UUID_GLOBALS L"{8BE4DF61-93CA-11D2-AA0D-00E098032B8C}" 65 69 /** Defines an UEFI dummy UUID. */ 66 70 #define VBOX_UEFI_UUID_DUMMY L"{00000000-0000-0000-0000-000000000000}" 71 72 73 /********************************************************************************************************************************* 74 * Global Variables * 75 *********************************************************************************************************************************/ 76 static volatile bool g_fResolvedApis = false; 77 static decltype(GetFirmwareType) *g_pfnGetFirmwareType; 78 static decltype(GetFirmwareEnvironmentVariableW) *g_pfnGetFirmwareEnvironmentVariableW; 79 80 81 static void rtSystemFirmwareResolveApis(void) 82 { 83 FARPROC pfnTmp1 = GetProcAddress(g_hModKernel32, "GetFirmwareType"); 84 FARPROC pfnTmp2 = GetProcAddress(g_hModKernel32, "GetFirmwareEnvironmentVariableW"); 85 ASMCompilerBarrier(); /* paranoia^2 */ 86 87 g_pfnGetFirmwareType = (decltype(GetFirmwareType) *)pfnTmp1; 88 g_pfnGetFirmwareEnvironmentVariableW = (decltype(GetFirmwareEnvironmentVariableW) *)pfnTmp2; 89 ASMAtomicWriteBool(&g_fResolvedApis, true); 90 } 67 91 68 92 … … 95 119 96 120 97 RTDECL(int) RTSystemFirmwareQueryType(PRTSYSFWTYPE pFirmwareType) 98 { 99 AssertPtrReturn(pFirmwareType, VERR_INVALID_POINTER); 100 101 RTSYSFWTYPE fwType = RTSYSFWTYPE_UNKNOWN; 102 103 RTLDRMOD hKernel32 = NIL_RTLDRMOD; 104 int rc = RTLdrLoadSystem("Kernel32.dll", /* fNoUnload = */ true, &hKernel32); 105 if (RT_SUCCESS(rc)) 106 { 107 PFNGETFIRMWARETYPE pfnGetFirmwareType; 108 rc = RTLdrGetSymbol(hKernel32, "GetFirmwareType", (void **)&pfnGetFirmwareType); /* Only >= Windows 8. */ 109 if (RT_SUCCESS(rc)) 110 { 111 RTWINFWTYPE winFwType; 112 if (pfnGetFirmwareType(&winFwType)) 121 RTDECL(int) RTSystemFirmwareQueryType(PRTSYSFWTYPE penmFirmwareType) 122 { 123 AssertPtrReturn(penmFirmwareType, VERR_INVALID_POINTER); 124 125 if (!g_fResolvedApis) 126 rtSystemFirmwareResolveApis(); 127 128 *penmFirmwareType = RTSYSFWTYPE_INVALID; 129 int rc = VERR_NOT_SUPPORTED; 130 131 /* GetFirmwareType is Windows 8 and later. */ 132 if (g_pfnGetFirmwareType) 133 { 134 FIRMWARE_TYPE enmWinFwType; 135 if (g_pfnGetFirmwareType(&enmWinFwType)) 136 { 137 switch (enmWinFwType) 113 138 { 114 switch (winFwType) 115 { 116 case kRTWinFirmwareTypeBios: 117 fwType = RTSYSFWTYPE_BIOS; 118 break; 119 120 case kRTWinFirmwareTypeUefi: 121 fwType = RTSYSFWTYPE_UEFI; 122 break; 123 124 default: /* Huh? */ 125 fwType = RTSYSFWTYPE_UNKNOWN; 126 break; 127 } 139 case FirmwareTypeBios: 140 *penmFirmwareType = RTSYSFWTYPE_BIOS; 141 break; 142 case FirmwareTypeUefi: 143 *penmFirmwareType = RTSYSFWTYPE_UEFI; 144 break; 145 default: 146 *penmFirmwareType = RTSYSFWTYPE_UNKNOWN; 147 AssertMsgFailed(("%d\n", enmWinFwType)); 148 break; 149 } 150 rc = VINF_SUCCESS; 151 } 152 else 153 rc = RTErrConvertFromWin32(GetLastError()); 154 } 155 /* GetFirmwareEnvironmentVariableW is XP and later. */ 156 else if (g_pfnGetFirmwareEnvironmentVariableW) 157 { 158 rtSystemFirmwareGetPrivileges(SE_SYSTEM_ENVIRONMENT_NAME); 159 160 uint8_t fEnabled = 0; /** @todo This type doesn't make sense to bird. */ 161 DWORD cbRet = g_pfnGetFirmwareEnvironmentVariableW(L"", VBOX_UEFI_UUID_GLOBALS, &fEnabled, sizeof(fEnabled)); 162 if (cbRet) 163 { 164 Assert(cbRet == sizeof(fEnabled)); 165 *penmFirmwareType = fEnabled ? RTSYSFWTYPE_UEFI : RTSYSFWTYPE_BIOS; 166 rc = VINF_SUCCESS; 167 } 168 else 169 { 170 DWORD dwErr = GetLastError(); 171 if (dwErr == ERROR_INVALID_FUNCTION) 172 { 173 *penmFirmwareType = RTSYSFWTYPE_BIOS; 174 rc = VINF_SUCCESS; 128 175 } 129 176 else 130 rc = RTErrConvertFromWin32(GetLastError()); 131 } 132 else /* Fallback for OSes < Windows 8. */ 133 { 134 rc = rtSystemFirmwareGetPrivileges(SE_SYSTEM_ENVIRONMENT_NAME); 135 if (RT_SUCCESS(rc)) 136 { 137 PCWCHAR pcwszGUID = VBOX_UEFI_UUID_GLOBALS; /* UEFI Globals. */ 138 PCWCHAR pcwszName = L""; 139 140 uint8_t uEnabled = 0; 141 DWORD dwRet = GetFirmwareEnvironmentVariableW(pcwszName, pcwszGUID, &uEnabled, sizeof(uEnabled)); 142 if (dwRet) /* Returns the bytes written. */ 143 { 144 Assert(dwRet == sizeof(uEnabled)); 145 fwType = RT_BOOL(uEnabled) ? RTSYSFWTYPE_UEFI : RTSYSFWTYPE_BIOS; 146 } 147 else 148 rc = RTErrConvertFromWin32(GetLastError()); 149 } 150 } 151 152 RTLdrClose(hKernel32); 153 } 154 155 if (RT_SUCCESS(rc)) 156 *pFirmwareType = fwType; 157 177 rc = RTErrConvertFromWin32(dwErr); 178 } 179 } 158 180 return rc; 159 181 } 160 182 161 183 162 RTDECL(void) RTSystemFirmwareValueFree(PRTSYSFWVALUE pValue) 163 { 164 if (!pValue) 165 return; 166 167 /** @todo Implement cleanup here. */ 168 } 169 170 171 RTDECL(int) RTSystemFirmwareValueQuery(RTSYSFWPROP enmProp, PRTSYSFWVALUE *ppValue) 172 { 173 int rc = rtSystemFirmwareGetPrivileges(SE_SYSTEM_ENVIRONMENT_NAME); 174 if (RT_FAILURE(rc)) 175 return rc; 176 177 PRTSYSFWVALUE pValue = (PRTSYSFWVALUE)RTMemAlloc(sizeof(RTSYSFWVALUE)); 178 if (!pValue) 179 return VERR_NO_MEMORY; 180 181 char *pszName = NULL; 182 DWORD dwSize = 0; 183 184 RTDECL(void) RTSystemFirmwareFreeValue(PRTSYSFWVALUE pValue) 185 { 186 RT_NOREF(pValue); 187 } 188 189 190 RTDECL(int) RTSystemFirmwareQueryValue(RTSYSFWPROP enmProp, PRTSYSFWVALUE pValue) 191 { 192 RT_ZERO(*pValue); 193 194 /* 195 * Translate the enmProp to a name and type: 196 */ 197 const wchar_t *pwszName = NULL; 184 198 switch (enmProp) 185 199 { 186 200 case RTSYSFWPROP_SECURE_BOOT: 187 201 { 188 rc = RTStrAAppend(&pszName, "SecureBoot"); 189 if (RT_FAILURE(rc)) 190 break; 191 202 pwszName = L"SecureBoot"; 192 203 pValue->enmType = RTSYSFWVALUETYPE_BOOLEAN; 193 dwSize = 1;194 204 break; 195 205 } 196 206 197 case RTSYSFWPROP_BOOT_CURRENT: 198 RT_FALL_THROUGH(); 199 case RTSYSFWPROP_BOOT_ORDER: 200 RT_FALL_THROUGH(); 201 case RTSYSFWPROP_BOOT_NEXT: 202 RT_FALL_THROUGH(); 203 case RTSYSFWPROP_TIMEOUT: 204 RT_FALL_THROUGH(); 205 case RTSYSFWPROP_PLATFORM_LANG: 206 rc = VERR_NOT_IMPLEMENTED; 207 default: 208 AssertReturn(enmProp > RTSYSFWPROP_INVALID && enmProp < RTSYSFWPROP_END, VERR_INVALID_PARAMETER); 209 return VERR_SYS_UNSUPPORTED_FIRMWARE_PROPERTY; 210 } 211 212 if (!g_pfnGetFirmwareEnvironmentVariableW) 213 return VERR_NOT_SUPPORTED; 214 rtSystemFirmwareGetPrivileges(SE_SYSTEM_ENVIRONMENT_NAME); 215 216 int rc; 217 switch (pValue->enmType) 218 { 219 case RTSYSFWVALUETYPE_BOOLEAN: 220 { 221 uint8_t bValue = 0; 222 DWORD cbRet = g_pfnGetFirmwareEnvironmentVariableW(pwszName, VBOX_UEFI_UUID_GLOBALS, &bValue, sizeof(bValue)); 223 pValue->u.fVal = cbRet != 0 && bValue != 0; 224 rc = cbRet != 0 || GetLastError() == ERROR_INVALID_FUNCTION ? VINF_SUCCESS : RTErrConvertFromWin32(GetLastError()); 207 225 break; 226 } 208 227 209 228 default: 210 rc = VERR_INVALID_PARAMETER; 211 break; 212 } 213 214 if (RT_SUCCESS(rc)) 215 { 216 PRTUTF16 pwszName; 217 rc = RTStrToUtf16(pszName, &pwszName); 218 if (RT_SUCCESS(rc)) 219 { 220 void *pvBuf = RTMemAlloc(dwSize); 221 DWORD dwBuf = dwSize; 222 223 if (pvBuf) 224 { 225 DWORD dwRet = GetFirmwareEnvironmentVariableW(pwszName, VBOX_UEFI_UUID_GLOBALS, pvBuf, dwBuf); 226 if (dwRet) 227 { 228 switch (pValue->enmType) 229 { 230 case RTSYSFWVALUETYPE_BOOLEAN: 231 pValue->u.fVal = RT_BOOL(*(uint8_t *)pvBuf); 232 break; 233 234 case RTSYSFWVALUETYPE_INVALID: 235 RT_FALL_THROUGH(); 236 default: 237 AssertFailed(); 238 break; 239 } 240 } 241 else 242 rc = RTErrConvertFromWin32(GetLastError()); 243 244 RTMemFree(pvBuf); 245 } 246 else 247 rc = VERR_NO_MEMORY; 248 249 RTUtf16Free(pwszName); 250 } 251 } 252 253 RTStrFree(pszName); 254 255 if (RT_SUCCESS(rc)) 256 { 257 *ppValue = pValue; 258 } 259 else 260 RTSystemFirmwareValueFree(pValue); 229 AssertFailedReturn(VERR_INTERNAL_ERROR); 230 } 261 231 262 232 return rc;
Note:
See TracChangeset
for help on using the changeset viewer.