Changeset 2836
- Timestamp:
- Aug 23, 2016, 6:27:34 PM (9 years ago)
- Location:
- trunk/src/kWorker
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kWorker/Makefile.kmk
r2833 r2836 41 41 $(LIB_KDEP) \ 42 42 $(LIB_KUTIL) 43 include $(KBUILD_PATH)/sdks/WINDDK .kmk43 include $(KBUILD_PATH)/sdks/WINDDK71.kmk 44 44 kWorker_LIBS.win = \ 45 45 $(TEMPLATE_BIN_LIBS) \ 46 $(PATH_SDK_WINDDK _LIB_WNET)/ntdll.lib46 $(PATH_SDK_WINDDK71_LIB_WNET)/ntdll.lib 47 47 kWorker_LDFLAGS.win = \ 48 48 /BASE:0x10000 /DYNAMICBASE:NO /FIXED /SECTION:DefLdBuf,EWR -
trunk/src/kWorker/kWorker.c
r2835 r2836 37 37 #include <intrin.h> 38 38 #include <setjmp.h> 39 #include <ctype.h> 39 40 40 41 #include <nt/ntstat.h> … … 80 81 /** Maximum handle value we can deal with. */ 81 82 #define KW_HANDLE_MAX 0x20000 83 84 /** @def WITH_TEMP_MEMORY_FILES 85 * Enables temporary memory files for cl.exe. */ 86 #define WITH_TEMP_MEMORY_FILES 87 88 /** Max temporary file size (memory backed). */ 89 #if K_ARCH_BITS >= 64 90 # define KWFS_TEMP_FILE_MAX (256*1024*1024) 91 #else 92 # define KWFS_TEMP_FILE_MAX (64*1024*1024) 93 #endif 82 94 83 95 … … 209 221 HANDLE hCached; 210 222 /** The file size. */ 211 K SIZEcbCached;223 KU32 cbCached; 212 224 /** Cached file content. */ 213 225 KU8 *pbCached; … … 283 295 284 296 297 typedef struct KWFSTEMPFILESEG *PKWFSTEMPFILESEG; 298 typedef struct KWFSTEMPFILESEG 299 { 300 /** File offset of data. */ 301 KU32 offData; 302 /** The size of the buffer pbData points to. */ 303 KU32 cbDataAlloc; 304 /** The segment data. */ 305 KU8 *pbData; 306 } KWFSTEMPFILESEG; 307 308 typedef struct KWFSTEMPFILE *PKWFSTEMPFILE; 309 typedef struct KWFSTEMPFILE 310 { 311 /** Pointer to the next temporary file for this run. */ 312 PKWFSTEMPFILE pNext; 313 /** The UTF-16 path. (Allocated after this structure.) */ 314 const wchar_t *pwszPath; 315 /** The path length. */ 316 KU16 cwcPath; 317 /** Number of active handles using this file/mapping (<= 2). */ 318 KU8 cActiveHandles; 319 /** Number of active mappings (mapped views) (0 or 1). */ 320 KU8 cMappings; 321 /** The amount of space allocated in the segments. */ 322 KU32 cbFileAllocated; 323 /** The current file size. */ 324 KU32 cbFile; 325 /** The number of segments. */ 326 KU32 cSegs; 327 /** Segments making up the file. */ 328 PKWFSTEMPFILESEG paSegs; 329 } KWFSTEMPFILE; 330 331 285 332 /** Handle type. */ 286 333 typedef enum KWHANDLETYPE 287 334 { 288 335 KWHANDLETYPE_INVALID = 0, 289 KWHANDLETYPE_FSOBJ_READ_CACHE 290 //KWHANDLETYPE_TEMP_FILE_CACHE, 336 KWHANDLETYPE_FSOBJ_READ_CACHE, 337 KWHANDLETYPE_TEMP_FILE, 338 KWHANDLETYPE_TEMP_FILE_MAPPING 291 339 //KWHANDLETYPE_CONSOLE_CACHE 292 340 } KWHANDLETYPE; … … 298 346 /** The current file offset. */ 299 347 KU32 offFile; 348 /** Handle access. */ 349 KU32 dwDesiredAccess; 300 350 /** The handle. */ 301 351 HANDLE hHandle; … … 306 356 /** The file system object. */ 307 357 PKWFSOBJ pFsObj; 358 /** Temporary file handle or mapping handle. */ 359 PKWFSTEMPFILE pTempFile; 308 360 } u; 309 361 } KWHANDLE; … … 319 371 KWTOOLTYPE_END 320 372 } KWTOOLTYPE; 373 374 typedef enum KWTOOLHINT 375 { 376 KWTOOLHINT_INVALID = 0, 377 KWTOOLHINT_NONE, 378 KWTOOLHINT_VISUAL_CPP_CL, 379 KWTOOLHINT_END 380 } KWTOOLHINT; 321 381 322 382 typedef struct KWTOOL *PKWTOOL; … … 343 403 * These will be kept loaded till the tool is destroyed (if we ever do that). */ 344 404 PKWDYNLOAD pDynLoadHead; 405 /** Tool hint (for hacks and such). */ 406 KWTOOLHINT enmHint; 345 407 } Sandboxed; 346 408 } u; … … 395 457 /** Number of active handles in the table. */ 396 458 KU32 cActiveHandles; 459 460 /** Head of the list of temporary file. */ 461 PKWFSTEMPFILE pTempFileHead; 397 462 398 463 UNICODE_STRING SavedCommandLine; … … 906 971 907 972 973 /** 974 * Get the pointer to the filename part of the path. 975 * 976 * @returns Pointer to where the filename starts within the string pointed to by pszFilename. 977 * @returns Pointer to the terminator char if no filename. 978 * @param pszPath The path to parse. 979 */ 980 static wchar_t *kwPathGetFilenameW(const wchar_t *pwszPath) 981 { 982 const wchar_t *pwszLast = NULL; 983 for (;;) 984 { 985 wchar_t wc = *pwszPath; 986 #if K_OS == K_OS_OS2 || K_OS == K_OS_WINDOWS 987 if (wc == '/' || wc == '\\' || wc == ':') 988 { 989 while ((wc = *++pwszPath) == '/' || wc == '\\' || wc == ':') 990 /* nothing */; 991 pwszLast = pwszPath; 992 } 993 #else 994 if (wc == '/') 995 { 996 while ((wc = *++pszFilename) == '/') 997 /* betsuni */; 998 pwszLast = pwszPath; 999 } 1000 #endif 1001 if (!wc) 1002 return (wchar_t *)(pwszLast ? pwszLast : pwszPath); 1003 pwszPath++; 1004 } 1005 } 1006 1007 908 1008 909 1009 /** … … 1675 1775 if (!pTool->u.Sandboxed.pExe) 1676 1776 pTool->enmType = KWTOOLTYPE_EXEC; 1777 else if (kHlpStrICompAscii(pTool->u.Sandboxed.pExe->pLdrMod->pszName, "cl.exe") == 0) 1778 pTool->u.Sandboxed.enmHint = KWTOOLHINT_VISUAL_CPP_CL; 1779 else 1780 pTool->u.Sandboxed.enmHint = KWTOOLHINT_NONE; 1677 1781 1678 1782 /* Link the tool. */ … … 2954 3058 */ 2955 3059 3060 #ifdef WITH_TEMP_MEMORY_FILES 3061 3062 /** 3063 * Checks for a cl.exe temporary file. 3064 * 3065 * There are quite a bunch of these. They seems to be passing data between the 3066 * first and second compiler pass. Since they're on disk, they get subjected to 3067 * AV software screening and normal file consistency rules. So, not necessarily 3068 * a very efficient way of handling reasonably small amounts of data. 3069 * 3070 * We make the files live in virtual memory by intercepting their opening, 3071 * writing, reading, closing , mapping, unmapping, and maybe some more stuff. 3072 * 3073 * @returns K_TRUE / K_FALSE 3074 * @param pwszFilename The file name being accessed. 3075 */ 3076 static KBOOL kwFsIsClTempFileW(const wchar_t *pwszFilename) 3077 { 3078 wchar_t const *pwszName = kwPathGetFilenameW(pwszFilename); 3079 if (pwszName) 3080 { 3081 /* The name starts with _CL_... */ 3082 if ( pwszName[0] == '_' 3083 && pwszName[1] == 'C' 3084 && pwszName[2] == 'L' 3085 && pwszName[3] == '_' ) 3086 { 3087 /* ... followed by 8 xdigits and ends with a two letter file type. Simplify 3088 this check by just checking that it's alpha numerical ascii from here on. */ 3089 wchar_t wc; 3090 pwszName += 4; 3091 while ((wc = *pwszName++) != '\0') 3092 { 3093 if (wc < 127 && iswalnum(wc)) 3094 { /* likely */ } 3095 else 3096 return K_FALSE; 3097 } 3098 return K_TRUE; 3099 } 3100 } 3101 return K_FALSE; 3102 } 3103 3104 3105 /** 3106 * Creates a handle to a temporary file. 3107 * 3108 * @returns The handle on success. 3109 * INVALID_HANDLE_VALUE and SetLastError on failure. 3110 * @param pTempFile The temporary file. 3111 * @param dwDesiredAccess The desired access to the handle. 3112 * @param fMapping Whether this is a mapping (K_TRUE) or file 3113 * (K_FALSE) handle type. 3114 */ 3115 static HANDLE kwFsTempFileCreateHandle(PKWFSTEMPFILE pTempFile, DWORD dwDesiredAccess, KBOOL fMapping) 3116 { 3117 /* 3118 * Create a handle to the temporary file. 3119 */ 3120 HANDLE hFile = INVALID_HANDLE_VALUE; 3121 HANDLE hProcSelf = GetCurrentProcess(); 3122 if (DuplicateHandle(hProcSelf, hProcSelf, 3123 hProcSelf, &hFile, 3124 SYNCHRONIZE, FALSE, 3125 0 /*dwOptions*/)) 3126 { 3127 PKWHANDLE pHandle = (PKWHANDLE)kHlpAlloc(sizeof(*pHandle)); 3128 if (pHandle) 3129 { 3130 pHandle->enmType = !fMapping ? KWHANDLETYPE_TEMP_FILE : KWHANDLETYPE_TEMP_FILE_MAPPING; 3131 pHandle->offFile = 0; 3132 pHandle->hHandle = hFile; 3133 pHandle->dwDesiredAccess = dwDesiredAccess; 3134 pHandle->u.pTempFile = pTempFile; 3135 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle)) 3136 { 3137 pTempFile->cActiveHandles++; 3138 kHlpAssert(pTempFile->cActiveHandles >= 1); 3139 kHlpAssert(pTempFile->cActiveHandles <= 2); 3140 KWFS_LOG(("kwFsTempFileCreateHandle: Temporary file '%ls' -> %p\n", pTempFile->pwszPath, hFile)); 3141 return hFile; 3142 } 3143 3144 kHlpFree(pHandle); 3145 } 3146 else 3147 KWFS_LOG(("kwFsTempFileCreateHandle: Out of memory!\n")); 3148 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 3149 } 3150 else 3151 KWFS_LOG(("kwFsTempFileCreateHandle: DuplicateHandle failed: err=%u\n", GetLastError())); 3152 return INVALID_HANDLE_VALUE; 3153 } 3154 3155 3156 static HANDLE kwFsTempFileCreateW(const wchar_t *pwszFilename, DWORD dwDesiredAccess, DWORD dwCreationDisposition) 3157 { 3158 HANDLE hFile; 3159 DWORD dwErr; 3160 3161 /* 3162 * Check if we've got an existing temp file. 3163 * ASSUME exact same path for now. 3164 */ 3165 KSIZE const cwcFilename = kwUtf16Len(pwszFilename); 3166 PKWFSTEMPFILE pTempFile; 3167 for (pTempFile = g_Sandbox.pTempFileHead; pTempFile != NULL; pTempFile = pTempFile->pNext) 3168 { 3169 /* Since the last two chars are usually the only difference, we check them manually before calling memcmp. */ 3170 if ( pTempFile->cwcPath == cwcFilename 3171 && pTempFile->pwszPath[cwcFilename - 1] == pwszFilename[cwcFilename - 1] 3172 && pTempFile->pwszPath[cwcFilename - 2] == pwszFilename[cwcFilename - 2] 3173 && kHlpMemComp(pTempFile->pwszPath, pwszFilename, cwcFilename) == 0) 3174 break; 3175 } 3176 3177 /* 3178 * Create a new temporary file instance if not found. 3179 */ 3180 if (pTempFile == NULL) 3181 { 3182 KSIZE cbFilename; 3183 3184 switch (dwCreationDisposition) 3185 { 3186 case CREATE_ALWAYS: 3187 case OPEN_ALWAYS: 3188 dwErr = NO_ERROR; 3189 break; 3190 3191 case CREATE_NEW: 3192 kHlpAssertFailed(); 3193 SetLastError(ERROR_ALREADY_EXISTS); 3194 return INVALID_HANDLE_VALUE; 3195 3196 case OPEN_EXISTING: 3197 case TRUNCATE_EXISTING: 3198 kHlpAssertFailed(); 3199 SetLastError(ERROR_FILE_NOT_FOUND); 3200 return INVALID_HANDLE_VALUE; 3201 3202 default: 3203 kHlpAssertFailed(); 3204 SetLastError(ERROR_INVALID_PARAMETER); 3205 return INVALID_HANDLE_VALUE; 3206 } 3207 3208 cbFilename = (cwcFilename + 1) * sizeof(wchar_t); 3209 pTempFile = (PKWFSTEMPFILE)kHlpAlloc(sizeof(*pTempFile) + cbFilename); 3210 if (pTempFile) 3211 { 3212 pTempFile->cwcPath = (KU16)cwcFilename; 3213 pTempFile->cbFile = 0; 3214 pTempFile->cbFileAllocated = 0; 3215 pTempFile->cActiveHandles = 0; 3216 pTempFile->cMappings = 0; 3217 pTempFile->cSegs = 0; 3218 pTempFile->paSegs = NULL; 3219 pTempFile->pwszPath = (wchar_t const *)kHlpMemCopy(pTempFile + 1, pwszFilename, cbFilename); 3220 3221 pTempFile->pNext = g_Sandbox.pTempFileHead; 3222 g_Sandbox.pTempFileHead = pTempFile; 3223 KWFS_LOG(("kwFsTempFileCreateW: Created new temporary file '%ls'\n", pwszFilename)); 3224 } 3225 else 3226 { 3227 KWFS_LOG(("kwFsTempFileCreateW: Out of memory!\n")); 3228 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 3229 return INVALID_HANDLE_VALUE; 3230 } 3231 } 3232 else 3233 { 3234 switch (dwCreationDisposition) 3235 { 3236 case OPEN_EXISTING: 3237 dwErr = NO_ERROR; 3238 break; 3239 case OPEN_ALWAYS: 3240 dwErr = ERROR_ALREADY_EXISTS ; 3241 break; 3242 3243 case TRUNCATE_EXISTING: 3244 case CREATE_ALWAYS: 3245 kHlpAssertFailed(); 3246 pTempFile->cbFile = 0; 3247 dwErr = ERROR_ALREADY_EXISTS; 3248 break; 3249 3250 case CREATE_NEW: 3251 kHlpAssertFailed(); 3252 SetLastError(ERROR_FILE_EXISTS); 3253 return INVALID_HANDLE_VALUE; 3254 3255 default: 3256 kHlpAssertFailed(); 3257 SetLastError(ERROR_INVALID_PARAMETER); 3258 return INVALID_HANDLE_VALUE; 3259 } 3260 } 3261 3262 /* 3263 * Create a handle to the temporary file. 3264 */ 3265 hFile = kwFsTempFileCreateHandle(pTempFile, dwDesiredAccess, K_FALSE /*fMapping*/); 3266 if (hFile != INVALID_HANDLE_VALUE) 3267 SetLastError(dwErr); 3268 return hFile; 3269 } 3270 3271 #endif /* WITH_TEMP_MEMORY_FILES */ 3272 3273 2956 3274 /** 2957 3275 * Checks if the file extension indicates that the file/dir is something we … … 2969 3287 /* C++ header without an extension or a directory. */ 2970 3288 if (chFirst == '\0') 3289 { 3290 /** @todo exclude temporary files... */ 2971 3291 return K_TRUE; 3292 } 2972 3293 2973 3294 /* C Header: .h */ … … 3088 3409 if (pbCache) 3089 3410 { 3090 if (ReadFile(hFile, pbCache, cbCache, NULL, NULL)) 3411 DWORD cbActually = 0; 3412 if ( ReadFile(hFile, pbCache, cbCache, &cbActually, NULL) 3413 && cbActually == cbCache) 3091 3414 { 3092 3415 LARGE_INTEGER offZero; … … 3099 3422 return K_TRUE; 3100 3423 } 3101 else 3102 3424 3425 KWFS_LOG(("Failed to seek to start of cached file! err=%u\n", GetLastError())); 3103 3426 } 3104 3427 else 3105 KWFS_LOG(("Failed to read %#x bytes into cache! err=%u\n", cbCache, GetLastError())); 3428 KWFS_LOG(("Failed to read %#x bytes into cache! err=%u cbActually=%#x\n", 3429 cbCache, GetLastError(), cbActually)); 3106 3430 kHlpFree(pbCache); 3107 3431 } … … 3172 3496 if (pHandle) 3173 3497 { 3174 pHandle->enmType = KWHANDLETYPE_FSOBJ_READ_CACHE; 3175 pHandle->offFile = 0; 3176 pHandle->hHandle = *phFile; 3177 pHandle->u.pFsObj = pFsObj; 3498 pHandle->enmType = KWHANDLETYPE_FSOBJ_READ_CACHE; 3499 pHandle->offFile = 0; 3500 pHandle->hHandle = *phFile; 3501 pHandle->dwDesiredAccess = dwDesiredAccess; 3502 pHandle->u.pFsObj = pFsObj; 3178 3503 if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle)) 3179 3504 return K_TRUE; … … 3196 3521 return K_FALSE; 3197 3522 } 3523 3198 3524 3199 3525 /** Kernel32 - CreateFileA */ … … 3252 3578 { 3253 3579 HANDLE hFile; 3580 3581 #ifdef WITH_TEMP_MEMORY_FILES 3582 /* First check for temporary files (cl.exe only). */ 3583 if ( g_Sandbox.pTool->u.Sandboxed.enmHint == KWTOOLHINT_VISUAL_CPP_CL 3584 && !(dwFlagsAndAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE | FILE_FLAG_BACKUP_SEMANTICS)) 3585 && !(dwDesiredAccess & (GENERIC_EXECUTE | FILE_EXECUTE)) 3586 && kwFsIsClTempFileW(pwszFilename)) 3587 { 3588 hFile = kwFsTempFileCreateW(pwszFilename, dwDesiredAccess, dwCreationDisposition); 3589 KWFS_LOG(("CreateFileW(%ls) -> %p [temp]\n", pwszFilename, hFile)); 3590 return hFile; 3591 } 3592 #endif 3593 3594 /* Then check for include files and similar. */ 3254 3595 if (dwCreationDisposition == FILE_OPEN_IF) 3255 3596 { … … 3301 3642 if (pHandle != NULL) 3302 3643 { 3644 KU32 cbFile; 3303 3645 KI64 offMove = pcbMoveHi ? ((KI64)*pcbMoveHi << 32) | cbMove : cbMove; 3304 3646 switch (pHandle->enmType) 3305 3647 { 3306 3648 case KWHANDLETYPE_FSOBJ_READ_CACHE: 3649 cbFile = pHandle->u.pFsObj->cbCached; 3650 break; 3651 #ifdef WITH_TEMP_MEMORY_FILES 3652 case KWHANDLETYPE_TEMP_FILE: 3653 cbFile = pHandle->u.pTempFile->cbFile; 3654 break; 3655 case KWHANDLETYPE_TEMP_FILE_MAPPING: 3656 #endif 3657 default: 3658 kHlpAssertFailed(); 3659 SetLastError(ERROR_INVALID_FUNCTION); 3660 return INVALID_SET_FILE_POINTER; 3661 } 3662 3663 switch (dwMoveMethod) 3664 { 3665 case FILE_BEGIN: 3666 break; 3667 case FILE_CURRENT: 3668 offMove += pHandle->offFile; 3669 break; 3670 case FILE_END: 3671 offMove += cbFile; 3672 break; 3673 default: 3674 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 3675 SetLastError(ERROR_INVALID_PARAMETER); 3676 return INVALID_SET_FILE_POINTER; 3677 } 3678 if (offMove >= 0) 3679 { 3680 if (offMove >= (KSSIZE)cbFile) 3307 3681 { 3308 PKWFSOBJ pFsObj = pHandle->u.pFsObj; 3309 switch (dwMoveMethod) 3682 /* For read-only files, seeking beyond the end isn't useful to us, so clamp it. */ 3683 if (pHandle->enmType != KWHANDLETYPE_TEMP_FILE) 3684 offMove = (KSSIZE)cbFile; 3685 /* For writable files, seeking beyond the end is fine, but check that we've got 3686 the type range for the request. */ 3687 else if (((KU64)offMove & KU32_MAX) != (KU64)offMove) 3310 3688 { 3311 case FILE_BEGIN: 3312 break; 3313 case FILE_CURRENT: 3314 offMove += pHandle->offFile; 3315 break; 3316 case FILE_END: 3317 offMove += pFsObj->cbCached; 3318 break; 3319 default: 3320 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 3321 SetLastError(ERROR_INVALID_PARAMETER); 3322 return INVALID_SET_FILE_POINTER; 3323 } 3324 if (offMove >= 0) 3325 { 3326 if (offMove >= (KSSIZE)pFsObj->cbCached) 3327 offMove = (KSSIZE)pFsObj->cbCached; 3328 pHandle->offFile = (KU32)offMove; 3329 } 3330 else 3331 { 3332 KWFS_LOG(("SetFilePointer(%p) - negative seek! [cached]\n", hFile)); 3333 SetLastError(ERROR_NEGATIVE_SEEK); 3689 kHlpAssertMsgFailed(("%#llx\n", offMove)); 3690 SetLastError(ERROR_SEEK); 3334 3691 return INVALID_SET_FILE_POINTER; 3335 3692 } 3336 if (pcbMoveHi)3337 *pcbMoveHi = (KU64)offMove >> 32;3338 KWFS_LOG(("SetFilePointer(%p) -> %#llx [cached]\n", hFile, offMove));3339 return (KU32)offMove;3340 3693 } 3341 default: 3342 kHlpAssertFailed(); 3694 pHandle->offFile = (KU32)offMove; 3343 3695 } 3696 else 3697 { 3698 KWFS_LOG(("SetFilePointer(%p) - negative seek! [cached]\n", hFile)); 3699 SetLastError(ERROR_NEGATIVE_SEEK); 3700 return INVALID_SET_FILE_POINTER; 3701 } 3702 if (pcbMoveHi) 3703 *pcbMoveHi = (KU64)offMove >> 32; 3704 KWFS_LOG(("SetFilePointer(%p) -> %#llx [cached]\n", hFile, offMove)); 3705 SetLastError(NO_ERROR); 3706 return (KU32)offMove; 3344 3707 } 3345 3708 } … … 3360 3723 { 3361 3724 KI64 offMyMove = offMove.QuadPart; 3725 KU32 cbFile; 3362 3726 switch (pHandle->enmType) 3363 3727 { 3364 3728 case KWHANDLETYPE_FSOBJ_READ_CACHE: 3729 cbFile = pHandle->u.pFsObj->cbCached; 3730 break; 3731 #ifdef WITH_TEMP_MEMORY_FILES 3732 case KWHANDLETYPE_TEMP_FILE: 3733 cbFile = pHandle->u.pTempFile->cbFile; 3734 break; 3735 case KWHANDLETYPE_TEMP_FILE_MAPPING: 3736 #endif 3737 default: 3738 kHlpAssertFailed(); 3739 SetLastError(ERROR_INVALID_FUNCTION); 3740 return INVALID_SET_FILE_POINTER; 3741 } 3742 3743 switch (dwMoveMethod) 3744 { 3745 case FILE_BEGIN: 3746 break; 3747 case FILE_CURRENT: 3748 offMyMove += pHandle->offFile; 3749 break; 3750 case FILE_END: 3751 offMyMove += cbFile; 3752 break; 3753 default: 3754 KWFS_LOG(("SetFilePointer(%p) - invalid seek method %u! [cached]\n", hFile)); 3755 SetLastError(ERROR_INVALID_PARAMETER); 3756 return INVALID_SET_FILE_POINTER; 3757 } 3758 if (offMyMove >= 0) 3759 { 3760 if (offMyMove >= (KSSIZE)cbFile) 3365 3761 { 3366 PKWFSOBJ pFsObj = pHandle->u.pFsObj; 3367 switch (dwMoveMethod) 3762 /* For read-only files, seeking beyond the end isn't useful to us, so clamp it. */ 3763 if (pHandle->enmType != KWHANDLETYPE_TEMP_FILE) 3764 offMyMove = (KSSIZE)cbFile; 3765 /* For writable files, seeking beyond the end is fine, but check that we've got 3766 the type range for the request. */ 3767 else if (((KU64)offMyMove & KU32_MAX) != (KU64)offMyMove) 3368 3768 { 3369 case FILE_BEGIN: 3370 break; 3371 case FILE_CURRENT: 3372 offMyMove += pHandle->offFile; 3373 break; 3374 case FILE_END: 3375 offMyMove += pFsObj->cbCached; 3376 break; 3377 default: 3378 KWFS_LOG(("SetFilePointerEx(%p) - invalid seek method %u! [cached]\n", hFile)); 3379 SetLastError(ERROR_INVALID_PARAMETER); 3380 return FALSE; 3381 } 3382 if (offMyMove >= 0) 3383 { 3384 if (offMyMove >= (KSSIZE)pFsObj->cbCached) 3385 offMyMove = (KSSIZE)pFsObj->cbCached; 3386 pHandle->offFile = (KU32)offMyMove; 3387 } 3388 else 3389 { 3390 KWFS_LOG(("SetFilePointerEx(%p) - negative seek! [cached]\n", hFile)); 3391 SetLastError(ERROR_NEGATIVE_SEEK); 3769 kHlpAssertMsgFailed(("%#llx\n", offMyMove)); 3770 SetLastError(ERROR_SEEK); 3392 3771 return INVALID_SET_FILE_POINTER; 3393 3772 } 3394 if (poffNew)3395 poffNew->QuadPart = offMyMove;3396 KWFS_LOG(("SetFilePointerEx(%p) -> TRUE, %#llx [cached]\n", hFile, offMyMove));3397 return TRUE;3398 3773 } 3399 default: 3400 kHlpAssertFailed(); 3774 pHandle->offFile = (KU32)offMyMove; 3401 3775 } 3776 else 3777 { 3778 KWFS_LOG(("SetFilePointerEx(%p) - negative seek! [cached]\n", hFile)); 3779 SetLastError(ERROR_NEGATIVE_SEEK); 3780 return INVALID_SET_FILE_POINTER; 3781 } 3782 if (poffNew) 3783 poffNew->QuadPart = offMyMove; 3784 KWFS_LOG(("SetFilePointerEx(%p) -> TRUE, %#llx [cached]\n", hFile, offMyMove)); 3785 return TRUE; 3402 3786 } 3403 3787 } … … 3422 3806 { 3423 3807 PKWFSOBJ pFsObj = pHandle->u.pFsObj; 3424 K SIZEcbActually = pFsObj->cbCached - pHandle->offFile;3808 KU32 cbActually = pFsObj->cbCached - pHandle->offFile; 3425 3809 if (cbActually > cbToRead) 3426 3810 cbActually = cbToRead; 3427 3811 3428 3812 kHlpMemCopy(pvBuffer, &pFsObj->pbCached[pHandle->offFile], cbActually); 3429 pHandle->offFile += (KU32)cbActually;3813 pHandle->offFile += cbActually; 3430 3814 3431 3815 kHlpAssert(!pOverlapped); kHlpAssert(pcbActuallyRead); 3432 *pcbActuallyRead = (KU32)cbActually;3433 3434 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [cached]\n", hFile, cbToRead, (KU32)cbActually));3816 *pcbActuallyRead = cbActually; 3817 3818 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [cached]\n", hFile, cbToRead, cbActually)); 3435 3819 return TRUE; 3436 3820 } 3821 3822 #ifdef WITH_TEMP_MEMORY_FILES 3823 case KWHANDLETYPE_TEMP_FILE: 3824 { 3825 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 3826 KU32 cbActually; 3827 if (pHandle->offFile < pTempFile->cbFile) 3828 { 3829 cbActually = pTempFile->cbFile - pHandle->offFile; 3830 if (cbActually > cbToRead) 3831 cbActually = cbToRead; 3832 3833 /* Copy the data. */ 3834 if (cbActually > 0) 3835 { 3836 KU32 cbLeft; 3837 KU32 offSeg; 3838 KWFSTEMPFILESEG const *paSegs = pTempFile->paSegs; 3839 3840 /* Locate the segment containing the byte at offFile. */ 3841 KU32 iSeg = pTempFile->cSegs - 1; 3842 kHlpAssert(pTempFile->cSegs > 0); 3843 while (paSegs[iSeg].offData > pHandle->offFile) 3844 iSeg--; 3845 3846 /* Copy out the data. */ 3847 cbLeft = cbActually; 3848 offSeg = (pHandle->offFile - paSegs[iSeg].offData); 3849 for (;;) 3850 { 3851 KU32 cbAvail = paSegs[iSeg].cbDataAlloc - offSeg; 3852 if (cbAvail >= cbLeft) 3853 { 3854 kHlpMemCopy(pvBuffer, &paSegs[iSeg].pbData[offSeg], cbLeft); 3855 break; 3856 } 3857 3858 pvBuffer = kHlpMemPCopy(pvBuffer, &paSegs[iSeg].pbData[offSeg], cbAvail); 3859 cbLeft -= cbAvail; 3860 offSeg = 0; 3861 iSeg++; 3862 kHlpAssert(iSeg < pTempFile->cSegs); 3863 } 3864 3865 /* Update the file offset. */ 3866 pHandle->offFile += cbActually; 3867 } 3868 } 3869 /* Read does not commit file space, so return zero bytes. */ 3870 else 3871 cbActually = 0; 3872 3873 kHlpAssert(!pOverlapped); kHlpAssert(pcbActuallyRead); 3874 *pcbActuallyRead = cbActually; 3875 3876 KWFS_LOG(("ReadFile(%p,,%#x) -> TRUE, %#x bytes [temp]\n", hFile, cbToRead, (KU32)cbActually)); 3877 return TRUE; 3878 } 3879 3880 case KWHANDLETYPE_TEMP_FILE_MAPPING: 3881 #endif /* WITH_TEMP_MEMORY_FILES */ 3437 3882 default: 3438 3883 kHlpAssertFailed(); 3884 SetLastError(ERROR_INVALID_FUNCTION); 3885 *pcbActuallyRead = 0; 3886 return FALSE; 3439 3887 } 3440 3888 } … … 3464 3912 } 3465 3913 3914 #ifdef WITH_TEMP_MEMORY_FILES 3915 3916 static KBOOL kwFsTempFileEnsureSpace(PKWFSTEMPFILE pTempFile, KU32 offFile, KU32 cbNeeded) 3917 { 3918 KU32 cbMinFile = offFile + cbNeeded; 3919 if (cbMinFile >= offFile) 3920 { 3921 /* Calc how much space we've already allocated and */ 3922 if (cbMinFile <= pTempFile->cbFileAllocated) 3923 return K_TRUE; 3924 3925 /* Grow the file. */ 3926 if (cbMinFile <= KWFS_TEMP_FILE_MAX) 3927 { 3928 int rc; 3929 KU32 cSegs = pTempFile->cSegs; 3930 KU32 cbNewSeg = cbMinFile > 4*1024*1024 ? 256*1024 : 4*1024*1024; 3931 do 3932 { 3933 /* grow the segment array? */ 3934 if ((cSegs % 16) == 0) 3935 { 3936 void *pvNew = kHlpRealloc(pTempFile->paSegs, (cSegs + 16) * sizeof(pTempFile->paSegs[0])); 3937 if (!pvNew) 3938 return K_FALSE; 3939 pTempFile->paSegs = (PKWFSTEMPFILESEG)pvNew; 3940 } 3941 3942 /* Use page alloc here to simplify mapping later. */ 3943 rc = kHlpPageAlloc((void **)&pTempFile->paSegs[cSegs].pbData, cbNewSeg, KPROT_READWRITE, K_FALSE); 3944 if (rc == 0) 3945 { /* likely */ } 3946 else 3947 { 3948 cbNewSeg = 64*1024*1024; 3949 rc = kHlpPageAlloc((void **)&pTempFile->paSegs[cSegs].pbData, cbNewSeg, KPROT_READWRITE, K_FALSE); 3950 if (rc != 0) 3951 return K_FALSE; 3952 } 3953 pTempFile->paSegs[cSegs].offData = pTempFile->cbFileAllocated; 3954 pTempFile->paSegs[cSegs].cbDataAlloc = cbNewSeg; 3955 pTempFile->cbFileAllocated += cbNewSeg; 3956 pTempFile->cSegs = ++cSegs; 3957 3958 } while (pTempFile->cbFileAllocated < cbMinFile); 3959 3960 return K_TRUE; 3961 } 3962 } 3963 3964 kHlpAssertMsgFailed(("Out of bounds offFile=%#x + cbNeeded=%#x = %#x\n", offFile, cbNeeded, offFile + cbNeeded)); 3965 return K_FALSE; 3966 } 3967 3968 3969 /** Kernel32 - WriteFile */ 3970 static BOOL WINAPI kwSandbox_Kernel32_WriteFile(HANDLE hFile, LPCVOID pvBuffer, DWORD cbToWrite, LPDWORD pcbActuallyWritten, 3971 LPOVERLAPPED pOverlapped) 3972 { 3973 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 3974 if (idxHandle < g_Sandbox.cHandles) 3975 { 3976 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 3977 if (pHandle != NULL) 3978 { 3979 switch (pHandle->enmType) 3980 { 3981 case KWHANDLETYPE_TEMP_FILE: 3982 { 3983 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 3984 3985 kHlpAssert(!pOverlapped); 3986 kHlpAssert(pcbActuallyWritten); 3987 3988 if (kwFsTempFileEnsureSpace(pTempFile, pHandle->offFile, cbToWrite)) 3989 { 3990 KU32 cbLeft; 3991 KU32 offSeg; 3992 3993 /* Locate the segment containing the byte at offFile. */ 3994 KWFSTEMPFILESEG const *paSegs = pTempFile->paSegs; 3995 KU32 iSeg = pTempFile->cSegs - 1; 3996 kHlpAssert(pTempFile->cSegs > 0); 3997 while (paSegs[iSeg].offData > pHandle->offFile) 3998 iSeg--; 3999 4000 /* Copy in the data. */ 4001 cbLeft = cbToWrite; 4002 offSeg = (pHandle->offFile - paSegs[iSeg].offData); 4003 for (;;) 4004 { 4005 KU32 cbAvail = paSegs[iSeg].cbDataAlloc - offSeg; 4006 if (cbAvail >= cbLeft) 4007 { 4008 kHlpMemCopy(&paSegs[iSeg].pbData[offSeg], pvBuffer, cbLeft); 4009 break; 4010 } 4011 4012 kHlpMemCopy(&paSegs[iSeg].pbData[offSeg], pvBuffer, cbAvail); 4013 pvBuffer = (KU8 const *)pvBuffer + cbAvail; 4014 cbLeft -= cbAvail; 4015 offSeg = 0; 4016 iSeg++; 4017 kHlpAssert(iSeg < pTempFile->cSegs); 4018 } 4019 4020 /* Update the file offset. */ 4021 pHandle->offFile += cbToWrite; 4022 if (pHandle->offFile > pTempFile->cbFile) 4023 pTempFile->cbFile = pHandle->offFile; 4024 4025 *pcbActuallyWritten = cbToWrite; 4026 KWFS_LOG(("WriteFile(%p,,%#x) -> TRUE [temp]\n", hFile, cbToWrite)); 4027 return TRUE; 4028 } 4029 4030 *pcbActuallyWritten = 0; 4031 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 4032 return FALSE; 4033 } 4034 4035 case KWHANDLETYPE_FSOBJ_READ_CACHE: 4036 kHlpAssertFailed(); 4037 SetLastError(ERROR_ACCESS_DENIED); 4038 *pcbActuallyWritten = 0; 4039 return FALSE; 4040 4041 default: 4042 case KWHANDLETYPE_TEMP_FILE_MAPPING: 4043 kHlpAssertFailed(); 4044 SetLastError(ERROR_INVALID_FUNCTION); 4045 *pcbActuallyWritten = 0; 4046 return FALSE; 4047 } 4048 } 4049 } 4050 4051 KWFS_LOG(("WriteFile(%p)\n", hFile)); 4052 return WriteFile(hFile, pvBuffer, cbToWrite, pcbActuallyWritten, pOverlapped); 4053 } 4054 4055 4056 /** Kernel32 - WriteFileEx */ 4057 static BOOL WINAPI kwSandbox_Kernel32_WriteFileEx(HANDLE hFile, LPCVOID pvBuffer, DWORD cbToWrite, LPOVERLAPPED pOverlapped, 4058 LPOVERLAPPED_COMPLETION_ROUTINE pfnCompletionRoutine) 4059 { 4060 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 4061 if (idxHandle < g_Sandbox.cHandles) 4062 { 4063 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 4064 if (pHandle != NULL) 4065 { 4066 kHlpAssertFailed(); 4067 } 4068 } 4069 4070 KWFS_LOG(("WriteFileEx(%p)\n", hFile)); 4071 return WriteFileEx(hFile, pvBuffer, cbToWrite, pOverlapped, pfnCompletionRoutine); 4072 } 4073 4074 4075 /** Kernel32 - SetEndOfFile; */ 4076 static BOOL WINAPI kwSandbox_Kernel32_SetEndOfFile(HANDLE hFile) 4077 { 4078 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 4079 if (idxHandle < g_Sandbox.cHandles) 4080 { 4081 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 4082 if (pHandle != NULL) 4083 { 4084 switch (pHandle->enmType) 4085 { 4086 case KWHANDLETYPE_TEMP_FILE: 4087 { 4088 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 4089 if ( pHandle->offFile > pTempFile->cbFile 4090 && !kwFsTempFileEnsureSpace(pTempFile, pHandle->offFile, 0)) 4091 { 4092 kHlpAssertFailed(); 4093 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 4094 return FALSE; 4095 } 4096 4097 pTempFile->cbFile = pHandle->offFile; 4098 KWFS_LOG(("SetEndOfFile(%p) -> TRUE (cbFile=%#x)\n", hFile, pTempFile->cbFile)); 4099 return TRUE; 4100 } 4101 4102 case KWHANDLETYPE_FSOBJ_READ_CACHE: 4103 kHlpAssertFailed(); 4104 SetLastError(ERROR_ACCESS_DENIED); 4105 return FALSE; 4106 4107 default: 4108 case KWHANDLETYPE_TEMP_FILE_MAPPING: 4109 kHlpAssertFailed(); 4110 SetLastError(ERROR_INVALID_FUNCTION); 4111 return FALSE; 4112 } 4113 } 4114 } 4115 4116 KWFS_LOG(("SetEndOfFile(%p)\n", hFile)); 4117 return SetEndOfFile(hFile); 4118 } 4119 4120 4121 /** Kernel32 - GetFileType */ 4122 static BOOL WINAPI kwSandbox_Kernel32_GetFileType(HANDLE hFile) 4123 { 4124 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 4125 if (idxHandle < g_Sandbox.cHandles) 4126 { 4127 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 4128 if (pHandle != NULL) 4129 { 4130 switch (pHandle->enmType) 4131 { 4132 case KWHANDLETYPE_FSOBJ_READ_CACHE: 4133 KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [cached]\n", hFile)); 4134 return FILE_TYPE_DISK; 4135 4136 case KWHANDLETYPE_TEMP_FILE: 4137 KWFS_LOG(("GetFileType(%p) -> FILE_TYPE_DISK [temp]\n", hFile)); 4138 return FILE_TYPE_DISK; 4139 } 4140 } 4141 } 4142 4143 KWFS_LOG(("GetFileType(%p)\n", hFile)); 4144 return GetFileType(hFile); 4145 } 4146 4147 4148 /** Kernel32 - GetFileSize */ 4149 static DWORD WINAPI kwSandbox_Kernel32_GetFileSize(HANDLE hFile, LPDWORD pcbHighDword) 4150 { 4151 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 4152 if (idxHandle < g_Sandbox.cHandles) 4153 { 4154 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 4155 if (pHandle != NULL) 4156 { 4157 if (pcbHighDword) 4158 *pcbHighDword = 0; 4159 SetLastError(NO_ERROR); 4160 switch (pHandle->enmType) 4161 { 4162 case KWHANDLETYPE_FSOBJ_READ_CACHE: 4163 KWFS_LOG(("GetFileSize(%p) -> %#x [cached]\n", hFile, pHandle->u.pFsObj->cbCached)); 4164 return pHandle->u.pFsObj->cbCached; 4165 4166 case KWHANDLETYPE_TEMP_FILE: 4167 KWFS_LOG(("GetFileSize(%p) -> %#x [temp]\n", hFile, pHandle->u.pTempFile->cbFile)); 4168 return pHandle->u.pTempFile->cbFile; 4169 4170 default: 4171 kHlpAssertFailed(); 4172 SetLastError(ERROR_INVALID_FUNCTION); 4173 return INVALID_FILE_SIZE; 4174 } 4175 } 4176 } 4177 4178 KWFS_LOG(("GetFileSize(%p,)\n", hFile)); 4179 return GetFileSize(hFile, pcbHighDword); 4180 } 4181 4182 4183 /** Kernel32 - GetFileSizeEx */ 4184 static BOOL WINAPI kwSandbox_Kernel32_GetFileSizeEx(HANDLE hFile, PLARGE_INTEGER pcbFile) 4185 { 4186 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 4187 if (idxHandle < g_Sandbox.cHandles) 4188 { 4189 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 4190 if (pHandle != NULL) 4191 { 4192 switch (pHandle->enmType) 4193 { 4194 case KWHANDLETYPE_FSOBJ_READ_CACHE: 4195 KWFS_LOG(("GetFileSizeEx(%p) -> TRUE, %#x [cached]\n", hFile, pHandle->u.pFsObj->cbCached)); 4196 pcbFile->QuadPart = pHandle->u.pFsObj->cbCached; 4197 return TRUE; 4198 4199 case KWHANDLETYPE_TEMP_FILE: 4200 KWFS_LOG(("GetFileSizeEx(%p) -> TRUE, %#x [temp]\n", hFile, pHandle->u.pTempFile->cbFile)); 4201 pcbFile->QuadPart = pHandle->u.pTempFile->cbFile; 4202 return TRUE; 4203 4204 default: 4205 kHlpAssertFailed(); 4206 SetLastError(ERROR_INVALID_FUNCTION); 4207 return INVALID_FILE_SIZE; 4208 } 4209 } 4210 } 4211 4212 KWFS_LOG(("GetFileSizeEx(%p,)\n", hFile)); 4213 return GetFileSizeEx(hFile, pcbFile); 4214 } 4215 4216 4217 /** Kernel32 - CreateFileMapping */ 4218 static HANDLE WINAPI kwSandbox_Kernel32_CreateFileMappingW(HANDLE hFile, LPSECURITY_ATTRIBUTES pSecAttrs, 4219 DWORD fProtect, DWORD dwMaximumSizeHigh, 4220 DWORD dwMaximumSizeLow, LPCWSTR pwszName) 4221 { 4222 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hFile); 4223 if (idxHandle < g_Sandbox.cHandles) 4224 { 4225 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 4226 if (pHandle != NULL) 4227 { 4228 switch (pHandle->enmType) 4229 { 4230 case KWHANDLETYPE_TEMP_FILE: 4231 { 4232 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 4233 if ( ( fProtect == PAGE_READONLY 4234 || fProtect == PAGE_EXECUTE_READ) 4235 && dwMaximumSizeHigh == 0 4236 && ( dwMaximumSizeLow == 0 4237 || dwMaximumSizeLow == pTempFile->cbFile) 4238 && pwszName == NULL) 4239 { 4240 HANDLE hMapping = kwFsTempFileCreateHandle(pHandle->u.pTempFile, GENERIC_READ, K_TRUE /*fMapping*/); 4241 KWFS_LOG(("CreateFileMappingW(%p, %u) -> %p [temp]\n", hFile, fProtect, hMapping)); 4242 return hMapping; 4243 } 4244 kHlpAssertMsgFailed(("fProtect=%#x cb=%#x'%08x name=%p\n", 4245 fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName)); 4246 SetLastError(ERROR_ACCESS_DENIED); 4247 return INVALID_HANDLE_VALUE; 4248 } 4249 } 4250 } 4251 } 4252 4253 KWFS_LOG(("CreateFileMappingW(%p)\n", hFile)); 4254 return CreateFileMappingW(hFile, pSecAttrs, fProtect, dwMaximumSizeHigh, dwMaximumSizeLow, pwszName); 4255 } 4256 4257 /** Kernel32 - MapViewOfFile */ 4258 static HANDLE WINAPI kwSandbox_Kernel32_MapViewOfFile(HANDLE hSection, DWORD dwDesiredAccess, 4259 DWORD offFileHigh, DWORD offFileLow, SIZE_T cbToMap) 4260 { 4261 KUPTR const idxHandle = KW_HANDLE_TO_INDEX(hSection); 4262 if (idxHandle < g_Sandbox.cHandles) 4263 { 4264 PKWHANDLE pHandle = g_Sandbox.papHandles[idxHandle]; 4265 if (pHandle != NULL) 4266 { 4267 switch (pHandle->enmType) 4268 { 4269 case KWHANDLETYPE_FSOBJ_READ_CACHE: 4270 case KWHANDLETYPE_TEMP_FILE: 4271 kHlpAssertFailed(); 4272 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 4273 return NULL; 4274 4275 case KWHANDLETYPE_TEMP_FILE_MAPPING: 4276 { 4277 PKWFSTEMPFILE pTempFile = pHandle->u.pTempFile; 4278 if ( dwDesiredAccess == FILE_MAP_READ 4279 && offFileHigh == 0 4280 && offFileLow == 0 4281 && (cbToMap == 0 || cbToMap == pTempFile->cbFile) ) 4282 { 4283 kHlpAssert(pTempFile->cMappings == 0 || pTempFile->cSegs == 1); 4284 if (pTempFile->cSegs != 1) 4285 { 4286 KU32 iSeg; 4287 KU32 cbLeft; 4288 KU32 cbAll = pTempFile->cbFile ? (KU32)K_ALIGN_Z(pTempFile->cbFile, 0x2000) : 0x1000; 4289 KU8 *pbAll = NULL; 4290 int rc = kHlpPageAlloc((void **)&pbAll, cbAll, KPROT_READWRITE, K_FALSE); 4291 if (rc != 0) 4292 { 4293 kHlpAssertFailed(); 4294 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 4295 return NULL; 4296 } 4297 4298 cbLeft = pTempFile->cbFile; 4299 for (iSeg = 0; iSeg < pTempFile->cSegs && cbLeft > 0; iSeg++) 4300 { 4301 KU32 cbToCopy = K_MIN(cbLeft, pTempFile->paSegs[iSeg].cbDataAlloc); 4302 kHlpMemCopy(&pbAll[pTempFile->paSegs[iSeg].offData], pTempFile->paSegs[iSeg].pbData, cbToCopy); 4303 cbLeft -= cbToCopy; 4304 } 4305 4306 for (iSeg = 0; iSeg < pTempFile->cSegs; iSeg++) 4307 { 4308 kHlpPageFree(pTempFile->paSegs[iSeg].pbData, pTempFile->paSegs[iSeg].cbDataAlloc); 4309 pTempFile->paSegs[iSeg].pbData = NULL; 4310 pTempFile->paSegs[iSeg].cbDataAlloc = 0; 4311 } 4312 4313 pTempFile->cSegs = 1; 4314 pTempFile->cbFileAllocated = cbAll; 4315 pTempFile->paSegs[0].cbDataAlloc = cbAll; 4316 pTempFile->paSegs[0].pbData = pbAll; 4317 pTempFile->paSegs[0].offData = 0; 4318 } 4319 4320 pTempFile->cMappings++; 4321 kHlpAssert(pTempFile->cMappings == 1); 4322 4323 KWFS_LOG(("CreateFileMappingW(%p) -> %p [temp]\n", hSection, pTempFile->paSegs[0].pbData)); 4324 return pTempFile->paSegs[0].pbData; 4325 } 4326 4327 kHlpAssertMsgFailed(("dwDesiredAccess=%#x offFile=%#x'%08x cbToMap=%#x (cbFile=%#x)\n", 4328 dwDesiredAccess, offFileHigh, offFileLow, cbToMap, pTempFile->cbFile)); 4329 SetLastError(ERROR_NOT_ENOUGH_MEMORY); 4330 return NULL; 4331 } 4332 } 4333 } 4334 } 4335 4336 KWFS_LOG(("MapViewOfFile(%p)\n", hSection)); 4337 return MapViewOfFile(hSection, dwDesiredAccess, offFileHigh, offFileLow, cbToMap); 4338 } 4339 /** @todo MapViewOfFileEx */ 4340 4341 4342 /** Kernel32 - UnmapViewOfFile */ 4343 static BOOL WINAPI kwSandbox_Kernel32_UnmapViewOfFile(LPCVOID pvBase) 4344 { 4345 /* Is this one of our temporary mappings? */ 4346 PKWFSTEMPFILE pCur = g_Sandbox.pTempFileHead; 4347 while (pCur) 4348 { 4349 if ( pCur->cMappings > 0 4350 && pCur->paSegs[0].pbData == (KU8 *)pvBase) 4351 { 4352 pCur->cMappings--; 4353 KWFS_LOG(("UnmapViewOfFile(%p) -> TRUE [temp]\n", pvBase)); 4354 return TRUE; 4355 } 4356 pCur = pCur->pNext; 4357 } 4358 4359 KWFS_LOG(("UnmapViewOfFile(%p)\n", pvBase)); 4360 return UnmapViewOfFile(pvBase); 4361 } 4362 4363 /** @todo UnmapViewOfFileEx */ 4364 4365 4366 #endif /* WITH_TEMP_MEMORY_FILES */ 3466 4367 3467 4368 /** Kernel32 - CloseHandle */ … … 3479 4380 g_Sandbox.papHandles[idxHandle] = NULL; 3480 4381 g_Sandbox.cActiveHandles--; 4382 #ifdef WITH_TEMP_MEMORY_FILES 4383 if (pHandle->enmType == KWHANDLETYPE_TEMP_FILE) 4384 { 4385 kHlpAssert(pHandle->u.pTempFile->cActiveHandles > 0); 4386 pHandle->u.pTempFile->cActiveHandles--; 4387 } 4388 #endif 3481 4389 kHlpFree(pHandle); 3482 4390 KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle]\n", hObject)); … … 3601 4509 { TUPLE("ReadFile"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFile }, 3602 4510 { TUPLE("ReadFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFileEx }, 4511 #ifdef WITH_TEMP_MEMORY_FILES 4512 { TUPLE("WriteFile"), NULL, (KUPTR)kwSandbox_Kernel32_WriteFile }, 4513 { TUPLE("WriteFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_WriteFileEx }, 4514 { TUPLE("SetEndOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_SetEndOfFile }, 4515 { TUPLE("GetFileType"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileType }, 4516 { TUPLE("GetFileSize"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileSize }, 4517 { TUPLE("GetFileSizeEx"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileSizeEx }, 4518 { TUPLE("CreateFileMappingW"), NULL, (KUPTR)kwSandbox_Kernel32_CreateFileMappingW }, 4519 { TUPLE("MapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_MapViewOfFile }, 4520 { TUPLE("UnmapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_UnmapViewOfFile }, 4521 #endif 3603 4522 { TUPLE("SetFilePointer"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointer }, 3604 4523 { TUPLE("SetFilePointerEx"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointerEx }, … … 3681 4600 { TUPLE("ReadFile"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFile }, 3682 4601 { TUPLE("ReadFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_ReadFileEx }, 4602 #ifdef WITH_TEMP_MEMORY_FILES 4603 { TUPLE("WriteFile"), NULL, (KUPTR)kwSandbox_Kernel32_WriteFile }, 4604 { TUPLE("WriteFileEx"), NULL, (KUPTR)kwSandbox_Kernel32_WriteFileEx }, 4605 { TUPLE("SetEndOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_SetEndOfFile }, 4606 { TUPLE("GetFileType"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileType }, 4607 { TUPLE("GetFileSize"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileSize }, 4608 { TUPLE("GetFileSizeEx"), NULL, (KUPTR)kwSandbox_Kernel32_GetFileSizeEx }, 4609 { TUPLE("CreateFileMappingW"), NULL, (KUPTR)kwSandbox_Kernel32_CreateFileMappingW }, 4610 { TUPLE("MapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_MapViewOfFile }, 4611 { TUPLE("UnmapViewOfFile"), NULL, (KUPTR)kwSandbox_Kernel32_UnmapViewOfFile }, 4612 #endif 3683 4613 { TUPLE("SetFilePointer"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointer }, 3684 4614 { TUPLE("SetFilePointerEx"), NULL, (KUPTR)kwSandbox_Kernel32_SetFilePointerEx }, … … 3852 4782 static void kwSandboxCleanup(PKWSANDBOX pSandbox) 3853 4783 { 4784 #ifdef WITH_TEMP_MEMORY_FILES 4785 PKWFSTEMPFILE pTempFile; 4786 #endif 3854 4787 PPEB pPeb = kwSandboxGetProcessEnvironmentBlock(); 3855 4788 pPeb->ProcessParameters->CommandLine = pSandbox->SavedCommandLine; 3856 4789 /** @todo lots more to do here! */ 4790 4791 #ifdef WITH_TEMP_MEMORY_FILES 4792 pTempFile = pSandbox->pTempFileHead; 4793 pSandbox->pTempFileHead = NULL; 4794 while (pTempFile) 4795 { 4796 PKWFSTEMPFILE pNext = pTempFile->pNext; 4797 KU32 iSeg = pTempFile->cSegs; 4798 while (iSeg-- > 0) 4799 kHlpPageFree(pTempFile->paSegs[iSeg].pbData, pTempFile->paSegs[iSeg].cbDataAlloc); 4800 kHlpFree(pTempFile->paSegs); 4801 pTempFile->pNext = NULL; 4802 kHlpFree(pTempFile); 4803 4804 pTempFile = pNext; 4805 } 4806 #endif 4807 3857 4808 } 3858 4809 … … 3914 4865 } 3915 4866 } 4867 4868 kwSandboxCleanup(&g_Sandbox); 3916 4869 } 3917 4870 … … 3968 4921 K_NOREF(i); 3969 4922 #else 3970 // run 4: 32.67/1024 = 0x0 (0.031904296875) 3971 // run 3: 32.77/1024 = 0x0 (0.032001953125) 3972 // run 2: 34/1024 = 0x0 (0.033203125) 3973 // run 1: 37/1024 = 0x0 (0.0361328125) 3974 // kmk 1: 44/1024 = 0x0 (0.04296875) 3975 // cmd 1: 48/1024 = 0x0 (0.046875) 4923 // Skylake (W10/amd64, only stdandard MS defender): 4924 // run 4: 32.67/1024 = 0x0 (0.031904296875) 4925 // run 3: 32.77/1024 = 0x0 (0.032001953125) 4926 // run 2: 34/1024 = 0x0 (0.033203125) 4927 // run 1: 37/1024 = 0x0 (0.0361328125) 4928 // kmk 1: 44/1024 = 0x0 (0.04296875) 4929 // cmd 1: 48/1024 = 0x0 (0.046875) 4930 // Dell (W7/amd64, infected by mcafee): 4931 // kmk 1: 285.278/1024 = 0x0 (0.278591796875) 4932 // run 1: 134.503/1024 = 0x0 (0.1313505859375) [w/o temp files in memory] 4933 // run 2: 78.161/1024 = 0x0 (0.0763291015625) [with temp files in memory] 3976 4934 g_cVerbose = 0; 3977 4935 for (i = 0; i < 1024 && rc == 0; i++)
Note:
See TracChangeset
for help on using the changeset viewer.