mirror of
https://github.com/WinampDesktop/winamp.git
synced 2024-09-24 15:54:12 +00:00
271 lines
5.9 KiB
C++
271 lines
5.9 KiB
C++
|
#include "main.h"
|
||
|
#include "./util.h"
|
||
|
#include "api__ml_wire.h"
|
||
|
|
||
|
#include <strsafe.h>
|
||
|
|
||
|
LPWSTR Plugin_MallocString( size_t cchLen )
|
||
|
{
|
||
|
return (LPWSTR)calloc( cchLen, sizeof( WCHAR ) );
|
||
|
}
|
||
|
|
||
|
void Plugin_FreeString( LPWSTR pszString )
|
||
|
{
|
||
|
if ( NULL != pszString )
|
||
|
{
|
||
|
free( pszString );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
LPWSTR Plugin_ReAllocString( LPWSTR pszString, size_t cchLen )
|
||
|
{
|
||
|
return (LPWSTR)realloc( pszString, sizeof( WCHAR ) * cchLen );
|
||
|
}
|
||
|
|
||
|
LPWSTR Plugin_CopyString( LPCWSTR pszSource )
|
||
|
{
|
||
|
if ( NULL == pszSource )
|
||
|
return NULL;
|
||
|
|
||
|
//INT cchSource = lstrlenW( pszSource ) + 1;
|
||
|
|
||
|
//LPWSTR copy = Plugin_MallocString( cchSource );
|
||
|
//if ( NULL != copy )
|
||
|
//{
|
||
|
// CopyMemory( copy, pszSource, sizeof( WCHAR ) * cchSource );
|
||
|
//}
|
||
|
//
|
||
|
return _wcsdup( pszSource );
|
||
|
}
|
||
|
|
||
|
LPSTR Plugin_MallocAnsiString( size_t cchLen )
|
||
|
{
|
||
|
return (LPSTR)calloc( cchLen, sizeof( CHAR ) );
|
||
|
}
|
||
|
|
||
|
LPSTR Plugin_CopyAnsiString( LPCSTR pszSource )
|
||
|
{
|
||
|
if ( NULL == pszSource )
|
||
|
return NULL;
|
||
|
|
||
|
//INT cchSource = lstrlenA(pszSource) + 1;
|
||
|
//
|
||
|
//LPSTR copy = Plugin_MallocAnsiString(cchSource);
|
||
|
//if (NULL != copy)
|
||
|
//{
|
||
|
// CopyMemory(copy, pszSource, sizeof(CHAR) * cchSource);
|
||
|
//}
|
||
|
|
||
|
return _strdup( pszSource );
|
||
|
}
|
||
|
|
||
|
void Plugin_FreeAnsiString( LPSTR pszString )
|
||
|
{
|
||
|
Plugin_FreeString( (LPWSTR)pszString );
|
||
|
}
|
||
|
|
||
|
LPSTR Plugin_WideCharToMultiByte( UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar )
|
||
|
{
|
||
|
INT cchBuffer = WideCharToMultiByte( codePage, dwFlags, lpWideCharStr, cchWideChar, NULL, 0, lpDefaultChar, lpUsedDefaultChar );
|
||
|
if ( 0 == cchBuffer )
|
||
|
return NULL;
|
||
|
|
||
|
LPSTR buffer = Plugin_MallocAnsiString( cchBuffer );
|
||
|
if ( NULL == buffer )
|
||
|
return NULL;
|
||
|
|
||
|
if ( 0 == WideCharToMultiByte( codePage, dwFlags, lpWideCharStr, cchWideChar, buffer, cchBuffer, lpDefaultChar, lpUsedDefaultChar ) )
|
||
|
{
|
||
|
Plugin_FreeAnsiString( buffer );
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
return buffer;
|
||
|
}
|
||
|
|
||
|
LPWSTR Plugin_MultiByteToWideChar( UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte )
|
||
|
{
|
||
|
if ( NULL == lpMultiByteStr )
|
||
|
return NULL;
|
||
|
|
||
|
INT cchBuffer = MultiByteToWideChar( codePage, dwFlags, lpMultiByteStr, cbMultiByte, NULL, 0 );
|
||
|
|
||
|
if ( NULL == cchBuffer )
|
||
|
return NULL;
|
||
|
|
||
|
if ( cbMultiByte > 0 )
|
||
|
cchBuffer++;
|
||
|
|
||
|
LPWSTR buffer = Plugin_MallocString( cchBuffer );
|
||
|
|
||
|
if ( NULL == buffer )
|
||
|
return NULL;
|
||
|
|
||
|
if ( 0 == MultiByteToWideChar( codePage, dwFlags, lpMultiByteStr, cbMultiByte, buffer, cchBuffer ) )
|
||
|
{
|
||
|
Plugin_FreeString( buffer );
|
||
|
return NULL;
|
||
|
}
|
||
|
|
||
|
if ( cbMultiByte > 0 )
|
||
|
{
|
||
|
buffer[ cchBuffer - 1 ] = L'\0';
|
||
|
}
|
||
|
|
||
|
return buffer;
|
||
|
}
|
||
|
|
||
|
|
||
|
LPWSTR Plugin_DuplicateResString( LPCWSTR pszResource )
|
||
|
{
|
||
|
return ( IS_INTRESOURCE( pszResource ) ) ? (LPWSTR)pszResource : Plugin_CopyString( pszResource );
|
||
|
}
|
||
|
|
||
|
void Plugin_FreeResString( LPWSTR pszResource )
|
||
|
{
|
||
|
if ( !IS_INTRESOURCE( pszResource ) )
|
||
|
Plugin_FreeString( pszResource );
|
||
|
}
|
||
|
|
||
|
HRESULT Plugin_CopyResString( LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString )
|
||
|
{
|
||
|
if ( NULL == pszBuffer )
|
||
|
return E_INVALIDARG;
|
||
|
|
||
|
HRESULT hr = S_OK;
|
||
|
|
||
|
if ( NULL == pszString )
|
||
|
{
|
||
|
pszBuffer[ 0 ] = L'\0';
|
||
|
}
|
||
|
else if ( IS_INTRESOURCE( pszString ) )
|
||
|
{
|
||
|
if ( NULL == WASABI_API_LNG )
|
||
|
hr = E_FAIL;
|
||
|
else
|
||
|
WASABI_API_LNGSTRINGW_BUF( (INT)(INT_PTR)pszString, pszBuffer, cchBufferMax );
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
hr = StringCchCopy( pszBuffer, cchBufferMax, pszString );
|
||
|
}
|
||
|
|
||
|
return hr;
|
||
|
}
|
||
|
|
||
|
void Plugin_SafeRelease( IUnknown *pUnk )
|
||
|
{
|
||
|
if ( NULL != pUnk )
|
||
|
pUnk->Release();
|
||
|
}
|
||
|
|
||
|
HRESULT Plugin_FileExtensionFromUrl( LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszUrl, LPCWSTR defaultExtension )
|
||
|
{
|
||
|
LPCWSTR cursor = pszUrl;
|
||
|
while ( L'\0' != *cursor && L'?' != *cursor )
|
||
|
cursor = CharNext( cursor );
|
||
|
|
||
|
LPCWSTR end = cursor;
|
||
|
|
||
|
while ( cursor != pszUrl && L'/' != *cursor && L'\\' != *cursor && L'.' != *cursor )
|
||
|
cursor = CharPrev( pszUrl, cursor );
|
||
|
|
||
|
if ( L'.' == *cursor && cursor != pszUrl )
|
||
|
{
|
||
|
if ( CharNext( cursor ) < end )
|
||
|
{
|
||
|
INT cchExtension = (INT)(INT_PTR)( end - cursor );
|
||
|
return StringCchCopyN( pszBuffer, cchBufferMax, cursor, cchExtension );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return StringCchCopy( pszBuffer, cchBufferMax, defaultExtension );
|
||
|
}
|
||
|
|
||
|
void Plugin_ReplaceBadPathChars( LPWSTR pszPath )
|
||
|
{
|
||
|
if ( NULL == pszPath )
|
||
|
return;
|
||
|
|
||
|
while ( L'\0' != *pszPath )
|
||
|
{
|
||
|
switch ( *pszPath )
|
||
|
{
|
||
|
case L'?':
|
||
|
case L'/':
|
||
|
case L'\\':
|
||
|
case L':':
|
||
|
case L'*':
|
||
|
case L'\"':
|
||
|
case L'<':
|
||
|
case L'>':
|
||
|
case L'|':
|
||
|
*pszPath = L'_';
|
||
|
break;
|
||
|
default:
|
||
|
if ( *pszPath < 32 )
|
||
|
*pszPath = L'_';
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
pszPath = CharNextW( pszPath );
|
||
|
}
|
||
|
}
|
||
|
|
||
|
INT Plugin_CleanDirectory( LPWSTR pszPath )
|
||
|
{
|
||
|
if ( NULL == pszPath )
|
||
|
return 0;
|
||
|
|
||
|
INT cchPath = lstrlen( pszPath );
|
||
|
LPWSTR cursor = pszPath + cchPath;
|
||
|
while ( cursor-- != pszPath && ( L' ' == *cursor || L'.' == *cursor ) )
|
||
|
*cursor = L'\0';
|
||
|
|
||
|
return ( cchPath - (INT)(INT_PTR)( cursor - pszPath ) - 1 );
|
||
|
}
|
||
|
|
||
|
HRESULT Plugin_EnsurePathExist( LPCWSTR pszDirectory )
|
||
|
{
|
||
|
DWORD ec = ERROR_SUCCESS;
|
||
|
|
||
|
UINT errorMode = SetErrorMode( SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS );
|
||
|
|
||
|
if ( 0 == CreateDirectory( pszDirectory, NULL ) )
|
||
|
{
|
||
|
ec = GetLastError();
|
||
|
if ( ERROR_PATH_NOT_FOUND == ec )
|
||
|
{
|
||
|
LPCWSTR pszBlock = pszDirectory;
|
||
|
WCHAR szBuffer[ MAX_PATH ] = { 0 };
|
||
|
|
||
|
LPCTSTR pszCursor = PathFindNextComponent( pszBlock );
|
||
|
ec = ( pszCursor == pszBlock || S_OK != StringCchCopyN( szBuffer, ARRAYSIZE( szBuffer ), pszBlock, ( pszCursor - pszBlock ) ) ) ? ERROR_INVALID_NAME : ERROR_SUCCESS;
|
||
|
|
||
|
pszBlock = pszCursor;
|
||
|
|
||
|
while ( ERROR_SUCCESS == ec && NULL != ( pszCursor = PathFindNextComponent( pszBlock ) ) )
|
||
|
{
|
||
|
if ( pszCursor == pszBlock || S_OK != StringCchCatN( szBuffer, ARRAYSIZE( szBuffer ), pszBlock, ( pszCursor - pszBlock ) ) )
|
||
|
ec = ERROR_INVALID_NAME;
|
||
|
|
||
|
if ( ERROR_SUCCESS == ec && !CreateDirectory( szBuffer, NULL ) )
|
||
|
{
|
||
|
ec = GetLastError();
|
||
|
if ( ERROR_ALREADY_EXISTS == ec )
|
||
|
ec = ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
pszBlock = pszCursor;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ( ERROR_ALREADY_EXISTS == ec )
|
||
|
ec = ERROR_SUCCESS;
|
||
|
}
|
||
|
|
||
|
SetErrorMode( errorMode );
|
||
|
SetLastError( ec );
|
||
|
|
||
|
return HRESULT_FROM_WIN32( ec );
|
||
|
}
|