Exemple #1
0
/*++
MangleObjectNameW

Mangle an object name to be side-by-side with other Rotors

lplpObjectName - [in out] pointer to pointer to object name to mangle
lpMangledObjectName - buffer of MAX_PATH characters to store the mangled
                      object name in

Returns TRUE on success.  On failure, returns FALSE with LastError set.

--*/
BOOL MangleObjectNameW(LPCWSTR *lplpObjectName, LPWSTR lpMangledObjectName)
{
    size_t ObjectNameLength;
    LPCWSTR lpObjectName;
    WCHAR *pSlash;

    lpObjectName = *lplpObjectName;
    if (!lpObjectName) {
        // No object name, so no work to do.
        return TRUE;
    }

    ObjectNameLength = PAL_wcslen(lpObjectName);
    if (ObjectNameLength+NameManglerLength+1 >= MAX_PATH) {
        SetLastError(ERROR_FILENAME_EXCED_RANGE);
        return FALSE;
    }

    *lplpObjectName = lpMangledObjectName;

    pSlash = PAL_wcschr(lpObjectName, L'\\');
    if (pSlash) {
        size_t PathPartLength;

        // The mangling needs to be done after the Global\\ or Local\\ portion
        PathPartLength = pSlash-lpObjectName+1;
        memcpy(lpMangledObjectName, lpObjectName, PathPartLength*sizeof(WCHAR));
        lpObjectName+=PathPartLength;
        lpMangledObjectName+=PathPartLength;
    }
    PAL_wcsncpy(lpMangledObjectName, NameManglerW, NameManglerLength);
    PAL_wcscpy(lpMangledObjectName+NameManglerLength, lpObjectName);

    return TRUE;
}
Exemple #2
0
/*++
Function:
  GetLongPathNameW

See MSDN doc.

Note:
  Since short path names are not implemented (nor supported) in the PAL, 
  this function simply copies the given path into the new buffer.

--*/
DWORD
PALAPI
GetLongPathNameW(
		 IN LPCWSTR lpszShortPath,
         OUT LPWSTR lpszLongPath,
  		 IN DWORD cchBuffer)
{
    DWORD dwPathLen = 0;

    PERF_ENTRY(GetLongPathNameW);
    ENTRY("GetLongPathNameW(lpszShortPath=%p (%S), lpszLongPath=%p (%S), "
          "cchBuffer=%d\n", lpszShortPath, lpszShortPath, lpszLongPath, lpszLongPath, cchBuffer);

    if ( !lpszShortPath )
    {
        ERROR( "lpszShortPath was not a valid pointer.\n" )
        SetLastError( ERROR_INVALID_PARAMETER );
        LOGEXIT("GetLongPathNameW returns DWORD 0\n");
        PERF_EXIT(GetLongPathNameW);
        return 0;
    }
    else if (INVALID_FILE_ATTRIBUTES == GetFileAttributesW( lpszShortPath ))
    {
        // last error has been set by GetFileAttributes
        ERROR( "lpszShortPath does not exist.\n" )
        LOGEXIT("GetLongPathNameW returns DWORD 0\n");
        PERF_EXIT(GetLongPathNameW);
        return 0;
    }

    /* all lengths are # of TCHAR characters */
    /* "required size" includes space for the terminating null character */
    dwPathLen = PAL_wcslen(lpszShortPath)+1;

    /* lpszLongPath == 0 means caller is asking only for size */
    if ( lpszLongPath )
    {
        if ( dwPathLen > cchBuffer )
        {
            ERROR("Buffer is too small, need %d characters\n", dwPathLen);
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
        } else 
        {
            if ( lpszShortPath != lpszLongPath )
            {
                // Note: MSDN doesn’t specify the behavior of GetLongPathName API
                //       if the buffers are overlap.
                PAL_wcsncpy( lpszLongPath, lpszShortPath, cchBuffer );
            }

            /* actual size not including terminating null is returned */
            dwPathLen--;
        }
    }

    LOGEXIT("GetLongPathNameW returns DWORD %u\n", dwPathLen);
    PERF_EXIT(GetLongPathNameW);
    return dwPathLen;
}
Exemple #3
0
/*++
Function:
  FormatMessageW

See MSDN doc.
--*/
DWORD
PALAPI
FormatMessageW(
           IN DWORD dwFlags,
           IN LPCVOID lpSource,
           IN DWORD dwMessageId,
           IN DWORD dwLanguageId,
           OUT LPWSTR lpBuffer,
           IN DWORD nSize,
           IN va_list *Arguments)
{
    BOOL bIgnoreInserts = FALSE;
    BOOL bIsVaList = TRUE;
    BOOL bIsLocalAlloced = FALSE;
    LPWSTR lpSourceString = NULL;
    UINT nCount = 0;
    LPWSTR lpReturnString = NULL;
    LPWSTR lpWorkingString = NULL; 
    

    PERF_ENTRY(FormatMessageW);
    ENTRY( "FormatMessageW(dwFlags=%#x, lpSource=%p, dwMessageId=%#x, "
           "dwLanguageId=%#x, lpBuffer=%p, nSize=%u, va_list=%p)\n", 
           dwFlags, lpSource, dwMessageId, dwLanguageId, lpBuffer, nSize,
           Arguments);
    
    /* Sanity checks. */
    if ( dwFlags & FORMAT_MESSAGE_FROM_STRING && !lpSource )
    {
        /* This behavior is different then in Windows.  
           Windows would just crash.*/
        ERROR( "lpSource cannot be NULL.\n" );
        SetLastError( ERROR_INVALID_PARAMETER );
        goto exit;
    }

    if ( !(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER ) && !lpBuffer )
    {
        /* This behavior is different then in Windows.  
           Windows would just crash.*/
        ERROR( "lpBuffer cannot be NULL, if "
               " FORMAT_MESSAGE_ALLOCATE_BUFFER is not specified.\n" );
        SetLastError( ERROR_INVALID_PARAMETER );
        goto exit;
    }
    
    if ( ( dwFlags & FORMAT_MESSAGE_FROM_STRING ) && 
         ( dwFlags & FORMAT_MESSAGE_FROM_SYSTEM ) )
    {
        ERROR( "These flags cannot co-exist. You can either "
               "specify FORMAT_MESSAGE_FROM_STRING, or "
               "FORMAT_MESSAGE_FROM_SYSTEM.\n" );
        SetLastError( ERROR_INVALID_PARAMETER );
        goto exit;
    }
    
    if ( !( dwFlags & FORMAT_MESSAGE_FROM_STRING ) && 
         ( dwLanguageId != 0
#if ENABLE_DOWNLEVEL_FOR_NLS         
         && dwLanguageId != MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ) 
#endif
         ) )
    {
        ERROR( "Invalid language indentifier.\n" );
        SetLastError( ERROR_RESOURCE_LANG_NOT_FOUND );
        goto exit;
    }

    /* Parameter processing. */
    if ( dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER )
    {
        TRACE( "Allocated %d TCHARs. Don't forget to call LocalFree to "
               "free the memory when done.\n", nSize );
        bIsLocalAlloced = TRUE;
    }
    
    if ( dwFlags & FORMAT_MESSAGE_IGNORE_INSERTS )
    {
        bIgnoreInserts = TRUE;
    }

    if ( dwFlags & FORMAT_MESSAGE_ARGUMENT_ARRAY )
    {
        if ( !Arguments && !bIgnoreInserts )
        {
            ERROR( "The va_list cannot be NULL.\n" );
            SetLastError( ERROR_INVALID_PARAMETER );
            goto exit;
        }
        else
        {
            bIsVaList = FALSE;
        }
    }
    
    if ( dwFlags & FORMAT_MESSAGE_FROM_STRING )
    {
        lpSourceString = (LPWSTR)lpSource;
    }
    else if ( dwFlags & FORMAT_MESSAGE_FROM_SYSTEM ) 
    {
        if ((dwMessageId & 0xFFFF0000) == 0x80070000)
        {
            // This message has been produced by HRESULT_FROM_WIN32.  Undo its work.
            dwMessageId &= 0xFFFF;
        }

        lpWorkingString = lpReturnString = 
            FMTMSG_GetMessageString( dwMessageId );
        
        if ( !lpWorkingString )
        {
            ERROR( "Unable to find the message %d.\n", dwMessageId );
            SetLastError( ERROR_INTERNAL_ERROR );
            nCount = 0;
            goto exit;
        }

        nCount = PAL_wcslen( lpWorkingString );
        
        if ( !bIsLocalAlloced && nCount > nSize )
        {
            ERROR( "Insufficient buffer.\n" );
            SetLastError( ERROR_INSUFFICIENT_BUFFER );
            lpWorkingString = NULL;
            nCount = 0;
            goto exit;
        }
        if ( !lpWorkingString )
        {
            ERROR( "Invalid error indentifier.\n" );
            SetLastError( ERROR_INVALID_ADDRESS );
        }
        goto exit;
    }
    else
    {
        ERROR( "Unknown flag.\n" );
        SetLastError( ERROR_INVALID_PARAMETER );
        goto exit;
    }

    if ( nSize == 0 && bIsLocalAlloced )
    {
        nSize = 1;
    }

    lpWorkingString = static_cast<WCHAR *>(
        LocalAlloc( LMEM_FIXED, nSize * sizeof( WCHAR ) ) );
    if ( !lpWorkingString )
    {
        ERROR( "Unable to allocate memory for the working string.\n" );
        SetLastError( ERROR_INSUFFICIENT_BUFFER );
        goto exit;
    }


    /* Process the string. */
    lpReturnString = lpWorkingString;
    while ( *lpSourceString )
    {
        if ( *lpSourceString == '%' && !bIgnoreInserts )
        {
            lpSourceString++;
            /* Escape sequences. */
            if ( *lpSourceString == '0' )
            {
                /* Terminates a message without a newline character. */
                *lpWorkingString = '\0';
                goto exit;
            }
            else if ( PAL_iswdigit( *lpSourceString ) )
            {
                /* Get the insert number. */
                WCHAR Number[] = { '\0', '\0', '\0' };
                SIZE_T Index = 0;

                Number[ 0 ] = *lpSourceString;
                lpSourceString++;
                
                if ( PAL_iswdigit( *lpSourceString ) )
                {
                    Number[ 1 ] = *lpSourceString;
                    lpSourceString++;
                    if ( PAL_iswdigit( *lpSourceString ) )
                    {
                        ERROR( "Invalid insert indentifier.\n" );
                        SetLastError( ERROR_INVALID_PARAMETER );
                        lpWorkingString = NULL;
                        nCount = 0;
                        goto exit;
                    }
                }
                Index = FMTMSG__watoi( Number );
                if ( Index == 0 )
                {
                    ERROR( "Invalid insert indentifier.\n" );
                    SetLastError( ERROR_INVALID_PARAMETER );
                    lpWorkingString = NULL;
                    nCount = 0;
                    goto exit;
                }
                if ( *lpSourceString == '!' )
                {
                    LPWSTR lpInsertString = NULL;
                    LPWSTR lpPrintfString = NULL;
                    LPWSTR lpStartOfFormattedString = NULL;
                    UINT nPrintfLength = 0;
                    LPWSTR lpFormattedString = NULL;
                    UINT nFormattedLength = 0;

                    if ( !bIsVaList )
                    {
                        lpInsertString = (LPWSTR)Arguments[ Index - 1 ];
                    }
                    else
                    {
                        va_list TheArgs;
                        
                        va_copy(TheArgs, *Arguments);
                        UINT i = 0;
                        for ( ; i < Index; i++ )
                        {
                            lpInsertString = va_arg( TheArgs, LPWSTR );
                        }
                    }

                    /* Calculate the length, and extract the printf string.*/
                    lpSourceString++;
                    {
                        LPWSTR p = PAL_wcschr( lpSourceString, '!' );

                        if ( NULL == p )
                        {
                            nPrintfLength = 0;
                        }
                        else
                        {
                            nPrintfLength = p - lpSourceString;
                        }
                    }
                                        
                    lpPrintfString = 
                        (LPWSTR)PAL_malloc( ( nPrintfLength + 1 ) * sizeof( WCHAR ) );
                    
                    if ( !lpPrintfString )
                    {
                        ERROR( "Unable to allocate memory.\n" );
                        SetLastError( ERROR_NOT_ENOUGH_MEMORY );
                        lpWorkingString = NULL;
                        nCount = 0;
                        goto exit;
                    }
                    
                    PAL_wcsncpy( lpPrintfString, lpSourceString, nPrintfLength );
                    *( lpPrintfString + nPrintfLength ) = '\0';

                    lpStartOfFormattedString = lpFormattedString = 
                           FMTMSG_ProcessPrintf( *lpPrintfString, 
                                                 lpPrintfString, 
                                                 lpInsertString);

                    if ( !lpFormattedString )
                    {
                        ERROR( "Unable to process the format string.\n" );
                        /* Function will set the error code. */
                        PAL_free( lpPrintfString );
                        lpWorkingString = NULL;
                        goto exit;
                    }
                     

                    nFormattedLength = PAL_wcslen( lpFormattedString );
                    
                    /* Append the processed printf string into the working string */
                    while ( *lpFormattedString )
                    {
                        _CHECKED_ADD_TO_STRING( *lpFormattedString );
                        lpFormattedString++;
                    }
                    
                    lpSourceString += nPrintfLength + 1;
                    PAL_free( lpPrintfString );
                    PAL_free( lpStartOfFormattedString );
                    lpPrintfString = lpFormattedString = NULL;
                }
                else
                {
                    /* The printf format string defaults to 's'.*/
                    LPWSTR lpInsert = NULL;

                    if ( !bIsVaList )
                    {
                         lpInsert = (LPWSTR)Arguments[ Index - 1 ];
                    }
                    else
                    {
                        va_list TheArgs;
                        va_copy(TheArgs, *Arguments);
                        UINT i = 0;
                        for ( ; i < Index; i++ )
                        {
                            lpInsert = va_arg( TheArgs, LPWSTR );
                        }
                    }

                    while ( *lpInsert )
                    {
                        _CHECKED_ADD_TO_STRING( *lpInsert );
                        lpInsert++;
                    }
                }
            }
            /* Format specifiers. */
            else if ( *lpSourceString == '%' )
            {
                _CHECKED_ADD_TO_STRING( '%' );
                lpSourceString++;
            }
            else if ( *lpSourceString == 'n' )
            {
                /* Hard line break. */
                _CHECKED_ADD_TO_STRING( '\n' );
                lpSourceString++;
            }
            else if ( *lpSourceString == '.' )
            {
                _CHECKED_ADD_TO_STRING( '.' );
                lpSourceString++;
            }
            else if ( *lpSourceString == '!' )
            {
                _CHECKED_ADD_TO_STRING( '!' );
                lpSourceString++;
            }
            else if ( !*lpSourceString )
            {
                ERROR( "Invalid parameter.\n" );
                SetLastError( ERROR_INVALID_PARAMETER );
                lpWorkingString = NULL;
                nCount = 0;
                goto exit;
            }
            else /* Append the character. */
            {
                _CHECKED_ADD_TO_STRING( *lpSourceString );
                lpSourceString++;
            }
        }/* END if ( *lpSourceString == '%' ) */
        else
        {
            /* In Windows if FormatMessage is called with ignore inserts,
            then FormatMessage strips %1!s! down to %1, since string is the
            default. */
            if ( bIgnoreInserts && *lpSourceString == '!' && 
                 *( lpSourceString + 1 ) == 's' )
            {
                LPWSTR lpLastBang = PAL_wcschr( lpSourceString + 1, '!' );

                if ( lpLastBang && ( 2 == lpLastBang - lpSourceString ) )
                {
                    lpSourceString = lpLastBang + 1;
                }
                else
                {
                    ERROR( "Mal-formed string\n" );
                    SetLastError( ERROR_INVALID_PARAMETER );
                    lpWorkingString = NULL;
                    nCount = 0;
                    goto exit;
                }
            }
            else
            {
                /* Append to the string. */
                _CHECKED_ADD_TO_STRING( *lpSourceString );
                lpSourceString++;
            }
        }
    }
    
    /* Terminate the message. */
    _CHECKED_ADD_TO_STRING( '\0' );
    /* NULL does not count. */
    nCount--;

exit: /* Function clean-up and exit. */
    if ( lpWorkingString )
    {
        if ( bIsLocalAlloced )
        {
            TRACE( "Assigning the buffer to the pointer.\n" );
            // when FORMAT_MESSAGE_ALLOCATE_BUFFER is specified, nSize
            // does not specify the size of lpBuffer, rather it specifies
            // the minimum size of the string
            // as such we have to blindly assume that lpBuffer has enough space to
            // store PVOID
            // might cause a prefast warning, but there is no good way to suppress it yet
            _ASSERTE(dwFlags & FORMAT_MESSAGE_ALLOCATE_BUFFER);
            *((LPVOID*)lpBuffer) = (LPVOID)lpReturnString;
        }
        else /* Only delete lpReturnString if the caller has their own buffer.*/
        {
            TRACE( "Copying the string into the buffer.\n" );
            PAL_wcsncpy( lpBuffer, lpReturnString, nCount + 1 );
            LocalFree( lpReturnString );
        }
    }
    else /* Error, something occured. */
    {
        if ( lpReturnString )
        {
            LocalFree( lpReturnString );
        }
    }
    LOGEXIT( "FormatMessageW returns %d.\n", nCount );
    PERF_EXIT(FormatMessageW);
    return nCount;
}