Changeset 2836


Ignore:
Timestamp:
Aug 23, 2016, 6:27:34 PM (9 years ago)
Author:
bird
Message:

kWorker: More hacking to prevent the temporary _CL_xxxxxxyy files from C1.dll from hitting the disk. Storing them in memory.

Location:
trunk/src/kWorker
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kWorker/Makefile.kmk

    r2833 r2836  
    4141        $(LIB_KDEP) \
    4242        $(LIB_KUTIL)
    43 include $(KBUILD_PATH)/sdks/WINDDK.kmk
     43include $(KBUILD_PATH)/sdks/WINDDK71.kmk
    4444kWorker_LIBS.win = \
    4545        $(TEMPLATE_BIN_LIBS) \
    46         $(PATH_SDK_WINDDK_LIB_WNET)/ntdll.lib
     46        $(PATH_SDK_WINDDK71_LIB_WNET)/ntdll.lib
    4747kWorker_LDFLAGS.win = \
    4848        /BASE:0x10000 /DYNAMICBASE:NO /FIXED /SECTION:DefLdBuf,EWR
  • trunk/src/kWorker/kWorker.c

    r2835 r2836  
    3737#include <intrin.h>
    3838#include <setjmp.h>
     39#include <ctype.h>
    3940
    4041#include <nt/ntstat.h>
     
    8081/** Maximum handle value we can deal with.   */
    8182#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
    8294
    8395
     
    209221    HANDLE              hCached;
    210222    /** The file size. */
    211     KSIZE               cbCached;
     223    KU32                cbCached;
    212224    /** Cached file content. */
    213225    KU8                *pbCached;
     
    283295
    284296
     297typedef struct KWFSTEMPFILESEG *PKWFSTEMPFILESEG;
     298typedef 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
     308typedef struct KWFSTEMPFILE *PKWFSTEMPFILE;
     309typedef 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
    285332/** Handle type.   */
    286333typedef enum KWHANDLETYPE
    287334{
    288335    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
    291339    //KWHANDLETYPE_CONSOLE_CACHE
    292340} KWHANDLETYPE;
     
    298346    /** The current file offset. */
    299347    KU32                offFile;
     348    /** Handle access. */
     349    KU32                dwDesiredAccess;
    300350    /** The handle. */
    301351    HANDLE              hHandle;
     
    306356        /** The file system object.   */
    307357        PKWFSOBJ            pFsObj;
     358        /** Temporary file handle or mapping handle. */
     359        PKWFSTEMPFILE       pTempFile;
    308360    } u;
    309361} KWHANDLE;
     
    319371    KWTOOLTYPE_END
    320372} KWTOOLTYPE;
     373
     374typedef enum KWTOOLHINT
     375{
     376    KWTOOLHINT_INVALID = 0,
     377    KWTOOLHINT_NONE,
     378    KWTOOLHINT_VISUAL_CPP_CL,
     379    KWTOOLHINT_END
     380} KWTOOLHINT;
    321381
    322382typedef struct KWTOOL *PKWTOOL;
     
    343403             * These will be kept loaded till the tool is destroyed (if we ever do that). */
    344404            PKWDYNLOAD  pDynLoadHead;
     405            /** Tool hint (for hacks and such). */
     406            KWTOOLHINT  enmHint;
    345407        } Sandboxed;
    346408    } u;
     
    395457    /** Number of active handles in the table. */
    396458    KU32            cActiveHandles;
     459
     460    /** Head of the list of temporary file. */
     461    PKWFSTEMPFILE   pTempFileHead;
    397462
    398463    UNICODE_STRING  SavedCommandLine;
     
    906971
    907972
     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 */
     980static 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
    9081008
    9091009/**
     
    16751775        if (!pTool->u.Sandboxed.pExe)
    16761776            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;
    16771781
    16781782        /* Link the tool. */
     
    29543058 */
    29553059
     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 */
     3076static 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 */
     3115static 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
     3156static 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
    29563274/**
    29573275 * Checks if the file extension indicates that the file/dir is something we
     
    29693287    /* C++ header without an extension or a directory. */
    29703288    if (chFirst == '\0')
     3289    {
     3290        /** @todo exclude temporary files...  */
    29713291        return K_TRUE;
     3292    }
    29723293
    29733294    /* C Header: .h */
     
    30883409            if (pbCache)
    30893410            {
    3090                 if (ReadFile(hFile, pbCache, cbCache, NULL, NULL))
     3411                DWORD cbActually = 0;
     3412                if (   ReadFile(hFile, pbCache, cbCache, &cbActually, NULL)
     3413                    && cbActually == cbCache)
    30913414                {
    30923415                    LARGE_INTEGER offZero;
     
    30993422                        return K_TRUE;
    31003423                    }
    3101                     else
    3102                         KWFS_LOG(("Failed to seek to start of cached file! err=%u\n", GetLastError()));
     3424
     3425                    KWFS_LOG(("Failed to seek to start of cached file! err=%u\n", GetLastError()));
    31033426                }
    31043427                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));
    31063430                kHlpFree(pbCache);
    31073431            }
     
    31723496                if (pHandle)
    31733497                {
    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;
    31783503                    if (kwSandboxHandleTableEnter(&g_Sandbox, pHandle))
    31793504                        return K_TRUE;
     
    31963521    return K_FALSE;
    31973522}
     3523
    31983524
    31993525/** Kernel32 - CreateFileA */
     
    32523578{
    32533579    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. */
    32543595    if (dwCreationDisposition == FILE_OPEN_IF)
    32553596    {
     
    33013642        if (pHandle != NULL)
    33023643        {
     3644            KU32 cbFile;
    33033645            KI64 offMove = pcbMoveHi ? ((KI64)*pcbMoveHi << 32) | cbMove : cbMove;
    33043646            switch (pHandle->enmType)
    33053647            {
    33063648                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)
    33073681                {
    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)
    33103688                    {
    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);
    33343691                        return INVALID_SET_FILE_POINTER;
    33353692                    }
    3336                     if (pcbMoveHi)
    3337                         *pcbMoveHi = (KU64)offMove >> 32;
    3338                     KWFS_LOG(("SetFilePointer(%p) -> %#llx [cached]\n", hFile, offMove));
    3339                     return (KU32)offMove;
    33403693                }
    3341                 default:
    3342                     kHlpAssertFailed();
     3694                pHandle->offFile = (KU32)offMove;
    33433695            }
     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;
    33443707        }
    33453708    }
     
    33603723        {
    33613724            KI64 offMyMove = offMove.QuadPart;
     3725            KU32 cbFile;
    33623726            switch (pHandle->enmType)
    33633727            {
    33643728                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)
    33653761                {
    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)
    33683768                    {
    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);
    33923771                        return INVALID_SET_FILE_POINTER;
    33933772                    }
    3394                     if (poffNew)
    3395                         poffNew->QuadPart = offMyMove;
    3396                     KWFS_LOG(("SetFilePointerEx(%p) -> TRUE, %#llx [cached]\n", hFile, offMyMove));
    3397                     return TRUE;
    33983773                }
    3399                 default:
    3400                     kHlpAssertFailed();
     3774                pHandle->offFile = (KU32)offMyMove;
    34013775            }
     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;
    34023786        }
    34033787    }
     
    34223806                {
    34233807                    PKWFSOBJ    pFsObj     = pHandle->u.pFsObj;
    3424                     KSIZE       cbActually = pFsObj->cbCached - pHandle->offFile;
     3808                    KU32        cbActually = pFsObj->cbCached - pHandle->offFile;
    34253809                    if (cbActually > cbToRead)
    34263810                        cbActually = cbToRead;
    34273811
    34283812                    kHlpMemCopy(pvBuffer, &pFsObj->pbCached[pHandle->offFile], cbActually);
    3429                     pHandle->offFile += (KU32)cbActually;
     3813                    pHandle->offFile += cbActually;
    34303814
    34313815                    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));
    34353819                    return TRUE;
    34363820                }
     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 */
    34373882                default:
    34383883                    kHlpAssertFailed();
     3884                    SetLastError(ERROR_INVALID_FUNCTION);
     3885                    *pcbActuallyRead = 0;
     3886                    return FALSE;
    34393887            }
    34403888        }
     
    34643912}
    34653913
     3914#ifdef WITH_TEMP_MEMORY_FILES
     3915
     3916static 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 */
     3970static 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 */
     4057static 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; */
     4076static 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  */
     4122static 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  */
     4149static 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  */
     4184static 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  */
     4218static 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  */
     4258static 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  */
     4343static 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 */
    34664367
    34674368/** Kernel32 - CloseHandle */
     
    34794380            g_Sandbox.papHandles[idxHandle] = NULL;
    34804381            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
    34814389            kHlpFree(pHandle);
    34824390            KWFS_LOG(("CloseHandle(%p) -> TRUE [intercepted handle]\n", hObject));
     
    36014509    { TUPLE("ReadFile"),                    NULL,       (KUPTR)kwSandbox_Kernel32_ReadFile },
    36024510    { 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
    36034522    { TUPLE("SetFilePointer"),              NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointer },
    36044523    { TUPLE("SetFilePointerEx"),            NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointerEx },
     
    36814600    { TUPLE("ReadFile"),                    NULL,       (KUPTR)kwSandbox_Kernel32_ReadFile },
    36824601    { 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
    36834613    { TUPLE("SetFilePointer"),              NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointer },
    36844614    { TUPLE("SetFilePointerEx"),            NULL,       (KUPTR)kwSandbox_Kernel32_SetFilePointerEx },
     
    38524782static void kwSandboxCleanup(PKWSANDBOX pSandbox)
    38534783{
     4784#ifdef WITH_TEMP_MEMORY_FILES
     4785    PKWFSTEMPFILE pTempFile;
     4786#endif
    38544787    PPEB pPeb = kwSandboxGetProcessEnvironmentBlock();
    38554788    pPeb->ProcessParameters->CommandLine = pSandbox->SavedCommandLine;
    38564789    /** @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
    38574808}
    38584809
     
    39144865            }
    39154866        }
     4867
     4868        kwSandboxCleanup(&g_Sandbox);
    39164869    }
    39174870
     
    39684921    K_NOREF(i);
    39694922#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]
    39764934    g_cVerbose = 0;
    39774935    for (i = 0; i < 1024 && rc == 0; i++)
Note: See TracChangeset for help on using the changeset viewer.