Пример #1
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;
}
Пример #2
0
/*++
Function:
  SetFileTime

Notes: This function will drop one digit (radix 10) of precision from
the supplied times, since Unix can set to the microsecond (at most, i.e.
if the futimes() function is available).

As noted in the file header, there is no analog to "creation time" on Unix
systems, so the lpCreationTime argument to this function will always be
ignored, and the inode change time will be set to the current time.
--*/
BOOL
PALAPI
SetFileTime(
        IN HANDLE hFile,
        IN CONST FILETIME *lpCreationTime,
        IN CONST FILETIME *lpLastAccessTime,
        IN CONST FILETIME *lpLastWriteTime)
{
    CPalThread *pThread;
    PAL_ERROR palError = NO_ERROR;
    const UINT64 MAX_FILETIMEVALUE = 0x8000000000000000LL;

    PERF_ENTRY(SetFileTime);
    ENTRY("SetFileTime(hFile=%p, lpCreationTime=%p, lpLastAccessTime=%p, "
          "lpLastWriteTime=%p)\n", hFile, lpCreationTime, lpLastAccessTime, 
          lpLastWriteTime);

    pThread = InternalGetCurrentThread();

    /* validate filetime values */
    if ( (lpCreationTime && (((UINT64)lpCreationTime->dwHighDateTime   << 32) + 
          lpCreationTime->dwLowDateTime   >= MAX_FILETIMEVALUE)) ||        
         (lpLastAccessTime && (((UINT64)lpLastAccessTime->dwHighDateTime << 32) + 
          lpLastAccessTime->dwLowDateTime >= MAX_FILETIMEVALUE)) ||
         (lpLastWriteTime && (((UINT64)lpLastWriteTime->dwHighDateTime  << 32) + 
          lpLastWriteTime->dwLowDateTime  >= MAX_FILETIMEVALUE)))
    {
        pThread->SetLastError(ERROR_INVALID_HANDLE);
        return FALSE;
    }

    palError = InternalSetFileTime(
        pThread,
        hFile,
        lpCreationTime,
        lpLastAccessTime,
        lpLastWriteTime
        );

    if (NO_ERROR != palError)
    {
        pThread->SetLastError(palError);
    }

    LOGEXIT("SetFileTime returns BOOL %s\n", NO_ERROR == palError ? "TRUE":"FALSE");
    PERF_EXIT(SetFileTime);
    return NO_ERROR == palError;
}
Пример #3
0
/*++
Function:
  TlsGetValue

See MSDN doc.
--*/
LPVOID
PALAPI
TlsGetValue(
        IN DWORD dwTlsIndex)
{
    CPalThread *pThread;
    
    PERF_ENTRY(TlsGetValue);
    ENTRY("TlsGetValue()\n");
    
    if (dwTlsIndex == (DWORD) -1 || dwTlsIndex >= TLS_SLOT_SIZE)
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return 0;
    }

    pThread = InternalGetCurrentThread();

    /* From MSDN : "The TlsGetValue function calls SetLastError to clear a
       thread's last error when it succeeds." */
    pThread->SetLastError(NO_ERROR);
    
    LOGEXIT("TlsGetValue \n" );
    PERF_EXIT(TlsGetValue);
    
    return pThread->tlsInfo.tlsSlots[dwTlsIndex];
}
Пример #4
0
/*++
Function:
  GetFileTime

Notes: As noted at the top of this file, there is no analog to "creation
time" on Unix systems, so the inode change time is used instead. Also, Win32
LastAccessTime is updated after a write operation, but it is not on Unix.
To be consistent with Win32, this function returns the greater of mtime and
atime for LastAccessTime.
--*/
BOOL
PALAPI
GetFileTime(
        IN HANDLE hFile,
        OUT LPFILETIME lpCreationTime,
        OUT LPFILETIME lpLastAccessTime,
        OUT LPFILETIME lpLastWriteTime)
{
    CPalThread *pThread;
    PAL_ERROR palError = NO_ERROR;

    PERF_ENTRY(GetFileTime);
    ENTRY("GetFileTime(hFile=%p, lpCreationTime=%p, lpLastAccessTime=%p, "
          "lpLastWriteTime=%p)\n",
          hFile, lpCreationTime, lpLastAccessTime, lpLastWriteTime);

    pThread = InternalGetCurrentThread();

    palError = InternalGetFileTime(
        pThread,
        hFile,
        lpCreationTime,
        lpLastAccessTime,
        lpLastWriteTime
        );

    if (NO_ERROR != palError)
    {
        pThread->SetLastError(palError);
    }

    LOGEXIT("GetFileTime returns BOOL %s\n", NO_ERROR == palError ? "TRUE":"FALSE");
    PERF_EXIT(GetFileTime);
    return NO_ERROR == palError;
}
Пример #5
0
/*++
Function:

  ResumeThread

See MSDN doc.
--*/
DWORD
PALAPI
ResumeThread(
         IN HANDLE hThread
         )
{
    PAL_ERROR palError;
    CPalThread *pthrResumer;
    DWORD dwSuspendCount = (DWORD)-1;

    PERF_ENTRY(ResumeThread);
    ENTRY("ResumeThread(hThread=%p)\n", hThread);

    pthrResumer = InternalGetCurrentThread();
    palError = InternalResumeThread(
        pthrResumer,
        hThread,
        &dwSuspendCount
        );

    if (NO_ERROR != palError)
    {
        pthrResumer->SetLastError(palError);
        dwSuspendCount = (DWORD) -1;
    }
    else
    {
        _ASSERT_MSG(dwSuspendCount != static_cast<DWORD>(-1), "InternalResumeThread returned success but dwSuspendCount did not change.\n");   
    }

    LOGEXIT("ResumeThread returns DWORD %u\n", dwSuspendCount);
    PERF_EXIT(ResumeThread);
    return dwSuspendCount;
}
Пример #6
0
BOOL
PALAPI
ReleaseSemaphore(
         IN HANDLE hSemaphore,
         IN LONG lReleaseCount,
         OUT LPLONG lpPreviousCount)
{
    PAL_ERROR palError = NO_ERROR;
    CPalThread *pthr = NULL;

    PERF_ENTRY(ReleaseSemaphore);
    ENTRY("ReleaseSemaphore(hSemaphore=%p, lReleaseCount=%d, "
          "lpPreviousCount=%p)\n",
          hSemaphore, lReleaseCount, lpPreviousCount);

    pthr = InternalGetCurrentThread();
    
    palError = InternalReleaseSemaphore(
        pthr,
        hSemaphore,
        lReleaseCount,
        lpPreviousCount
        );

    if (NO_ERROR != palError)
    {
        pthr->SetLastError(palError);
    }

    LOGEXIT ("ReleaseSemaphore returns BOOL %d\n", (NO_ERROR == palError));
    PERF_EXIT(ReleaseSemaphore);
    return (NO_ERROR == palError);
}
Пример #7
0
HANDLE
PALAPI
CreateMutexW(
    IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
    IN BOOL bInitialOwner,
    IN LPCWSTR lpName)
{
    HANDLE hMutex = NULL;
    PAL_ERROR palError;
    CPalThread *pthr = NULL;
    char utf8Name[SHARED_MEMORY_MAX_NAME_CHAR_COUNT + 1];

    PERF_ENTRY(CreateMutexW);
    ENTRY("CreateMutexW(lpMutexAttr=%p, bInitialOwner=%d, lpName=%p (%S)\n",
          lpMutexAttributes, bInitialOwner, lpName, lpName?lpName:W16_NULLSTRING);

    pthr = InternalGetCurrentThread();

    if (lpName != nullptr)
    {
        int bytesWritten = WideCharToMultiByte(CP_ACP, 0, lpName, -1, utf8Name, _countof(utf8Name), nullptr, nullptr);
        if (bytesWritten == 0)
        {
            DWORD errorCode = GetLastError();
            if (errorCode == ERROR_INSUFFICIENT_BUFFER)
            {
                palError = static_cast<DWORD>(SharedMemoryError::NameTooLong);
            }
            else
            {
                ASSERT("WideCharToMultiByte failed (%u)\n", errorCode);
                palError = errorCode;
            }
            goto CreateMutexWExit;
        }
    }

    palError = InternalCreateMutex(
        pthr,
        lpMutexAttributes,
        bInitialOwner,
        lpName == nullptr ? nullptr : utf8Name,
        &hMutex
        );

CreateMutexWExit:
    //
    // We always need to set last error, even on success:
    // we need to protect ourselves from the situation
    // where last error is set to ERROR_ALREADY_EXISTS on
    // entry to the function
    //

    pthr->SetLastError(palError);

    LOGEXIT("CreateMutexW returns HANDLE %p\n", hMutex);
    PERF_EXIT(CreateMutexW);
    return hMutex;
}
Пример #8
0
HANDLE
PALAPI
OpenMutexA (
       IN DWORD dwDesiredAccess,
       IN BOOL bInheritHandle,
       IN LPCSTR lpName)
{
    HANDLE hMutex = NULL;
    WCHAR pwName[c_cchMaxMutex];
    CPalThread *pthr = NULL;
    PAL_ERROR palError;
    
    PERF_ENTRY(OpenMutexA);
    ENTRY("OpenMutexA(dwDesiredAccess=%#x, bInheritHandle=%d, lpName=%p (%s))\n", 
          dwDesiredAccess, bInheritHandle, lpName, lpName?lpName:"NULL");

    pthr = InternalGetCurrentThread();

    /* validate parameters */
    if (lpName == NULL)
    {
        ERROR("name is NULL\n");
        palError = ERROR_INVALID_PARAMETER;
        goto OpenMutexAExit;            
    }
    
    palError = InternalWszNameFromSzName(
        pthr,
        lpName,
        pwName,
        sizeof(pwName) / sizeof(pwName[0])
        );

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

    palError = InternalOpenMutex(
        pthr,
        dwDesiredAccess,
        bInheritHandle,
        pwName,
        &hMutex
        );

OpenMutexAExit:

    if (NO_ERROR != palError)
    {
        pthr->SetLastError(palError);
    }
        
    LOGEXIT("OpenMutexA returns HANDLE %p\n", hMutex);
    PERF_EXIT(OpenMutexA);
    return hMutex;
}
Пример #9
0
HANDLE
PALAPI
OpenMutexW(
       IN DWORD dwDesiredAccess,
       IN BOOL bInheritHandle,
       IN LPCWSTR lpName)
{
    HANDLE hMutex = NULL;
    PAL_ERROR palError = NO_ERROR;
    CPalThread *pthr = NULL;
    char utf8Name[SHARED_MEMORY_MAX_NAME_CHAR_COUNT + 1];

    PERF_ENTRY(OpenMutexW);
    ENTRY("OpenMutexW(dwDesiredAccess=%#x, bInheritHandle=%d, lpName=%p (%S))\n", 
          dwDesiredAccess, bInheritHandle, lpName, lpName?lpName:W16_NULLSTRING);

    pthr = InternalGetCurrentThread();

    /* validate parameters */
    if (lpName == nullptr)
    {
        ERROR("name is NULL\n");
        palError = ERROR_INVALID_PARAMETER;
        goto OpenMutexWExit;
    }

    {
        int bytesWritten = WideCharToMultiByte(CP_ACP, 0, lpName, -1, utf8Name, _countof(utf8Name), nullptr, nullptr);
        if (bytesWritten == 0)
        {
            DWORD errorCode = GetLastError();
            if (errorCode == ERROR_INSUFFICIENT_BUFFER)
            {
                palError = static_cast<DWORD>(SharedMemoryError::NameTooLong);
            }
            else
            {
                ASSERT("WideCharToMultiByte failed (%u)\n", errorCode);
                palError = errorCode;
            }
            goto OpenMutexWExit;
        }
    }

    palError = InternalOpenMutex(pthr, dwDesiredAccess, bInheritHandle, lpName == nullptr ? nullptr : utf8Name, &hMutex);

OpenMutexWExit:
    if (NO_ERROR != palError)
    {
        pthr->SetLastError(palError);
    }

    LOGEXIT("OpenMutexW returns HANDLE %p\n", hMutex);
    PERF_EXIT(OpenMutexW);

    return hMutex;
}
Пример #10
0
HANDLE
PALAPI
CreateSemaphoreA(
         IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
         IN LONG lInitialCount,
         IN LONG lMaximumCount,
         IN LPCSTR lpName)
{
    HANDLE hSemaphore = NULL;
    CPalThread *pthr = NULL;
    PAL_ERROR palError;

    PERF_ENTRY(CreateSemaphoreA);
    ENTRY("CreateSemaphoreA(lpSemaphoreAttributes=%p, lInitialCount=%d, "
          "lMaximumCount=%d, lpName=%p (%s))\n",
          lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName, lpName?lpName:"NULL");

    pthr = InternalGetCurrentThread();
    
    if (lpName != nullptr)
    {
        ASSERT("lpName: Cross-process named objects are not supported in PAL");
        palError = ERROR_NOT_SUPPORTED;
    }
    else
    {
        palError = InternalCreateSemaphore(
            pthr,
            lpSemaphoreAttributes,
            lInitialCount,
            lMaximumCount,
            NULL,
            &hSemaphore
            );
    }

    //
    // We always need to set last error, even on success:
    // we need to protect ourselves from the situation
    // where last error is set to ERROR_ALREADY_EXISTS on
    // entry to the function
    //

    pthr->SetLastError(palError);
    
    LOGEXIT("CreateSemaphoreA returns HANDLE %p\n", hSemaphore);
    PERF_EXIT(CreateSemaphoreA);
    return hSemaphore;
}
Пример #11
0
HANDLE
PALAPI
OpenSemaphoreW(
       IN DWORD dwDesiredAccess,
       IN BOOL bInheritHandle,
       IN LPCWSTR lpName)
{
    HANDLE hSemaphore = NULL;
    PAL_ERROR palError = NO_ERROR;
    CPalThread *pthr = NULL;

    PERF_ENTRY(OpenSemaphoreW);
    ENTRY("OpenSemaphoreW(dwDesiredAccess=%#x, bInheritHandle=%d, lpName=%p (%S))\n", 
          dwDesiredAccess, bInheritHandle, lpName, lpName?lpName:W16_NULLSTRING);

    pthr = InternalGetCurrentThread();

    /* validate parameters */
    if (lpName == NULL)
    {
        ERROR("lpName is NULL\n");
        palError = ERROR_INVALID_PARAMETER;
        goto OpenSemaphoreWExit;            
    }

    palError = InternalOpenSemaphore(
        pthr,
        dwDesiredAccess,
        bInheritHandle,
        lpName,
        &hSemaphore
        );

OpenSemaphoreWExit:

    if (NO_ERROR != palError)
    {
        pthr->SetLastError(palError);
    }

    LOGEXIT("OpenSemaphoreW returns HANDLE %p\n", hSemaphore);
    PERF_EXIT(OpenSemaphoreW);

    return hSemaphore;
}
Пример #12
0
HANDLE
PALAPI
CreateSemaphoreW(
         IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
         IN LONG lInitialCount,
         IN LONG lMaximumCount,
         IN LPCWSTR lpName)
{
    HANDLE hSemaphore = NULL;
    PAL_ERROR palError;
    CPalThread *pthr = NULL;

    PERF_ENTRY(CreateSemaphoreW);
    ENTRY("CreateSemaphoreW(lpSemaphoreAttributes=%p, lInitialCount=%d, "
          "lMaximumCount=%d, lpName=%p (%S))\n",
          lpSemaphoreAttributes, lInitialCount, lMaximumCount, 
          lpName, lpName?lpName:W16_NULLSTRING);

    pthr = InternalGetCurrentThread();

    palError = InternalCreateSemaphore(
        pthr,
        lpSemaphoreAttributes, 
        lInitialCount,
        lMaximumCount,
        lpName,
        &hSemaphore
        );

    //
    // We always need to set last error, even on success:
    // we need to protect ourselves from the situation
    // where last error is set to ERROR_ALREADY_EXISTS on
    // entry to the function
    //

    pthr->SetLastError(palError);

    LOGEXIT("CreateSemaphoreW returns HANDLE %p\n", hSemaphore);
    PERF_EXIT(CreateSemaphoreW);
    return hSemaphore;
}
Пример #13
0
/*++
Function:
  Sleep

See MSDN doc.
--*/
VOID
PALAPI
Sleep(IN DWORD dwMilliseconds)
{
    PERF_ENTRY(Sleep);
    ENTRY("Sleep(dwMilliseconds=%u)\n", dwMilliseconds);

    CPalThread * pThread = InternalGetCurrentThread();

    DWORD internalSleepRet = InternalSleepEx(pThread, dwMilliseconds, FALSE);

    if (internalSleepRet != 0)
    {
        ERROR("Sleep(dwMilliseconds=%u) failed [error=%u]\n", dwMilliseconds, internalSleepRet);
        pThread->SetLastError(internalSleepRet);
    }

    LOGEXIT("Sleep returns VOID\n");
    PERF_EXIT(Sleep);
}
Пример #14
0
HANDLE
PALAPI
OpenSemaphoreW(
       IN DWORD dwDesiredAccess,
       IN BOOL bInheritHandle,
       IN LPCWSTR lpName)
{
    HANDLE hSemaphore = NULL;
    PAL_ERROR palError = NO_ERROR;
    CPalThread *pthr = NULL;

    PERF_ENTRY(OpenSemaphoreW);
    ENTRY("OpenSemaphoreW(dwDesiredAccess=%#x, bInheritHandle=%d, lpName=%p (%S))\n", 
          dwDesiredAccess, bInheritHandle, lpName, lpName?lpName:W16_NULLSTRING);

    pthr = InternalGetCurrentThread();

    /* validate parameters */
    if (lpName == nullptr)
    {
        ERROR("lpName is NULL\n");
        palError = ERROR_INVALID_PARAMETER;
    }
    else
    {
        ASSERT("lpName: Cross-process named objects are not supported in PAL");
        palError = ERROR_NOT_SUPPORTED;
    }

    if (NO_ERROR != palError)
    {
        pthr->SetLastError(palError);
    }

    LOGEXIT("OpenSemaphoreW returns HANDLE %p\n", hSemaphore);
    PERF_EXIT(OpenSemaphoreW);

    return hSemaphore;
}
Пример #15
0
HANDLE
PALAPI
CreateMutexA(
    IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
    IN BOOL bInitialOwner,
    IN LPCSTR lpName)
{
    HANDLE hMutex = NULL;
    CPalThread *pthr = NULL;
    PAL_ERROR palError;
    
    PERF_ENTRY(CreateMutexA);
    ENTRY("CreateMutexA(lpMutexAttr=%p, bInitialOwner=%d, lpName=%p (%s)\n",
          lpMutexAttributes, bInitialOwner, lpName, lpName?lpName:"NULL");

    pthr = InternalGetCurrentThread();
    
    palError = InternalCreateMutex(
        pthr,
        lpMutexAttributes,
        bInitialOwner,
        lpName,
        &hMutex
        );

    //
    // We always need to set last error, even on success:
    // we need to protect ourselves from the situation
    // where last error is set to ERROR_ALREADY_EXISTS on
    // entry to the function
    //

    pthr->SetLastError(palError);
    
    LOGEXIT("CreateMutexA returns HANDLE %p\n", hMutex);
    PERF_EXIT(CreateMutexA);
    return hMutex;
}
Пример #16
0
BOOL
PALAPI
ReleaseMutex( IN HANDLE hMutex )
{
    PAL_ERROR palError = NO_ERROR;
    CPalThread *pthr = NULL;
    
    PERF_ENTRY(ReleaseMutex);
    ENTRY("ReleaseMutex(hMutex=%p)\n", hMutex);

    pthr = InternalGetCurrentThread();
    
    palError = InternalReleaseMutex(pthr, hMutex);

    if (NO_ERROR != palError)
    {
        pthr->SetLastError(palError);
    }

    LOGEXIT("ReleaseMutex returns BOOL %d\n", (NO_ERROR == palError));
    PERF_EXIT(ReleaseMutex);
    return (NO_ERROR == palError);
}
Пример #17
0
/*++
Function:
    GetComputerNameW

Uses gethostname to get the computer name. See MSDN for functional spec.

--*/
PALIMPORT
BOOL
PALAPI
GetComputerNameW(
    OUT LPWSTR lpBuffer, // address of name buffer
    IN OUT LPDWORD nSize)    // address of size of name buffer
{
    BOOL fRet = FALSE;
    char szHostName[MAXHOSTNAMELEN+1];
    char *pchDot = NULL;
    DWORD cwchLen = 0;
    CPalThread *pPalThread = InternalGetCurrentThread();

    PERF_ENTRY(GetComputerNameW);
    ENTRY("GetComputerNameW(lpBuffer = %p, nSize = %p (%d)\n",
          lpBuffer, nSize, nSize?*nSize:0);

    if (NULL == lpBuffer || NULL == nSize)
    {
        ERROR("lpBuffer == NULL or nSize == NULL");
        pPalThread->SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }

    if (0 != gethostname(szHostName, sizeof(szHostName)/sizeof(szHostName[0])))
    {
        ERROR("gethostname failed with error (%d) %s\n", errno, strerror(errno));
        pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
        goto done;
    }

    // Null terminate the string
    szHostName[sizeof(szHostName)/sizeof(szHostName[0])-1] = '\0';

    // some OSes return the hostname with the domain name included.
    // We want to return only the host part of the name (see the spec for
    // more details
    pchDot = strchr(szHostName, '.');
    if (NULL != pchDot)
    {
        *pchDot = '\0'; // remove the domain name info
    }

    // clip the hostname to MAX_COMPUTERNAME_LENGTH
    if (sizeof(szHostName) > MAX_COMPUTERNAME_LENGTH)
    {
        szHostName[MAX_COMPUTERNAME_LENGTH] = '\0';
    }

    // copy the hostname (including NULL character)
    cwchLen = MultiByteToWideChar(CP_ACP, 0, szHostName, -1, lpBuffer, *nSize);
    if (0 == cwchLen) 
    {
        ERROR ("MultiByteToWideChar failed with error %d when trying to convert the hostname "
                "%s to wide char\n", pPalThread->GetLastError(), szHostName);
        if (ERROR_INSUFFICIENT_BUFFER == pPalThread->GetLastError())
        {
            // Find the required size (including NULL)
            cwchLen = MultiByteToWideChar(CP_ACP, 0, szHostName, -1, NULL, 0);
            if (0 == cwchLen)
            {
                ERROR ("MultiByteToWideChar failed with error %d when trying to find the size of "
                       "%s in wide chars\n", pPalThread->GetLastError(), szHostName);
                pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            }
            else
            {
                // Update the required size
                *nSize = cwchLen - 1; // don't include the NULL
                pPalThread->SetLastError(ERROR_BUFFER_OVERFLOW);
            }
        }
        goto done;
    }

    *nSize = cwchLen - 1; // don't include the NULL
    fRet = TRUE;

done:
    LOGEXIT("GetComputerNameW returning BOOL %d\n", fRet);
    PERF_EXIT(GetComputerNameW);
    return fRet;
}
Пример #18
0
/*++
Function:
    GetUserNameW

Uses getpwuid_r to get the user name and if it's not available uses
getpwuid (with the safety of a critical section). See MSDN for functional spec.

--*/
PALIMPORT
BOOL
PALAPI
GetUserNameW(
    OUT LPWSTR lpBuffer, // address of name buffer
    IN OUT LPDWORD nSize )    // address of size of name buffer
{
    BOOL fRet = FALSE;
    struct passwd *pPasswd = NULL;
    char *szUserName = NULL;
    DWORD cwchLen = 0;
    int iEuid = -1;
    int iRet = -1;
    CPalThread *pPalThread = InternalGetCurrentThread();

#if HAVE_GETPWUID_R
    
    char *pchBuffer = NULL;
    DWORD dwBufLen = 0;
    struct passwd sPasswd;
    
#endif // HAVE_GETPWUID_R

    PERF_ENTRY(GetUserNameW);
    ENTRY("GetUserNameW(lpBuffer = %p, nSize = %p (%d)\n",
          lpBuffer, nSize, nSize?*nSize:0);

    iEuid = geteuid();

    if (NULL == lpBuffer || NULL == nSize)
    {
        ERROR("lpBuffer == NULL or nSize == NULL");
        pPalThread->SetLastError(ERROR_INVALID_PARAMETER);
        goto done;
    }

#if HAVE_GETPWUID_R

    dwBufLen = dwInitialPasswdBufferSize;

    while (NULL == pPasswd)
    {
        pchBuffer = (char*) InternalMalloc(pPalThread, sizeof(pchBuffer[0]) * dwBufLen);
        if (NULL == pchBuffer)
        {
            pPalThread->SetLastError(ERROR_OUTOFMEMORY);
            goto done;
        }

        iRet = InternalGetpwuid_r(pPalThread, iEuid, &sPasswd, pchBuffer, dwBufLen, &pPasswd);
        if (0 != iRet)
        {
            WARN("getpwuid_r(%d) returns %d for a buffer size of %d, error string is %s\n", 
                        iEuid, iRet, dwBufLen, strerror(iRet));

            if (ERANGE == iRet) // need a bigger buffer
            {
                InternalFree(pPalThread, pchBuffer);
                pchBuffer = NULL;
                pPasswd = NULL;
                dwBufLen *= 2; // double the buffer
                continue; // try again
            }

            pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            goto done;
        }

        // Unfortunately, HPUX returns success and result = NULL even when the buffer size is small
        // (instead of returning ERANGE error). But, since we are using either
        // sysconf(_SC_GETPW_R_SIZE_MAX) or the HP recommended value of 1024, buffer should always
        // be big enough for getpwuid_r.

        if (NULL == pPasswd || NULL == pPasswd->pw_name)
        {
            // No matching entry found! something failed somewhere.
            ERROR("getpwuid_r(%d) returned %p with name NULL!\n", iEuid, pPasswd);
            pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            goto done;
        }
    }

    szUserName = pPasswd->pw_name;

#else // HAVE_GETPWUID_R

    InternalEnterCriticalSection(pPalThread, &identity_critsec);
    pPasswd = getpwuid(iEuid);

    if ((NULL == pPasswd) || (NULL == pPasswd->pw_name))
    {
        InternalLeaveCriticalSection(pPalThread, &identity_critsec);
        ERROR("getpwuid(%d) returned %p with name NULL! error (%d) is %s\n",
                iEuid, pPasswd, errno, strerror(errno));
        pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
        goto done;
    }

    // make a copy so that we can modify it
    szUserName = InternalStrdup(pPalThread, pPasswd->pw_name);
    if (NULL == szUserName)
    {
        InternalLeaveCriticalSection(pPalThread, &identity_critsec);
        pPalThread->SetLastError(ERROR_OUTOFMEMORY);
        goto done;
    }

    InternalLeaveCriticalSection(pPalThread, &identity_critsec);
#endif // HAVE_GETPWUID_R

    // truncate the user name if it exceeds the maximum allowed limit
    if (strlen(szUserName) > UNLEN)
    {
        szUserName[UNLEN] = '\0';
    }

    // Copy from pPasswd->pw_name
    cwchLen = MultiByteToWideChar(CP_ACP, 0, szUserName, -1, lpBuffer, *nSize);
    if (0 == cwchLen)
    {
        ERROR ("MultiByteToWideChar failed with error %d when trying to convert the username "
               "%s to wide char\n", pPalThread->GetLastError(), szUserName);
        if (ERROR_INSUFFICIENT_BUFFER == pPalThread->GetLastError())
        {
            // Find the required size (including NULL)
            cwchLen = MultiByteToWideChar(CP_ACP, 0, szUserName, -1, NULL, 0);
            if (0 == cwchLen)
            {
                ERROR ("MultiByteToWideChar failed with error %d when trying to find the size of "
                       "%s in wide chars\n", pPalThread->GetLastError(), szUserName);
                pPalThread->SetLastError(ERROR_INTERNAL_ERROR);
            }
            else
            {
                // Update the required size
                *nSize = cwchLen;
                pPalThread->SetLastError(ERROR_MORE_DATA);
            }
        }
        goto done;
    }

    *nSize = cwchLen;
    fRet = TRUE;

done:
#if HAVE_GETPWUID_R
    if (NULL != pchBuffer)
    {
        InternalFree(pPalThread, pchBuffer);
    }
#else // HAVE_GETPWUID_R
    if (NULL != szUserName)
    {
        InternalFree(pPalThread, szUserName);
    }
#endif // HAVE_GETPWUID_R

    LOGEXIT("GetUserNameW returning BOOL %d\n", fRet);
    PERF_EXIT(GetUserNameW);
    return fRet;
}
Пример #19
0
HANDLE
PALAPI
CreateSemaphoreA(
         IN LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,
         IN LONG lInitialCount,
         IN LONG lMaximumCount,
         IN LPCSTR lpName)
{
    HANDLE hSemaphore = NULL;
    WCHAR pwName[c_cchMaxSemaphore];
    CPalThread *pthr = NULL;
    PAL_ERROR palError;

    PERF_ENTRY(CreateSemaphoreA);
    ENTRY("CreateSemaphoreA(lpSemaphoreAttributes=%p, lInitialCount=%d, "
          "lMaximumCount=%d, lpName=%p (%s))\n",
          lpSemaphoreAttributes, lInitialCount, lMaximumCount, lpName, lpName?lpName:"NULL");

    pthr = InternalGetCurrentThread();
    
    if (lpName != NULL)
    {
        palError = InternalWszNameFromSzName(
            pthr,
            lpName,
            pwName,
            sizeof(pwName) / sizeof(pwName[0])
            );

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

        palError = InternalCreateSemaphore(
            pthr,
            lpSemaphoreAttributes,
            lInitialCount,
            lMaximumCount,
            pwName,
            &hSemaphore
            );
    }
    else
    {
        palError = InternalCreateSemaphore(
            pthr,
            lpSemaphoreAttributes,
            lInitialCount,
            lMaximumCount,
            NULL,
            &hSemaphore
            );
    }

CreateSemaphoreAExit:
    
    //
    // We always need to set last error, even on success:
    // we need to protect ourselves from the situation
    // where last error is set to ERROR_ALREADY_EXISTS on
    // entry to the function
    //

    pthr->SetLastError(palError);
    
    LOGEXIT("CreateSemaphoreA returns HANDLE %p\n", hSemaphore);
    PERF_EXIT(CreateSemaphoreA);
    return hSemaphore;
}
Пример #20
0
HANDLE
PALAPI
CreateMutexA (
    IN LPSECURITY_ATTRIBUTES lpMutexAttributes,
    IN BOOL bInitialOwner,
    IN LPCSTR lpName)
{
    HANDLE hMutex = NULL;
    WCHAR pwName[c_cchMaxMutex];
    CPalThread *pthr = NULL;
    PAL_ERROR palError;
    
    PERF_ENTRY(CreateMutexA);
    ENTRY("CreateMutexA(lpMutexAttr=%p, bInitialOwner=%d, lpName=%p (%s)\n",
          lpMutexAttributes, bInitialOwner, lpName, lpName?lpName:"NULL");

    pthr = InternalGetCurrentThread();
    
    if (lpName != NULL)
    {
        palError = InternalWszNameFromSzName(
            pthr,
            lpName,
            pwName,
            sizeof(pwName) / sizeof(pwName[0])
            );

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

        palError = InternalCreateMutex(
            pthr,
            lpMutexAttributes,
            bInitialOwner,
            pwName,
            &hMutex
            );
    }
    else
    {
        palError = InternalCreateMutex(
            pthr,
            lpMutexAttributes,
            bInitialOwner,
            NULL,
            &hMutex
            );
    }

CreateMutexAExit:
    
    //
    // We always need to set last error, even on success:
    // we need to protect ourselves from the situation
    // where last error is set to ERROR_ALREADY_EXISTS on
    // entry to the function
    //

    pthr->SetLastError(palError);
    
    LOGEXIT("CreateMutexA returns HANDLE %p\n", hMutex);
    PERF_EXIT(CreateMutexA);
    return hMutex;
}