예제 #1
0
/*++
Function:
  InternalResumeThread

InternalResumeThread converts the handle of the target thread to a 
CPalThread, and passes both the resumer and target thread references
to InternalResumeThreadFromData. A reference to the suspend count from
the resumption attempt is passed back to the caller of this function.
--*/
PAL_ERROR
CorUnix::InternalResumeThread(
    CPalThread *pthrResumer,
    HANDLE hTargetThread,
    DWORD *pdwSuspendCount
    )
{
    PAL_ERROR palError = NO_ERROR;
    CPalThread *pthrTarget = NULL;
    IPalObject *pobjThread = NULL;

    palError = InternalGetThreadDataFromHandle(
        pthrResumer,
        hTargetThread,
        0, // THREAD_SUSPEND_RESUME
        &pthrTarget,
        &pobjThread
        );

    if (NO_ERROR == palError)
    {
        palError = pthrResumer->suspensionInfo.InternalResumeThreadFromData(
            pthrResumer,
            pthrTarget,
            pdwSuspendCount
            );
    }

    if (NULL != pobjThread)
    {
        pobjThread->ReleaseReference(pthrResumer);
    }

    return palError;
}
예제 #2
0
/*++
Function:
  GetThreadContext

See MSDN doc.
--*/
BOOL
PALAPI
GetThreadContext(
           IN HANDLE hThread,
           IN OUT LPCONTEXT lpContext)
{
    PAL_ERROR palError;
    CPalThread *pThread;
    CPalThread *pTargetThread;
    IPalObject *pobjThread = NULL;
    BOOL ret = FALSE;
    
    PERF_ENTRY(GetThreadContext);
    ENTRY("GetThreadContext (hThread=%p, lpContext=%p)\n",hThread,lpContext);

    pThread = InternalGetCurrentThread();

    palError = InternalGetThreadDataFromHandle(
        pThread,
        hThread,
        0, // THREAD_GET_CONTEXT
        &pTargetThread,
        &pobjThread
        );

    if (NO_ERROR == palError)
    {
        if (!pTargetThread->IsDummy())
        {
            ret = CONTEXT_GetThreadContext(
                GetCurrentProcessId(),
                pTargetThread->GetPThreadSelf(),
                lpContext
                );
        }
        else
        {
            ASSERT("Dummy thread handle passed to GetThreadContext\n");
            pThread->SetLastError(ERROR_INVALID_HANDLE);
        }
    }
    else
    {
        pThread->SetLastError(palError);
    }

    if (NULL != pobjThread)
    {
        pobjThread->ReleaseReference(pThread);
    }
    
    LOGEXIT("GetThreadContext returns ret:%d\n", ret);
    PERF_EXIT(GetThreadContext);
    return ret;
}
예제 #3
0
파일: wait.cpp 프로젝트: ROOTU/coreclr
/*++
Function:
  QueueUserAPC

See MSDN doc.
--*/
DWORD
PALAPI
QueueUserAPC(
    PAPCFUNC pfnAPC,
    HANDLE hThread,
    ULONG_PTR dwData)
{    
    CPalThread * pCurrentThread = NULL;
    CPalThread * pTargetThread = NULL;
    IPalObject * pTargetThreadObject = NULL;
    PAL_ERROR palErr;
    DWORD dwRet;

    PERF_ENTRY(QueueUserAPC);
    ENTRY("QueueUserAPC(pfnAPC=%p, hThread=%p, dwData=%#x)\n", 
          pfnAPC, hThread, dwData);
    
    /* NOTE: Windows does not check the validity of pfnAPC, even if it is 
       NULL.  It just does an access violation later on when the APC call 
       is attempted */                 

    pCurrentThread = InternalGetCurrentThread();

    palErr = InternalGetThreadDataFromHandle(
        pCurrentThread,
        hThread,
        0, // THREAD_SET_CONTEXT
        &pTargetThread,
        &pTargetThreadObject
        );

    if (NO_ERROR != palErr)
    {
        ERROR("Unable to obtain thread data for handle %p (error %x)!\n", 
                hThread, palErr);
        goto QueueUserAPC_exit;
    }
    

    palErr = g_pSynchronizationManager->QueueUserAPC(pCurrentThread, pTargetThread, 
                                                     pfnAPC, dwData);  

QueueUserAPC_exit:
    if (pTargetThreadObject)
    {
        pTargetThreadObject->ReleaseReference(pCurrentThread);
    }

    dwRet = (NO_ERROR == palErr) ? 1 : 0;
    
    LOGEXIT("QueueUserAPC returns DWORD %d\n", dwRet);
    PERF_EXIT(QueueUserAPC);
    return dwRet;
}
예제 #4
0
PAL_ERROR
CSimpleHandleManager::FreeHandle(
    CPalThread *pThread,
    HANDLE h
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobj = NULL;
    HANDLE_INDEX hi = HandleToHandleIndex(h);

    Lock(pThread);

    if (!ValidateHandle(h))
    {
        ERROR("Trying to free invalid handle %p.\n", h);
        palError = ERROR_INVALID_HANDLE;
        goto FreeHandleExit;
    }

    if (HandleIsSpecial(h))
    {
        ASSERT("Trying to free Special Handle %p.\n", h);
        palError = ERROR_INVALID_HANDLE;
        goto FreeHandleExit;
    }

    pobj = m_rghteHandleTable[hi].u.pObject;
    m_rghteHandleTable[hi].fEntryAllocated = FALSE;

    /* add handle to the free pool */
    if(m_hiFreeListEnd != c_hiInvalid)
    {
        m_rghteHandleTable[m_hiFreeListEnd].u.hiNextIndex = hi;
    }
    else
    {
        m_hiFreeListStart = hi;
    }
    
    m_rghteHandleTable[hi].u.hiNextIndex = c_hiInvalid;
    m_hiFreeListEnd = hi;

FreeHandleExit:    

    Unlock(pThread);

    if (NULL != pobj)
    {
        pobj->ReleaseReference(pThread);
    }

    return palError;
}
예제 #5
0
PAL_ERROR
CorUnix::InternalOpenSemaphore(
    CPalThread *pthr,
    DWORD dwDesiredAccess,
    BOOL bInheritHandle,
    LPCWSTR lpName,
    HANDLE *phSemaphore
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjSemaphore = NULL;
    CPalString sObjectName(lpName);

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != lpName);
    _ASSERTE(NULL != phSemaphore);

    ENTRY("InternalOpenSemaphore(pthr=%p, dwDesiredAccess=%d, bInheritHandle=%d, "
        "lpName=%p, phSemaphore=%p)\n",
        pthr,
        dwDesiredAccess,
        bInheritHandle,
        phSemaphore
        );

    palError = g_pObjectManager->LocateObject(
        pthr,
        &sObjectName,
        &aotSempahore,
        &pobjSemaphore
        );

    if (NO_ERROR != palError)
    {
        goto InternalOpenSemaphoreExit;
    }

    palError = g_pObjectManager->ObtainHandleForObject(
        pthr,
        pobjSemaphore,
        dwDesiredAccess,
        bInheritHandle,
        NULL,
        phSemaphore
        );

    if (NO_ERROR != palError)
    {
        goto InternalOpenSemaphoreExit;
    }

InternalOpenSemaphoreExit:

    if (NULL != pobjSemaphore)
    {
        pobjSemaphore->ReleaseReference(pthr);
    }

    LOGEXIT("InternalOpenSemaphore returns %d\n", palError);
    
    return palError;
}
예제 #6
0
PAL_ERROR
CorUnix::InternalReleaseSemaphore(
    CPalThread *pthr,
    HANDLE hSemaphore,
    LONG lReleaseCount,
    LPLONG lpPreviousCount
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjSemaphore = NULL;
    ISynchStateController *pssc = NULL;
    SemaphoreImmutableData *pSemaphoreData;
    LONG lOldCount;

    _ASSERTE(NULL != pthr);

    ENTRY("InternalReleaseSempahore(pthr=%p, hSemaphore=%p, lReleaseCount=%d, "
        "lpPreviousCount=%p)\n",
        pthr,
        hSemaphore,
        lReleaseCount,
        lpPreviousCount
        );

    if (0 >= lReleaseCount)
    {
        palError = ERROR_INVALID_PARAMETER;
        goto InternalReleaseSemaphoreExit;
    }

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pthr,
        hSemaphore,
        &aotSempahore, 
        0, // Should be SEMAPHORE_MODIFY_STATE; currently ignored (no Win32 security)
        &pobjSemaphore
        );

    if (NO_ERROR != palError)
    {
        ERROR("Unable to obtain object for handle %p (error %d)!\n", hSemaphore, palError);
        goto InternalReleaseSemaphoreExit;
    }

    palError = pobjSemaphore->GetImmutableData(reinterpret_cast<void**>(&pSemaphoreData));
    
    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining object data\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    palError = pobjSemaphore->GetSynchStateController(
        pthr,
        &pssc
        );

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining synch state controller\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    palError = pssc->GetSignalCount(&lOldCount);

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining current signal count\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    _ASSERTE(lOldCount <= pSemaphoreData->lMaximumCount);
    if (lReleaseCount > pSemaphoreData->lMaximumCount - lOldCount)
    {
        palError = ERROR_INVALID_PARAMETER;
        goto InternalReleaseSemaphoreExit;
    }

    palError = pssc->IncrementSignalCount(lReleaseCount);
    
    if (NO_ERROR != palError)
    {
        ASSERT("Error %d incrementing signal count\n", palError);
        goto InternalReleaseSemaphoreExit;
    }

    if (NULL != lpPreviousCount)
    {
        *lpPreviousCount = lOldCount;
    }

InternalReleaseSemaphoreExit:

    if (NULL != pssc)
    {
        pssc->ReleaseController();
    }

    if (NULL != pobjSemaphore)
    {
        pobjSemaphore->ReleaseReference(pthr);
    }

    LOGEXIT("InternalReleaseSemaphore returns %d\n", palError);

    return palError;
}
예제 #7
0
PAL_ERROR
CorUnix::InternalCreateSemaphore(
    CPalThread *pthr,
    LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
    LONG lInitialCount,
    LONG lMaximumCount,
    LPCWSTR lpName,
    HANDLE *phSemaphore
    )
{
    CObjectAttributes oa(lpName, lpSemaphoreAttributes);
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjSemaphore = NULL;
    IPalObject *pobjRegisteredSemaphore = NULL;
    SemaphoreImmutableData *pSemaphoreData;

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != phSemaphore);

    ENTRY("InternalCreateSemaphore(pthr=%p, lpSemaphoreAttributes=%p, "
        "lInitialCount=%d, lMaximumCount=%d, lpName=%p, phSemaphore=%p)\n",
        pthr,
        lpSemaphoreAttributes,
        lInitialCount,
        lMaximumCount,
        lpName,
        phSemaphore
        );

    if (lpName != nullptr)
    {
        ASSERT("lpName: Cross-process named objects are not supported in PAL");
        palError = ERROR_NOT_SUPPORTED;
        goto InternalCreateSemaphoreExit;
    }

    if (lMaximumCount <= 0)
    {
        ERROR("lMaximumCount is invalid (%d)\n", lMaximumCount);
        palError = ERROR_INVALID_PARAMETER;
        goto InternalCreateSemaphoreExit;
    }

    if ((lInitialCount < 0) || (lInitialCount > lMaximumCount))
    {
        ERROR("lInitialCount is invalid (%d)\n", lInitialCount);
        palError = ERROR_INVALID_PARAMETER;
        goto InternalCreateSemaphoreExit;
    }

    palError = g_pObjectManager->AllocateObject(
        pthr,
        &otSemaphore,
        &oa,
        &pobjSemaphore
        );

    if (NO_ERROR != palError)
    {
        goto InternalCreateSemaphoreExit;
    }

    palError = pobjSemaphore->GetImmutableData(reinterpret_cast<void**>(&pSemaphoreData));

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining object data\n", palError);
        goto InternalCreateSemaphoreExit;
    }

    pSemaphoreData->lMaximumCount = lMaximumCount;

    if (0 != lInitialCount)
    {
        ISynchStateController *pssc;

        palError = pobjSemaphore->GetSynchStateController(
            pthr,
            &pssc
            );

        if (NO_ERROR == palError)
        {
            palError = pssc->SetSignalCount(lInitialCount);
            pssc->ReleaseController();
        }

        if (NO_ERROR != palError)
        {
            ASSERT("Unable to set new semaphore state (%d)\n", palError);
            goto InternalCreateSemaphoreExit;
        }
    }

    palError = g_pObjectManager->RegisterObject(
        pthr,
        pobjSemaphore,
        &aotSempahore, 
        0, // Should be SEMAPHORE_ALL_ACCESS; currently ignored (no Win32 security)
        phSemaphore,
        &pobjRegisteredSemaphore
        );

    //
    // pobjSemaphore is invalidated by the call to RegisterObject, so NULL it
    // out here to ensure that we don't try to release a reference on
    // it down the line.
    //
    
    pobjSemaphore = NULL;

InternalCreateSemaphoreExit:

    if (NULL != pobjSemaphore)
    {
        pobjSemaphore->ReleaseReference(pthr);
    }

    if (NULL != pobjRegisteredSemaphore)
    {
        pobjRegisteredSemaphore->ReleaseReference(pthr);
    }

    LOGEXIT("InternalCreateSemaphore returns %d\n", palError);

    return palError;
}
예제 #8
0
파일: debug.cpp 프로젝트: SpivEgin/coreclr
/*++
Function:
  DBGSetProcessAttached

Abstract
  saves the current process Id in the attached process structure

Parameter
  hProcess : process handle
  bAttach : true (false) to set the process as attached (as detached)
Return
 returns the number of attachment left on attachedProcId, or -1 if it fails
--*/
static int
DBGSetProcessAttached(
    CPalThread *pThread,
    HANDLE hProcess,
    BOOL  bAttach
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjProcess = NULL;
    IDataLock *pDataLock = NULL;
    CProcProcessLocalData *pLocalData = NULL;
    int ret = -1;
    CAllowedObjectTypes aotProcess(otiProcess);

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pThread,
        hProcess,
        &aotProcess,
        0,
        &pobjProcess
        );

    if (NO_ERROR != palError)
    {
        goto DBGSetProcessAttachedExit;
    }

    palError = pobjProcess->GetProcessLocalData(
        pThread,
        WriteLock,
        &pDataLock,
        reinterpret_cast<void **>(&pLocalData)
        );

    if (NO_ERROR != palError)
    {
        goto DBGSetProcessAttachedExit;
    }

    if (bAttach)
    {
        pLocalData->lAttachCount += 1;
    }
    else
    {
        pLocalData->lAttachCount -= 1;

        if (pLocalData->lAttachCount < 0)
        {
            ASSERT("pLocalData->lAttachCount < 0 check for extra DBGDetachProcess calls\n");
            palError = ERROR_INTERNAL_ERROR;
            goto DBGSetProcessAttachedExit;
        }
    }

    ret = pLocalData->lAttachCount;
    
DBGSetProcessAttachedExit:

    if (NULL != pDataLock)
    {
        pDataLock->ReleaseLock(pThread, TRUE);
    }

    if (NULL != pobjProcess)
    {
        pobjProcess->ReleaseReference(pThread);
    }
    
    return ret;
}
예제 #9
0
파일: debug.cpp 프로젝트: SpivEgin/coreclr
DWORD
PAL_DeleteExecWatchpoint(
    HANDLE hThread,
    PVOID pvInstruction
    )
{
    PERF_ENTRY(PAL_DeleteExecWatchpoint);
    ENTRY("PAL_DeleteExecWatchpoint (hThread=%p, pvInstruction=%p)\n", hThread, pvInstruction);

    DWORD dwError = ERROR_NOT_SUPPORTED;

#if HAVE_PRWATCH_T

    CPalThread *pThread = NULL;
    CPalThread *pTargetThread = NULL;
    IPalObject *pobjThread = NULL;
    int fd = -1;
    char ctlPath[50];

    struct
    {
        long ctlCode;
        prwatch_t prwatch;
    } ctlStruct;


    pThread = InternalGetCurrentThread();

    dwError = InternalGetThreadDataFromHandle(
        pThread,
        hThread,
        0, // THREAD_SET_CONTEXT
        &pTargetThread,
        &pobjThread
        );

    if (NO_ERROR != dwError)
    {
        goto PAL_DeleteExecWatchpointExit;
    }

    snprintf(ctlPath, sizeof(ctlPath), "/proc/%u/lwp/%u/lwpctl", getpid(), pTargetThread->GetLwpId());

    fd = InternalOpen(pThread, ctlPath, O_WRONLY);
    if (-1 == fd)
    {
        ERROR("Failed to open %s\n", ctlPath);
        dwError = ERROR_INVALID_ACCESS;
        goto PAL_DeleteExecWatchpointExit;
    }

    ctlStruct.ctlCode = PCWATCH;
    ctlStruct.prwatch.pr_vaddr = (uintptr_t) pvInstruction;
    ctlStruct.prwatch.pr_size = sizeof(DWORD);
    ctlStruct.prwatch.pr_wflags = 0;

    if (write(fd, (void*) &ctlStruct, sizeof(ctlStruct)) != sizeof(ctlStruct))
    {
        ERROR("Failure writing control structure (errno = %u)\n", errno);
        dwError = ERROR_INTERNAL_ERROR;
        goto PAL_DeleteExecWatchpointExit;
    }

    dwError = ERROR_SUCCESS;
    
PAL_DeleteExecWatchpointExit:

    if (NULL != pobjThread)
    {
        pobjThread->ReleaseReference(pThread);
    }

    if (-1 != fd)
    {
        close(fd);
    }

#endif // HAVE_PRWATCH_T    
    
    LOGEXIT("PAL_DeleteExecWatchpoint returns ret:%d\n", dwError);
    PERF_EXIT(PAL_DeleteExecWatchpoint);
    return dwError;
}
예제 #10
0
파일: mutex.cpp 프로젝트: SpivEgin/coreclr
PAL_ERROR
CorUnix::InternalCreateMutex(
    CPalThread *pthr,
    LPSECURITY_ATTRIBUTES lpMutexAttributes,
    BOOL bInitialOwner,
    LPCWSTR lpName,
    HANDLE *phMutex
    )
{
    CObjectAttributes oa(lpName, lpMutexAttributes);
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    IPalObject *pobjRegisteredMutex = NULL;
    ISynchStateController *pssc = NULL;

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != phMutex);

    ENTRY("InternalCreateMutex(pthr=%p, lpMutexAttributes=%p, bInitialOwner=%d"
        ", lpName=%p, phMutex=%p)\n",
        pthr,
        lpMutexAttributes,
        bInitialOwner,
        lpName,
        phMutex
        );

    if (lpName != nullptr)
    {
        ASSERT("lpName: Cross-process named objects are not supported in PAL");
        palError = ERROR_NOT_SUPPORTED;
        goto InternalCreateMutexExit;
    }

    palError = g_pObjectManager->AllocateObject(
        pthr,
        &otMutex,
        &oa,
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        goto InternalCreateMutexExit;
    }

    palError = pobjMutex->GetSynchStateController(
        pthr,
        &pssc
        );

    if (NO_ERROR != palError)
    {
        ASSERT("Unable to create state controller (%d)\n", palError);
        goto InternalCreateMutexExit;
    }

    if (bInitialOwner)
    {
        palError = pssc->SetOwner(pthr);
    }
    else
    {
        palError = pssc->SetSignalCount(1);
    }

    pssc->ReleaseController();

    if (NO_ERROR != palError)
    {
        ASSERT("Unable to set initial mutex state (%d)\n", palError);
        goto InternalCreateMutexExit;
    }

    palError = g_pObjectManager->RegisterObject(
        pthr,
        pobjMutex,
        &aotMutex, 
        0, // should be MUTEX_ALL_ACCESS -- currently ignored (no Win32 security)
        phMutex,
        &pobjRegisteredMutex
        );

    //
    // pobjMutex is invalidated by the call to RegisterObject, so NULL it
    // out here to ensure that we don't try to release a reference on
    // it down the line.
    //
    
    pobjMutex = NULL;

InternalCreateMutexExit:

    if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    if (NULL != pobjRegisteredMutex)
    {
        pobjRegisteredMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalCreateMutex returns %i\n", palError);

    return palError;
}
예제 #11
0
PAL_ERROR
CorUnix::InternalGetFileTime(
        CPalThread *pThread,
        IN HANDLE hFile,
        OUT LPFILETIME lpCreationTime,
        OUT LPFILETIME lpLastAccessTime,
        OUT LPFILETIME lpLastWriteTime)
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pFileObject = NULL;
    CFileProcessLocalData *pLocalData = NULL;
    IDataLock *pLocalDataLock = NULL;
    int   Fd = -1;

    struct stat StatData;

    if (INVALID_HANDLE_VALUE == hFile)
    {
        ERROR( "Invalid file handle\n" );
        palError = ERROR_INVALID_HANDLE;
        goto InternalGetFileTimeExit;
    }

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pThread,
        hFile,
        &aotFile,
        GENERIC_READ,
        &pFileObject
        );

    if (NO_ERROR != palError)
    {
        goto InternalGetFileTimeExit;
    }

    palError = pFileObject->GetProcessLocalData(
        pThread,
        ReadLock, 
        &pLocalDataLock,
        reinterpret_cast<void**>(&pLocalData)
        );

    if (NO_ERROR != palError)
    {
        goto InternalGetFileTimeExit;
    }

    Fd = pLocalData->unix_fd;

    if ( Fd == -1 )
    {
        TRACE("pLocalData = [%p], Fd = %d\n", pLocalData, Fd);
        palError = ERROR_INVALID_HANDLE;
        goto InternalGetFileTimeExit;
    }

    if ( fstat(Fd, &StatData) != 0 )
    {
        TRACE("fstat failed on file descriptor %d\n", Fd);
        palError = FILEGetLastErrorFromErrno();
        goto InternalGetFileTimeExit;
    }

    if ( lpCreationTime )
    {
        *lpCreationTime = FILEUnixTimeToFileTime(StatData.st_ctime,
                                                 ST_CTIME_NSEC(&StatData));
    }
    if ( lpLastWriteTime )
    {
        *lpLastWriteTime = FILEUnixTimeToFileTime(StatData.st_mtime,
                                                  ST_MTIME_NSEC(&StatData));
    }
    if ( lpLastAccessTime )
    {
        *lpLastAccessTime = FILEUnixTimeToFileTime(StatData.st_atime,
                                                   ST_ATIME_NSEC(&StatData));
        /* if Unix mtime is greater than atime, return mtime as the last
           access time */
        if ( lpLastWriteTime &&
             CompareFileTime(lpLastAccessTime, lpLastWriteTime) < 0 )
        {
            *lpLastAccessTime = *lpLastWriteTime;
        }
    }

InternalGetFileTimeExit:
    if (NULL != pLocalDataLock)
    {
        pLocalDataLock->ReleaseLock(pThread, FALSE);
    }

    if (NULL != pFileObject)
    {
        pFileObject->ReleaseReference(pThread);
    }

    return palError;
}
예제 #12
0
PAL_ERROR
CorUnix::InternalSetFileTime(
        CPalThread *pThread,
        IN HANDLE hFile,
        IN CONST FILETIME *lpCreationTime,
        IN CONST FILETIME *lpLastAccessTime,
        IN CONST FILETIME *lpLastWriteTime)
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pFileObject = NULL;
    CFileProcessLocalData *pLocalData = NULL;
    IDataLock *pLocalDataLock = NULL;
    struct timeval Times[2];
    int fd;
    long nsec;
    struct stat stat_buf;

    if (INVALID_HANDLE_VALUE == hFile)
    {
        ERROR( "Invalid file handle\n" );
        palError = ERROR_INVALID_HANDLE;
        goto InternalSetFileTimeExit;
    }

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pThread,
        hFile,
        &aotFile,
        GENERIC_READ,
        &pFileObject
        );

    if (NO_ERROR != palError)
    {
        goto InternalSetFileTimeExit;
    }

    palError = pFileObject->GetProcessLocalData(
        pThread,
        ReadLock, 
        &pLocalDataLock,
        reinterpret_cast<void**>(&pLocalData)
        );

    if (NO_ERROR != palError)
    {
        goto InternalSetFileTimeExit;
    }
    
    if (lpCreationTime)
    {
        palError = ERROR_NOT_SUPPORTED;
        goto InternalSetFileTimeExit;
    }

    if( !lpLastAccessTime && !lpLastWriteTime )
    { 
	// if both pointers are NULL, the function simply returns.
        goto InternalSetFileTimeExit;
    }
    else if( !lpLastAccessTime || !lpLastWriteTime )
    {
	// if either pointer is NULL, fstat will need to be called.
	fd = pLocalData->unix_fd;
	if ( fd == -1 )
        {
          TRACE("pLocalData = [%p], fd = %d\n", pLocalData, fd);
          palError = ERROR_INVALID_HANDLE;
          goto InternalSetFileTimeExit;
        } 

	if ( fstat(fd, &stat_buf) != 0 )
    	{
          TRACE("fstat failed on file descriptor %d\n", fd);
          palError = FILEGetLastErrorFromErrno();
          goto InternalSetFileTimeExit;
        }
    }

    if (lpLastAccessTime)
    {
        Times[0].tv_sec = FILEFileTimeToUnixTime( *lpLastAccessTime, &nsec );
        Times[0].tv_usec = nsec / 1000; /* convert to microseconds */
    }
    else
    {
	    Times[0].tv_sec = stat_buf.st_atime;
	    Times[0].tv_usec = ST_ATIME_NSEC(&stat_buf) / 1000;
    }

    if (lpLastWriteTime)
    {
        Times[1].tv_sec = FILEFileTimeToUnixTime( *lpLastWriteTime, &nsec );
        Times[1].tv_usec = nsec / 1000; /* convert to microseconds */
    }
    else
    {
        Times[1].tv_sec = stat_buf.st_mtime;
        Times[1].tv_usec = ST_MTIME_NSEC(&stat_buf) / 1000;
    }

    TRACE("Setting atime = [%ld.%ld], mtime = [%ld.%ld]\n",
          Times[0].tv_sec, Times[0].tv_usec,
          Times[1].tv_sec, Times[1].tv_usec);

#if HAVE_FUTIMES
    if ( futimes(pLocalData->unix_fd, Times) != 0 )
#elif HAVE_UTIMES
    if ( utimes(pLocalData->unix_filename, Times) != 0 )
#else
  #error Operating system not supported
#endif
    {
        palError = FILEGetLastErrorFromErrno();
    }

InternalSetFileTimeExit:
    if (NULL != pLocalDataLock)
    {
        pLocalDataLock->ReleaseLock(pThread, FALSE);
    }

    if (NULL != pFileObject)
    {
        pFileObject->ReleaseReference(pThread);
    }

    return palError;
}
예제 #13
0
파일: mutex.cpp 프로젝트: jamesqo/coreclr
PAL_ERROR
CorUnix::InternalOpenMutex(
    CPalThread *pthr,
    DWORD dwDesiredAccess,
    BOOL bInheritHandle,
    LPCSTR lpName,
    HANDLE *phMutex
    )
{
    CObjectAttributes oa;
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    IPalObject *pobjRegisteredMutex = NULL;
    HANDLE hMutex = nullptr;

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != lpName);
    _ASSERTE(NULL != phMutex);

    ENTRY("InternalOpenMutex(pthr=%p, dwDesiredAcces=%d, bInheritHandle=%d, "
        "lpName=%p, phMutex=%p)\n",
        pthr,
        dwDesiredAccess,
        bInheritHandle,
        lpName,
        phMutex
        );

    palError = g_pObjectManager->AllocateObject(
        pthr,
        &otNamedMutex,
        &oa,
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        goto InternalOpenMutexExit;
    }

    palError = g_pObjectManager->RegisterObject(
        pthr,
        pobjMutex,
        &aotNamedMutex,
        dwDesiredAccess,
        &hMutex,
        &pobjRegisteredMutex
        );

    if (palError != NO_ERROR)
    {
        _ASSERTE(palError != ERROR_ALREADY_EXISTS); // PAL's naming infrastructure is not used for named mutexes
        _ASSERTE(pobjRegisteredMutex == nullptr);
        _ASSERTE(hMutex == nullptr);
        goto InternalOpenMutexExit;
    }

    // Now that the object has been registered successfully, it would have a reference associated with the handle, so release
    // the initial reference. Any errors from now on need to revoke the handle.
    _ASSERTE(pobjRegisteredMutex == pobjMutex);
    _ASSERTE(hMutex != nullptr);
    pobjMutex->ReleaseReference(pthr);
    pobjRegisteredMutex = nullptr;

    {
        SharedMemoryProcessDataHeader *processDataHeader;
        try
        {
            processDataHeader = NamedMutexProcessData::Open(lpName);
        }
        catch (SharedMemoryException ex)
        {
            palError = ex.GetErrorCode();
            goto InternalOpenMutexExit;
        }
        if (processDataHeader == nullptr)
        {
            palError = ERROR_FILE_NOT_FOUND;
            goto InternalOpenMutexExit;
        }
        SharedMemoryProcessDataHeader::PalObject_SetProcessDataHeader(pobjMutex, processDataHeader);
    }

    *phMutex = hMutex;
    hMutex = nullptr;
    pobjMutex = nullptr;

InternalOpenMutexExit:

    _ASSERTE(pobjRegisteredMutex == nullptr);
    if (hMutex != nullptr)
    {
        g_pObjectManager->RevokeHandle(pthr, hMutex);
    }
    else if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalCreateMutex returns %i\n", palError);

    return palError;
}
예제 #14
0
파일: mutex.cpp 프로젝트: jamesqo/coreclr
PAL_ERROR
CorUnix::InternalReleaseMutex(
    CPalThread *pthr,
    HANDLE hMutex
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    ISynchStateController *pssc = NULL;
    PalObjectTypeId objectTypeId;

    _ASSERTE(NULL != pthr);

    ENTRY("InternalReleaseMutex(pthr=%p, hMutex=%p)\n",
        pthr,
        hMutex
        );

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pthr,
        hMutex,
        &aotAnyMutex,
        0, // should be MUTEX_MODIFY_STATE -- current ignored (no Win32 security)
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        ERROR("Unable to obtain object for handle %p (error %d)!\n", hMutex, palError);
        goto InternalReleaseMutexExit;
    }

    objectTypeId = pobjMutex->GetObjectType()->GetId();
    if (objectTypeId == otiMutex)
    {
        palError = pobjMutex->GetSynchStateController(
            pthr,
            &pssc
            );

        if (NO_ERROR != palError)
        {
            ASSERT("Error %d obtaining synch state controller\n", palError);
            goto InternalReleaseMutexExit;
        }

        palError = pssc->DecrementOwnershipCount();

        if (NO_ERROR != palError)
        {
            ERROR("Error %d decrementing mutex ownership count\n", palError);
            goto InternalReleaseMutexExit;
        }
    }
    else
    {
        _ASSERTE(objectTypeId == otiNamedMutex);

        SharedMemoryProcessDataHeader *processDataHeader =
            SharedMemoryProcessDataHeader::PalObject_GetProcessDataHeader(pobjMutex);
        _ASSERTE(processDataHeader != nullptr);
        try
        {
            static_cast<NamedMutexProcessData *>(processDataHeader->GetData())->ReleaseLock();
        }
        catch (SharedMemoryException ex)
        {
            palError = ex.GetErrorCode();
            goto InternalReleaseMutexExit;
        }
    }

InternalReleaseMutexExit:

    if (NULL != pssc)
    {
        pssc->ReleaseController();
    }

    if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalReleaseMutex returns %i\n", palError);

    return palError;
}
예제 #15
0
파일: mutex.cpp 프로젝트: jamesqo/coreclr
PAL_ERROR
CorUnix::InternalCreateMutex(
    CPalThread *pthr,
    LPSECURITY_ATTRIBUTES lpMutexAttributes,
    BOOL bInitialOwner,
    LPCSTR lpName,
    HANDLE *phMutex
    )
{
    CObjectAttributes oa(nullptr, lpMutexAttributes);
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    IPalObject *pobjRegisteredMutex = NULL;
    ISynchStateController *pssc = NULL;
    HANDLE hMutex = nullptr;

    _ASSERTE(NULL != pthr);
    _ASSERTE(NULL != phMutex);

    ENTRY("InternalCreateMutex(pthr=%p, lpMutexAttributes=%p, bInitialOwner=%d"
        ", lpName=%p, phMutex=%p)\n",
        pthr,
        lpMutexAttributes,
        bInitialOwner,
        lpName,
        phMutex
        );

    if (lpName != nullptr && lpName[0] == '\0')
    {
        // Empty name is treated as a request for an unnamed process-local mutex
        lpName = nullptr;
    }

    CObjectType *ot = lpName == nullptr ? &otMutex : &otNamedMutex;
    CAllowedObjectTypes *aot = lpName == nullptr ? &aotMutex : &aotNamedMutex;

    palError = g_pObjectManager->AllocateObject(
        pthr,
        ot,
        &oa,
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        goto InternalCreateMutexExit;
    }

    if (lpName == nullptr)
    {
        palError = pobjMutex->GetSynchStateController(
            pthr,
            &pssc
            );

        if (NO_ERROR != palError)
        {
            ASSERT("Unable to create state controller (%d)\n", palError);
            goto InternalCreateMutexExit;
        }

        if (bInitialOwner)
        {
            palError = pssc->SetOwner(pthr);
        }
        else
        {
            palError = pssc->SetSignalCount(1);
        }

        pssc->ReleaseController();

        if (NO_ERROR != palError)
        {
            ASSERT("Unable to set initial mutex state (%d)\n", palError);
            goto InternalCreateMutexExit;
        }
    }

    palError = g_pObjectManager->RegisterObject(
        pthr,
        pobjMutex,
        aot,
        0, // should be MUTEX_ALL_ACCESS -- currently ignored (no Win32 security)
        &hMutex,
        &pobjRegisteredMutex
        );

    if (palError != NO_ERROR)
    {
        _ASSERTE(palError != ERROR_ALREADY_EXISTS); // PAL's naming infrastructure is not used for named mutexes
        _ASSERTE(pobjRegisteredMutex == nullptr);
        _ASSERTE(hMutex == nullptr);
        goto InternalCreateMutexExit;
    }

    // Now that the object has been registered successfully, it would have a reference associated with the handle, so release
    // the initial reference. Any errors from now on need to revoke the handle.
    _ASSERTE(pobjRegisteredMutex == pobjMutex);
    _ASSERTE(hMutex != nullptr);
    pobjMutex->ReleaseReference(pthr);
    pobjRegisteredMutex = nullptr;

    if (lpName != nullptr)
    {
        SharedMemoryProcessDataHeader *processDataHeader;
        bool created = false;
        try
        {
            processDataHeader = NamedMutexProcessData::CreateOrOpen(lpName, !!bInitialOwner, &created);
        }
        catch (SharedMemoryException ex)
        {
            palError = ex.GetErrorCode();
            goto InternalCreateMutexExit;
        }
        SharedMemoryProcessDataHeader::PalObject_SetProcessDataHeader(pobjMutex, processDataHeader);

        if (!created)
        {
            // Indicate to the caller that an existing mutex was opened, and hence the caller will not have initial ownership
            // of the mutex if requested through bInitialOwner
            palError = ERROR_ALREADY_EXISTS;
        }
    }

    *phMutex = hMutex;
    hMutex = nullptr;
    pobjMutex = nullptr;

InternalCreateMutexExit:

    _ASSERTE(pobjRegisteredMutex == nullptr);
    if (hMutex != nullptr)
    {
        g_pObjectManager->RevokeHandle(pthr, hMutex);
    }
    else if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalCreateMutex returns %i\n", palError);

    return palError;
}
예제 #16
0
파일: mutex.cpp 프로젝트: SpivEgin/coreclr
PAL_ERROR
CorUnix::InternalReleaseMutex(
    CPalThread *pthr,
    HANDLE hMutex
    )
{
    PAL_ERROR palError = NO_ERROR;
    IPalObject *pobjMutex = NULL;
    ISynchStateController *pssc = NULL;

    _ASSERTE(NULL != pthr);

    ENTRY("InternalReleaseMutex(pthr=%p, hMutex=%p)\n",
        pthr,
        hMutex
        );

    palError = g_pObjectManager->ReferenceObjectByHandle(
        pthr,
        hMutex,
        &aotMutex,
        0, // should be MUTEX_MODIFY_STATE -- current ignored (no Win32 security)
        &pobjMutex
        );

    if (NO_ERROR != palError)
    {
        ERROR("Unable to obtain object for handle %p (error %d)!\n", hMutex, palError);
        goto InternalReleaseMutexExit;
    }
    
    palError = pobjMutex->GetSynchStateController(
        pthr,
        &pssc
        );

    if (NO_ERROR != palError)
    {
        ASSERT("Error %d obtaining synch state controller\n", palError);
        goto InternalReleaseMutexExit;
    }

    palError = pssc->DecrementOwnershipCount();

    if (NO_ERROR != palError)
    {
        ERROR("Error %d decrementing mutex ownership count\n", palError);
        goto InternalReleaseMutexExit;
    }

InternalReleaseMutexExit:

    if (NULL != pssc)
    {
        pssc->ReleaseController();
    }

    if (NULL != pobjMutex)
    {
        pobjMutex->ReleaseReference(pthr);
    }

    LOGEXIT("InternalReleaseMutex returns %i\n", palError);

    return palError;
}
예제 #17
0
파일: filecrt.cpp 프로젝트: nadyalo/coreclr
/*++
Function:
  _open_osfhandle

See MSDN doc.
--*/
int
__cdecl
_open_osfhandle( INT_PTR osfhandle, int flags )
{
    PAL_ERROR palError = NO_ERROR;
    CPalThread *pthrCurrent = NULL;
    IPalObject *pobjFile = NULL;
    CFileProcessLocalData *pLocalData = NULL;
    IDataLock *pDataLock = NULL;
    INT nRetVal = -1;
    INT openFlags = 0;

    PERF_ENTRY(_open_osfhandle);
    ENTRY( "_open_osfhandle (osfhandle=%#x, flags=%#x)\n", osfhandle, flags );

    pthrCurrent = InternalGetCurrentThread();

    if (flags != _O_RDONLY)
    {
        ASSERT("flag(%#x) not supported\n", flags);
        goto EXIT;
    }

    openFlags |= O_RDONLY;

    palError = g_pObjectManager->ReferenceObjectByHandle(
                   pthrCurrent,
                   reinterpret_cast<HANDLE>(osfhandle),
                   &aotFile,
                   0,
                   &pobjFile
               );

    if (NO_ERROR != palError)
    {
        ERROR("Error dereferencing file handle\n");
        goto EXIT;
    }

    palError = pobjFile->GetProcessLocalData(
                   pthrCurrent,
                   ReadLock,
                   &pDataLock,
                   reinterpret_cast<void **>(&pLocalData)
               );

    if (NO_ERROR == palError)
    {
        if ('\0' != pLocalData->unix_filename[0])
        {
            nRetVal = InternalOpen(pthrCurrent, pLocalData->unix_filename, openFlags);
        }
        else /* the only file object with no unix_filename is a pipe */
        {
            /* check if the file pipe descrptor is for read or write */
            if (pLocalData->open_flags == O_WRONLY)
            {
                ERROR( "Couldn't open a write pipe on read mode\n");
                goto EXIT;
            }

            nRetVal = pLocalData->unix_fd;
        }

        if ( nRetVal == -1 )
        {
            ERROR( "Error: %s.\n", strerror( errno ) );
        }
    }
    else
    {
        ASSERT("Unable to access file data");
    }

EXIT:

    if (NULL != pDataLock)
    {
        pDataLock->ReleaseLock(pthrCurrent, FALSE);
    }

    if (NULL != pobjFile)
    {
        pobjFile->ReleaseReference(pthrCurrent);
    }

    LOGEXIT( "_open_osfhandle return nRetVal:%d\n", nRetVal);
    PERF_EXIT(_open_osfhandle);
    return nRetVal;
}
예제 #18
0
파일: debug.cpp 프로젝트: SpivEgin/coreclr
DWORD
PAL_CreateExecWatchpoint(
    HANDLE hThread,
    PVOID pvInstruction
    )
{
    PERF_ENTRY(PAL_CreateExecWatchpoint);
    ENTRY("PAL_CreateExecWatchpoint (hThread=%p, pvInstruction=%p)\n", hThread, pvInstruction);

    DWORD dwError = ERROR_NOT_SUPPORTED;

#if HAVE_PRWATCH_T

    CPalThread *pThread = NULL;
    CPalThread *pTargetThread = NULL;
    IPalObject *pobjThread = NULL;
    int fd = -1;
    char ctlPath[50];

    struct
    {
        long ctlCode;
        prwatch_t prwatch;
    } ctlStruct;

    //
    // We must never set a watchpoint on an instruction that enters a syscall;
    // if such a request comes in we succeed it w/o actually creating the
    // watchpoint. This mirrors the behavior of setting the single-step flag
    // in a thread context when the thread is w/in a system service -- the
    // flag is ignored and will not be present when the thread returns
    // to user mode.
    //

#if defined(_SPARC_)
    if (*(DWORD*)pvInstruction == 0x91d02008) // ta 8
    {
        TRACE("Watchpoint requested on sysenter instruction -- ignoring");
        dwError = ERROR_SUCCESS;
        goto PAL_CreateExecWatchpointExit;        
    }
#else
#error Need syscall instruction for this platform
#endif // _SPARC_

    pThread = InternalGetCurrentThread();

    dwError = InternalGetThreadDataFromHandle(
        pThread,
        hThread,
        0, // THREAD_SET_CONTEXT
        &pTargetThread,
        &pobjThread
        );

    if (NO_ERROR != dwError)
    {
        goto PAL_CreateExecWatchpointExit;
    }

    snprintf(ctlPath, sizeof(ctlPath), "/proc/%u/lwp/%u/lwpctl", getpid(), pTargetThread->GetLwpId());

    fd = InternalOpen(pThread, ctlPath, O_WRONLY);
    if (-1 == fd)
    {
        ERROR("Failed to open %s\n", ctlPath);
        dwError = ERROR_INVALID_ACCESS;
        goto PAL_CreateExecWatchpointExit;
    }

    ctlStruct.ctlCode = PCWATCH;
    ctlStruct.prwatch.pr_vaddr = (uintptr_t) pvInstruction;
    ctlStruct.prwatch.pr_size = sizeof(DWORD);
    ctlStruct.prwatch.pr_wflags = WA_EXEC | WA_TRAPAFTER;

    if (write(fd, (void*) &ctlStruct, sizeof(ctlStruct)) != sizeof(ctlStruct))
    {
        ERROR("Failure writing control structure (errno = %u)\n", errno);
        dwError = ERROR_INTERNAL_ERROR;
        goto PAL_CreateExecWatchpointExit;
    }

    dwError = ERROR_SUCCESS;
    
PAL_CreateExecWatchpointExit:

    if (NULL != pobjThread)
    {
        pobjThread->ReleaseReference(pThread);
    }

    if (-1 != fd)
    {
        close(fd);
    }

#endif // HAVE_PRWATCH_T     
    
    LOGEXIT("PAL_CreateExecWatchpoint returns ret:%d\n", dwError);
    PERF_EXIT(PAL_CreateExecWatchpoint);
    return dwError;
}