Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@ -0,0 +1,51 @@
#ifndef NULLSOFT_ATOMPARSEH
#define NULLSOFT_ATOMPARSEH
#if 0
#include "RFCDate.h"
#include "XMLNode.h"
#include "Feeds.h"
#include "../nu/AutoChar.h"
#include "ChannelSync.h"
void ReadAtomItem(XMLNode *item, Channel &channel)
{
}
void ReadAtomChannel(XMLNode *node, Channel &newChannel)
{
XMLNode *curNode = 0;
curNode = node->Get(L"title");
if (curNode)
newChanneltitle = curNode->content;
curNode = node->Get(L"subtitle");
if (curNode)
newChannel.description = curNode->content;
XMLNode::NodeList &links = node->GetList(L"link");
XMLNode::NodeList::iterator linkItr;
for (linkItr=links.begin();linkItr!=links.end();linkItr++)
{
if ((*linkItr)->properties[L"rel"].empty()
|| (*linkItr)->properties[L"rel"]== L"alternate")
newChannel.link = (*linkItr)->properties[L"href"];
}
XMLNode::NodeList &entries = node->GetList(L"entry");
XMLNode::NodeList::iterator entryItr;
for (entryItr=entries.begin();entryItr!=entries.end();entryItr++)
{
}
}
void ReadAtom(XMLNode *atom, ChannelSync *sync)
{
sync->BeginChannelSync();
Channel newChannel;
ReadAtomChannel(atom, newChannel);
sync->NewChannel(newChannel);
sync->EndChannelSync();
}
#endif
#endif

View File

@ -0,0 +1,12 @@
major components:
Cloud
-----
The cloud is the object which is responsible for doing period updates on RSS feeds.
It automatically scans the feeds. You can manually refresh via the Refresh(string url) method

View File

@ -0,0 +1,43 @@
#include "main.h"
#include "Defaults.h"
#include <shlobj.h>
wchar_t defaultDownloadPath[MAX_PATH] = {0};
bool needToMakePodcastsView=true;
static BOOL UtilGetSpecialFolderPath( HWND hwnd, wchar_t *path, int folder )
{
ITEMIDLIST *pidl; // Shell Item ID List ptr
IMalloc *imalloc; // Shell IMalloc interface ptr
BOOL result; // Return value
if ( SHGetSpecialFolderLocation( hwnd, folder, &pidl ) != NOERROR )
return FALSE;
result = SHGetPathFromIDList( pidl, path );
if ( SHGetMalloc( &imalloc ) == NOERROR )
{
imalloc->Free( pidl );
imalloc->Release();
}
return result;
}
static void BuildDefaultDownloadPath( HWND hwnd )
{
wchar_t defaultPath[ MAX_PATH ] = L"";
if ( !UtilGetSpecialFolderPath( hwnd, defaultPath, CSIDL_MYMUSIC ) )
UtilGetSpecialFolderPath( hwnd, defaultPath, CSIDL_PERSONAL );
lstrcpyn( defaultDownloadPath, defaultPath, MAX_PATH );
}
/*
Requires an HWND because some of the shell functions require one. Theoretically it could be NULL
*/
void BuildDefaults( HWND hwnd )
{
BuildDefaultDownloadPath( hwnd );
}

View File

@ -0,0 +1,24 @@
#ifndef NULLSOFT_DEFAULTSH
#define NULLSOFT_DEFAULTSH
#include <windows.h>
extern wchar_t defaultDownloadPath[MAX_PATH];
#define DOWNLOADSSOURCEWIDTHDEFAULT 200
#define DOWNLOADSTITLEWIDTHDEFAULT 200
#define DOWNLOADSPROGRESSWIDTHDEFAULT 100
#define DOWNLOADSDATEWIDTHDEFAULTS 100
#define DOWNLOADSSIZEWIDTHDEFAULTS 100
#define DOWNLOADSPATHWIDTHDEFAULTS 200
extern int downloadsSourceWidth,
downloadsTitleWidth,
downloadsProgressWidth,
downloadsPathWidth,
downloadsSizeWidth,
downloadsDateWidth;
extern bool needToMakePodcastsView;
void BuildDefaults(HWND);
#endif

View File

@ -0,0 +1 @@
#include "main.h"

View File

@ -0,0 +1,158 @@
#include "main.h"
#include "api__ml_downloads.h"
#include "DownloadStatus.h"
#include "DownloadsDialog.h"
#include <strsafe.h>
DownloadStatus downloadStatus;
using namespace Nullsoft::Utility;
DownloadStatus::Status::Status()
{
Init();
}
DownloadStatus::Status::Status( size_t _downloaded, size_t _maxSize, const wchar_t *_source, const wchar_t *_title, const wchar_t *_path )
{
Init();
downloaded = _downloaded;
maxSize = _maxSize;
source = _wcsdup( _source );
title = _wcsdup( _title );
path = _wcsdup( _path );
}
const DownloadStatus::Status &DownloadStatus::Status::operator =( const DownloadStatus::Status &copy )
{
Reset();
Init();
downloaded = copy.downloaded;
maxSize = copy.maxSize;
source = _wcsdup( copy.source );
title = _wcsdup( copy.title );
path = _wcsdup( copy.path );
killswitch = copy.killswitch;
return *this;
}
DownloadStatus::Status::~Status()
{
Reset();
}
void DownloadStatus::Status::Init()
{
downloaded = 0;
maxSize = 0;
killswitch = 0;
source = 0;
title = 0;
path = 0;
}
void DownloadStatus::Status::Reset()
{
if ( source )
{
free( source );
source = 0;
}
if ( title )
{
free( title );
title = 0;
}
if ( path )
{
free( path );
path = 0;
}
}
void DownloadStatus::AddDownloadThread(DownloadToken token, const wchar_t *source, const wchar_t *title, const wchar_t *path)
{
{
AutoLock lock(statusLock);
downloads[token] = Status(0,0,source,title,path);
DownloadsUpdated(downloads[token],token);
}
static pluginMessage p = {ML_MSG_DOWNLOADS_VIEW_POSITION, 0, 0, 0};
PostMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&p, ML_IPC_SEND_PLUGIN_MESSAGE);
}
void DownloadStatus::DownloadThreadDone(DownloadToken token)
{
{
AutoLock lock(statusLock);
downloads.erase(token);
}
static pluginMessage p = {ML_MSG_DOWNLOADS_VIEW_POSITION, 0, 0, 0};
PostMessage(plugin.hwndLibraryParent, WM_ML_IPC, (WPARAM)&p, ML_IPC_SEND_PLUGIN_MESSAGE);
}
bool DownloadStatus::UpdateStatus(DownloadToken token, size_t downloaded, size_t maxSize)
{
AutoLock lock(statusLock);
downloads[token].downloaded = downloaded;
downloads[token].maxSize = maxSize;
return !!downloads[token].killswitch;
}
bool DownloadStatus::CurrentlyDownloading()
{
AutoLock lock(statusLock);
return !downloads.empty();
}
void DownloadStatus::GetStatusString( wchar_t *status, size_t len )
{
AutoLock lock( statusLock );
Downloads::iterator itr;
size_t bytesDownloaded = 0, bytesTotal = 0, numDownloads = 0;
bool unknownTotal = false;
for ( itr = downloads.begin(); itr != downloads.end(); itr++ )
{
Status &dlstatus = itr->second;
if ( dlstatus.maxSize )
{
numDownloads++;
bytesDownloaded += dlstatus.downloaded;
bytesTotal += dlstatus.maxSize;
}
else // don't have a max size
{
if ( dlstatus.downloaded ) // if we've downloaded some then we just don't know the total
{
unknownTotal = true;
numDownloads++;
bytesDownloaded += dlstatus.downloaded;
}
}
}
if ( 0 == numDownloads )
{
status[ 0 ] = L'\0';
}
else
{
wchar_t buf[ 128 ] = { 0 };
if ( unknownTotal || bytesTotal == 0 )
StringCchPrintf( status, len, WASABI_API_LNGSTRINGW( IDS_DOWNLOADING_COMPLETE ), numDownloads, numDownloads, WASABI_API_LNG->FormattedSizeString( buf, ARRAYSIZE( buf ), bytesDownloaded ) );
else
{
wchar_t buf2[ 128 ] = { 0 };
StringCchPrintf( status, len, WASABI_API_LNGSTRINGW( IDS_DOWNLOADING_PROGRESS ), numDownloads, WASABI_API_LNG->FormattedSizeString( buf, ARRAYSIZE( buf ), bytesDownloaded ), WASABI_API_LNG->FormattedSizeString( buf2, ARRAYSIZE( buf2 ), bytesTotal ), MulDiv( (int)bytesDownloaded, 100, (int)bytesTotal ) );
}
}
}

View File

@ -0,0 +1,41 @@
#ifndef NULLSOFT_DOWNLOADSTATUSH
#define NULLSOFT_DOWNLOADSTATUSH
#include "../nu/AutoLock.h"
#include <map>
class DownloadStatus
{
public:
class Status
{
public:
Status();
~Status();
const Status &operator =(const Status &copy);
Status(size_t _downloaded, size_t _maxSize, const wchar_t *source, const wchar_t *title, const wchar_t *path);
size_t downloaded, maxSize;
int killswitch;
wchar_t *source;
wchar_t *title;
wchar_t *path;
private:
void Init();
void Reset();
};
void AddDownloadThread(DownloadToken token, const wchar_t *source, const wchar_t *title, const wchar_t *path);
void DownloadThreadDone(DownloadToken token);
bool UpdateStatus(DownloadToken token, size_t downloaded, size_t maxSize);
bool CurrentlyDownloading();
void GetStatusString(wchar_t *status, size_t len);
typedef std::map<DownloadToken, Status> Downloads;
Downloads downloads;
Nullsoft::Utility::LockGuard statusLock;
};
extern DownloadStatus downloadStatus;
#endif

View File

@ -0,0 +1,65 @@
#include "Main.h"
#pragma warning(disable:4786)
#include "DownloadThread.h"
#include "api__ml_downloads.h"
#include <api/service/waServiceFactory.h>
#include "errors.h"
#include <strsafe.h>
DownloadThread::DownloadThread() : parser( 0 ), parserFactory( 0 )
{
parserFactory = plugin.service->service_getServiceByGuid( obj_xmlGUID );
if ( parserFactory )
parser = (obj_xml *)parserFactory->getInterface();
if ( parser )
{
parser->xmlreader_setCaseSensitive();
parser->xmlreader_registerCallback( L"*", &xmlDOM );
parser->xmlreader_open();
}
}
DownloadThread::~DownloadThread()
{
if ( parser )
{
parser->xmlreader_unregisterCallback( &xmlDOM );
parser->xmlreader_close();
}
if ( parserFactory && parser )
parserFactory->releaseInterface( parser );
parserFactory = 0;
parser = 0;
}
#define FILE_BUFFER_SIZE 32768
void DownloadThread::DownloadFile( const wchar_t *fileName )
{
if ( !parser )
return; // no sense in continuing if there's no parser available
HANDLE file = CreateFile( fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL );
if ( file == INVALID_HANDLE_VALUE )
return;
while ( true )
{
char data[ FILE_BUFFER_SIZE ] = { 0 };
DWORD bytesRead = 0;
if ( ReadFile( file, data, FILE_BUFFER_SIZE, &bytesRead, NULL ) && bytesRead )
{
parser->xmlreader_feed( (void *)data, bytesRead );
}
else
break;
}
CloseHandle( file );
parser->xmlreader_feed( 0, 0 );
ReadNodes( fileName );
}

View File

@ -0,0 +1,27 @@
#ifndef NULLSOFT_DOWNLOADTHREADH
#define NULLSOFT_DOWNLOADTHREADH
#include "../xml/obj_xml.h"
#include "../xml/XMLDOM.h"
#include "../nu/Alias.h"
#include "api__ml_downloads.h"
#include <api/service/waServiceFactory.h>
class DownloadThread
{
public:
DownloadThread();
virtual ~DownloadThread();
virtual void ReadNodes(const wchar_t *url) = 0;
void DownloadFile(const wchar_t *fileName);
protected:
XMLDOM xmlDOM;
private:
obj_xml *parser;
waServiceFactory *parserFactory;
};
#endif

View File

@ -0,0 +1,125 @@
#include "Main.h"
//#include "../Components/wac_downloads/wac_downloads_download_manager.h"
using namespace Nullsoft::Utility;
DownloadViewCallback::DownloadViewCallback()
{}
void DownloadViewCallback::OnInit( DownloadToken token )
{
// ---- Inform the download status service of our presence----
downloadStatus.AddDownloadThread( token, WAC_API_DOWNLOADMANAGER->GetSource( token ), WAC_API_DOWNLOADMANAGER->GetTitle( token ), WAC_API_DOWNLOADMANAGER->GetLocation( token ) );
}
void DownloadViewCallback::OnConnect( DownloadToken token )
{}
void DownloadViewCallback::OnData( DownloadToken token, void *data, size_t datalen )
{
if ( token == NULL )
return;
api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver( token );
size_t totalSize = http->content_length();
size_t downloaded = (size_t)WAC_API_DOWNLOADMANAGER->GetBytesDownloaded( token );
// if killswitch is turned on, then cancel download
downloadStatus.UpdateStatus( token, downloaded, totalSize );
dirty++;
}
void DownloadViewCallback::OnCancel( DownloadToken token )
{
api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver( token );
DownloadedFile *data = new DownloadedFile( AutoWide( http->get_url() ), WAC_API_DOWNLOADMANAGER->GetLocation( token ), WAC_API_DOWNLOADMANAGER->GetSource( token ), WAC_API_DOWNLOADMANAGER->GetTitle( token ), DownloadedFile::DOWNLOAD_CANCELED, _time64( 0 ) );
data->totalSize = http->content_length();
data->bytesDownloaded = (size_t)WAC_API_DOWNLOADMANAGER->GetBytesDownloaded( token );
{
AutoLock lock( downloadedFiles );
downloadedFiles.downloadList.push_back( *data );
DownloadsUpdated( token, &downloadedFiles.downloadList[ downloadedFiles.downloadList.size() - 1 ] );
}
downloadStatus.DownloadThreadDone( token );
delete data;
dirty++;
}
void DownloadViewCallback::OnError( DownloadToken token, int error )
{
api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver( token );
DownloadedFile *data = new DownloadedFile( AutoWide( http->get_url() ), WAC_API_DOWNLOADMANAGER->GetLocation( token ), WAC_API_DOWNLOADMANAGER->GetSource( token ), WAC_API_DOWNLOADMANAGER->GetTitle( token ), DownloadedFile::DOWNLOAD_FAILURE, _time64( 0 ) );
data->totalSize = http->content_length();
data->bytesDownloaded = (size_t)WAC_API_DOWNLOADMANAGER->GetBytesDownloaded( token );
{
AutoLock lock( downloadedFiles );
downloadedFiles.downloadList.push_back( *data );
DownloadsUpdated( token, &downloadedFiles.downloadList[ downloadedFiles.downloadList.size() - 1 ] );
}
downloadStatus.DownloadThreadDone( token );
delete data;
dirty++;
}
void DownloadViewCallback::OnFinish( DownloadToken token )
{
api_httpreceiver *http = WAC_API_DOWNLOADMANAGER->GetReceiver( token );
DownloadedFile *data = new DownloadedFile( AutoWide( http->get_url() ), WAC_API_DOWNLOADMANAGER->GetLocation( token ), WAC_API_DOWNLOADMANAGER->GetSource( token ), WAC_API_DOWNLOADMANAGER->GetTitle( token ), DownloadedFile::DOWNLOAD_SUCCESS, _time64( 0 ) );
data->totalSize = http->content_length();
data->bytesDownloaded = (size_t)WAC_API_DOWNLOADMANAGER->GetBytesDownloaded( token );
{
AutoLock lock( downloadedFiles );
downloadedFiles.downloadList.push_back( *data );
//AddDownloadData(*data);
DownloadsUpdated( token, &downloadedFiles.downloadList[ downloadedFiles.downloadList.size() - 1 ] );
}
downloadStatus.DownloadThreadDone( token );
delete data;
dirty++;
}
size_t DownloadViewCallback::AddRef()
{
return this->_ref_count.fetch_add( 1 );
}
size_t DownloadViewCallback::Release()
{
std::size_t l_ref_countr = this->_ref_count.fetch_sub( 1 );
if ( l_ref_countr == 0 )
delete( this );
return l_ref_countr;
}
DownloadViewCallback::~DownloadViewCallback()
{}
#define CBCLASS DownloadViewCallback
START_DISPATCH;
VCB( IFC_DOWNLOADMANAGERCALLBACK_ONFINISH, OnFinish )
VCB( IFC_DOWNLOADMANAGERCALLBACK_ONCANCEL, OnCancel )
VCB( IFC_DOWNLOADMANAGERCALLBACK_ONERROR, OnError )
VCB( IFC_DOWNLOADMANAGERCALLBACK_ONDATA, OnData )
VCB( IFC_DOWNLOADMANAGERCALLBACK_ONCONNECT, OnConnect )
VCB( IFC_DOWNLOADMANAGERCALLBACK_ONINIT, OnInit )
CB( ADDREF, AddRef )
CB( RELEASE, Release )
END_DISPATCH;
#undef CBCLASS

View File

@ -0,0 +1,37 @@
#include <atomic>
#include "Main.h"
#include "Downloaded.h"
#include "DownloadStatus.h"
#include "DownloadsDialog.h"
#include "api__ml_downloads.h"
#include "api/service/waServiceFactory.h"
#include "../../..\Components\wac_network\wac_network_http_receiver_api.h"
class DownloadViewCallback : public ifc_downloadManagerCallback
{
public:
DownloadViewCallback();
void OnInit( DownloadToken token );
void OnConnect( DownloadToken token );
void OnData( DownloadToken token, void *data, size_t datalen );
void OnCancel( DownloadToken token );
void OnError( DownloadToken token, int error );
void OnFinish( DownloadToken token );
size_t AddRef();
size_t Release();
private: // private destructor so no one accidentally calls delete directly on this reference counted object
~DownloadViewCallback();
protected:
RECVS_DISPATCH;
private:
std::atomic<std::size_t> _ref_count = 1;
};

View File

@ -0,0 +1,141 @@
#include "main.h"
#include "Downloaded.h"
DownloadList downloadedFiles;
using namespace Nullsoft::Utility;
Nullsoft::Utility::LockGuard downloadedLock;
DownloadedFile::DownloadedFile()
{
Init();
}
DownloadedFile::DownloadedFile( const wchar_t *_url, const wchar_t *_path, const wchar_t *_source, const wchar_t *_title, int downloadStatus, __time64_t downloadDate )
{
Init();
this->downloadStatus = downloadStatus;
this->downloadDate = downloadDate;
SetSource( _source );
SetTitle( _title );
SetPath( _path );
SetURL( _url );
}
DownloadedFile::DownloadedFile( const DownloadedFile &copy )
{
Init();
operator =( copy );
}
DownloadedFile::~DownloadedFile()
{
Reset();
}
void DownloadedFile::Init()
{
url = 0;
path = 0;
source = 0;
title = 0;
bytesDownloaded = 0;
totalSize = 0;
downloadDate = 0;
}
void DownloadedFile::Reset()
{
if ( url )
{
free( url );
url = 0;
}
if ( path )
{
free( path );
path = 0;
}
if ( source )
{
free( source );
source = 0;
}
if ( title )
{
free( title );
title = 0;
}
}
void DownloadedFile::SetPath( const wchar_t *_path )
{
if ( path )
free( path );
path = _wcsdup( _path );
}
void DownloadedFile::SetURL( const wchar_t *_url )
{
if ( url )
free( url );
url = _wcsdup( _url );
}
void DownloadedFile::SetTitle( const wchar_t *_title )
{
if ( title )
free( title );
title = _wcsdup( _title );
}
void DownloadedFile::SetSource( const wchar_t *_source )
{
if ( source )
free( source );
source = _wcsdup( _source );
}
const DownloadedFile &DownloadedFile::operator =( const DownloadedFile &copy )
{
Reset();
Init();
SetSource( copy.source );
SetTitle( copy.title );
bytesDownloaded = copy.bytesDownloaded;
totalSize = copy.totalSize;
downloadStatus = copy.downloadStatus;
downloadDate = copy.downloadDate;
SetPath( copy.path );
SetURL( copy.url );
return *this;
}
wchar_t *GetDownloadStatus( int downloadStatus )
{
switch ( downloadStatus )
{
case DownloadedFile::DOWNLOAD_SUCCESS:
return WASABI_API_LNGSTRINGW( IDS_DOWNLOAD_SUCCESS );
case DownloadedFile::DOWNLOAD_FAILURE:
return WASABI_API_LNGSTRINGW( IDS_DOWNLOAD_FAILURE );
case DownloadedFile::DOWNLOAD_CANCELED:
return WASABI_API_LNGSTRINGW( IDS_DOWNLOAD_CANCELED );
default:
return WASABI_API_LNGSTRINGW( IDS_DOWNLOAD_FAILURE );
}
}

View File

@ -0,0 +1,86 @@
#ifndef NULLSOFT_DOWNLOADEDH
#define NULLSOFT_DOWNLOADEDH
#include "../nu/AutoLock.h"
#include "../nu/AutoCharFn.h"
#include "..\..\General\gen_ml/ml.h"
#include <vector>
#include "../nu/MediaLibraryInterface.h"
class DownloadedFile
{
public:
DownloadedFile();
DownloadedFile( const wchar_t *_url, const wchar_t *_path, const wchar_t *_source, const wchar_t *_title, int downloadStatus, __time64_t downloadDate );
DownloadedFile( const DownloadedFile &copy );
~DownloadedFile();
const DownloadedFile &operator =( const DownloadedFile &copy );
void SetPath( const wchar_t *_path );
void SetURL( const wchar_t *_url );
void SetTitle( const wchar_t *_title );
void SetSource( const wchar_t *_source );
enum
{
DOWNLOAD_FAILURE = 0,
DOWNLOAD_SUCCESS = 1,
DOWNLOAD_CANCELED = 2,
};
size_t bytesDownloaded = 0;
size_t totalSize = 0;
int downloadStatus = 0;
__time64_t downloadDate = 0;
wchar_t *path = 0;
wchar_t *url = 0;
wchar_t *source = 0;
wchar_t *title = 0;
private:
void Init();
void Reset();
};
class DownloadList
{
public:
typedef std::vector<DownloadedFile> DownloadedFileList;
typedef DownloadedFileList::iterator iterator;
typedef DownloadedFileList::const_iterator const_iterator;
operator Nullsoft::Utility::LockGuard &() { return downloadedLock; }
void Remove( size_t index ) { downloadList.erase( downloadList.begin() + index ); }
bool RemoveAndDelete( int index )
{
SendMessage( mediaLibrary.library, WM_ML_IPC, (WPARAM)downloadList[ index ].path, ML_IPC_DB_REMOVEITEMW );
if ( !DeleteFile( downloadList[ index ].path ) && GetLastError() != ERROR_FILE_NOT_FOUND )
return false;
downloadList.erase( downloadList.begin() + index );
return true;
}
DownloadedFileList downloadList;
Nullsoft::Utility::LockGuard downloadedLock;
iterator begin() { return downloadList.begin(); }
iterator end() { return downloadList.end(); }
};
extern DownloadList downloadedFiles;
extern int downloadsItemSort;
extern bool downloadsSortAscending;
void CleanupDownloads();
wchar_t *GetDownloadStatus( int downloadStatus );
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,11 @@
#ifndef NULLSOFT_DOWNLOADSDIALOGH
#define NULLSOFT_DOWNLOADSDIALOGH
#include "DownloadStatus.h"
#include "Downloaded.h"
void DownloadsUpdated();
void DownloadsUpdated( DownloadToken token, const DownloadedFile *f );
void DownloadsUpdated( const DownloadStatus::Status &s, DownloadToken token );
#endif

View File

@ -0,0 +1,179 @@
#include "Main.h"
#include "DownloadsParse.h"
#include "Downloaded.h"
#include "Defaults.h"
#include "ParseUtil.h"
#include <wchar.h>
#include <locale.h>
static __time64_t filetime( const wchar_t *file )
{
if ( !file || !*file )
return 0;
WIN32_FIND_DATAW f = { 0 };
HANDLE h = FindFirstFileW( file, &f );
if ( h == INVALID_HANDLE_VALUE )
{
/*wchar_t tmp[128] = {0};
wsprintf(tmp,L"%d",GetLastError());
MessageBox(0,file,tmp,0);*/
return 0;
}
FindClose( h );
SYSTEMTIME s = { 0 };
FileTimeToSystemTime( &f.ftCreationTime, &s );
tm t = { 0 };
t.tm_year = s.wYear - 1900;
t.tm_mon = s.wMonth - 1;
t.tm_mday = s.wDay;
t.tm_hour = s.wHour;
t.tm_min = s.wMinute;
t.tm_sec = s.wMinute;
__time64_t ret = _mktime64(&t);
/*wchar_t tmp[128] = {0};
wsprintf(tmp,L"%d",ret);
MessageBox(0,tmp,0,0);*/
return ret;
}
size_t GetFileSize(LPCWSTR path)
{
WIN32_FIND_DATAW data = {0};
if (path && *path)
{
HANDLE h = FindFirstFileW(path, &data);
if (h == INVALID_HANDLE_VALUE)
return -1;
FindClose(h);
}
return data.nFileSizeLow/* | (__int64)data.nFileSizeHigh << 32*/;
}
static void ReadDownload( const XMLNode *item )
{
DownloadedFile newDownloaded;
const wchar_t *source = GetContent( item, L"source" );
if ( !source ) source = GetContent( item, L"channel" );
newDownloaded.SetSource( source );
const wchar_t *title = GetContent( item, L"title" );
if ( !title ) title = GetContent( item, L"item" );;
newDownloaded.SetTitle( title );
const wchar_t *url = GetContent( item, L"url" );
newDownloaded.SetURL( url );
const wchar_t *path = GetContent( item, L"path" );
newDownloaded.SetPath( path );
// TODO ideally should be able to cope with __int64
// but the db is setup for int currently...
const wchar_t *size = GetContent( item, L"size" );
if ( size && size[ 0 ] )
{
size_t val = _wtoi( size );
if ( val > 0 ) newDownloaded.totalSize = val;
else if ( !val )
{
val = GetFileSize( path );
if ( val > 0 ) newDownloaded.totalSize = val;
else newDownloaded.totalSize = -1;
dirty++;
}
}
else
{
size_t val = GetFileSize( path );
if ( val > 0 ) newDownloaded.totalSize = val;
else newDownloaded.totalSize = -1;
dirty++;
}
const wchar_t *downloadDate = GetContent( item, L"downloadDate" );
if ( downloadDate && downloadDate[ 0 ] )
{
__time64_t val = (__time64_t)_wtoi( downloadDate );
if ( time > 0 ) newDownloaded.downloadDate = val;
}
else
{
__time64_t val = filetime( newDownloaded.path );
if ( time > 0 ) newDownloaded.downloadDate = val;
}
const wchar_t *status = GetContent( item, L"downloadStatus" );
if ( status && status[ 0 ] )
{
newDownloaded.downloadStatus = _wtoi( status );
}
else
{
newDownloaded.downloadStatus = DownloadedFile::DOWNLOAD_SUCCESS;
}
downloadedFiles.downloadList.push_back( newDownloaded );
}
void DownloadsParse::ReadNodes( const wchar_t *url )
{
XMLNode::NodeList::const_iterator itr;
const XMLNode *curNode = xmlDOM.GetRoot();
if ( curNode->Present( L"winamp:preferences" ) )
curNode = curNode->Get( L"winamp:preferences" );
curNode = curNode->Get( L"downloads" );
if ( curNode )
{
const wchar_t *prop = curNode->GetProperty( L"downloadsTitleWidth" );
if ( prop && prop[ 0 ] )
downloadsTitleWidth = _wtoi( prop );
if ( downloadsTitleWidth <= 0 )
downloadsTitleWidth = DOWNLOADSTITLEWIDTHDEFAULT;
prop = curNode->GetProperty( L"downloadsProgressWidth" );
if ( prop && prop[ 0 ] )
downloadsProgressWidth = _wtoi( prop );
if ( downloadsProgressWidth <= 0 )
downloadsProgressWidth = DOWNLOADSPROGRESSWIDTHDEFAULT;
prop = curNode->GetProperty( L"downloadsDateWidth" );
if ( prop && prop[ 0 ] )
downloadsDateWidth = _wtoi( prop );
if ( downloadsDateWidth <= 0 )
downloadsDateWidth = DOWNLOADSDATEWIDTHDEFAULTS;
prop = curNode->GetProperty( L"downloadsSourceWidth" );
if ( prop && prop[ 0 ] )
downloadsSourceWidth = _wtoi( prop );
if ( downloadsSourceWidth <= 0 )
downloadsSourceWidth = DOWNLOADSSOURCEWIDTHDEFAULT;
prop = curNode->GetProperty( L"downloadsPathWidth" );
if ( prop && prop[ 0 ] )
downloadsPathWidth = _wtoi( prop );
if ( downloadsPathWidth <= 0 )
downloadsPathWidth = DOWNLOADSPATHWIDTHDEFAULTS;
prop = curNode->GetProperty( L"downloadsItemSort" );
if ( prop && prop[ 0 ] )
downloadsItemSort = _wtoi( prop );
prop = curNode->GetProperty( L"downloadsSortAscending" );
if ( prop && prop[ 0 ] )
downloadsSortAscending = !PropertyIsFalse( curNode, L"downloadsSortAscending" );
const XMLNode::NodeList *downloadsList = curNode->GetList( L"download" );
if ( downloadsList )
{
for ( itr = downloadsList->begin(); itr != downloadsList->end(); itr++ )
ReadDownload( *itr );
}
}
}

View File

@ -0,0 +1,13 @@
#ifndef NULLSOFT_DOWNLOADSPARSEH
#define NULLSOFT_DOWNLOADSPARSEH
#include "DownloadThread.h"
class DownloadsParse : public DownloadThread
{
public:
virtual void ReadNodes(const wchar_t *url);
};
#endif

View File

@ -0,0 +1,387 @@
#include "main.h"
#include "DownloadsDialog.h"
#include "DownloadsParse.h"
#include "Preferences.h"
#include "XMLWriter.h"
#include "..\..\General\gen_ml/ml.h"
#include "Defaults.h"
#include "..\..\General\gen_ml/ml_ipc_0313.h"
#include "api__ml_downloads.h"
#include "Downloaded.h"
#include "DownloadStatus.h"
#include <api/service/waServiceFactory.h>
#include <strsafe.h>
wchar_t *ml_cfg = 0,
xmlFileName[1024] = {0};
ATOM VIEWPROP = 0;
api_downloadManager *WAC_API_DOWNLOADMANAGER = 0;
DownloadViewCallback *downloadViewCallback = 0;
static int Init();
static void Quit();
static INT_PTR MessageProc(int message_type, INT_PTR param1, INT_PTR param2, INT_PTR param3);
DWORD threadStorage=TLS_OUT_OF_INDEXES;
extern "C" winampMediaLibraryPlugin plugin =
{
MLHDR_VER,
"nullsoft(ml_downloads.dll)",
Init,
Quit,
MessageProc,
0,
0,
0,
};
//static prefsDlgRecW preferences;
//static wchar_t preferencesName[64] = {0};
int downloads_treeItem = 0,
podcast_parent = 0,
no_auto_hide = 0;
HANDLE hMainThread;
HCURSOR hDragNDropCursor;
int winampVersion = 0, dirty = 0;
api_application *applicationApi = NULL;
api_explorerfindfile *WASABI_API_EXPLORERFINDFILE = 0;
// wasabi based services for localisation support
api_language *WASABI_API_LNG = 0;
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
int icons[4] = {-1, -1, -1, -1};
int activeIcon = 0;
int totalIcons = 4;
static Nullsoft::Utility::LockGuard navigationLock;
// used to get the downloads view parented to the podcast view
#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
#define NAVITEM_PREFIX L"podcast_svc_"
#define SERVICE_PODCAST 720
enum
{
DOWNLOADS_TIMER_NAVNODE = 35784,
};
HNAVITEM Navigation_FindService(UINT serviceId)
{
HWND hLibrary = plugin.hwndLibraryParent;
INT cchPrefix = ARRAYSIZE(NAVITEM_PREFIX) - 1;
WCHAR szBuffer[256] = {0};
NAVITEM itemInfo = {0};
itemInfo.cbSize = sizeof(itemInfo);
itemInfo.mask = NIMF_TEXTINVARIANT;
itemInfo.cchInvariantMax = ARRAYSIZE(szBuffer);
itemInfo.pszInvariant = szBuffer;
itemInfo.hItem = MLNavCtrl_GetFirst(hLibrary);
while(NULL != itemInfo.hItem)
{
if (FALSE != MLNavItem_GetInfo(hLibrary, &itemInfo) &&
CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, itemInfo.pszInvariant, cchPrefix,
NAVITEM_PREFIX, cchPrefix))
{
return itemInfo.hItem;
}
itemInfo.hItem = MLNavItem_GetNext(hLibrary, itemInfo.hItem);
}
return NULL;
}
void Navigation_Update_Icon(void)
{
Nullsoft::Utility::AutoLock navlock(navigationLock);
HNAVITEM hItem = NULL;
if(downloads_treeItem)
{
hItem = MLNavCtrl_FindItemById(plugin.hwndLibraryParent,downloads_treeItem);
}
if (hItem)
{
NAVITEM item;
item.cbSize = sizeof(NAVITEM);
item.hItem = hItem;
item.iSelectedImage = item.iImage = icons[activeIcon];
activeIcon = (activeIcon + 1) % totalIcons;
item.mask = NIMF_IMAGE | NIMF_IMAGESEL;
MLNavItem_SetInfo(plugin.hwndLibraryParent, &item);
}
}
BOOL Navigation_Update(void)
{
int activeDownloads = 0;
int historyDownloads = 0;
{
Nullsoft::Utility::AutoLock historylock(downloadedFiles.downloadedLock);
historyDownloads = (int)downloadedFiles.downloadList.size();
}
{
Nullsoft::Utility::AutoLock statuslock(downloadStatus.statusLock);
activeDownloads = (int)downloadStatus.downloads.size();
}
Nullsoft::Utility::AutoLock navlock(navigationLock);
HNAVITEM hItem = NULL;
if (downloads_treeItem)
{
hItem = MLNavCtrl_FindItemById(plugin.hwndLibraryParent,downloads_treeItem);
}
NAVINSERTSTRUCT nis = {0};
nis.item.cbSize = sizeof(NAVITEM);
nis.item.pszText = WASABI_API_LNGSTRINGW(IDS_DOWNLOADS);
nis.item.iSelectedImage = nis.item.iImage = icons[0];
WCHAR szName[256] = {0};
if (activeDownloads && SUCCEEDED(StringCchPrintf(szName, ARRAYSIZE(szName), L"%s (%u)", WASABI_API_LNGSTRINGW(IDS_DOWNLOADS), activeDownloads)))
nis.item.pszText = szName;
if (activeDownloads > 0 || historyDownloads > 0 || no_auto_hide == 2)
{
if (!hItem)
{
nis.item.pszInvariant = NAVITEM_UNIQUESTR;
nis.item.mask = NIMF_TEXT | NIMF_TEXTINVARIANT | NIMF_IMAGE | NIMF_IMAGESEL;
if(podcast_parent) nis.hParent = Navigation_FindService(SERVICE_PODCAST);
NAVITEM nvItem = {sizeof(NAVITEM),0,NIMF_ITEMID,};
nvItem.hItem = MLNavCtrl_InsertItem(plugin.hwndLibraryParent, &nis);
MLNavItem_GetInfo(plugin.hwndLibraryParent, &nvItem);
downloads_treeItem = nvItem.id;
}
else
{
nis.item.hItem = hItem;
nis.item.mask = NIMF_TEXT;
MLNavItem_SetInfo(plugin.hwndLibraryParent, &nis.item);
}
}
else if (hItem)
{
nis.item.hItem = hItem;
nis.item.mask = NIMF_TEXT | NIMF_IMAGE | NIMF_IMAGESEL;
MLNavItem_SetInfo(plugin.hwndLibraryParent, &nis.item);
}
return TRUE;
}
void CALLBACK Downloads_Nav_Timer(HWND hwnd, UINT uMsg, UINT_PTR eventId, ULONG elapsed)
{
switch (eventId)
{
case DOWNLOADS_TIMER_NAVNODE:
if (downloadStatus.CurrentlyDownloading())
Navigation_Update_Icon();
break;
}
}
int Init()
{
hMainThread = GetCurrentThread();
hDragNDropCursor = LoadCursor( GetModuleHandle( L"gen_ml.dll" ), MAKEINTRESOURCE( ML_IDC_DRAGDROP ) );
threadStorage = TlsAlloc();
if ( 0 == VIEWPROP )
{
VIEWPROP = GlobalAddAtom( L"Nullsoft_DownloadsView" );
if ( VIEWPROP == 0 )
return ML_INIT_FAILURE;
}
winampVersion = (int)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETVERSION );
waServiceFactory *sf = plugin.service->service_getServiceByGuid( DownloadManagerGUID );
if ( !sf ) // no sense in continuing
return ML_INIT_FAILURE;
else
WAC_API_DOWNLOADMANAGER = reinterpret_cast<api_downloadManager *>( sf->getInterface() );
// loader so that we can get the localisation service api for use
sf = plugin.service->service_getServiceByGuid( languageApiGUID );
if ( sf )
WASABI_API_LNG = reinterpret_cast<api_language*>( sf->getInterface() );
sf = plugin.service->service_getServiceByGuid( applicationApiServiceGuid );
if ( sf )
WASABI_API_APP = reinterpret_cast<api_application*>( sf->getInterface() );
sf = plugin.service->service_getServiceByGuid( ExplorerFindFileApiGUID );
if ( sf )
WASABI_API_EXPLORERFINDFILE = reinterpret_cast<api_explorerfindfile*>( sf->getInterface() );
// need to have this initialised before we try to do anything with localisation features
WASABI_API_START_LANG( plugin.hDllInstance, MlDownloadsLangGUID );
static wchar_t szDescription[ 256 ];
StringCchPrintf( szDescription, ARRAYSIZE( szDescription ), WASABI_API_LNGSTRINGW( IDS_PLUGIN_NAME ), PLUGIN_VERSION_MAJOR, PLUGIN_VERSION_MINOR );
plugin.description = (char*)szDescription;
mediaLibrary.library = plugin.hwndLibraryParent;
mediaLibrary.winamp = plugin.hwndWinampParent;
mediaLibrary.instance = plugin.hDllInstance;
BuildDefaults( plugin.hwndWinampParent );
mediaLibrary.BuildPath( L"Plugins\\ml\\downloads.xml", xmlFileName, 1024 );
if ( PathFileExists( xmlFileName ) )
{
DownloadsParse downloader;
downloader.DownloadFile( xmlFileName );
}
else
{
wchar_t xmlRssFileName[ 1024 ] = { 0 };
mediaLibrary.BuildPath( L"Plugins\\ml\\feeds\\rss.xml", xmlRssFileName, 1024 );
{
DownloadsParse rssDownloader;
rssDownloader.DownloadFile( xmlRssFileName );
}
}
icons[ 0 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS );
icons[ 1 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS1 );
icons[ 2 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS2 );
icons[ 3 ] = mediaLibrary.AddTreeImageBmp( IDB_TREEITEM_DOWNLOADS3 );
ml_cfg = (wchar_t *)SendMessage( plugin.hwndWinampParent, WM_WA_IPC, 0, IPC_GETMLINIFILEW );
podcast_parent = ( !!GetPrivateProfileInt( L"gen_ml_config", L"podcast_parent", 0, ml_cfg ) );
no_auto_hide = GetPrivateProfileInt( L"gen_ml_config", L"no_auto_hide", 0, ml_cfg );
Navigation_Update();
downloadViewCallback = new DownloadViewCallback();
WAC_API_DOWNLOADMANAGER->RegisterStatusCallback( downloadViewCallback );
SetTimer( plugin.hwndLibraryParent, DOWNLOADS_TIMER_NAVNODE, 1000, Downloads_Nav_Timer );
return ML_INIT_SUCCESS;
}
void Quit()
{
KillTimer( plugin.hwndLibraryParent, DOWNLOADS_TIMER_NAVNODE );
// If there are still files downloading, cancel download to remove incomplete downloaded files
while ( downloadStatus.CurrentlyDownloading() )
{
Nullsoft::Utility::AutoLock lock(downloadStatus.statusLock);
DownloadToken dltoken = downloadStatus.downloads.begin()->first;
WAC_API_DOWNLOADMANAGER->CancelDownload(dltoken);
}
if (dirty)
{
SaveDownloads( xmlFileName, downloadedFiles );
dirty = 0;
}
WAC_API_DOWNLOADMANAGER->UnregisterStatusCallback( downloadViewCallback );
downloadViewCallback->Release();
waServiceFactory *sf = plugin.service->service_getServiceByGuid( applicationApiServiceGuid );
if ( sf != NULL )
sf->releaseInterface(WASABI_API_APP);
sf = plugin.service->service_getServiceByGuid(ExplorerFindFileApiGUID);
if ( sf != NULL )
sf->releaseInterface(WASABI_API_EXPLORERFINDFILE);
sf = plugin.service->service_getServiceByGuid(DownloadManagerGUID);
if ( sf != NULL )
sf->releaseInterface(WAC_API_DOWNLOADMANAGER);
if ( VIEWPROP != 0 )
{
GlobalDeleteAtom(VIEWPROP);
VIEWPROP = 0;
}
}
HWND CALLBACK DownloadDialog_Create( HWND hParent );
INT_PTR MessageProc( int msg, INT_PTR param1, INT_PTR param2, INT_PTR param3 )
{
switch ( msg )
{
case ML_MSG_DOWNLOADS_VIEW_LOADED:
return TRUE;
case ML_MSG_DOWNLOADS_VIEW_POSITION:
{
// toggle the position of the node based on the preferences settings
if ( param2 )
{
podcast_parent = (int)param1;
if ( downloads_treeItem )
{
HNAVITEM hItem = MLNavCtrl_FindItemById( plugin.hwndLibraryParent, downloads_treeItem );
if (hItem)
{
if ( MLNavCtrl_DeleteItem( plugin.hwndLibraryParent, hItem ) )
{
downloads_treeItem = 0;
}
}
}
}
Navigation_Update();
return 0;
}
case ML_MSG_TREE_ONCREATEVIEW:
return ( param1 == downloads_treeItem ) ? (INT_PTR)DownloadDialog_Create( (HWND)param2 ) : 0;
case ML_MSG_NO_CONFIG:
return TRUE;
case ML_MSG_NOTOKTOQUIT:
if (downloadStatus.CurrentlyDownloading())
{
wchar_t titleStr[32] = {0};
if ( MessageBox( plugin.hwndLibraryParent, WASABI_API_LNGSTRINGW( IDS_CANCEL_DOWNLOADS_AND_QUIT ), WASABI_API_LNGSTRINGW_BUF( IDS_CONFIRM_QUIT, titleStr, 32 ), MB_YESNO | MB_ICONQUESTION ) == IDNO )
return TRUE;
}
return FALSE;
case ML_MSG_WRITE_CONFIG:
if ( dirty )
{
SaveDownloads( xmlFileName, downloadedFiles );
dirty = 0;
}
break;
case ML_MSG_VIEW_PLAY_ENQUEUE_CHANGE:
enqueuedef = (int)param1;
groupBtn = (int)param2;
PostMessage( downloads_window, WM_APP + 104, param1, param2 );
return 0;
}
return 0;
}
extern "C" __declspec(dllexport) winampMediaLibraryPlugin *winampGetMediaLibraryPlugin()
{
return &plugin;
}

View File

@ -0,0 +1,43 @@
#ifndef NULLSOFT_MAINH
#define NULLSOFT_MAINH
#include "Downloaded.h"
#define PLUGIN_VERSION_MAJOR 1
#define PLUGIN_VERSION_MINOR 33
extern int winampVersion, podcast_parent, dirty;
#define NAVITEM_UNIQUESTR L"download_svc"
BOOL Navigation_Update(void);
bool AddDownloadData(const DownloadedFile &data);
void CloseDatabase();
#include "resource.h"
#include "../nu/DialogSkinner.h"
#include "../nu/MediaLibraryInterface.h"
#include "../nu/AutoChar.h"
#include "../nu/AutoWide.h"
#include "../nu/AutoLock.h"
#include <windows.h>
#include <shlwapi.h>
extern ATOM VIEWPROP;
extern winampMediaLibraryPlugin plugin;
extern int downloads_treeItem;
#include "../Components/wac_downloadManager/wac_downloadManager_api.h"
#define ML_ENQDEF_VAL() (!!GetPrivateProfileInt(L"gen_ml_config", L"enqueuedef", 0, ml_cfg))
#define ML_GROUPBTN_VAL() (!!GetPrivateProfileInt(L"gen_ml_config", L"groupbtn", 1, ml_cfg))
extern wchar_t* ml_cfg;
#include "DownloadViewCallback.h"
extern DownloadViewCallback *downloadViewCallback;
#endif
extern HWND downloads_window;
extern int groupBtn, enqueuedef;

View File

@ -0,0 +1,7 @@
#include "main.h"
#include "MessageProcessor.h"
#define CBCLASS MessageProcessor
START_DISPATCH;
CB(API_MESSAGEPROCESSOR_PROCESS_MESSAGE, ProcessMessage)
END_DISPATCH;

View File

@ -0,0 +1,35 @@
#ifndef NULLSOFT_ML_WIRE_MESSAGEPROCESSOR_H
#define NULLSOFT_ML_WIRE_MESSAGEPROCESSOR_H
#include <api/application/api_messageprocessor.h>
#include "main.h"
#ifndef WM_FORWARDMSG
#define WM_FORWARDMSG 0x037F
#endif
class MessageProcessor : public api_messageprocessor
{
public:
bool ProcessMessage(MSG *msg)
{
if (msg->message < WM_KEYFIRST || msg->message > WM_KEYLAST)
return false;
HWND hWndCtl = ::GetFocus();
if (IsChild(browserHWND, hWndCtl))
{
// find a direct child of the dialog from the window that has focus
while(::GetParent(hWndCtl) != browserHWND)
hWndCtl = ::GetParent(hWndCtl);
if (activeBrowser->translateKey(*msg))
return true;
}
return false;
}
protected:
RECVS_DISPATCH;
};
#endif

View File

@ -0,0 +1,43 @@
#include "ParseUtil.h"
bool PropertyIsTrue( const XMLNode *item, const wchar_t *property )
{
if ( !item )
return false;
const wchar_t *value = item->GetProperty( property );
if ( !value )
return false;
return !_wcsicmp( value, L"true" );
}
bool PropertyIsFalse( const XMLNode *item, const wchar_t *property )
{
if ( !item )
return false;
const wchar_t *value = item->GetProperty( property );
if ( !value )
return false;
return !_wcsicmp( value, L"false" );
}
const wchar_t *GetContent( const XMLNode *item, const wchar_t *tag )
{
const XMLNode *curNode = item->Get( tag );
if ( curNode )
return curNode->GetContent();
else
return 0;
}
const wchar_t *GetProperty( const XMLNode *item, const wchar_t *tag, const wchar_t *property )
{
const XMLNode *curNode = item->Get( tag );
if ( curNode )
return curNode->GetProperty( property );
else
return 0;
}

View File

@ -0,0 +1,8 @@
#pragma once
#include "../xml/XMLNode.h"
#include <bfc/platform/types.h>
bool PropertyIsTrue(const XMLNode *item, const wchar_t *property);
// not necessarily the opposite of PropertyIsTrue (returns false when field is empty
bool PropertyIsFalse(const XMLNode *item, const wchar_t *property);
const wchar_t *GetContent(const XMLNode *item, const wchar_t *tag);
const wchar_t *GetProperty(const XMLNode *item, const wchar_t *tag, const wchar_t *property);

View File

@ -0,0 +1,77 @@
#include "main.h"
#include "api__ml_downloads.h"
#include "../winamp/wa_ipc.h"
#include "Defaults.h"
#include <shlobj.h>
void Preferences_Init(HWND hwndDlg)
{
SetDlgItemText(hwndDlg, IDC_DOWNLOADLOCATION, defaultDownloadPath);
}
BOOL CALLBACK browseEnumProc(HWND hwnd, LPARAM lParam)
{
wchar_t cl[32] = {0};
GetClassNameW(hwnd, cl, ARRAYSIZE(cl));
if (!lstrcmpiW(cl, WC_TREEVIEW))
{
PostMessage(hwnd, TVM_ENSUREVISIBLE, 0, (LPARAM)TreeView_GetSelection(hwnd));
return FALSE;
}
return TRUE;
}
int CALLBACK WINAPI BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
if(uMsg == BFFM_INITIALIZED)
{
SendMessageW(hwnd, BFFM_SETSELECTIONW, 1, (LPARAM)defaultDownloadPath);
// this is not nice but it fixes the selection not working correctly on all OSes
EnumChildWindows(hwnd, browseEnumProc, 0);
}
return 0;
}
void Preferences_Browse(HWND hwndDlg)
{
wchar_t folder[MAX_PATH] = {0};
BROWSEINFO browse = {0};
lstrcpyn(folder, defaultDownloadPath, MAX_PATH);
browse.hwndOwner = hwndDlg;
browse.lpszTitle = WASABI_API_LNGSTRINGW(IDS_CHOOSE_FOLDER);
browse.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE;
browse.lpfn = BrowseCallbackProc;
LPITEMIDLIST itemList = SHBrowseForFolder(&browse);
if (itemList)
{
SHGetPathFromIDList(itemList, folder);
lstrcpyn(defaultDownloadPath, folder, MAX_PATH);
SetWindowText(GetDlgItem(hwndDlg, IDC_DOWNLOADLOCATION), folder);
LPMALLOC malloc;
SHGetMalloc(&malloc);
malloc->Free(itemList);
}
}
BOOL CALLBACK PreferencesDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
switch (uMsg)
{
case WM_INITDIALOG:
Preferences_Init(hwndDlg);
break;
case WM_COMMAND:
switch (LOWORD(wParam))
{
case IDC_BROWSE:
Preferences_Browse(hwndDlg);
break;
}
break;
}
return 0;
}

View File

@ -0,0 +1,6 @@
#ifndef NULLSOFT_PREFERENCESH
#define NULLSOFT_PREFERENCESH
BOOL CALLBACK PreferencesDialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
#endif

View File

@ -0,0 +1,216 @@
#include "main.h"
#include "RFCDate.h"
#include <strsafe.h>
void MakeDateString(__time64_t convertTime, wchar_t *date_str, size_t len)
{
SYSTEMTIME sysTime = {0};
tm *newtime = _localtime64(&convertTime);
sysTime.wYear = newtime->tm_year + 1900;
sysTime.wMonth = newtime->tm_mon + 1;
sysTime.wDayOfWeek = newtime->tm_wday;
sysTime.wDay = newtime->tm_mday;
sysTime.wHour = newtime->tm_hour;
sysTime.wMinute = newtime->tm_min;
sysTime.wSecond = newtime->tm_sec;
GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &sysTime, NULL, date_str, (int)len);
}
void MakeRFCDateString(__time64_t convertTime, wchar_t *data_str, size_t len)
{
SYSTEMTIME sysTime = {0};
tm *newtime = _gmtime64(&convertTime);
sysTime.wYear = newtime->tm_year + 1900;
sysTime.wMonth = newtime->tm_mon + 1;
sysTime.wDayOfWeek = newtime->tm_wday;
sysTime.wDay = newtime->tm_mday;
sysTime.wHour = newtime->tm_hour;
sysTime.wMinute = newtime->tm_min;
sysTime.wSecond = newtime->tm_sec;
wchar_t rfcDate[64] = {0}, rfcTime[64] = {0};
GetDateFormat(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, &sysTime, L"ddd',' d MMM yyyy ", rfcDate, 64);
GetTimeFormat(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT), 0, &sysTime, L"HH':'mm':'ss 'GMT'", rfcTime, 64);
StringCchPrintf(data_str,len,L"%s%s",rfcDate,rfcTime);
}
static int getMonthOfYear(const wchar_t *str);
static int validateTime(struct tm *tmloc, int gmoffset);
static const wchar_t *getNextField(const wchar_t *pos);
static int getGMOffset(const wchar_t *str);
enum
{
DAY_OF_MONTH = 0,
MONTH_OF_YEAR,
YEAR,
TIME,
TIMEZONE,
DATE_END
};
__time64_t MakeRFCDate(const wchar_t *date)
{
__time64_t result = 0;
const wchar_t *pos = date;
tm tmloc = {0};
const wchar_t *strmin;
const wchar_t *strsec;
int gmoffset = 1;
int state = DAY_OF_MONTH;
tzset();
/* skip weekday if present */
while (pos && *pos && !iswdigit(*pos)) pos++;
do
{
switch (state)
{
case DAY_OF_MONTH:
tmloc.tm_mday = _wtoi(pos);
break;
case MONTH_OF_YEAR:
tmloc.tm_mon = getMonthOfYear(pos);
break;
case YEAR:
{
/* TODO: we're only accepting 4-digit dates...*/
const wchar_t *test = pos; int numDigits = 0;
while (iswdigit(*test) && *test) { test++; numDigits++; }
if (numDigits == 2) // let's hope we never have 2 digit years!
tmloc.tm_year = _wtoi(pos) + 100; // assume 2 digit years are 20xx
else
tmloc.tm_year = _wtoi(pos) - 1900;
}
break;
case TIME:
strmin = wcschr(pos, L':');
strsec = strmin ? wcschr(strmin + 1, L':') : 0;
tmloc.tm_hour = _wtoi(pos);
if (!strmin) return _time64(0);
tmloc.tm_min = _wtoi(strmin + 1);
if (!strsec) return _time64(0);
tmloc.tm_sec = _wtoi(strsec + 1);
break;
case TIMEZONE:
gmoffset = getGMOffset(pos);
break;
case DATE_END:
pos = 0;
break;
}
state++;
}
while ((pos = getNextField(pos)));
tmloc.tm_isdst = 0; //_daylight;
if (validateTime(&tmloc, gmoffset))
{
result = _mktime64(&tmloc) - _timezone;
//if (_daylight)
}
return result;
}
const wchar_t *getNextField(const wchar_t *pos)
{
if (!pos)
return 0;
while (pos && *pos && !iswspace(*pos)) pos++;
while (pos && *pos && iswspace(*pos)) pos++;
return ((pos && *pos) ? pos : 0);
}
int validateTime(struct tm *tmloc, int gmoffset)
{
int result = 1;
if (tmloc->tm_mday < 1 || tmloc->tm_mday > 31 ||
tmloc->tm_mon < 0 || tmloc->tm_mon > 11 ||
tmloc->tm_year < 0 || tmloc->tm_year > 2000 ||
tmloc->tm_hour < 0 || tmloc->tm_hour > 23 ||
tmloc->tm_min < 0 || tmloc->tm_min > 59 ||
tmloc->tm_sec < 0 || tmloc->tm_sec > 59 ||
gmoffset == 1)
result = 0;
return result;
}
int getMonthOfYear(const wchar_t *str)
{
int mon = -1;
/* This is not the most efficient way to determine
the month (we could use integer comparisons, for instance)
but I don't think this will be a performance bottleneck :)
*/
if (!wcsnicmp(str, L"Jan", 3))
mon = 0;
else if (!wcsnicmp(str, L"Feb", 3))
mon = 1;
else if (!wcsnicmp(str, L"Mar", 3))
mon = 2;
else if (!wcsnicmp(str, L"Apr", 3))
mon = 3;
else if (!wcsnicmp(str, L"May", 3))
mon = 4;
else if (!wcsnicmp(str, L"Jun", 3))
mon = 5;
else if (!wcsnicmp(str, L"Jul", 3))
mon = 6;
else if (!wcsnicmp(str, L"Aug", 3))
mon = 7;
else if (!wcsnicmp(str, L"Sep", 3))
mon = 8;
else if (!wcsnicmp(str, L"Oct", 3))
mon = 9;
else if (!wcsnicmp(str, L"Nov", 3))
mon = 10;
else if (!wcsnicmp(str, L"Dec", 3))
mon = 11;
return mon;
}
int getGMOffset(const wchar_t *str)
{
int secs = 0;
/* See note in getMonthOfYear() */
if (!wcsnicmp(str, L"UT", 2) || !wcsnicmp(str, L"GMT", 3))
secs = 0;
else if (!wcsnicmp(str, L"EDT", 3))
secs = -4 * 3600;
else if (!wcsnicmp(str, L"PST", 3))
secs = -8 * 3600;
else if (!wcsnicmp(str, L"EST", 3) || !wcsnicmp(str, L"CDT", 3))
secs = -5 * 3600;
else if (!wcsnicmp(str, L"MST", 3) || !wcsnicmp(str, L"PDT", 3))
secs = -7 * 3600;
else if (!wcsnicmp(str, L"CST", 3) || !wcsnicmp(str, L"MDT", 3))
secs = -6 * 3600;
else if ( (str[0] == L'+' || str[0] == L'-') &&
iswdigit(str[1]) && iswdigit(str[2]) &&
iswdigit(str[3]) && iswdigit(str[4]))
{
secs = 3600 * (10 * (str[1] - 48) + str[2] - 48);
secs += 60 * (10 * (str[3] - 48) + str[4] - 48);
if (str[0] == L'-')
secs = -secs;
}
else
secs = 1;
return secs;
}

View File

@ -0,0 +1,7 @@
#ifndef NULLSOFT_RFCDATEH
#define NULLSOFT_RFCDATEH
void MakeRFCDateString(__time64_t convertTime, wchar_t *data_str, size_t len);
__time64_t MakeRFCDate(const wchar_t *date);
void MakeDateString(__time64_t convertTime, wchar_t *date_str, size_t len);
#endif

View File

@ -0,0 +1,51 @@
to fix
----
crash on shutdown
/////------------ 1.1 below --------------
automatically switch to 'custom' if you click on dropdown in "add" or "edit" url dialog
need icon for listened media
maybe one for read text?
strip whitespace from beginning of titles
multiple-select
Allow for customizing the download location in add/edit url
deletable items (needs to move to a separate 'deleted items' list so we don't re-add them next rss refresh)
drag-n-drop from webpages
once we get an HTTP 200, we should put the downloaded on the 'downloads' list, and be able to update the download percentage status as necessary
BACKGROUND DOWNLOADER
<<<
avoid multiple downloads of the same thing
avoid downlaoding things that have already been downloaded.
range / if-range to handle download resuming
save the last modified dates from "Last-Modified" header
save unfinished downloads to an XML file and read on load
>>>
UNIFIED DOWNLOAD MANAGER CONCEPT !!!!!
who needs updates
downloaded file list
downloads page (to refresh view)
item object
podcast page (to refresh view)
new way of listing items
---
create a common "items" data structure that select channels add their items to.
When a channel is select, it adds its items.
When a channel is deselected, it removes its items.
When a channel is refreshed, it re-adds its items (assuming the item-adder function protects against dupes)
only potential issue is if a channel somehow "loses" items (or an item's GUID is changes)
could be fixed by either 1) keeps track of "parent channel" in the items list
2) rebuilding the entire items list on every channel refresh
or 3) preventing GUID changes and item deletions (or forcing an item list rebuild if it does occur)

View File

@ -0,0 +1,64 @@
#ifndef NULLSOFT_PODCAST_PLUGIN_UTIL_HEADER
#define NULLSOFT_PODCAST_PLUGIN_UTIL_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
#include <wtypes.h>
#include "../nu/trace.h"
#define CSTR_INVARIANT MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT)
#ifndef ARRAYSIZE
#define ARRAYSIZE(blah) (sizeof(blah)/sizeof(*blah))
#endif
#ifndef LONGX86
#ifdef _WIN64
#define LONGX86 LONG_PTR
#else /*_WIN64*/
#define LONGX86 LONG
#endif /*_WIN64*/
#endif // LONGX86
#ifdef __cplusplus
#define SENDMSG(__hwnd, __msgId, __wParam, __lParam) ::SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam))
#else
#define SENDMSG(__hwnd, __msgId, __wParam, __lParam) SendMessageW((__hwnd), (__msgId), (__wParam), (__lParam))
#endif // __cplusplus
#define SENDMLIPC(__hwndML, __ipcMsgId, __param) SENDMSG((__hwndML), WM_ML_IPC, (WPARAM)(__param), (LPARAM)(__ipcMsgId))
#define SENDWAIPC(__hwndWA, __ipcMsgId, __param) SENDMSG((__hwndWA), WM_WA_IPC, (WPARAM)(__param), (LPARAM)(__ipcMsgId))
#define MSGRESULT(__hwnd, __result) { SetWindowLongPtrW((__hwnd), DWL_MSGRESULT, ((LONGX86)(LONG_PTR)(__result))); return TRUE; }
#define SENDCMD(__hwnd, __ctrlId, __eventId, __hctrl) (SENDMSG((__hwnd), WM_COMMAND, MAKEWPARAM(__ctrlId, __eventId), (LPARAM)(__hctrl)))
LPWSTR Plugin_MallocString(size_t cchLen);
LPWSTR Plugin_ReAllocString(LPWSTR pszString, size_t cchLen);
void Plugin_FreeString(LPWSTR pszString);
LPWSTR Plugin_CopyString(LPCWSTR pszSource);
LPSTR Plugin_MallocAnsiString(size_t cchLen);
LPSTR Plugin_CopyAnsiString(LPCSTR pszSource);
void Plugin_FreeAnsiString(LPSTR pszString);
LPWSTR Plugin_DuplicateResString(LPCWSTR pszResource);
void Plugin_FreeResString(LPWSTR pszResource);
HRESULT Plugin_CopyResString(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszString);
LPSTR Plugin_WideCharToMultiByte(UINT codePage, DWORD dwFlags, LPCWSTR lpWideCharStr, INT cchWideChar, LPCSTR lpDefaultChar, LPBOOL lpUsedDefaultChar);
LPWSTR Plugin_MultiByteToWideChar(UINT codePage, DWORD dwFlags, LPCSTR lpMultiByteStr, INT cbMultiByte);
void Plugin_SafeRelease(IUnknown *pUnk);
HRESULT Plugin_FileExtensionFromUrl(LPWSTR pszBuffer, INT cchBufferMax, LPCWSTR pszUrl, LPCWSTR defaultExtension);
void Plugin_ReplaceBadPathChars(LPWSTR pszPath);
INT Plugin_CleanDirectory(LPWSTR pszPath);
HRESULT Plugin_EnsurePathExist(LPCWSTR pszDirectory);
#endif // NULLSOFT_PODCAST_PLUGIN_UTIL_HEADER

View File

@ -0,0 +1,125 @@
#include "Main.h"
#include "RFCDate.h"
#include "Downloaded.h"
#include "../nu/AutoLock.h"
#include "Defaults.h"
#include "../Agave/Language/api_language.h"
using namespace Nullsoft::Utility;
static void XMLWriteString(FILE *fp, const wchar_t *str)
{
for (const wchar_t *itr = str; *itr; itr=CharNextW(itr))
{
switch (*itr)
{
case '<': fputws(L"&lt;", fp); break;
case '>': fputws(L"&gt;", fp); break;
case '&': fputws(L"&amp;", fp); break;
case '\"': fputws(L"&quot;", fp); break;
case '\'': fputws(L"&apos;", fp); break;
default: fputwc(*itr, fp); break;
}
}
}
static void InstaProp(FILE *fp, const wchar_t *property, const wchar_t *value)
{
fwprintf(fp, L" %s=\"", property);
XMLWriteString(fp, value);
fputws(L"\"", fp);
}
static void InstaProp(FILE *fp, const wchar_t *property, int value)
{
fwprintf(fp, L" %s=\"%i\"", property, value);
}
static void InstaPropI64(FILE *fp, const wchar_t *property, int64_t value)
{
fwprintf(fp, L" %s=\"%I64d\"", property, value);
}
static void InstaPropTime(FILE *fp, const wchar_t *property, __time64_t value)
{
fwprintf(fp, L" %s=\"%I64u\"", property, value);
}
static void InstaProp(FILE *fp, const wchar_t *property, float value)
{
_fwprintf_l(fp, L" %s=\"%3.3f\"", WASABI_API_LNG->Get_C_NumericLocale(), property, value);
}
static void InstaProp(FILE *fp, const wchar_t *property, bool value)
{
fwprintf(fp, L" %s=\"", property);
if (value)
fputws(L"true\"", fp);
else
fputws(L"false\"", fp);
}
static void InstaTag(FILE *fp, const wchar_t *tag, const wchar_t *content)
{
if (content && !((INT_PTR)content < 65536) && *content)
{
fwprintf(fp, L"<%s>", tag);
XMLWriteString(fp, content);
fwprintf(fp, L"</%s>\r\n", tag);
}
}
static void InstaTag(FILE *fp, const wchar_t *tag, unsigned int uint)
{
fwprintf(fp, L"<%s>%u</%s>", tag, uint, tag);
}
static void InstaTag(FILE *fp, const wchar_t *tag, __time64_t uint)
{
fwprintf(fp, L"<%s>%I64u</%s>", tag, uint, tag);
}
static void BuildXMLDownloads(FILE *fp, DownloadList &downloads)
{
fputws(L"<downloads", fp);
InstaProp(fp, L"downloadsTitleWidth", downloadsTitleWidth);
InstaProp(fp, L"downloadsProgressWidth", downloadsProgressWidth);
InstaProp(fp, L"downloadsDateWidth", downloadsDateWidth);
InstaProp(fp, L"downloadsSourceWidth", downloadsSourceWidth);
InstaProp(fp, L"downloadsPathWidth", downloadsPathWidth);
InstaProp(fp, L"downloadsItemSort", downloadsItemSort);
InstaProp(fp, L"downloadsSortAscending", downloadsSortAscending);
fputws(L">\r\n", fp);
AutoLock lock (downloads);
DownloadList::const_iterator itr;
for ( itr = downloads.begin(); itr != downloads.end(); itr++ )
{
fputws(L"<download>", fp);
InstaTag(fp, L"source", itr->source);
InstaTag(fp, L"title", itr->title);
InstaTag(fp, L"url", itr->url);
InstaTag(fp, L"path", itr->path);
InstaTag(fp, L"size", (unsigned int)itr->totalSize);
InstaTag(fp, L"downloadDate", itr->downloadDate);
wchar_t status[64] = {0};
_itow(itr->downloadStatus, status, 10);
InstaTag(fp, L"downloadStatus", status);
fputws(L"</download>\r\n", fp);
}
fputws(L"</downloads>", fp);
}
void SaveDownloads(const wchar_t *fileName, DownloadList &downloads)
{
FILE *fp = _wfopen(fileName, L"wb");
if (fp)
{
wchar_t BOM = 0xFEFF;
fwrite(&BOM, sizeof(BOM), 1, fp);
fputws(L"<?xml version=\"1.0\" encoding=\"UTF-16\"?>\r\n", fp);
BuildXMLDownloads(fp, downloads);
fclose(fp);
}
}

View File

@ -0,0 +1,6 @@
#ifndef NULLSOFT_XMLWRITERH
#define NULLSOFT_XMLWRITERH
#include "Downloaded.h"
void SaveDownloads(const wchar_t *fileName, DownloadList &downloads);
#endif

View File

@ -0,0 +1,11 @@
#ifndef NULLSOFT_ML_DOWNLOADS_API_H
#define NULLSOFT_ML_DOWNLOADS_API_H
#include "../Agave/Language/api_language.h"
#include "api/application/api_application.h"
#define WASABI_API_APP applicationApi
#include "../Agave/ExplorerFindFile/api_explorerfindfile.h"
#endif // !NULLSOFT_ML_DOWNLOADS_API_H

View File

@ -0,0 +1 @@
#include "time.h"

View File

@ -0,0 +1,20 @@
#ifndef _OD_DATE_
#define _OD_DATE_
#include <time.h>
/* These functions all work with "Internet"(RFC 822) format Date/Time strings only */
/* An example of an RFC 822 format Date/Time string is "Thu, 28 Aug 2003 21:30:47 EDT" */
/* converts the RFC 822 format date string into UTC Calendar time */
time_t getDateSecs(char *date);
/* returns a string that represents the given UTC Calendar time value as an
RFC 822 format string. The buffer is user-supplied and must be at least
30 bytes in size. */
char *getDateStr(time_t tmval, char *buffer, int gmt);
#endif /*_OD_DATE_*/

View File

@ -0,0 +1,150 @@
#include <shlwapi.h>
#include "api__ml_downloads.h"
#include "Downloaded.h"
#include "../nde/nde_c.h"
#include "../nu/AutoLock.h"
/* DB Schema
Source
Url
Title
DownloadDate
Length
Filename
*/
static Nullsoft::Utility::LockGuard dbcs;
static nde_table_t table = 0;
static nde_database_t db = 0;
using namespace Nullsoft::Utility;
enum
{
DB_ID_SOURCE = 0,
DB_ID_URL = 1,
DB_ID_TITLE = 2,
DB_ID_DOWNLOADDATE = 3,
DB_ID_LENGTH = 4,
DB_ID_FILENAME = 5
};
static bool OpenDatabase()
{
AutoLock lock(dbcs);
if (!db)
db = NDE_CreateDatabase();
return true;
}
void CloseDatabase()
{
AutoLock lock( dbcs );
if ( db )
{
if ( table )
NDE_Database_CloseTable( db, table );
NDE_DestroyDatabase( db );
}
db = 0;
}
static void CreateFields( nde_table_t table )
{
// create defaults
NDE_Table_NewColumnW( table, DB_ID_SOURCE, L"source", FIELD_STRING );
NDE_Table_NewColumnW( table, DB_ID_URL, L"url", FIELD_STRING );
NDE_Table_NewColumnW( table, DB_ID_TITLE, L"title", FIELD_STRING );
NDE_Table_NewColumnW( table, DB_ID_DOWNLOADDATE, L"downloaddate", FIELD_DATETIME );
NDE_Table_NewColumnW( table, DB_ID_LENGTH, L"length", FIELD_INTEGER );
NDE_Table_NewColumnW( table, DB_ID_FILENAME, L"filename", FIELD_FILENAME );
NDE_Table_PostColumns( table );
NDE_Table_AddIndexByIDW( table, DB_ID_URL, L"url" );
}
static bool OpenTable()
{
AutoLock lock( dbcs );
if ( !OpenDatabase() )
return false;
if ( !table )
{
const wchar_t *inidir = WASABI_API_APP->path_getUserSettingsPath();
wchar_t tablePath[ MAX_PATH ] = { 0 }, indexPath[ MAX_PATH ] = { 0 };
PathCombineW( tablePath, inidir, L"plugins" );
PathAppendW( tablePath, L"downloads.dat" );
PathCombineW( indexPath, inidir, L"plugins" );
PathAppendW( indexPath, L"downloads.idx" );
table = NDE_Database_OpenTable( db, tablePath, indexPath, NDE_OPEN_ALWAYS, NDE_CACHE );
if ( table )
CreateFields( table );
}
return !!table;
}
static void db_add( nde_scanner_t s, unsigned char id, wchar_t *data )
{
if ( data )
{
nde_field_t f = NDE_Scanner_NewFieldByID( s, id );
NDE_StringField_SetString( f, data );
}
}
static void db_add_int( nde_scanner_t s, unsigned char id, int data )
{
if ( data )
{
nde_field_t f = NDE_Scanner_NewFieldByID( s, id );
NDE_IntegerField_SetValue( f, data );
}
}
static void db_add_time( nde_scanner_t s, unsigned char id, time_t data )
{
if ( data )
{
nde_field_t f = NDE_Scanner_NewFieldByID( s, id );
NDE_IntegerField_SetValue( f, static_cast<int>( data ) );
}
}
bool AddDownloadData( const DownloadedFile &data )
{
AutoLock lock( dbcs );
if ( !OpenTable() )
return false;
nde_scanner_t s = NDE_Table_CreateScanner( table );
if ( s )
{
NDE_Scanner_New( s );
db_add( s, DB_ID_SOURCE, data.source );
db_add( s, DB_ID_URL, data.url );
db_add( s, DB_ID_TITLE, data.title );
db_add_time( s, DB_ID_DOWNLOADDATE, data.downloadDate );
db_add_int( s, DB_ID_LENGTH, (int)data.totalSize );
db_add( s, DB_ID_FILENAME, data.path );
NDE_Scanner_Post( s );
NDE_Table_DestroyScanner( table, s );
NDE_Table_Sync( table );
return true;
}
return false;
}
void CompactDatabase()
{
AutoLock lock( dbcs );
if ( OpenTable() )
NDE_Table_Compact( table );
}

View File

@ -0,0 +1,15 @@
#ifndef NULLSOFT_ML_DOWNLOADS_ERRORS_H
#define NULLSOFT_ML_DOWNLOADS_ERRORS_H
enum
{
DOWNLOAD_SUCCESS = 0,
DOWNLOAD_404,
DOWNLOAD_TIMEOUT,
DOWNLOAD_NOHTTP,
DOWNLOAD_NOPARSER,
DOWNLOAD_CONNECTIONRESET,
DOWNLOAD_ERROR_PARSING_XML,
};
#endif

View File

@ -0,0 +1,215 @@
#include "./layout.h"
#include <windows.h>
BOOL Layout_Initialize( HWND hwnd, const INT *itemList, INT itemCount, LAYOUTITEM *layout )
{
if ( NULL == itemList || NULL == layout )
return FALSE;
LAYOUTITEM *item;
for ( INT i = 0; i < itemCount; i++ )
{
item = &layout[ i ];
item->hwnd = GetDlgItem( hwnd, itemList[ i ] );
if ( item->hwnd == NULL )
continue;
if ( FALSE == GetWindowRect( item->hwnd, &item->rect ) )
SetRectEmpty( &item->rect );
else
MapWindowPoints( HWND_DESKTOP, hwnd, (POINT *)&item->rect, 2 );
item->cx = item->rect.right - item->rect.left;
item->cy = item->rect.bottom - item->rect.top;
item->x = item->rect.left;
item->y = item->rect.top;
item->flags = 0;
}
return TRUE;
}
BOOL Layout_Perform( HWND hwnd, LAYOUTITEM *layout, INT layoutCount, BOOL fRedraw )
{
HDWP hdwp, hdwpTemp;
hdwp = BeginDeferWindowPos( layoutCount );
if ( hdwp == NULL )
return FALSE;
UINT baseFlags = SWP_NOACTIVATE | SWP_NOZORDER;
if ( fRedraw == FALSE )
baseFlags |= ( SWP_NOREDRAW | SWP_NOCOPYBITS );
LAYOUTITEM *item;
for ( INT i = 0; i < layoutCount; i++ )
{
item = &layout[ i ];
if ( item->hwnd == NULL )
continue;
UINT flags = baseFlags | ( item->flags & ~( SWP_HIDEWINDOW | SWP_SHOWWINDOW ) );
if ( item->x == item->rect.left && item->y == item->rect.top )
flags |= SWP_NOMOVE;
if ( item->cx == ( item->rect.right - item->rect.left ) && item->cy == ( item->rect.bottom - item->rect.top ) )
flags |= SWP_NOSIZE;
if ( ( SWP_HIDEWINDOW & item->flags ) != 0 )
{
UINT windowStyle = (UINT)GetWindowLongPtr( item->hwnd, GWL_STYLE );
if ( ( WS_VISIBLE & windowStyle ) != 0 )
{
SetWindowLongPtr( item->hwnd, GWL_STYLE, windowStyle & ~WS_VISIBLE );
if ( FALSE != fRedraw )
{
RedrawWindow( hwnd, &item->rect, NULL, RDW_INVALIDATE | RDW_ERASE );
}
}
}
if ( ( SWP_NOSIZE | SWP_NOMOVE ) != ( ( SWP_NOSIZE | SWP_NOMOVE | SWP_FRAMECHANGED ) & flags ) )
{
hdwpTemp = DeferWindowPos( hdwp, item->hwnd, NULL, item->x, item->y, item->cx, item->cy, flags );
if ( hdwpTemp == NULL )
break;
hdwp = hdwpTemp;
}
}
BOOL result = ( hdwp != NULL ) ? EndDeferWindowPos( hdwp ) : FALSE;
for ( INT i = 0; i < layoutCount; i++ )
{
item = &layout[ i ];
if ( NULL != item->hwnd && 0 != ( SWP_SHOWWINDOW & item->flags ) )
{
UINT windowStyle = (UINT)GetWindowLongPtr( item->hwnd, GWL_STYLE );
if ( 0 == ( WS_VISIBLE & windowStyle ) )
{
SetWindowLongPtr( item->hwnd, GWL_STYLE, windowStyle | WS_VISIBLE );
if ( FALSE != fRedraw )
RedrawWindow( item->hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_FRAME | RDW_ALLCHILDREN );
}
}
}
return result;
}
static void Layout_SetItemVisibility( const RECT *rect, LAYOUTITEM *item )
{
if ( NULL == item || NULL == item->hwnd )
return;
BOOL outsider = ( item->cx <= 0 || item->cy <= 0 ||
item->x >= rect->right || item->y >= rect->bottom ||
( item->x + item->cx ) < rect->left || ( item->y + item->cy ) < rect->top );
UINT windowStyle = (UINT)GetWindowLongPtr( item->hwnd, GWL_STYLE );
if ( 0 == ( WS_VISIBLE & windowStyle ) )
{
if ( !outsider )
{
item->flags |= SWP_SHOWWINDOW;
}
}
else
{
if ( outsider )
{
item->flags |= SWP_HIDEWINDOW;
}
}
}
BOOL Layout_SetVisibility( const RECT *rect, LAYOUTITEM *layout, INT layoutCount )
{
if ( NULL == rect || NULL == layout )
return FALSE;
for ( INT i = 0; i < layoutCount; i++ )
{
Layout_SetItemVisibility( rect, &layout[ i ] );
}
return TRUE;
}
BOOL Layout_SetVisibilityEx( const RECT *rect, const INT *indexList, INT indexCount, LAYOUTITEM *layout )
{
if ( NULL == rect || NULL == indexList || NULL == layout )
return FALSE;
for ( INT i = 0; i < indexCount; i++ )
{
Layout_SetItemVisibility( rect, &layout[ indexList[ i ] ] );
}
return TRUE;
}
BOOL Layout_GetValidRgn( HRGN validRgn, POINTS parrentOffset, const RECT *validRect, LAYOUTITEM *layout, INT layoutCount )
{
if ( NULL == validRgn )
return FALSE;
SetRectRgn( validRgn, 0, 0, 0, 0 );
if ( NULL == layout )
return FALSE;
HRGN rgn = CreateRectRgn( 0, 0, 0, 0 );
if ( NULL == rgn )
return FALSE;
LAYOUTITEM *item;
LONG l, t, r, b;
for ( INT i = 0; i < layoutCount; i++ )
{
item = &layout[ i ];
if ( NULL != item->hwnd && 0 == ( ( SWP_HIDEWINDOW | SWP_SHOWWINDOW ) & item->flags ) )
{
l = item->x + parrentOffset.x;
t = item->y + parrentOffset.y;
r = l + item->cx;
b = t + item->cy;
if ( 0 != ( SWP_NOREDRAW & item->flags ) || ( l == item->rect.left && t == item->rect.top && r == item->rect.right && b == item->rect.bottom ) )
{
if ( NULL != validRect )
{
if ( l < validRect->left )
l = validRect->left;
if ( t < validRect->top )
t = validRect->top;
if ( r > validRect->right )
r = validRect->right;
if ( b > validRect->bottom )
b = validRect->bottom;
}
if ( l < r && t < b )
{
SetRectRgn( rgn, l, t, r, b );
CombineRgn( validRgn, validRgn, rgn, RGN_OR );
if ( NULLREGION != GetUpdateRgn( item->hwnd, rgn, FALSE ) )
{
OffsetRgn( rgn, parrentOffset.x, parrentOffset.y );
CombineRgn( validRgn, validRgn, rgn, RGN_DIFF );
}
}
}
}
}
DeleteObject( rgn );
return TRUE;
}

View File

@ -0,0 +1,43 @@
#ifndef NULLSOFT_PODCAST_PLUGIN_LAYOUT_HEADER
#define NULLSOFT_PODCAST_PLUGIN_LAYOUT_HEADER
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif
#include <wtypes.h>
typedef struct __LAYOUTITEM
{
HWND hwnd;
LONG x;
LONG y;
LONG cx;
LONG cy;
UINT flags;
RECT rect;
} LAYOUTITEM;
#define LI_GET_R(__li) ((__li).x + (__li).cx)
#define LI_GET_B(__li) ((__li).y + (__li).cy)
#define LI_EXPAND_W(__li, __delta) { (__li).cx += (__delta); }
#define LI_EXPAND_H(__li, __delta) { (__li).cy += (__delta); }
#define LI_SHIFT_L(__li, __delta) { (__li).x += (__delta); }
#define LI_SHIFT_T(__li, __delta) { { (__li).y += (__delta); }
#define LI_SET_L(__li, __val) { (__li).x = (__val); }
#define LI_SET_T(__li, __val) { (__li).y = (__val); }
#define LI_SET_W(__li, __val) { (__li).cx = (__val); }
#define LI_SET_H(__li, __val) { (__li).cy = (__val); }
#define LI_SET_R(__li, __val) { (__li).cx = ((__val) - (__li).x); }
#define LI_SET_B(__li, __val) { (__li).cy = ((__val) - (__li).y); }
BOOL Layout_Initialize(HWND hwnd, const INT *itemList, INT itemCount, LAYOUTITEM *layout);
BOOL Layout_SetVisibilityEx(const RECT *rect, const INT *indexList, INT indexCount, LAYOUTITEM *layout);
BOOL Layout_SetVisibility(const RECT *rect, LAYOUTITEM *layout, INT layoutCount);
BOOL Layout_Perform(HWND hwnd, LAYOUTITEM *layout, INT layoutCount, BOOL fRedraw);
BOOL Layout_GetValidRgn(HRGN validRgn, POINTS parrentOffset, const RECT *validRect, LAYOUTITEM *layout, INT layoutCount);
#endif //NULLSOFT_PODCAST_PLUGIN_LAYOUT_HEADER

View File

@ -0,0 +1,249 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE
BEGIN
"#include ""afxres.h""\r\n"
"\0"
END
3 TEXTINCLUDE
BEGIN
"#include ""version.rc2""\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_DOWNLOADS DIALOGEX 0, 0, 266, 92
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD | WS_CLIPSIBLINGS | WS_CLIPCHILDREN
EXSTYLE WS_EX_CONTROLPARENT
FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN
CONTROL "",IDC_DOWNLOADLIST,"SysListView32",LVS_REPORT | LVS_ALIGNLEFT | LVS_OWNERDATA | WS_TABSTOP,0,0,264,79
CONTROL "Play",IDC_PLAY,"Button",BS_OWNERDRAW | WS_TABSTOP,0,81,37,11
CONTROL "Enqueue",IDC_ENQUEUE,"Button",BS_OWNERDRAW | WS_TABSTOP,39,81,37,11
CONTROL "Remove",IDC_REMOVE,"Button",BS_OWNERDRAW | WS_TABSTOP,80,81,37,11
CONTROL "Clean up",IDC_CLEANUP,"Button",BS_OWNERDRAW | WS_TABSTOP,120,81,37,11
CONTROL "",IDC_STATUS,"Static",SS_LEFTNOWORDWRAP | SS_CENTERIMAGE | SS_ENDELLIPSIS | WS_GROUP,163,81,102,11
END
/////////////////////////////////////////////////////////////////////////////
//
// Menu
//
IDR_MENU1 MENU
BEGIN
POPUP "Downloads"
BEGIN
MENUITEM "Play selection\tEnter", IDC_PLAY
MENUITEM "Enqueue selection\tShift+Enter", IDC_ENQUEUE
POPUP "Send to:"
BEGIN
MENUITEM "", ID_Menu
END
MENUITEM SEPARATOR
MENUITEM "Select all\tCtrl+A", IDC_SELECTALL
MENUITEM "View file info...\tAlt+3", IDC_INFOBOX
MENUITEM "Explore item folder\tCtrl+F", ID_DOWNLOADS_EXPLORERITEMFOLDER
MENUITEM SEPARATOR
MENUITEM "Remove from list\tDel", IDC_REMOVE
MENUITEM "Delete file\tShift+Del", IDC_DELETE
MENUITEM "Cancel download", ID_DOWNLOADS_CANCELDOWNLOAD
END
POPUP "Navigation"
BEGIN
MENUITEM "&Preferences", ID_NAVIGATION_PREFERENCES
MENUITEM SEPARATOR
MENUITEM "Help", ID_NAVIGATION_HELP
END
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_TREEITEM_DOWNLOADS BITMAP "resources\\downloadIcon.bmp"
IDB_TREEITEM_DOWNLOADS1 BITMAP "resources\\downloadIcon1.bmp"
IDB_TREEITEM_DOWNLOADS2 BITMAP "resources\\downloadIcon2.bmp"
IDB_TREEITEM_DOWNLOADS3 BITMAP "resources\\downloadIcon3.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDR_VIEW_DOWNLOAD_ACCELERATORS ACCELERATORS
BEGIN
"F", ID_DOWNLOADS_EXPLORERITEMFOLDER, VIRTKEY, CONTROL, NOINVERT
VK_DELETE, IDC_DELETE, VIRTKEY, SHIFT, NOINVERT
VK_RETURN, IDC_ENQUEUE, VIRTKEY, SHIFT, NOINVERT
"3", IDC_INFOBOX, VIRTKEY, ALT, NOINVERT
VK_RETURN, IDC_PLAY, VIRTKEY, NOINVERT
VK_DELETE, IDC_REMOVE, VIRTKEY, NOINVERT
"A", IDC_SELECTALL, VIRTKEY, CONTROL, NOINVERT
VK_RETURN, IDC_CUSTOM, VIRTKEY, SHIFT, CONTROL, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE
BEGIN
IDS_PLUGIN_NAME "Nullsoft Downloads v%d.%02d"
65535 "{706549D3-D813-45dd-9A0B-E3793A1B63A8}"
END
STRINGTABLE
BEGIN
IDS_DOWNLOADS "Downloads"
IDS_DOWNLOADING "Downloading..."
IDS_CHOOSE_FOLDER "Choose folder to store downloaded media."
IDS_FILE_NOT_FOUND "Cannot connect to %s\nFile not Found."
IDS_CONNECTION_TIMED_OUT "Cannot connect to %s\nConnection timed out."
IDS_NO_JNETLIB "HTTP Downloader library is missing.\nPlease reinstall Winamp."
IDS_JNETLIB_MISSING "JNetLib missing"
IDS_NO_EXPAT "XML Parsing library is missing.\nPlease reinstall Winamp."
END
STRINGTABLE
BEGIN
IDS_EXPAT_MISSING "Expat missing"
IDS_WDAY_SUN "Sun"
IDS_WDAY_MON "Mon"
IDS_WDAY_TUE "Tue"
IDS_WDAY_WED "Wed"
END
STRINGTABLE
BEGIN
IDS_WDAY_THU "Thu"
IDS_WDAY_FRI "Fri"
IDS_WDAY_SAT "Sat"
IDS_MONTH_JAN "Jan"
IDS_MONTH_FEB "Feb"
IDS_MONTH_MAR "Mar"
IDS_MONTH_APR "Apr"
IDS_MONTH_MAY "May"
IDS_MONTH_JUN "Jun"
IDS_MONTH_JUL "Jul"
IDS_MONTH_AUG "Aug"
IDS_MONTH_SEP "Sep"
IDS_MONTH_OCT "Oct"
IDS_MONTH_NOV "Nov"
IDS_MONTH_DEC "Dec"
END
STRINGTABLE
BEGIN
IDS_INVALID_LINK "Invalid link (404 or timeout)"
IDS_CONNECTION_RESET_BY_PEER "Connection reset by peer."
IDS_DOWNLOADING_PERCENT "Downloading %d%%"
IDS_SOURCE "Source"
IDS_TITLE "Title"
IDS_PROGRESS "Status"
IDS_PATH "Download Location"
IDS_PERM_DELETE_ARE_YOU_SURE
"This will permanently delete this file, are you sure?"
IDS_PERM_DELETE_THESE_ARE_YOU_SURE
"This will permanently delete these %d files, are you sure?"
IDS_DELETION "Deletion"
END
STRINGTABLE
BEGIN
IDS_CLEAR_ALL_FINISHED_DOWNLOADS
"This will clear all finished downloads, are you sure?\n\nTip: You can view all your downloaded podcasts in Local Media/Podcasts"
IDS_CLEAN_UP_LIST "Clean Up List"
IDS_DONE "Done"
IDS_SAVE "Save"
IDS_REQUIRES_INTERNET_CONNECTION_ENSURE_CONNECTION
"The media library feature you are attempting to use requires an internet connection. Please make sure you are connected to the internet and try again."
IDS_ADD_TO_DOWNLOADS "Added to downloads."
IDS_SURE_YOU_WANT_TO_REMOVE_THIS
"Are you sure you want to remove %s\n(%s)"
IDS_CONFIRM "Confirm"
IDS_CANCEL_DOWNLOADS_AND_QUIT
"There are downloads currently in progress.\nAre you sure you want to cancel these downloads and quit?"
IDS_CONFIRM_QUIT "Confirm Quit"
END
STRINGTABLE
BEGIN
IDS_DELETEFAILED "Delete Failed"
IDS_SORRY "Sorry"
IDS_DATE "Download Date"
IDS_N_A "n/a"
IDS_SIZE "Size"
END
STRINGTABLE
BEGIN
IDS_DOWNLOAD_SUCCESS "Completed"
IDS_DOWNLOAD_FAILURE "Failed"
IDS_DOWNLOAD_CANCELED "Cancelled"
IDS_DOWNLOAD_PENDING "Pending..."
IDS_DOWNLOADING_PROGRESS
"Downloading %u file(s), %s of %s complete (%d%%)"
IDS_DOWNLOADING_COMPLETE "Downloading %u files, %s complete"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
#include "version.rc2"
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,93 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29509.3
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ml_downloads", "ml_downloads.vcxproj", "{23E1FE5D-8833-4095-97D5-A5972CFA477C}"
ProjectSection(ProjectDependencies) = postProject
{57C90706-B25D-4ACA-9B33-95CDB2427C27} = {57C90706-B25D-4ACA-9B33-95CDB2427C27}
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915} = {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}
{E105A0A2-7391-47C5-86AC-718003524C3D} = {E105A0A2-7391-47C5-86AC-718003524C3D}
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nde", "..\nde\nde.vcxproj", "{4D25C321-7F8B-424E-9899-D80A364BAF1A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nx", "..\replicant\nx\nx.vcxproj", "{57C90706-B25D-4ACA-9B33-95CDB2427C27}"
ProjectSection(ProjectDependencies) = postProject
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nu", "..\replicant\nu\nu.vcxproj", "{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jnetlib", "..\replicant\jnetlib\jnetlib.vcxproj", "{E105A0A2-7391-47C5-86AC-718003524C3D}"
ProjectSection(ProjectDependencies) = postProject
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "..\replicant\zlib\zlib.vcxproj", "{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
Debug|x64 = Debug|x64
Release|Win32 = Release|Win32
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Debug|Win32.ActiveCfg = Debug|Win32
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Debug|Win32.Build.0 = Debug|Win32
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Debug|x64.ActiveCfg = Debug|x64
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Debug|x64.Build.0 = Debug|x64
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Release|Win32.ActiveCfg = Release|Win32
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Release|Win32.Build.0 = Release|Win32
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Release|x64.ActiveCfg = Release|x64
{23E1FE5D-8833-4095-97D5-A5972CFA477C}.Release|x64.Build.0 = Release|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|Win32.ActiveCfg = Debug|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|Win32.Build.0 = Debug|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|x64.ActiveCfg = Debug|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Debug|x64.Build.0 = Debug|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|Win32.ActiveCfg = Release|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|Win32.Build.0 = Release|Win32
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|x64.ActiveCfg = Release|x64
{4D25C321-7F8B-424E-9899-D80A364BAF1A}.Release|x64.Build.0 = Release|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|Win32.ActiveCfg = Debug|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|Win32.Build.0 = Debug|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|x64.ActiveCfg = Debug|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Debug|x64.Build.0 = Debug|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|Win32.ActiveCfg = Release|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|Win32.Build.0 = Release|Win32
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|x64.ActiveCfg = Release|x64
{57C90706-B25D-4ACA-9B33-95CDB2427C27}.Release|x64.Build.0 = Release|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.ActiveCfg = Debug|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|Win32.Build.0 = Debug|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.ActiveCfg = Debug|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Debug|x64.Build.0 = Debug|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.ActiveCfg = Release|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|Win32.Build.0 = Release|Win32
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.ActiveCfg = Release|x64
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}.Release|x64.Build.0 = Release|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|Win32.ActiveCfg = Debug|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|Win32.Build.0 = Debug|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|x64.ActiveCfg = Debug|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Debug|x64.Build.0 = Debug|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|Win32.ActiveCfg = Release|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|Win32.Build.0 = Release|Win32
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|x64.ActiveCfg = Release|x64
{E105A0A2-7391-47C5-86AC-718003524C3D}.Release|x64.Build.0 = Release|x64
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.ActiveCfg = Debug|Win32
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|Win32.Build.0 = Debug|Win32
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.ActiveCfg = Debug|x64
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Debug|x64.Build.0 = Debug|x64
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.ActiveCfg = Release|Win32
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|Win32.Build.0 = Release|Win32
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.ActiveCfg = Release|x64
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C4E799C1-027B-487B-8E1A-31F2D26A1AFE}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,370 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{23E1FE5D-8833-4095-97D5-A5972CFA477C}</ProjectGuid>
<RootNamespace>ml_downloads</RootNamespace>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<IncludePath>$(IncludePath)</IncludePath>
<LibraryPath>$(LibraryPath)</LibraryPath>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
<EmbedManifest>true</EmbedManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg">
<VcpkgEnableManifest>false</VcpkgEnableManifest>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
<VcpkgConfiguration>Debug</VcpkgConfiguration>
</PropertyGroup>
<PropertyGroup Label="Vcpkg" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<VcpkgInstalledDir>
</VcpkgInstalledDir>
<VcpkgUseStatic>false</VcpkgUseStatic>
<VcpkgTriplet>x86-windows-static-md</VcpkgTriplet>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<Optimization>Disabled</Optimization>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<TreatWChar_tAsBuiltInType>false</TreatWChar_tAsBuiltInType>
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>true</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\
xcopy /Y /D $(IntDir)$(TargetName).pdb ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN32;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;IGNORE_API_GRACENOTE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>true</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<TargetMachine>MachineX86</TargetMachine>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<Optimization>MinSpace</Optimization>
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;WIN64;_WIN32_IE=0x0A00;_CRT_SECURE_NO_WARNINGS;IGNORE_API_GRACENOTE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
<BufferSecurityCheck>true</BufferSecurityCheck>
<WarningLevel>Level3</WarningLevel>
<DebugInformationFormat>None</DebugInformationFormat>
<DisableSpecificWarnings>4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
</ClCompile>
<Link>
<AdditionalDependencies>comctl32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
<GenerateDebugInformation>false</GenerateDebugInformation>
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
<SubSystem>Windows</SubSystem>
<OptimizeReferences>true</OptimizeReferences>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<RandomizedBaseAddress>false</RandomizedBaseAddress>
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
<PostBuildEvent>
<Command>xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\ </Command>
<Message>Post build event: 'xcopy /Y /D $(OutDir)$(TargetName)$(TargetExt) ..\..\..\..\Build\Winamp_$(PlatformShortName)_$(Configuration)\Plugins\'</Message>
</PostBuildEvent>
<ResourceCompile>
<PreprocessorDefinitions>_WIN32_WINNT=0x0601;WINVER=0x0601;_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ResourceCompile>
<Manifest>
<OutputManifestFile>$(IntDir)$(TargetName)$(TargetExt).intermediate.manifest</OutputManifestFile>
</Manifest>
</ItemDefinitionGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\nde\nde.vcxproj">
<Project>{4d25c321-7f8b-424e-9899-d80a364baf1a}</Project>
<CopyLocalSatelliteAssemblies>true</CopyLocalSatelliteAssemblies>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
</ProjectReference>
<ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\General\gen_ml\menu.h" />
<ClInclude Include="..\..\..\nu\Alias.h" />
<ClInclude Include="..\..\..\nu\ChildSizer.h" />
<ClInclude Include="..\..\..\nu\DialogSkinner.h" />
<ClInclude Include="..\..\..\nu\MediaLibraryInterface.h" />
<ClInclude Include="..\..\..\nu\menushortcuts.h" />
<ClInclude Include="..\..\..\xml\XMLDOM.h" />
<ClInclude Include="..\..\..\xml\XMLNode.h" />
<ClInclude Include="api__ml_downloads.h" />
<ClInclude Include="Defaults.h" />
<ClInclude Include="Downloaded.h" />
<ClInclude Include="DownloadsDialog.h" />
<ClInclude Include="DownloadsParse.h" />
<ClInclude Include="DownloadStatus.h" />
<ClInclude Include="DownloadThread.h" />
<ClInclude Include="DownloadViewCallback.h" />
<ClInclude Include="errors.h" />
<ClInclude Include="layout.h" />
<ClInclude Include="Main.h" />
<ClInclude Include="ParseUtil.h" />
<ClInclude Include="Preferences.h" />
<ClInclude Include="resource.h" />
<ClInclude Include="RFCDate.h" />
<ClInclude Include="Util.h" />
<ClInclude Include="XMLWriter.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\General\gen_ml\menu.cpp" />
<ClCompile Include="..\..\General\gen_ml\ml_lib.cpp" />
<ClCompile Include="..\..\..\nu\ChildSizer.cpp" />
<ClCompile Include="..\..\..\nu\DialogSkinner.cpp" />
<ClCompile Include="..\..\..\nu\listview.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename)1.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename)1.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename)1.obj</ObjectFileName>
</ClCompile>
<ClCompile Include="..\..\..\nu\MediaLibraryInterface.cpp" />
<ClCompile Include="..\..\..\nu\menushortcuts.cpp" />
<ClCompile Include="..\..\..\xml\XMLDOM.cpp" />
<ClCompile Include="..\..\..\xml\XMLNode.cpp" />
<ClCompile Include="db.cpp" />
<ClCompile Include="Defaults.cpp" />
<ClCompile Include="Downloaded.cpp" />
<ClCompile Include="DownloadsDialog.cpp" />
<ClCompile Include="DownloadsParse.cpp" />
<ClCompile Include="DownloadStatus.cpp" />
<ClCompile Include="DownloadThread.cpp" />
<ClCompile Include="DownloadViewCallback.cpp" />
<ClCompile Include="layout.cpp" />
<ClCompile Include="Main.cpp" />
<ClCompile Include="ParseUtil.cpp" />
<ClCompile Include="Preferences.cpp" />
<ClCompile Include="RFCDate.cpp" />
<ClCompile Include="util.cpp">
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)%(Filename)2.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)%(Filename)2.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)%(Filename)2.obj</ObjectFileName>
<ObjectFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)%(Filename)2.obj</ObjectFileName>
</ClCompile>
<ClCompile Include="XMLWriter.cpp" />
</ItemGroup>
<ItemGroup>
<Image Include="resources\bitmap1.bmp" />
<Image Include="resources\downloadIcon.bmp" />
<Image Include="resources\downloadIcon1.bmp" />
<Image Include="resources\downloadIcon2.bmp" />
<Image Include="resources\downloadIcon3.bmp" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ml_downloads.rc" />
</ItemGroup>
<ItemGroup>
<Text Include="DESIGN.txt" />
<Text Include="TODO.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@ -0,0 +1,215 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="db.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Defaults.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Downloaded.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DownloadsDialog.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DownloadsParse.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DownloadStatus.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DownloadThread.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="DownloadViewCallback.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="layout.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Main.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="ParseUtil.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Preferences.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="RFCDate.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="util.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="XMLWriter.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\ChildSizer.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\DialogSkinner.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\listview.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\MediaLibraryInterface.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\General\gen_ml\menu.cpp">
<Filter>Source Files\gen_ml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\nu\menushortcuts.cpp">
<Filter>Source Files\nu</Filter>
</ClCompile>
<ClCompile Include="..\..\General\gen_ml\ml_lib.cpp">
<Filter>Source Files\gen_ml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\xml\XMLDOM.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\..\..\xml\XMLNode.cpp">
<Filter>Source Files\xml</Filter>
</ClCompile>
<ClCompile Include="..\..\..\xml\XMLDOM.cpp">
<Filter>Source Files\xml</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="api__ml_downloads.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Defaults.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Downloaded.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DownloadsDialog.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DownloadsParse.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DownloadStatus.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DownloadThread.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="DownloadViewCallback.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="errors.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="layout.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Main.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="XMLWriter.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Util.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="RFCDate.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="resource.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Preferences.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ParseUtil.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="..\..\..\nu\Alias.h">
<Filter>Header Files\nu</Filter>
</ClInclude>
<ClInclude Include="..\..\..\nu\ChildSizer.h">
<Filter>Header Files\nu</Filter>
</ClInclude>
<ClInclude Include="..\..\..\nu\DialogSkinner.h">
<Filter>Header Files\nu</Filter>
</ClInclude>
<ClInclude Include="..\..\..\nu\MediaLibraryInterface.h">
<Filter>Header Files\nu</Filter>
</ClInclude>
<ClInclude Include="..\..\General\gen_ml\menu.h">
<Filter>Header Files\gen_ml</Filter>
</ClInclude>
<ClInclude Include="..\..\..\nu\menushortcuts.h">
<Filter>Header Files\nu</Filter>
</ClInclude>
<ClInclude Include="..\..\..\xml\XMLDOM.h">
<Filter>Header Files\xml</Filter>
</ClInclude>
<ClInclude Include="..\..\..\xml\XMLNode.h">
<Filter>Header Files\xml</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Image Include="resources\downloadIcon.bmp">
<Filter>Image Files</Filter>
</Image>
<Image Include="resources\downloadIcon1.bmp">
<Filter>Image Files</Filter>
</Image>
<Image Include="resources\downloadIcon2.bmp">
<Filter>Image Files</Filter>
</Image>
<Image Include="resources\downloadIcon3.bmp">
<Filter>Image Files</Filter>
</Image>
<Image Include="resources\bitmap1.bmp">
<Filter>Image Files</Filter>
</Image>
</ItemGroup>
<ItemGroup>
<Text Include="DESIGN.txt" />
<Text Include="TODO.txt" />
</ItemGroup>
<ItemGroup>
<Filter Include="Header Files">
<UniqueIdentifier>{fbb3be6a-b7ea-4313-b14c-3e90ed67b4ec}</UniqueIdentifier>
</Filter>
<Filter Include="Ressource Files">
<UniqueIdentifier>{52a7174b-e9ac-428f-8f7c-921bcb4e1637}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files">
<UniqueIdentifier>{dcbaa963-b32c-488a-a8d0-cd04a987d873}</UniqueIdentifier>
</Filter>
<Filter Include="Image Files">
<UniqueIdentifier>{3d2c389d-dacb-4c28-985e-6404ec435898}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\nu">
<UniqueIdentifier>{87d018de-72e8-4fe5-94e6-ca03aeb0ede9}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\gen_ml">
<UniqueIdentifier>{4ec61852-ecfb-400c-ae96-803f47338909}</UniqueIdentifier>
</Filter>
<Filter Include="Source Files\xml">
<UniqueIdentifier>{87422940-a801-4fae-9a04-bac04b096146}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\nu">
<UniqueIdentifier>{7d1c9f6a-447c-4b7e-bb0a-bd7aef6f1919}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\gen_ml">
<UniqueIdentifier>{b5409075-f53b-4665-991a-3996953e0b03}</UniqueIdentifier>
</Filter>
<Filter Include="Header Files\xml">
<UniqueIdentifier>{c8ff3a21-0fca-40ea-bce7-8b7492a07ad0}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="ml_downloads.rc">
<Filter>Ressource Files</Filter>
</ResourceCompile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,63 @@
// Microsoft Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// RCDATA
//
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE
BEGIN
"resource.\0"
END
3 TEXTINCLUDE
BEGIN
"\r\0"
END
#endif // APSTUDIO_INVOKED
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED

View File

@ -0,0 +1,120 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by ml_downloads.rc
//
#define IDS_NULLSOFT_PODCAST 0
#define IDS_PODCASTS 1
#define IDS_DOWNLOADING_KB_COMPLETE 2
#define IDS_DOWNLOADING_KB_PROGRESS 3
#define IDS_DOWNLOADS 5
#define IDS_DOWNLOADING 6
#define IDS_CHOOSE_FOLDER 7
#define IDS_FILE_NOT_FOUND 9
#define IDS_CONNECTION_TIMED_OUT 10
#define IDS_ERROR_PARSING_XML 11
#define IDS_NO_JNETLIB 13
#define IDS_JNETLIB_MISSING 14
#define IDS_NO_EXPAT 15
#define IDS_EXPAT_MISSING 16
#define IDS_CONNECTION_RESET 17
#define IDS_WDAY_SUN 28
#define IDS_WDAY_MON 29
#define IDS_WDAY_TUE 30
#define IDS_WDAY_WED 31
#define IDS_WDAY_THU 32
#define IDS_WDAY_FRI 33
#define IDS_WDAY_SAT 34
#define IDS_MONTH_JAN 35
#define IDS_MONTH_FEB 36
#define IDS_MONTH_MAR 37
#define IDS_MONTH_APR 38
#define IDS_MONTH_MAY 39
#define IDS_MONTH_JUN 40
#define IDS_MONTH_JUL 41
#define IDS_MONTH_AUG 42
#define IDS_MONTH_SEP 43
#define IDS_MONTH_OCT 44
#define IDS_MONTH_NOV 45
#define IDS_MONTH_DEC 46
#define IDS_INVALID_LINK 54
#define IDS_CONNECTION_RESET_BY_PEER 55
#define IDS_DOWNLOADING_PERCENT 56
#define IDS_SOURCE 57
#define IDS_ITEM 58
#define IDS_TITLE 58
#define IDS_PROGRESS 59
#define IDS_PATH 60
#define IDS_PERM_DELETE_ARE_YOU_SURE 61
#define IDS_PERM_DELETE_THESE_ARE_YOU_SURE 62
#define IDS_DELETION 63
#define IDS_CLEAR_ALL_FINISHED_DOWNLOADS 64
#define IDS_CLEAN_UP_LIST 65
#define IDS_DONE 66
#define IDS_SAVE 67
#define IDS_REQUIRES_INTERNET_CONNECTION_ENSURE_CONNECTION 68
#define IDS_ADD_TO_DOWNLOADS 69
#define IDS_SURE_YOU_WANT_TO_REMOVE_THIS 74
#define IDS_CONFIRM 75
#define IDS_CANCEL_DOWNLOADS_AND_QUIT 76
#define IDS_CONFIRM_QUIT 77
#define IDS_DELETEFAILED 80
#define IDS_SORRY 81
#define IDS_DATE 82
#define IDS_N_A 83
#define IDS_SIZE 84
#define IDD_DOWNLOADS 107
#define IDR_MENU1 112
#define IDR_VIEW_DOWNLOAD_ACCELERATORS 122
#define IDB_TREEITEM_DOWNLOADS 126
#define IDB_TREEITEM_DOWNLOADS1 131
#define IDS_DOWNLOAD_SUCCESS 134
#define IDS_DOWNLOAD_FAILURE 135
#define IDS_DOWNLOAD_CANCELED 136
#define IDB_TREEITEM_DOWNLOADS2 136
#define IDB_BITMAP2 137
#define IDB_TREEITEM_DOWNLOADS3 137
#define IDS_DOWNLOAD_PENDING 138
#define IDS_DOWNLOADING_PROGRESS 139
#define IDS_DOWNLOADING_COMPLETE 140
#define IDC_CUSTOM 1000
#define IDC_DELETE 1011
#define IDC_DOWNLOADLIST 1029
#define IDC_STATICDOWNLOADLOCATION 1034
#define IDC_STATICAUTODOWNLOAD 1035
#define IDC_ADD 1044
#define IDC_EDIT 1045
#define IDC_PLAY 1047
#define IDC_ENQUEUE 1048
#define IDC_DOWNLOAD 1050
#define IDC_CANCEL 1051
#define IDC_BROWSE 1051
#define IDC_ENQUEUE2 1051
#define IDC_BROWSER 1057
#define IDC_STATUS 1058
#define IDC_DOWNLOADLOCATION 1059
#define IDC_SETTINGSBOX 1060
#define IDC_CLEANUP 1060
#define IDC_PLAYACTION 1065
#define IDC_ENQUEUEACTION 1066
#define ID_PLAYMEDIA_IDC 40018
#define IDC_REMOVE 40024
#define ID_Menu 40026
#define IDC_INFOBOX 40028
#define IDC_SELECTALL 40030
#define ID_NAVIGATION_PREFERENCES 40032
#define ID_NAVIGATION_HELP 40033
#define ID_DOWNLOADS_EXPLORERITEMFOLDER 40034
#define ID_ENQUEUE 40036
#define ID_DOWNLOADS_CANCELDOWNLOAD 40043
#define IDS_PLUGIN_NAME 65534
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 141
#define _APS_NEXT_COMMAND_VALUE 40044
#define _APS_NEXT_CONTROL_VALUE 1068
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -0,0 +1,255 @@
#include "main.h"
#include "./util.h"
#include "api__ml_downloads.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 copy;
}
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 copy;
}
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);
}

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////
//
// Version
//
#include "../../../Winamp/buildType.h"
VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,33,0,0
PRODUCTVERSION WINAMP_PRODUCTVER
FILEFLAGSMASK 0x17L
#ifdef _DEBUG
FILEFLAGS 0x1L
#else
FILEFLAGS 0x0L
#endif
FILEOS 0x4L
FILETYPE 0x2L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "CompanyName", "Winamp SA"
VALUE "FileDescription", "Winamp Media Library Plug-in"
VALUE "FileVersion", "1,33,0,0"
VALUE "InternalName", "Nullsoft Downloads"
VALUE "LegalCopyright", "Copyright <20> 2010-2023 Winamp SA"
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
VALUE "OriginalFilename", "ml_downloads.dll"
VALUE "ProductName", "Winamp"
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END