Changeset 57906 in vbox for trunk/src/VBox/Runtime
- Timestamp:
- Sep 25, 2015 8:43:36 PM (9 years ago)
- svn:sync-xref-src-repo-rev:
- 102878
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/process-win.cpp
r57845 r57906 32 32 #include <iprt/asm.h> /* hack */ 33 33 34 #include <iprt/nt/nt-and-windows.h> 34 35 #include <Userenv.h> 35 #include <Windows.h>36 36 #include <tlhelp32.h> 37 37 #include <process.h> … … 136 136 *********************************************************************************************************************************/ 137 137 static int rtProcWinFindExe(uint32_t fFlags, RTENV hEnv, const char *pszExec, PRTUTF16 *ppwszExec); 138 static int rtProcWinCreateEnvBlockAndFindExe(uint32_t fFlags, RTENV hEnv, const char *pszExec, 139 PRTUTF16 *ppwszzBlock, PRTUTF16 *ppwszExec); 138 140 139 141 … … 369 371 switch (dwError) 370 372 { 371 case ERROR_NOACCESS: 372 case ERROR_PRIVILEGE_NOT_HELD: 373 case ERROR_NOACCESS: /** @todo r=bird: this is a bogus transation. Used a couple of places in main. */ 373 374 rc = VERR_PERMISSION_DENIED; 374 break;375 376 case ERROR_PASSWORD_EXPIRED:377 case ERROR_ACCOUNT_RESTRICTION: /* See: http://support.microsoft.com/kb/303846/ */378 case ERROR_PASSWORD_RESTRICTION:379 case ERROR_ACCOUNT_DISABLED: /* See: http://support.microsoft.com/kb/263936 */380 rc = VERR_ACCOUNT_RESTRICTED;381 break;382 383 case ERROR_FILE_CORRUPT:384 rc = VERR_BAD_EXE_FORMAT;385 break;386 387 case ERROR_BAD_DEVICE: /* Can happen when opening funny things like "CON". */388 rc = VERR_INVALID_NAME;389 375 break; 390 376 … … 660 646 * for NULL domain names when running on NT4 here, pass an empty string if so. 661 647 * However, passing FQDNs should work! 662 */ 648 * 649 * The SE_TCB_NAME (Policy: Act as part of the operating system) right 650 * is required on older windows versions (NT4, W2K, possibly XP). 651 */ 652 PCRTUTF16 pwszDomainToUse = g_enmWinVer < kRTWinOSType_2K ? L"" /* NT4 and older */ : NULL /* Windows 2000 and up */; 663 653 BOOL fRc = LogonUserW(pwszUser, 664 g_enmWinVer < kRTWinOSType_2K ? L"" /* NT4 and older */ : NULL /* Windows 2000 and up */,654 pwszDomainToUse, 665 655 pwszPassword, 666 656 LOGON32_LOGON_INTERACTIVE, … … 671 661 672 662 DWORD dwErr = GetLastError(); 673 int rc = rtProcWinMapErrorCodes(dwErr);663 int rc = dwErr == ERROR_PRIVILEGE_NOT_HELD ? VERR_PROC_TCB_PRIV_NOT_HELD : rtProcWinMapErrorCodes(dwErr); 674 664 if (rc == VERR_UNRESOLVED_ERROR) 675 665 LogRelFunc(("dwErr=%u (%#x), rc=%Rrc\n", dwErr, dwErr, rc)); … … 751 741 752 742 return rc; 743 } 744 745 746 /** 747 * Figures which privilege we're missing for success application of 748 * CreateProcessAsUserW. 749 * 750 * @returns IPRT error status. 751 */ 752 static int rtProcWinFigureWhichPrivilegeNotHeld2(void) 753 { 754 HANDLE hToken; 755 if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) 756 { 757 static struct 758 { 759 const char *pszName; 760 int rc; 761 } const s_aPrivileges[] = 762 { 763 { SE_TCB_NAME, VERR_PROC_TCB_PRIV_NOT_HELD }, 764 { SE_ASSIGNPRIMARYTOKEN_NAME, VERR_PROC_APT_PRIV_NOT_HELD }, 765 { SE_INCREASE_QUOTA_NAME, VERR_PROC_IQ_PRIV_NOT_HELD }, 766 }; 767 for (uint32_t i = 0; i < RT_ELEMENTS(s_aPrivileges); i++) 768 { 769 union 770 { 771 TOKEN_PRIVILEGES TokPriv; 772 char abAlloced[sizeof(TOKEN_PRIVILEGES) + sizeof(LUID_AND_ATTRIBUTES)]; 773 } uNew, uOld; 774 uNew.TokPriv.PrivilegeCount = 1; 775 uNew.TokPriv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; 776 AssertStmt(LookupPrivilegeValue(NULL, s_aPrivileges[i].pszName, &uNew.TokPriv.Privileges[0].Luid), continue); 777 uOld = uNew; 778 SetLastError(NO_ERROR); 779 DWORD cbActual = RT_OFFSETOF(TOKEN_PRIVILEGES, Privileges[1]); 780 AdjustTokenPrivileges(hToken, FALSE /*fDisableAllPrivileges*/, &uNew.TokPriv, cbActual, &uOld.TokPriv, &cbActual); 781 if (GetLastError() != NO_ERROR) 782 { 783 CloseHandle(hToken); 784 return s_aPrivileges[i].rc; 785 } 786 if (uOld.TokPriv.Privileges[0].Attributes == 0) 787 AdjustTokenPrivileges(hToken, FALSE /*fDisableAllPrivileges*/, &uOld.TokPriv, 0, NULL, NULL); 788 } 789 AssertFailed(); 790 CloseHandle(hToken); 791 } 792 else 793 AssertFailed(); 794 return VERR_PRIVILEGE_NOT_HELD; 753 795 } 754 796 … … 782 824 * The following rights are needed in order to use LogonUserW and 783 825 * CreateProcessAsUserW, so the local policy has to be modified to: 784 * - SE_TCB_NAME = Act as part of the operating system785 * - SE_ASSIGNPRIMARYTOKEN_NAME = Create/replace a token object786 * - SE_INCREASE_QUOTA_NAME 826 * - SE_TCB_NAME = Act as part of the operating system 827 * - SE_ASSIGNPRIMARYTOKEN_NAME = Create/replace a (process) token object 828 * - SE_INCREASE_QUOTA_NAME = Increase quotas 787 829 * 788 830 * We may fail here with ERROR_PRIVILEGE_NOT_HELD. 789 831 */ 790 /** @todo r=bird: Both methods starts with rtProcWinUserLogon, so we could probably do that once in the parent function, right... */791 832 DWORD dwErr = NO_ERROR; 792 833 HANDLE hTokenLogon = INVALID_HANDLE_VALUE; … … 831 872 } 832 873 else 833 dwErr = GetLastError() != NO_ERROR ? GetLastError() : ERROR_INTERNAL_ERROR; 874 { 875 dwErr = GetLastError(); 876 rc = dwErr != NO_ERROR ? RTErrConvertFromWin32(dwErr) : VERR_INTERNAL_ERROR_3; 877 } 834 878 RTMemFree(pwszDomain); 835 879 } … … 844 888 /* If we got an error due to account lookup/loading above, don't 845 889 * continue here. */ 846 if ( dwErr == NO_ERROR)890 if (RT_SUCCESS(rc)) 847 891 { 848 892 /* … … 868 912 869 913 if (!g_pfnLoadUserProfileW(hTokenToUse, &ProfileInfo)) 870 dwErr = GetLastError();914 rc = RTErrConvertFromWin32(GetLastError()); 871 915 } 872 if ( dwErr == NO_ERROR)916 if (RT_SUCCESS(rc)) 873 917 { 874 918 /* … … 906 950 pProcInfo); 907 951 if (fRc) 908 dwErr = NO_ERROR;952 rc = VINF_SUCCESS; 909 953 else 910 dwErr = GetLastError(); /* CreateProcessAsUserW() failed. */ 954 { 955 dwErr = GetLastError(); 956 if (dwErr == ERROR_PRIVILEGE_NOT_HELD) 957 rc = rtProcWinFigureWhichPrivilegeNotHeld2(); 958 else 959 rc = RTErrConvertFromWin32(dwErr); 960 } 911 961 } 912 962 RTEnvFreeUtf16Block(pwszzBlock); … … 939 989 CloseHandle(hTokenLogon); 940 990 941 /* 942 * Do error conversion. 943 */ 944 if ( RT_SUCCESS(rc) 945 && dwErr != NO_ERROR) 946 { 947 rc = rtProcWinMapErrorCodes(dwErr); 948 if (rc == VERR_UNRESOLVED_ERROR) 949 LogRelFunc(("dwErr=%u (%#x), rc=%Rrc\n", dwErr, dwErr, rc)); 950 } 991 if (rc == VERR_UNRESOLVED_ERROR) 992 LogRelFunc(("dwErr=%u (%#x), rc=%Rrc\n", dwErr, dwErr, rc)); 951 993 } 952 994 return rc; … … 955 997 956 998 /** 999 * Plants a standard handle into a child process on older windows versions. 1000 * 1001 * This is only needed when using CreateProcessWithLogonW on older windows 1002 * versions. It would appear that newer versions of windows does this for us. 1003 * 1004 * @param hSrcHandle The source handle. 1005 * @param hDstProcess The child process handle. 1006 * @param offProcParamMember The offset to RTL_USER_PROCESS_PARAMETERS. 1007 * @param ppvDstProcParamCache Where where cached the address of 1008 * RTL_USER_PROCESS_PARAMETERS in the child. 1009 */ 1010 static void rtProcWinDupStdHandleIntoChild(HANDLE hSrcHandle, HANDLE hDstProcess, uint32_t offProcParamMember, 1011 PVOID *ppvDstProcParamCache) 1012 { 1013 if (hSrcHandle != NULL && hSrcHandle != INVALID_HANDLE_VALUE) 1014 { 1015 HANDLE hDstHandle; 1016 if (DuplicateHandle(GetCurrentProcess(), hSrcHandle, hDstProcess, &hDstHandle, 1017 0 /*IgnoredDesiredAccess*/, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS)) 1018 { 1019 if (hSrcHandle == hDstHandle) 1020 return; 1021 1022 if (!*ppvDstProcParamCache) 1023 { 1024 PROCESS_BASIC_INFORMATION BasicInfo; 1025 ULONG cbIgn; 1026 NTSTATUS rcNt = NtQueryInformationProcess(hDstProcess, ProcessBasicInformation, 1027 &BasicInfo, sizeof(BasicInfo), &cbIgn); 1028 if (NT_SUCCESS(rcNt)) 1029 { 1030 SIZE_T cbCopied = 0; 1031 if (!ReadProcessMemory(hDstProcess, 1032 (char *)BasicInfo.PebBaseAddress + RT_OFFSETOF(PEB_COMMON, ProcessParameters), 1033 ppvDstProcParamCache, sizeof(*ppvDstProcParamCache), &cbCopied)) 1034 { 1035 AssertMsgFailed(("PebBaseAddress=%p %d\n", BasicInfo.PebBaseAddress, GetLastError())); 1036 *ppvDstProcParamCache = NULL; 1037 } 1038 } 1039 else 1040 AssertMsgFailed(("rcNt=%#x\n", rcNt)); 1041 } 1042 if (*ppvDstProcParamCache) 1043 { 1044 if (WriteProcessMemory(hDstProcess, (char *)*ppvDstProcParamCache + offProcParamMember, 1045 &hDstHandle, sizeof(hDstHandle), NULL)) 1046 return; 1047 } 1048 1049 /* 1050 * Close the handle. 1051 */ 1052 HANDLE hSrcHandle2; 1053 if (DuplicateHandle(hDstProcess, hDstHandle, GetCurrentProcess(), &hSrcHandle2, 1054 0 /*IgnoredDesiredAccess*/, FALSE /*fInherit*/, DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE)) 1055 CloseHandle(hSrcHandle2); 1056 else 1057 AssertMsgFailed(("hDstHandle=%p %u\n", hDstHandle, GetLastError())); 1058 } 1059 else 1060 AssertMsg(GetLastError() == ERROR_INVALID_PARAMETER, ("%u\n", GetLastError())); 1061 } 1062 } 1063 1064 1065 /** 957 1066 * Method \#1. 958 1067 * 959 * This m ay fail on too old (NT4) platforms or if the calling process960 * is running on a SYSTEM account (like a service, ERROR_ACCESS_DENIED) on newer961 * platforms (however, this works on W2K!).1068 * This method requires Windows 2000 or later. It may fail if the process is 1069 * running under the SYSTEM account (like a service, ERROR_ACCESS_DENIED) on 1070 * newer platforms (however, this works on W2K!). 962 1071 */ 963 1072 static int rtProcWinCreateAsUser1(PRTUTF16 pwszUser, PRTUTF16 pwszPassword, PRTUTF16 *ppwszExec, PRTUTF16 pwszCmdLine, … … 966 1075 uint32_t fFlags, const char *pszExec) 967 1076 { 1077 /* The CreateProcessWithLogonW API was introduced with W2K and later. It uses a service 1078 for launching the process. */ 968 1079 if (!g_pfnCreateProcessWithLogonW) 969 1080 return VERR_SYMBOL_NOT_FOUND; 970 1081 971 RTENV hEnvToUse = NIL_RTENV; 972 HANDLE hToken; 973 int rc = rtProcWinUserLogon(pwszUser, pwszPassword, NULL /* Domain */, &hToken); 1082 /* 1083 * Create the environment block and find the executable first. 1084 * 1085 * We try to skip this when RTPROC_FLAGS_PROFILE is set so we can sidestep 1086 * potential missing TCB privilege issues when calling UserLogonW. At least 1087 * NT4 and W2K requires the trusted code base (TCB) privilege for logon use. 1088 * Passing pwszzBlock=NULL and LOGON_WITH_PROFILE means the child process 1089 * gets the environment specified by the user profile. 1090 */ 1091 int rc = VINF_SUCCESS; 1092 PRTUTF16 pwszzBlock = NULL; 1093 1094 /* Eliminating the path search flags simplifies things a little. */ 1095 if ( (fFlags & RTPROC_FLAGS_SEARCH_PATH) 1096 && (RTPathHasPath(pszExec) || RTPathExists(pszExec))) 1097 fFlags &= ~RTPROC_FLAGS_SEARCH_PATH; 1098 1099 /* 1100 * No profile is simple, as is a user specified environment (no change record). 1101 */ 1102 if ( !(fFlags & RTPROC_FLAGS_PROFILE) 1103 || ( !(fFlags & RTPROC_FLAGS_ENV_CHANGE_RECORD) 1104 && hEnv != RTENV_DEFAULT)) 1105 rc = rtProcWinCreateEnvBlockAndFindExe(fFlags, hEnv, pszExec, &pwszzBlock, ppwszExec); 1106 /* 1107 * Default profile environment without changes or path searching we leave 1108 * to the service that implements the API. 1109 */ 1110 else if ( hEnv == RTENV_DEFAULT 1111 && !(fFlags & (RTPROC_FLAGS_ENV_CHANGE_RECORD | RTPROC_FLAGS_SEARCH_PATH))) 1112 pwszzBlock = NULL; 1113 /* 1114 * Otherwise, we need to get the user profile environment. 1115 */ 1116 else 1117 { 1118 RTENV hEnvToUse = NIL_RTENV; 1119 HANDLE hToken; 1120 rc = rtProcWinUserLogon(pwszUser, pwszPassword, NULL /* Domain */, &hToken); 1121 if (RT_SUCCESS(rc)) 1122 { 1123 /** @todo r=bird: Why didn't we load the environment here? The 1124 * CreateEnvironmentBlock docs indicate that USERPROFILE isn't set 1125 * unless we call LoadUserProfile first. However, experiments here on W10 1126 * shows it isn't really needed though. Weird. 1127 * Update: It works even on W2K. Possible only required for roaming profiles? */ 1128 #if 0 1129 if (fFlags & RTPROC_FLAGS_PROFILE) 1130 { 1131 PROFILEINFOW ProfileInfo; 1132 RT_ZERO(ProfileInfo); 1133 ProfileInfo.dwSize = sizeof(ProfileInfo); 1134 ProfileInfo.lpUserName = pwszUser; 1135 ProfileInfo.dwFlags = PI_NOUI; /* Prevents the display of profile error messages. */ 1136 1137 if (g_pfnLoadUserProfileW(hToken, &ProfileInfo)) 1138 { 1139 rc = rtProcWinCreateEnvFromToken(hToken, hEnv, fFlags, &hEnvToUse); 1140 1141 if (!g_pfnUnloadUserProfile(hToken, ProfileInfo.hProfile)) 1142 AssertFailed(); 1143 } 1144 else 1145 rc = RTErrConvertFromWin32(GetLastError()); 1146 } 1147 else 1148 #endif 1149 rc = rtProcWinCreateEnvFromToken(hToken, hEnv, fFlags, &hEnvToUse); 1150 CloseHandle(hToken); 1151 1152 /* 1153 * Query the environment block and find the executable file, 1154 * Then destroy any temp env block. 1155 */ 1156 if (RT_SUCCESS(rc)) 1157 { 1158 rc = rtProcWinFindExe(fFlags, hEnv, pszExec, ppwszExec); 1159 if (RT_SUCCESS(rc)) 1160 rc = RTEnvQueryUtf16Block(hEnvToUse, &pwszzBlock); 1161 if (hEnvToUse != hEnv) 1162 RTEnvDestroy(hEnvToUse); 1163 } 1164 } 1165 } 974 1166 if (RT_SUCCESS(rc)) 975 1167 { 976 /** @todo r=bird: Why didn't we load the environment here? The 977 * CreateEnvironmentBlock docs indicate that USERPROFILE isn't set 978 * unless we call LoadUserProfile first. However, experiments here on W10 979 * shows it isn't really needed though. Weird. */ 980 #if 0 981 if (fFlags & RTPROC_FLAGS_PROFILE) 982 { 983 PROFILEINFOW ProfileInfo; 984 RT_ZERO(ProfileInfo); 985 ProfileInfo.dwSize = sizeof(ProfileInfo); 986 ProfileInfo.lpUserName = pwszUser; 987 ProfileInfo.dwFlags = PI_NOUI; /* Prevents the display of profile error messages. */ 988 989 if (g_pfnLoadUserProfileW(hToken, &ProfileInfo)) 990 { 991 rc = rtProcWinCreateEnvFromToken(hToken, hEnv, fFlags, &hEnvToUse); 992 993 if (!g_pfnUnloadUserProfile(hToken, ProfileInfo.hProfile)) 994 AssertFailed(); 995 } 1168 Assert(!(dwCreationFlags & CREATE_SUSPENDED)); 1169 bool const fCreatedSuspended = g_enmWinVer < kRTWinOSType_XP; 1170 BOOL fRc = g_pfnCreateProcessWithLogonW(pwszUser, 1171 NULL, /* lpDomain*/ 1172 pwszPassword, 1173 fFlags & RTPROC_FLAGS_PROFILE ? 1 /*LOGON_WITH_ PROFILE*/ : 0, 1174 *ppwszExec, 1175 pwszCmdLine, 1176 dwCreationFlags | (fCreatedSuspended ? CREATE_SUSPENDED : 0), 1177 pwszzBlock, 1178 NULL, /* pCurrentDirectory */ 1179 pStartupInfo, 1180 pProcInfo); 1181 if (fRc) 1182 { 1183 if (!fCreatedSuspended) 1184 rc = VINF_SUCCESS; 996 1185 else 997 rc = RTErrConvertFromWin32(GetLastError()); 1186 { 1187 /* Duplicate standard handles into the child process, we ignore failures here as it's 1188 legal to have bad standard handle values and we cannot dup console I/O handles. */ 1189 PVOID pvDstProcParamCache = NULL; 1190 rtProcWinDupStdHandleIntoChild(pStartupInfo->hStdInput, pProcInfo->hProcess, 1191 RT_OFFSETOF(RTL_USER_PROCESS_PARAMETERS, StandardInput), &pvDstProcParamCache); 1192 rtProcWinDupStdHandleIntoChild(pStartupInfo->hStdOutput, pProcInfo->hProcess, 1193 RT_OFFSETOF(RTL_USER_PROCESS_PARAMETERS, StandardOutput), &pvDstProcParamCache); 1194 rtProcWinDupStdHandleIntoChild(pStartupInfo->hStdError, pProcInfo->hProcess, 1195 RT_OFFSETOF(RTL_USER_PROCESS_PARAMETERS, StandardError), &pvDstProcParamCache); 1196 1197 if (ResumeThread(pProcInfo->hThread) == ~(DWORD)0) 1198 rc = RTErrConvertFromWin32(GetLastError()); 1199 if (RT_FAILURE(rc)) 1200 { 1201 TerminateProcess(pProcInfo->hProcess, 127); 1202 CloseHandle(pProcInfo->hThread); 1203 CloseHandle(pProcInfo->hProcess); 1204 } 1205 } 998 1206 } 999 1207 else 1000 #endif 1001 rc = rtProcWinCreateEnvFromToken(hToken, hEnv, fFlags, &hEnvToUse); 1002 CloseHandle(hToken); 1003 } 1004 if (RT_SUCCESS(rc)) 1005 { 1006 PRTUTF16 pwszzBlock; 1007 rc = RTEnvQueryUtf16Block(hEnvToUse, &pwszzBlock); 1008 if (RT_SUCCESS(rc)) 1009 { 1010 rc = rtProcWinFindExe(fFlags, hEnv, pszExec, ppwszExec); 1011 if (RT_SUCCESS(rc)) 1012 { 1013 BOOL fRc = g_pfnCreateProcessWithLogonW(pwszUser, 1014 NULL, /* lpDomain*/ 1015 pwszPassword, 1016 fFlags & RTPROC_FLAGS_PROFILE ? 1 /*LOGON_WITH_PROFILE*/ : 0, 1017 *ppwszExec, 1018 pwszCmdLine, 1019 dwCreationFlags, 1020 pwszzBlock, 1021 NULL, /* pCurrentDirectory */ 1022 pStartupInfo, 1023 pProcInfo); 1024 if (fRc) 1025 rc = VINF_SUCCESS; 1026 else 1027 { 1028 DWORD dwErr = GetLastError(); 1029 rc = rtProcWinMapErrorCodes(dwErr); 1030 if (rc == VERR_UNRESOLVED_ERROR) 1031 LogRelFunc(("g_pfnCreateProcessWithLogonW (%p) failed: dwErr=%u (%#x), rc=%Rrc\n", 1032 g_pfnCreateProcessWithLogonW, dwErr, dwErr, rc)); 1033 } 1034 } 1208 { 1209 DWORD dwErr = GetLastError(); 1210 rc = rtProcWinMapErrorCodes(dwErr); 1211 if (rc == VERR_UNRESOLVED_ERROR) 1212 LogRelFunc(("g_pfnCreateProcessWithLogonW (%p) failed: dwErr=%u (%#x), rc=%Rrc\n", 1213 g_pfnCreateProcessWithLogonW, dwErr, dwErr, rc)); 1214 } 1215 if (pwszzBlock) 1035 1216 RTEnvFreeUtf16Block(pwszzBlock); 1036 }1037 if (hEnvToUse != hEnv)1038 RTEnvDestroy(hEnvToUse);1039 1217 } 1040 1218 return rc; … … 1049 1227 /* 1050 1228 * If we run as a service CreateProcessWithLogon will fail, so don't even 1051 * try it (because of Local System context). This method may not work on 1052 * older OSes, it will fail and we try the next alternative. 1229 * try it (because of Local System context). This method is very slow on W2K. 1053 1230 */ 1054 1231 if (!(fFlags & RTPROC_FLAGS_SERVICE)) -
trunk/src/VBox/Runtime/testcase/tstRTProcCreateEx.cpp
r57869 r57906 168 168 #if 1 169 169 /* For manual testing. */ 170 if (strcmp(argv[2],"noinherit-change-record") == 0) 170 if (strcmp(argv[2],"noinherit") == 0) 171 //if (strcmp(argv[2],"noinherit-change-record") == 0) 171 172 { 172 173 RTENV hEnv; … … 230 231 RTTESTI_CHECK_RC_RETV(RTEnvCreateChangeRecord(&hEnvChange), VINF_SUCCESS); 231 232 RTTESTI_CHECK_RC_RETV(RTEnvSetEx(hEnvChange, "testcase-child-6", "changed"), VINF_SUCCESS); 232 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, hEnvChange, RTPROC_FLAGS_ENV_CHANGE_RECORD, 233 int rc; 234 RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, hEnvChange, RTPROC_FLAGS_ENV_CHANGE_RECORD, 233 235 NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS); 234 ProcStatus.enmReason = RTPROCEXITREASON_ABEND; 235 ProcStatus.iStatus = -1; 236 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); 237 238 if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) 239 RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); 236 if (RT_SUCCESS(rc)) 237 { 238 ProcStatus.enmReason = RTPROCEXITREASON_ABEND; 239 ProcStatus.iStatus = -1; 240 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); 241 242 if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) 243 RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); 244 } 240 245 241 246 242 247 /* Use profile environment this time. */ 243 248 apszArgs[2] = "noinherit"; 244 RTTESTI_CHECK_RC _RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, RTPROC_FLAGS_PROFILE,249 RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, RTPROC_FLAGS_PROFILE, 245 250 NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS); 246 ProcStatus.enmReason = RTPROCEXITREASON_ABEND; 247 ProcStatus.iStatus = -1; 248 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); 249 250 if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) 251 RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); 251 if (RT_SUCCESS(rc)) 252 { 253 ProcStatus.enmReason = RTPROCEXITREASON_ABEND; 254 ProcStatus.iStatus = -1; 255 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); 256 257 if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) 258 RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); 259 } 252 260 253 261 /* Use profile environment this time. */ 254 262 apszArgs[2] = "noinherit-change-record"; 255 RTTESTI_CHECK_RC _RETV(RTProcCreateEx(g_szExecName, apszArgs, hEnvChange,263 RTTESTI_CHECK_RC(rc = RTProcCreateEx(g_szExecName, apszArgs, hEnvChange, 256 264 RTPROC_FLAGS_PROFILE | RTPROC_FLAGS_ENV_CHANGE_RECORD, 257 265 NULL, NULL, NULL, pszAsUser, pszPassword, &hProc), VINF_SUCCESS); 258 ProcStatus.enmReason = RTPROCEXITREASON_ABEND; 259 ProcStatus.iStatus = -1; 260 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); 261 262 if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) 263 RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); 266 if (RT_SUCCESS(rc)) 267 { 268 ProcStatus.enmReason = RTPROCEXITREASON_ABEND; 269 ProcStatus.iStatus = -1; 270 RTTESTI_CHECK_RC(RTProcWait(hProc, RTPROCWAIT_FLAGS_BLOCK, &ProcStatus), VINF_SUCCESS); 271 272 if (ProcStatus.enmReason != RTPROCEXITREASON_NORMAL || ProcStatus.iStatus != 0) 273 RTTestIFailed("enmReason=%d iStatus=%d", ProcStatus.enmReason, ProcStatus.iStatus); 274 } 264 275 265 276 … … 403 414 404 415 /* Test for invalid logons. */ 405 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 406 NULL, NULL, "non-existing-user", "wrong-password", &hProc), VERR_AUTHENTICATION_FAILURE); 416 int rc = RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, NULL, NULL, 417 "non-existing-user", "wrong-password", &hProc); 418 if (rc != VERR_AUTHENTICATION_FAILURE && rc != VERR_PRIVILEGE_NOT_HELD && rc != VERR_PROC_TCB_PRIV_NOT_HELD) 419 RTTestIFailed("rc=%Rrc"); 420 407 421 /* Test for invalid application. */ 408 RTTESTI_CHECK_RC _RETV(RTProcCreateEx("non-existing-app", apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL,409 422 RTTESTI_CHECK_RC(RTProcCreateEx("non-existing-app", apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, 423 NULL, NULL, NULL, NULL, &hProc), VERR_FILE_NOT_FOUND); 410 424 /* Test a (hopefully) valid user/password logon (given by parameters of this function). */ 411 425 RTTESTI_CHECK_RC_RETV(RTProcCreateEx(g_szExecName, apszArgs, RTENV_DEFAULT, 0 /*fFlags*/, NULL, -
trunk/src/VBox/Runtime/win/RTErrConvertFromWin32.cpp
r57358 r57906 148 148 149 149 case ERROR_INVALID_NAME: 150 case ERROR_BAD_DEVICE: 150 151 case ERROR_BAD_PATHNAME: return VERR_INVALID_NAME; 151 152 … … 184 185 case ERROR_INVALID_EXE_SIGNATURE: return VERR_INVALID_EXE_SIGNATURE; 185 186 case ERROR_BAD_EXE_FORMAT: return VERR_BAD_EXE_FORMAT; 187 case ERROR_FILE_CORRUPT: return VERR_BAD_EXE_FORMAT; 186 188 case ERROR_RESOURCE_DATA_NOT_FOUND: return VERR_NO_DATA; ///@todo fix ERROR_RESOURCE_DATA_NOT_FOUND translation 187 189 case ERROR_INVALID_ADDRESS: return VERR_INVALID_POINTER; ///@todo fix ERROR_INVALID_ADDRESS translation - dbghelp returns it on some line number queries. … … 192 194 193 195 case ERROR_LOGON_FAILURE: return VERR_AUTHENTICATION_FAILURE; 196 case ERROR_PRIVILEGE_NOT_HELD: return VERR_PRIVILEGE_NOT_HELD; 197 198 case ERROR_PASSWORD_EXPIRED: 199 case ERROR_ACCOUNT_RESTRICTION: 200 case ERROR_PASSWORD_RESTRICTION: 201 case ERROR_ACCOUNT_DISABLED: return VERR_ACCOUNT_RESTRICTED; 202 194 203 195 204 /*
Note:
See TracChangeset
for help on using the changeset viewer.