Changeset 59396 in vbox for trunk/src/VBox/Runtime/r3/win
- Timestamp:
- Jan 19, 2016 3:32:03 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/r3/win/ldrNative-win.cpp
r59394 r59396 30 30 *********************************************************************************************************************************/ 31 31 #define LOG_GROUP RTLOGGROUP_LDR 32 #include < Windows.h>32 #include <iprt/nt/nt-and-windows.h> 33 33 34 34 #include <iprt/ldr.h> … … 37 37 #include <iprt/alloca.h> 38 38 #include <iprt/assert.h> 39 #include <iprt/ctype.h> 39 40 #include <iprt/err.h> 40 41 #include <iprt/file.h> … … 170 171 171 172 /* 172 * We only try the System32 directory.173 * Resolve side-by-side resolver API. 173 174 */ 175 static bool volatile s_fInitialized = false; 176 static decltype(RtlDosApplyFileIsolationRedirection_Ustr) *s_pfnApplyRedir = NULL; 177 if (!s_fInitialized) 178 { 179 s_pfnApplyRedir = (decltype(s_pfnApplyRedir))GetProcAddress(g_hModNtDll, 180 "RtlDosApplyFileIsolationRedirection_Ustr"); 181 ASMCompilerBarrier(); 182 s_fInitialized = true; 183 } 184 185 /* 186 * We try WinSxS via undocumented NTDLL API and flal back on the System32 187 * directory. No other locations are supported. 188 */ 189 int rc = VERR_TRY_AGAIN; 190 char szPath[RTPATH_MAX]; 191 char *pszPath = szPath; 192 193 /* Get the windows system32 directory so we can sanity check the WinSxS result. */ 174 194 WCHAR wszSysDir[MAX_PATH]; 175 195 UINT cwcSysDir = GetSystemDirectoryW(wszSysDir, MAX_PATH); … … 177 197 return VERR_FILENAME_TOO_LONG; 178 198 179 /** @todo On w2k3r1/64 winhttp.dll is only found under WinSxS. Try use 180 * RtlDosApplyFileIsolationRedirection_Ustr to resolve this issue 181 * (see http-curl.cpp). */ 182 183 char szPath[RTPATH_MAX]; 184 char *pszPath = szPath; 185 int rc = RTUtf16ToUtf8Ex(wszSysDir, RTSTR_MAX, &pszPath, sizeof(szPath), NULL); 199 /* Try side-by-side first (see COMCTL32.DLL). */ 200 if (s_pfnApplyRedir) 201 { 202 size_t cwcName = 0; 203 RTUTF16 wszName[MAX_PATH]; 204 PRTUTF16 pwszName = wszName; 205 int rc2 = RTStrToUtf16Ex(pszFilename, RTSTR_MAX, &pwszName, RT_ELEMENTS(wszName), &cwcName); 206 if (RT_SUCCESS(rc2)) 207 { 208 static UNICODE_STRING const s_DefaultSuffix = RTNT_CONSTANT_UNISTR(L".dll"); 209 WCHAR wszPath[MAX_PATH]; 210 UNICODE_STRING UniStrStatic = { 0, (USHORT)sizeof(wszPath) - sizeof(WCHAR), wszPath }; 211 UNICODE_STRING UniStrDynamic = { 0, 0, NULL }; 212 PUNICODE_STRING pUniStrResult = NULL; 213 UNICODE_STRING UniStrName = 214 { (USHORT)(cwcName * sizeof(RTUTF16)), (USHORT)((cwcName + 1) * sizeof(RTUTF16)), wszName }; 215 216 NTSTATUS rcNt = s_pfnApplyRedir(1 /*fFlags*/, 217 &UniStrName, 218 (PUNICODE_STRING)&s_DefaultSuffix, 219 &UniStrStatic, 220 &UniStrDynamic, 221 &pUniStrResult, 222 NULL /*pNewFlags*/, 223 NULL /*pcbFilename*/, 224 NULL /*pcbNeeded*/); 225 if (NT_SUCCESS(rcNt)) 226 { 227 /* 228 * Check that the resolved path has similarities to the 229 * system directory. 230 * 231 * ASSUMES the windows directory is a root directory and 232 * that both System32 and are on the same level. So, we'll 233 * have 2 matching components (or more if the resolver 234 * returns a system32 path for some reason). 235 */ 236 unsigned cMatchingComponents = 0; 237 unsigned cSlashes = 0; 238 size_t off = 0; 239 while (off < pUniStrResult->Length) 240 { 241 RTUTF16 wc1 = wszSysDir[off]; 242 RTUTF16 wc2 = pUniStrResult->Buffer[off]; 243 if (!RTPATH_IS_SLASH(wc1)) 244 { 245 if (wc1 == wc2) 246 off++; 247 else if ( wc1 < 127 248 && wc2 < 127 249 && RT_C_TO_LOWER(wc1) == RT_C_TO_LOWER(wc2) ) 250 off++; 251 else 252 break; 253 } 254 else if (RTPATH_IS_SLASH(wc2)) 255 { 256 cMatchingComponents += off > 0; 257 do 258 off++; 259 while ( off < pUniStrResult->Length 260 && RTPATH_IS_SLASH(wszSysDir[off]) 261 && RTPATH_IS_SLASH(pUniStrResult->Buffer[off])); 262 } 263 else 264 break; 265 } 266 if (cMatchingComponents >= 2) 267 { 268 pszPath = szPath; 269 rc2 = RTUtf16ToUtf8Ex(pUniStrResult->Buffer, pUniStrResult->Length / sizeof(RTUTF16), 270 &pszPath, sizeof(szPath), NULL); 271 if (RT_SUCCESS(rc2)) 272 rc = VINF_SUCCESS; 273 } 274 else 275 AssertMsgFailed(("%s -> '%*.ls'\n", pszFilename, pUniStrResult->Length, pUniStrResult->Buffer)); 276 RtlFreeUnicodeString(&UniStrDynamic); 277 } 278 } 279 else 280 AssertMsgFailed(("%Rrc\n", rc)); 281 } 282 283 /* If the above didn't succeed, create a system32 path. */ 284 if (RT_FAILURE(rc)) 285 { 286 rc = RTUtf16ToUtf8Ex(wszSysDir, RTSTR_MAX, &pszPath, sizeof(szPath), NULL); 287 if (RT_SUCCESS(rc)) 288 { 289 rc = RTPathAppend(szPath, sizeof(szPath), pszFilename); 290 if (pszExt && RT_SUCCESS(rc)) 291 rc = RTStrCat(szPath, sizeof(szPath), pszExt); 292 } 293 } 294 295 /* Do the actual loading, if we were successful constructing a name. */ 186 296 if (RT_SUCCESS(rc)) 187 297 { 188 rc = RTPathAppend(szPath, sizeof(szPath), pszFilename); 189 if (pszExt && RT_SUCCESS(rc)) 190 rc = RTStrCat(szPath, sizeof(szPath), pszExt); 191 if (RT_SUCCESS(rc)) 192 { 193 if (RTFileExists(szPath)) 194 rc = RTLdrLoadEx(szPath, phLdrMod, fFlags, NULL); 195 else 196 rc = VERR_MODULE_NOT_FOUND; 197 } 298 if (RTFileExists(szPath)) 299 rc = RTLdrLoadEx(szPath, phLdrMod, fFlags, NULL); 300 else 301 rc = VERR_MODULE_NOT_FOUND; 198 302 } 199 303
Note:
See TracChangeset
for help on using the changeset viewer.