Changeset 57620 in vbox
- Timestamp:
- Sep 4, 2015 10:08:46 AM (9 years ago)
- File:
-
- 1 edited
-
trunk/src/VBox/Runtime/r3/win/fileio-win.cpp (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/fileio-win.cpp
r57603 r57620 36 36 37 37 #include <iprt/file.h> 38 39 #include <iprt/asm.h> 40 #include <iprt/assert.h> 38 41 #include <iprt/path.h> 39 #include <iprt/assert.h>40 42 #include <iprt/string.h> 41 43 #include <iprt/err.h> … … 831 833 if (!GetFileInformationByHandle(hHandle, &Data)) 832 834 { 835 /* 836 * Console I/O handles make trouble here. On older windows versions they 837 * end up with ERROR_INVALID_HANDLE when handed to the above API, while on 838 * more recent ones they cause different errors to appear. 839 * 840 * Thus, we must ignore the latter and doubly verify invalid handle claims. 841 * We use the undocumented VerifyConsoleIoHandle to do this, falling back on 842 * GetFileType should it not be there. 843 */ 833 844 DWORD dwErr = GetLastError(); 834 /* Only return if we *really* don't have a valid handle value,835 * everything else is fine here ... */836 845 if (dwErr == ERROR_INVALID_HANDLE) 837 846 { 838 /* 839 * On Windows 7 or earlier certain standard handles such as 840 * stdin, stdout and stderr were ring-3 pseudo handles which the 841 * kernel didn't know about. 842 * 843 * So simply ignore the ERROR_INVALID_HANDLE in that case to not 844 * break other parts which rely on this function. 845 */ 846 OSVERSIONINFOEX OSInfoEx = { 0 }; 847 OSInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 848 849 bool fIgnoreError = false; 850 851 /* Windows 7 or earlier? */ 852 if ( GetVersionEx((LPOSVERSIONINFO) &OSInfoEx) 853 && (OSInfoEx.dwPlatformId == VER_PLATFORM_WIN32_NT) 854 && (OSInfoEx.dwMajorVersion <= 6) 855 && (OSInfoEx.dwMinorVersion <= 1)) 847 static PFNVERIFYCONSOLEIOHANDLE s_pfnVerifyConsoleIoHandle = NULL; 848 static bool volatile s_fInitialized = false; 849 PFNVERIFYCONSOLEIOHANDLE pfnVerifyConsoleIoHandle; 850 if (fInitialized) 851 pfnVerifyConsoleIoHandle = s_pfnVerifyConsoleIoHandle; 852 else 856 853 { 857 PFNVERIFYCONSOLEIOHANDLE pfnVerifyConsoleIoHandle = NULL; 858 859 /* 860 * As the standard I/O handles could have been overwritten by SetStdHandle() we cannot assume 861 * that GetStdHandle will actually return real console I/O handles. 862 * 863 * So try to dynamically load the undocumented VerifyConsoleIoHandle from kernel32.dll. 864 * This function will check if the given handle actually is a console I/O handle, and if so, 865 * we know that we have to ignore the ERROR_INVALID_HANDLE on Windows 7 or earlier. 866 * 867 */ 868 RTLDRMOD hKernel32 = NIL_RTLDRMOD; 869 int rc2 = RTLdrLoadSystem("kernel32.dll", true /*fNoUnload*/, &hKernel32); 870 if (RT_SUCCESS(rc2)) 871 rc2 = RTLdrGetSymbol(hKernel32, "VerifyConsoleIoHandle", (void**)&pfnVerifyConsoleIoHandle); 872 873 if (RT_SUCCESS(rc2)) 874 { 875 AssertPtr(pfnVerifyConsoleIoHandle); 876 877 /* Is the handle a console handle? Then ignore ERROR_INVALID_HANDLE. */ 878 if (pfnVerifyConsoleIoHandle(hHandle)) 879 fIgnoreError = true; 880 } 881 882 if (hKernel32 != NIL_RTLDRMOD) 883 RTLdrClose(hKernel32); 854 int rc = RTLdrGetSystemSymbol(hKernel32, "VerifyConsoleIoHandle", (void **)&pfnVerifyConsoleIoHandle); 855 if (RT_SUCCESS(rc)) 856 s_pfnVerifyConsoleIoHandle = pfnVerifyConsoleIoHandle; 857 else 858 pfnVerifyConsoleIoHandle = NULL; 859 ASMAtomicWriteBool(&s_fInitialized, true); 884 860 } 885 886 if (!fIgnoreError) 887 return RTErrConvertFromWin32(dwErr); 861 if ( pfnVerifyConsoleIoHandle 862 ? !pfnVerifyConsoleIoHandle(hHandle) 863 : GetFileType(hHandle) == FILE_TYPE_UNKNOWN && GetLastError() != NO_ERROR) 864 return VERR_INVALID_HANDLE; 888 865 } 866 else 867 return RTErrConvertFromWin32(dwErr); 868 889 869 RT_ZERO(Data); 890 870 Data.dwFileAttributes = RTFS_DOS_NT_DEVICE;
Note:
See TracChangeset
for help on using the changeset viewer.

