Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
58
Src/Plugins/Portable/pmp_android/albumart.cpp
Normal file
58
Src/Plugins/Portable/pmp_android/albumart.cpp
Normal file
|
@ -0,0 +1,58 @@
|
|||
#include "../../Library/ml_pmp/pmp.h"
|
||||
#include "api.h"
|
||||
#include "../agave/albumart/svc_albumartprovider.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
extern PMPDevicePlugin plugin;
|
||||
|
||||
static svc_albumArtProvider *FindProvider(const wchar_t *filename, int providerType, waServiceFactory **factory)
|
||||
{
|
||||
FOURCC albumartprovider = svc_albumArtProvider::getServiceType();
|
||||
int n = (int)plugin.service->service_getNumServices(albumartprovider);
|
||||
for (int i=0; i<n; i++)
|
||||
{
|
||||
waServiceFactory *sf = plugin.service->service_enumService(albumartprovider,i);
|
||||
if (sf)
|
||||
{
|
||||
svc_albumArtProvider * provider = (svc_albumArtProvider*)sf->getInterface();
|
||||
if (provider)
|
||||
{
|
||||
if (provider->ProviderType() == providerType && provider->IsMine(filename))
|
||||
{
|
||||
*factory = sf;
|
||||
return provider;
|
||||
}
|
||||
sf->releaseInterface(provider);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void CopyAlbumArt(const wchar_t *source, const wchar_t *destination)
|
||||
{
|
||||
size_t datalen = 0;
|
||||
void *data = 0;
|
||||
wchar_t *mimeType = 0;
|
||||
waServiceFactory *destinationFactory = 0;
|
||||
svc_albumArtProvider *destinationProvider = FindProvider(destination, ALBUMARTPROVIDER_TYPE_EMBEDDED, &destinationFactory);
|
||||
if (destinationFactory)
|
||||
{
|
||||
/* First, look to see if there's already embedded album art */
|
||||
if (destinationProvider->GetAlbumArtData(destination, L"cover", &data, &datalen, &mimeType) == ALBUMARTPROVIDER_SUCCESS && data && datalen)
|
||||
{
|
||||
destinationFactory->releaseInterface(destinationProvider);
|
||||
WASABI_API_MEMMGR->sysFree(data);
|
||||
WASABI_API_MEMMGR->sysFree(mimeType);
|
||||
return;
|
||||
}
|
||||
else if (AGAVE_API_ALBUMART->GetAlbumArtData(source, L"cover", &data, &datalen, &mimeType) == ALBUMART_SUCCESS && data && datalen)
|
||||
{
|
||||
destinationProvider->SetAlbumArtData(destination, L"cover", data, datalen, mimeType);
|
||||
WASABI_API_MEMMGR->sysFree(data);
|
||||
WASABI_API_MEMMGR->sysFree(mimeType);
|
||||
|
||||
destinationFactory->releaseInterface(destinationProvider);
|
||||
}
|
||||
}
|
||||
}
|
1869
Src/Plugins/Portable/pmp_android/androiddevice.cpp
Normal file
1869
Src/Plugins/Portable/pmp_android/androiddevice.cpp
Normal file
File diff suppressed because it is too large
Load diff
240
Src/Plugins/Portable/pmp_android/androiddevice.h
Normal file
240
Src/Plugins/Portable/pmp_android/androiddevice.h
Normal file
|
@ -0,0 +1,240 @@
|
|||
#pragma once
|
||||
#include <windows.h>
|
||||
#include <Dbt.h>
|
||||
|
||||
#include "../../Library/ml_pmp/transcoder.h"
|
||||
#include "../../Library/ml_pmp/pmp.h"
|
||||
|
||||
#include "../nde/nde_c.h"
|
||||
#include "../nu/AutoLock.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#define WINAMP_ANDROID_MARKER_FILE L"\\.winamp\\winamp.info"
|
||||
|
||||
//Filename="E:\Howling Bells - Into The Chaos.MP3"
|
||||
//Artist="Howling Bells"
|
||||
//Album="E:"
|
||||
//Title="Into The Chaos"
|
||||
//Genre=""
|
||||
//AlbumArtist=""
|
||||
//Publisher=""
|
||||
//Composer=""
|
||||
//Year="0"
|
||||
//Track="0"
|
||||
//Bitrate="0"
|
||||
//Playcount="0"
|
||||
//Discnum="0"
|
||||
//Length="0"
|
||||
//Size="7767879"
|
||||
enum
|
||||
{
|
||||
NDE_ANDROID_FAILURE=0,
|
||||
NDE_ANDROID_SUCCESS=1,
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
DEVICEVIEW_COL_FILENAME = 0,
|
||||
DEVICEVIEW_COL_ARTIST=1,
|
||||
DEVICEVIEW_COL_ALBUM=2,
|
||||
DEVICEVIEW_COL_TITLE=3,
|
||||
DEVICEVIEW_COL_GENRE=4,
|
||||
DEVICEVIEW_COL_ALBUM_ARTIST=5,
|
||||
DEVICEVIEW_COL_PUBLISHER=6,
|
||||
DEVICEVIEW_COL_COMPOSER=7,
|
||||
DEVICEVIEW_COL_YEAR=8,
|
||||
DEVICEVIEW_COL_TRACK=9,
|
||||
DEVICEVIEW_COL_BITRATE=10,
|
||||
DEVICEVIEW_COL_DISC_NUMBER=11,
|
||||
DEVICEVIEW_COL_LENGTH=12,
|
||||
DEVICEVIEW_COL_SIZE=13,
|
||||
DEVICEVIEW_COL_PLAY_COUNT=14,
|
||||
};
|
||||
|
||||
#define TAG_CACHE L"winamp_metadata.dat"
|
||||
#define FIELD_LENGTH 1024
|
||||
|
||||
class AndroidSong {
|
||||
public:
|
||||
AndroidSong();
|
||||
wchar_t filename[MAX_PATH];
|
||||
wchar_t artist[FIELD_LENGTH];
|
||||
wchar_t album[FIELD_LENGTH];
|
||||
wchar_t title[FIELD_LENGTH];
|
||||
wchar_t genre[FIELD_LENGTH];
|
||||
wchar_t albumartist[FIELD_LENGTH];
|
||||
wchar_t publisher[FIELD_LENGTH];
|
||||
wchar_t composer[FIELD_LENGTH];
|
||||
int year,track,length,discnum,bitrate,playcount;
|
||||
__int64 size;
|
||||
BOOL filled;
|
||||
wchar_t ext[ 6 ];
|
||||
};
|
||||
|
||||
enum DeviceType {
|
||||
TYPE_OTHER,
|
||||
TYPE_PSP,
|
||||
};
|
||||
|
||||
class AndroidPlaylist;
|
||||
|
||||
class AndroidArt
|
||||
{
|
||||
public:
|
||||
AndroidArt(ARGB32 *bits, int w, int h);
|
||||
~AndroidArt();
|
||||
ARGB32 *bits;
|
||||
int w,h;
|
||||
};
|
||||
|
||||
class AndroidDevice : public Device
|
||||
{
|
||||
public:
|
||||
AndroidDevice(wchar_t drive, pmpDeviceLoading * load);
|
||||
~AndroidDevice();
|
||||
AndroidDevice();
|
||||
void fileProbe(wchar_t * indir);
|
||||
void tag(void); //load ID3 tags from cache or mp3 file
|
||||
void createDeviceFields();
|
||||
int openDeviceDatabase();
|
||||
int openDeviceTable();
|
||||
void closeDeviceTable();
|
||||
|
||||
static void CloseDatabase();
|
||||
void SeekToBegininngOfDevice(nde_scanner_t s);
|
||||
void refreshNDECache(void);
|
||||
void fillMetaData(AndroidSong *s);
|
||||
static int getFileInfoW(const wchar_t *filename, const wchar_t *metadata, wchar_t *dest, size_t len);
|
||||
void setupTranscoder();
|
||||
AndroidPlaylist* getMasterPlaylist();
|
||||
AndroidSong* findSongInMasterPlaylist(const wchar_t *songfn);
|
||||
void writeRecordToDB(AndroidSong* songToPrint);
|
||||
//////////////////////////////////////////
|
||||
|
||||
virtual __int64 getDeviceCapacityAvailable(); // in bytes
|
||||
virtual __int64 getDeviceCapacityTotal(); // in bytes
|
||||
|
||||
virtual void Eject(); // if you ejected successfully, you MUST call PMP_IPC_DEVICEDISCONNECTED and delete this;
|
||||
virtual void Close(); // save any changes, and call PMP_IPC_DEVICEDISCONNECTED AND delete this;
|
||||
|
||||
// return 0 for success, -1 for failed or cancelled
|
||||
virtual int transferTrackToDevice(const itemRecordW * track, // the track to transfer
|
||||
void * callbackContext, //pass this to the callback
|
||||
void (*callback)(void *callbackContext, wchar_t *status), // call this every so often so the GUI can be updated. Including when finished!
|
||||
songid_t * songid, // fill in the songid when you are finished
|
||||
int * killswitch // if this gets set to anything other than zero, the transfer has been cancelled by the user
|
||||
);
|
||||
virtual int trackAddedToTransferQueue(const itemRecordW *track); // return 0 to accept, -1 for "not enough space", -2 for "incorrect format"
|
||||
virtual void trackRemovedFromTransferQueue(const itemRecordW *track);
|
||||
|
||||
// return the amount of space that will be taken up on the device by the track (once it has been tranferred)
|
||||
// or 0 for incompatable. This is usually the filesize, unless you are transcoding. An estimate is acceptable.
|
||||
virtual __int64 getTrackSizeOnDevice(const itemRecordW *track);
|
||||
|
||||
virtual void deleteTrack(songid_t songid); // physically remove from device. Be sure to remove it from all the playlists!
|
||||
|
||||
virtual void commitChanges(); // optional. Will be called at a good time to save changes
|
||||
|
||||
virtual int getPlaylistCount(); // always at least 1. playlistnumber 0 is the Master Playlist containing all tracks.
|
||||
// PlaylistName(0) should return the name of the device.
|
||||
virtual void getPlaylistName(int playlistnumber, wchar_t *buf, int len);
|
||||
virtual int getPlaylistLength(int playlistnumber);
|
||||
virtual songid_t getPlaylistTrack(int playlistnumber,int songnum); // returns a songid
|
||||
|
||||
virtual void setPlaylistName(int playlistnumber, const wchar_t *buf); // with playlistnumber==0, set the name of the device.
|
||||
virtual void playlistSwapItems(int playlistnumber, int posA, int posB); // swap the songs at position posA and posB
|
||||
virtual void sortPlaylist(int playlistnumber, int sortBy);
|
||||
virtual void addTrackToPlaylist(int playlistnumber, songid_t songid); // adds songid to the end of the playlist
|
||||
virtual void removeTrackFromPlaylist(int playlistnumber, int songnum); //where songnum is the position of the track in the playlist
|
||||
|
||||
virtual void deletePlaylist(int playlistnumber);
|
||||
virtual int newPlaylist(const wchar_t *name); // create empty playlist, returns playlistnumber. -1 for failed.
|
||||
|
||||
virtual void getTrackArtist(songid_t songid, wchar_t *buf, int len);
|
||||
virtual void getTrackAlbum(songid_t songid, wchar_t *buf, int len);
|
||||
virtual void getTrackTitle(songid_t songid, wchar_t *buf, int len);
|
||||
virtual int getTrackTrackNum(songid_t songid);
|
||||
virtual int getTrackDiscNum(songid_t songid);
|
||||
virtual void getTrackGenre(songid_t songid, wchar_t * buf, int len);
|
||||
virtual int getTrackYear(songid_t songid);
|
||||
virtual __int64 getTrackSize(songid_t songid); // in bytes
|
||||
virtual int getTrackLength(songid_t songid); // in millisecs
|
||||
virtual int getTrackBitrate(songid_t songid); // in kbps
|
||||
virtual int getTrackPlayCount(songid_t songid);
|
||||
virtual int getTrackRating(songid_t songid); //0-5
|
||||
virtual __time64_t getTrackLastPlayed(songid_t songid); // in unix time format
|
||||
virtual __time64_t getTrackLastUpdated(songid_t songid); // in unix time format
|
||||
virtual void getTrackAlbumArtist(songid_t songid, wchar_t *buf, int len);
|
||||
virtual void getTrackPublisher(songid_t songid, wchar_t *buf, int len);
|
||||
virtual void getTrackComposer(songid_t songid, wchar_t *buf, int len);
|
||||
virtual int getTrackType(songid_t songid);
|
||||
virtual void getTrackExtraInfo(songid_t songid, const wchar_t *field, wchar_t *buf, int len) ; //optional
|
||||
|
||||
// feel free to ignore any you don't support
|
||||
virtual void setTrackArtist(songid_t songid, const wchar_t *value);
|
||||
virtual void setTrackAlbum(songid_t songid, const wchar_t *value);
|
||||
virtual void setTrackTitle(songid_t songid, const wchar_t *value);
|
||||
virtual void setTrackTrackNum(songid_t songid, int value);
|
||||
virtual void setTrackDiscNum(songid_t songid, int value);
|
||||
virtual void setTrackGenre(songid_t songid, const wchar_t *value);
|
||||
virtual void setTrackYear(songid_t songid, int year);
|
||||
virtual void setTrackPlayCount(songid_t songid, int value);
|
||||
virtual void setTrackRating(songid_t songid, int value);
|
||||
virtual void setTrackLastPlayed(songid_t songid, __time64_t value); // in unix time format
|
||||
virtual void setTrackLastUpdated(songid_t songid, __time64_t value); // in unix time format
|
||||
virtual void setTrackAlbumArtist(songid_t songid, const wchar_t *value);
|
||||
virtual void setTrackPublisher(songid_t songid, const wchar_t *value);
|
||||
virtual void setTrackComposer(songid_t songid, const wchar_t *value);
|
||||
virtual void setTrackExtraInfo(songid_t songid, const wchar_t *field, const wchar_t *value) ; //optional
|
||||
|
||||
virtual bool playTracks(songid_t * songidList, int listLength, int startPlaybackAt, bool enqueue); // return false if unsupported
|
||||
|
||||
virtual intptr_t extraActions(intptr_t param1, intptr_t param2, intptr_t param3,intptr_t param4);
|
||||
|
||||
virtual bool copyToHardDriveSupported();
|
||||
|
||||
virtual __int64 songSizeOnHardDrive(songid_t song); // how big a song will be when copied back. Return -1 for not supported.
|
||||
|
||||
virtual int copyToHardDrive(songid_t song, // the song to copy
|
||||
wchar_t * path, // path to copy to, in the form "c:\directory\song". The directory will already be created, you must append ".mp3" or whatever to this string! (there is space for at least 10 new characters).
|
||||
void * callbackContext, //pass this to the callback
|
||||
void (*callback)(void * callbackContext, wchar_t * status), // call this every so often so the GUI can be updated. Including when finished!
|
||||
int * killswitch // if this gets set to anything other than zero, the transfer has been cancelled by the user
|
||||
); // -1 for failed/not supported. 0 for success.
|
||||
|
||||
// art functions
|
||||
virtual void setArt(songid_t songid, void *buf, int w, int h); //buf is in format ARGB32*
|
||||
virtual pmpart_t getArt(songid_t songid);
|
||||
virtual void releaseArt(pmpart_t art);
|
||||
virtual int drawArt(pmpart_t art, HDC dc, int x, int y, int w, int h);
|
||||
virtual void getArtNaturalSize(pmpart_t art, int *w, int *h);
|
||||
virtual void setArtNaturalSize(pmpart_t art, int w, int h);
|
||||
virtual void getArtData(pmpart_t art, void* data); // data ARGB32* is at natural size
|
||||
virtual bool artIsEqual(pmpart_t a, pmpart_t b);
|
||||
|
||||
// Additional attributes
|
||||
Transcoder *transcoder;
|
||||
wchar_t drive;
|
||||
wchar_t iniFile[MAX_PATH];
|
||||
wchar_t pldir[MAX_PATH];
|
||||
wchar_t songFormat[MAX_PATH];
|
||||
wchar_t supportedFormats[MAX_PATH];
|
||||
wchar_t purgeFolders[2];
|
||||
int pl_write_mode; // used to determine how the playlists are stored
|
||||
__int64 transferQueueLength;
|
||||
std::vector<AndroidPlaylist*> androidPlaylists;
|
||||
bool loadedUpToDate; //whether or not songs in memory are tagged and correct
|
||||
|
||||
static nde_database_t discDB;
|
||||
nde_table_t deviceTable;
|
||||
Nullsoft::Utility::LockGuard dbcs;
|
||||
wchar_t ndeDataFile[100];
|
||||
wchar_t ndeIndexFile[100];
|
||||
|
||||
private:
|
||||
// update a track with new metadata (string)
|
||||
void updateTrackField(AndroidSong* song, unsigned int col, const void* newValue, int fieldType);
|
||||
bool readRecordFromDB(AndroidSong* song);
|
||||
bool songChanged(AndroidSong* song);
|
||||
};
|
134
Src/Plugins/Portable/pmp_android/androidplaylist.cpp
Normal file
134
Src/Plugins/Portable/pmp_android/androidplaylist.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
#include "./androiddevice.h"
|
||||
#include "./AndroidPlaylist.h"
|
||||
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
// dtor
|
||||
// cleanup the memory allocated for the vector of songs
|
||||
AndroidPlaylist::~AndroidPlaylist()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// this is the constructor that gets called
|
||||
AndroidPlaylist::AndroidPlaylist(AndroidDevice& d, LPCTSTR fileName, BOOL m)
|
||||
: device(d), master(m), dirty(false)
|
||||
{
|
||||
StringCbCopyW(filename, sizeof(filename), fileName);
|
||||
StringCbCopyW(playlistName, sizeof(playlistName), PathFindFileName(fileName));
|
||||
StringCbCopyW(playlistPath, sizeof(playlistName), fileName);
|
||||
PathRemoveFileSpec(playlistPath);
|
||||
}
|
||||
|
||||
|
||||
void AndroidPlaylist::OnFile( const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info )
|
||||
{
|
||||
if ( filename == NULL )
|
||||
return;
|
||||
|
||||
AndroidSong *song = NULL;
|
||||
//Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
song = device.findSongInMasterPlaylist( filename );
|
||||
songs.push_back( song );
|
||||
}
|
||||
|
||||
size_t AndroidPlaylist::size()
|
||||
{
|
||||
//Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
return songs.size();
|
||||
}
|
||||
|
||||
AndroidSong *&AndroidPlaylist::at(size_t index)
|
||||
{
|
||||
//Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
return songs.at(index);
|
||||
}
|
||||
|
||||
void AndroidPlaylist::push_back(AndroidSong *callback)
|
||||
{
|
||||
//Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
songs.push_back(callback);
|
||||
dirty=TRUE;
|
||||
}
|
||||
|
||||
void AndroidPlaylist::RemoveSong(AndroidSong *song)
|
||||
{
|
||||
//Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
size_t old_size = songs.size();
|
||||
|
||||
//songs.eraseAll(song);
|
||||
auto it = songs.begin();
|
||||
while (it != songs.end())
|
||||
{
|
||||
if (*it != song)
|
||||
{
|
||||
it++;
|
||||
continue;
|
||||
}
|
||||
|
||||
it = songs.erase(it);
|
||||
}
|
||||
|
||||
if (old_size != songs.size())
|
||||
dirty=TRUE;
|
||||
}
|
||||
|
||||
void AndroidPlaylist::swap(size_t index1, size_t index2)
|
||||
{
|
||||
//Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
AndroidSong *temp = songs[index1];
|
||||
songs[index1] = songs[index2];
|
||||
songs[index2] = temp;
|
||||
dirty = true;
|
||||
}
|
||||
|
||||
void AndroidPlaylist::eraseAt(size_t index)
|
||||
{
|
||||
// Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
songs.erase(songs.begin() + index);
|
||||
dirty=true;
|
||||
}
|
||||
|
||||
static int filenamecmp( const wchar_t *f1, const wchar_t *f2 )
|
||||
{
|
||||
for ( ;;)
|
||||
{
|
||||
wchar_t c1 = *f1++;
|
||||
wchar_t c2 = *f2++;
|
||||
if ( !c1 && !c2 )
|
||||
return 0;
|
||||
if ( !c1 )
|
||||
return -1;
|
||||
if ( !c2 )
|
||||
return 1;
|
||||
c1 = towupper( c1 );
|
||||
c2 = towupper( c2 );
|
||||
if ( c1 == '\\' )
|
||||
c1 = '/';
|
||||
if ( c2 == '\\' )
|
||||
c2 = '/';
|
||||
if ( c1 < c2 )
|
||||
return -1;
|
||||
else if ( c1 > c2 )
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
AndroidSong *AndroidPlaylist::FindSong(const wchar_t *filename)
|
||||
{
|
||||
//Nullsoft::Utility::AutoLock songs_lock(songs_guard);
|
||||
for (SongList::iterator e = songs.begin(); e != songs.end(); e++)
|
||||
{
|
||||
if (filenamecmp(filename, (*e)->filename) == 0)
|
||||
{
|
||||
return (*e);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CBCLASS AndroidPlaylist
|
||||
START_DISPATCH;
|
||||
VCB(IFC_PLAYLISTLOADERCALLBACK_ONFILE, OnFile)
|
||||
END_DISPATCH;
|
49
Src/Plugins/Portable/pmp_android/androidplaylist.h
Normal file
49
Src/Plugins/Portable/pmp_android/androidplaylist.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "../playlist/ifc_playlistloadercallback.h"
|
||||
#include "../nu/AutoLock.h"
|
||||
|
||||
class AndroidDevice;
|
||||
class AndroidSong;
|
||||
|
||||
class AndroidPlaylist: public ifc_playlistloadercallback
|
||||
{
|
||||
public:
|
||||
AndroidPlaylist(AndroidDevice& d, LPCTSTR pszPlaylist, BOOL master);
|
||||
~AndroidPlaylist();
|
||||
|
||||
public:
|
||||
/*** ifc_playlistloadercallback ***/
|
||||
void OnFile(const wchar_t *filename, const wchar_t *title, int lengthInMS, ifc_plentryinfo *info);
|
||||
|
||||
public:
|
||||
// utility
|
||||
BOOL isMaster() { return master; }
|
||||
wchar_t* getFilename() { return filename; }
|
||||
size_t size();
|
||||
AndroidSong *&at(size_t index);
|
||||
void push_back(AndroidSong *callback);
|
||||
void RemoveSong(AndroidSong *song);
|
||||
void swap(size_t index1, size_t index2);
|
||||
void eraseAt(size_t index);
|
||||
AndroidSong *FindSong(const wchar_t *filename);
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
private:
|
||||
|
||||
AndroidDevice &device;
|
||||
typedef std::vector<AndroidSong*> SongList;
|
||||
SongList songs;
|
||||
public:
|
||||
//Nullsoft::Utility::LockGuard songs_guard;
|
||||
wchar_t playlistName[MAX_PATH];
|
||||
wchar_t playlistPath[MAX_PATH];
|
||||
|
||||
wchar_t filename[MAX_PATH];
|
||||
BOOL master;
|
||||
BOOL dirty;
|
||||
};
|
||||
|
||||
|
74
Src/Plugins/Portable/pmp_android/androidplaylistsaver.cpp
Normal file
74
Src/Plugins/Portable/pmp_android/androidplaylistsaver.cpp
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "./androidplaylistsaver.h"
|
||||
#include "./androidplaylist.h"
|
||||
#include "./androiddevice.h"
|
||||
#include "./api.h"
|
||||
|
||||
#include <strsafe.h>
|
||||
|
||||
|
||||
AndroidPlaylistSaver::AndroidPlaylistSaver(LPCTSTR iFilename, LPCTSTR iPlaylistName, AndroidPlaylist *iPlaylist)
|
||||
: filename((LPTSTR)iFilename), title((LPTSTR)iPlaylistName), playlist(iPlaylist)
|
||||
{
|
||||
}
|
||||
|
||||
AndroidPlaylistSaver::~AndroidPlaylistSaver()
|
||||
{
|
||||
}
|
||||
|
||||
HRESULT AndroidPlaylistSaver::Save()
|
||||
{
|
||||
INT result = WASABI_API_PLAYLISTMNGR->Save(filename, this);
|
||||
|
||||
return (PLAYLISTMANAGER_SUCCESS == result) ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
size_t AndroidPlaylistSaver::GetNumItems()
|
||||
{
|
||||
return playlist->size();
|
||||
}
|
||||
|
||||
size_t AndroidPlaylistSaver::GetItem(size_t item, wchar_t *filename, size_t filenameCch)
|
||||
{
|
||||
AndroidSong* song = (AndroidSong *) playlist->at(item);
|
||||
if (!song) return 0;
|
||||
|
||||
HRESULT hr = StringCchCopyEx(filename, filenameCch, song->filename, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
if (FAILED(hr))
|
||||
*filename = L'\0';
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
size_t AndroidPlaylistSaver::GetItemTitle(size_t item, wchar_t *title, size_t titleCch)
|
||||
{
|
||||
AndroidSong* song = (AndroidSong *) playlist->at(item);
|
||||
if (!song) return 0;
|
||||
|
||||
HRESULT hr = StringCchCopyEx(title, titleCch, song->title, NULL, NULL, STRSAFE_IGNORE_NULLS);
|
||||
if (FAILED(hr))
|
||||
*title = L'\0';
|
||||
|
||||
return SUCCEEDED(hr);
|
||||
}
|
||||
|
||||
int AndroidPlaylistSaver::GetItemLengthMs(size_t item)
|
||||
{
|
||||
AndroidSong* song = (AndroidSong *) playlist->at(item);
|
||||
if (!song) return 0;
|
||||
|
||||
return song->length ? song->length: -1;
|
||||
}
|
||||
|
||||
size_t AndroidPlaylistSaver::GetItemExtendedInfo(size_t item, const wchar_t *metadata, wchar_t *info, size_t infoCch)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define CBCLASS AndroidPlaylistSaver
|
||||
START_DISPATCH;
|
||||
CB(IFC_PLAYLIST_GETNUMITEMS, GetNumItems)
|
||||
CB(IFC_PLAYLIST_GETITEM, GetItem)
|
||||
CB(IFC_PLAYLIST_GETITEMTITLE, GetItemTitle)
|
||||
CB(IFC_PLAYLIST_GETITEMLENGTHMILLISECONDS, GetItemLengthMs)
|
||||
CB(IFC_PLAYLIST_GETITEMEXTENDEDINFO, GetItemExtendedInfo)
|
||||
END_DISPATCH;
|
33
Src/Plugins/Portable/pmp_android/androidplaylistsaver.h
Normal file
33
Src/Plugins/Portable/pmp_android/androidplaylistsaver.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#pragma once
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../playlist/ifc_playlist.h"
|
||||
|
||||
class AndroidPlaylist;
|
||||
|
||||
class AndroidPlaylistSaver : public ifc_playlist
|
||||
{
|
||||
|
||||
public:
|
||||
AndroidPlaylistSaver(LPCTSTR iFilename, LPCTSTR iTitle, AndroidPlaylist * iPlaylist);
|
||||
virtual ~AndroidPlaylistSaver();
|
||||
|
||||
public:
|
||||
/*** ifc_playlist ***/
|
||||
size_t GetNumItems();
|
||||
size_t GetItem(size_t item, wchar_t *filename, size_t filenameCch);
|
||||
size_t GetItemTitle(size_t item, wchar_t *title, size_t titleCch);
|
||||
int GetItemLengthMs(size_t item); // TODO: maybe microsecond for better resolution?
|
||||
size_t GetItemExtendedInfo(size_t item, const wchar_t *metadata, wchar_t *info, size_t infoCch);
|
||||
|
||||
HRESULT Save();
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
|
||||
protected:
|
||||
LPTSTR title;
|
||||
LPTSTR filename;
|
||||
AndroidPlaylist *playlist;
|
||||
};
|
||||
|
||||
|
64
Src/Plugins/Portable/pmp_android/api.cpp
Normal file
64
Src/Plugins/Portable/pmp_android/api.cpp
Normal file
|
@ -0,0 +1,64 @@
|
|||
#include "../../Library/ml_pmp/pmp.h"
|
||||
#include "api.h"
|
||||
#include <api/service/waservicefactory.h>
|
||||
|
||||
api_language *WASABI_API_LNG = 0;
|
||||
HINSTANCE WASABI_API_LNG_HINST = 0, WASABI_API_ORIG_HINST = 0;
|
||||
|
||||
// Metadata service
|
||||
api_metadata *AGAVE_API_METADATA=0;
|
||||
api_playlistmanager *WASABI_API_PLAYLISTMNGR=0;
|
||||
api_threadpool *WASABI_API_THREADPOOL=0;
|
||||
api_albumart *AGAVE_API_ALBUMART=0;
|
||||
api_memmgr *WASABI_API_MEMMGR=0;
|
||||
api_application *WASABI_API_APP=0;
|
||||
api_devicemanager *AGAVE_API_DEVICEMANAGER = 0;
|
||||
|
||||
extern PMPDevicePlugin plugin;
|
||||
|
||||
template <class api_T>
|
||||
void ServiceBuild(api_T *&api_t, GUID factoryGUID_t)
|
||||
{
|
||||
if (plugin.service)
|
||||
{
|
||||
waServiceFactory *factory = plugin.service->service_getServiceByGuid(factoryGUID_t);
|
||||
if (factory)
|
||||
api_t = reinterpret_cast<api_T *>( factory->getInterface() );
|
||||
}
|
||||
}
|
||||
|
||||
template <class api_T>
|
||||
void ServiceRelease(api_T *api_t, GUID factoryGUID_t)
|
||||
{
|
||||
if (plugin.service && api_t)
|
||||
{
|
||||
waServiceFactory *factory = plugin.service->service_getServiceByGuid(factoryGUID_t);
|
||||
if (factory)
|
||||
factory->releaseInterface(api_t);
|
||||
}
|
||||
api_t = NULL;
|
||||
}
|
||||
|
||||
void WasabiInit()
|
||||
{
|
||||
ServiceBuild(WASABI_API_LNG, languageApiGUID);
|
||||
ServiceBuild(AGAVE_API_METADATA, api_metadataGUID);
|
||||
ServiceBuild(WASABI_API_PLAYLISTMNGR, api_playlistmanagerGUID);
|
||||
ServiceBuild(WASABI_API_THREADPOOL, ThreadPoolGUID);
|
||||
ServiceBuild(AGAVE_API_ALBUMART, albumArtGUID);
|
||||
ServiceBuild(WASABI_API_MEMMGR, memMgrApiServiceGuid);
|
||||
ServiceBuild(WASABI_API_APP, applicationApiServiceGuid);
|
||||
ServiceBuild(AGAVE_API_DEVICEMANAGER, DeviceManagerGUID);
|
||||
}
|
||||
|
||||
void WasabiQuit()
|
||||
{
|
||||
ServiceRelease(WASABI_API_LNG, languageApiGUID);
|
||||
ServiceRelease(WASABI_API_PLAYLISTMNGR, api_playlistmanagerGUID);
|
||||
ServiceRelease(AGAVE_API_METADATA, api_metadataGUID);
|
||||
ServiceRelease(WASABI_API_THREADPOOL, ThreadPoolGUID);
|
||||
ServiceRelease(AGAVE_API_ALBUMART, albumArtGUID);
|
||||
ServiceRelease(WASABI_API_MEMMGR, memMgrApiServiceGuid);
|
||||
ServiceRelease(WASABI_API_APP, applicationApiServiceGuid);
|
||||
ServiceRelease(AGAVE_API_DEVICEMANAGER, DeviceManagerGUID);
|
||||
}
|
34
Src/Plugins/Portable/pmp_android/api.h
Normal file
34
Src/Plugins/Portable/pmp_android/api.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
#pragma once
|
||||
|
||||
#include "../Agave/Language/api_language.h"
|
||||
|
||||
#include "../Agave/Metadata/api_metadata.h"
|
||||
extern api_metadata *metadataApi;
|
||||
#define AGAVE_API_METADATA metadataApi
|
||||
|
||||
#include "../playlist/api_playlistmanager.h"
|
||||
extern api_playlistmanager *playlistManagerApi;
|
||||
#define WASABI_API_PLAYLISTMNGR playlistManagerApi
|
||||
|
||||
#include "../nu/threadpool/api_threadpool.h"
|
||||
extern api_threadpool *threadPoolApi;
|
||||
#define WASABI_API_THREADPOOL threadPoolApi
|
||||
|
||||
#include "../Agave/AlbumArt/api_albumart.h"
|
||||
extern api_albumart *albumArtApi;
|
||||
#define AGAVE_API_ALBUMART albumArtApi
|
||||
|
||||
#include <api/memmgr/api_memmgr.h>
|
||||
extern api_memmgr *memmgr;
|
||||
#define WASABI_API_MEMMGR memmgr
|
||||
|
||||
#include <api/application/api_application.h>
|
||||
extern api_application *applicationApi;
|
||||
#define WASABI_API_APP applicationApi
|
||||
|
||||
#include "../devices/api_devicemanager.h"
|
||||
extern api_devicemanager *deviceManagerApi;
|
||||
#define AGAVE_API_DEVICEMANAGER deviceManagerApi
|
||||
|
||||
void WasabiInit();
|
||||
void WasabiQuit();
|
343
Src/Plugins/Portable/pmp_android/deviceprovider.cpp
Normal file
343
Src/Plugins/Portable/pmp_android/deviceprovider.cpp
Normal file
|
@ -0,0 +1,343 @@
|
|||
#include "api.h"
|
||||
#include "./deviceprovider.h"
|
||||
#include "../devices/api_devicemanager.h"
|
||||
|
||||
extern PMPDevicePlugin plugin;
|
||||
void connectDrive(wchar_t drive, bool checkSize, bool checkBlacklist);
|
||||
|
||||
static size_t tlsIndex = (size_t)-1;
|
||||
|
||||
static BOOL
|
||||
DiscoveryProvider_RegisterCancelSwitch(BOOL *cancelSwitch)
|
||||
{
|
||||
if ((size_t)-1 != tlsIndex &&
|
||||
NULL != WASABI_API_APP)
|
||||
{
|
||||
WASABI_API_APP->SetThreadStorage(tlsIndex, cancelSwitch);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
DiscoveryProvider_GetCancelSwitchOn()
|
||||
{
|
||||
if ((size_t)-1 != tlsIndex &&
|
||||
NULL != WASABI_API_APP)
|
||||
{
|
||||
BOOL *cancelSwitch = (BOOL*)WASABI_API_APP->GetThreadStorage(tlsIndex);
|
||||
if (NULL != cancelSwitch &&
|
||||
FALSE != *cancelSwitch)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
DeviceProvider_DriverEnumCb(wchar_t drive, unsigned int type)
|
||||
{
|
||||
if (DRIVE_REMOVABLE == type &&
|
||||
FALSE == DiscoveryProvider_GetCancelSwitchOn())
|
||||
{
|
||||
connectDrive(drive,true,true);
|
||||
}
|
||||
}
|
||||
|
||||
DeviceProvider::DeviceProvider()
|
||||
: ref(1), activity(0), manager(NULL), readyEvent(NULL), cancelDiscovery(FALSE)
|
||||
{
|
||||
InitializeCriticalSection(&lock);
|
||||
enumerator = (ENUMDRIVES)SendMessageW(plugin.hwndPortablesParent,
|
||||
WM_PMP_IPC, 0, PMP_IPC_ENUM_ACTIVE_DRIVES);
|
||||
}
|
||||
|
||||
DeviceProvider::~DeviceProvider()
|
||||
{
|
||||
CancelDiscovery();
|
||||
|
||||
if (NULL != readyEvent)
|
||||
CloseHandle(readyEvent);
|
||||
|
||||
DeleteCriticalSection(&lock);
|
||||
}
|
||||
|
||||
HRESULT DeviceProvider::CreateInstance(DeviceProvider **instance)
|
||||
{
|
||||
if (NULL == instance)
|
||||
return E_POINTER;
|
||||
|
||||
*instance = new DeviceProvider();
|
||||
|
||||
if (NULL == *instance)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
size_t DeviceProvider::AddRef()
|
||||
{
|
||||
return InterlockedIncrement((LONG*)&ref);
|
||||
}
|
||||
|
||||
size_t DeviceProvider::Release()
|
||||
{
|
||||
if (0 == ref)
|
||||
return ref;
|
||||
|
||||
LONG r = InterlockedDecrement((LONG*)&ref);
|
||||
if (0 == r)
|
||||
delete(this);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
int DeviceProvider::QueryInterface(GUID interface_guid, void **object)
|
||||
{
|
||||
if (NULL == object)
|
||||
return E_POINTER;
|
||||
|
||||
if (IsEqualIID(interface_guid, IFC_DeviceProvider))
|
||||
*object = static_cast<ifc_deviceprovider*>(this);
|
||||
else
|
||||
{
|
||||
*object = NULL;
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
if (NULL == *object)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
AddRef();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
void DeviceProvider::Lock()
|
||||
{
|
||||
EnterCriticalSection(&lock);
|
||||
}
|
||||
|
||||
void DeviceProvider::Unlock()
|
||||
{
|
||||
LeaveCriticalSection(&lock);
|
||||
}
|
||||
|
||||
DWORD DeviceProvider::DiscoveryThread()
|
||||
{
|
||||
IncrementActivity();
|
||||
|
||||
if (NULL != enumerator &&
|
||||
FALSE == cancelDiscovery)
|
||||
{
|
||||
DiscoveryProvider_RegisterCancelSwitch(&cancelDiscovery);
|
||||
|
||||
enumerator(DeviceProvider_DriverEnumCb);
|
||||
|
||||
DiscoveryProvider_RegisterCancelSwitch(NULL);
|
||||
}
|
||||
|
||||
DecrementActivity();
|
||||
|
||||
Lock();
|
||||
|
||||
if (NULL != readyEvent)
|
||||
SetEvent(readyEvent);
|
||||
|
||||
Unlock();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int DeviceProvider_DiscoveryThreadStarter(HANDLE handle, void *user, intptr_t id)
|
||||
{
|
||||
DeviceProvider *self;
|
||||
DWORD result;
|
||||
|
||||
self = (DeviceProvider*)user;
|
||||
|
||||
if (NULL != self)
|
||||
result = self->DiscoveryThread();
|
||||
else
|
||||
result = -2;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
HRESULT DeviceProvider::BeginDiscovery(api_devicemanager *manager)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (NULL == enumerator)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
Lock();
|
||||
|
||||
if (NULL != readyEvent &&
|
||||
WAIT_TIMEOUT == WaitForSingleObject(readyEvent, 0))
|
||||
{
|
||||
hr = E_PENDING;
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = S_OK;
|
||||
|
||||
if (NULL == readyEvent)
|
||||
{
|
||||
readyEvent = CreateEvent(NULL, TRUE, TRUE, NULL);
|
||||
if (NULL == readyEvent)
|
||||
hr = E_FAIL;
|
||||
}
|
||||
|
||||
if ((size_t)-1 == tlsIndex &&
|
||||
NULL != WASABI_API_APP)
|
||||
{
|
||||
tlsIndex = WASABI_API_APP->AllocateThreadStorage();
|
||||
}
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
|
||||
cancelDiscovery = FALSE;
|
||||
ResetEvent(readyEvent);
|
||||
|
||||
if (0 != WASABI_API_THREADPOOL->RunFunction(0, DeviceProvider_DiscoveryThreadStarter,
|
||||
this, 0, api_threadpool::FLAG_LONG_EXECUTION))
|
||||
{
|
||||
|
||||
SetEvent(readyEvent);
|
||||
hr = E_FAIL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Unlock();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT DeviceProvider::CancelDiscovery()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = S_FALSE;
|
||||
|
||||
Lock();
|
||||
|
||||
if (NULL != readyEvent)
|
||||
{
|
||||
cancelDiscovery = TRUE;
|
||||
if (WAIT_OBJECT_0 == WaitForSingleObject(readyEvent, 0))
|
||||
hr = S_OK;
|
||||
|
||||
cancelDiscovery = FALSE;
|
||||
}
|
||||
|
||||
Unlock();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT DeviceProvider::GetActive()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
Lock();
|
||||
|
||||
if (0 != activity)
|
||||
hr = S_OK;
|
||||
else
|
||||
hr = S_FALSE;
|
||||
|
||||
Unlock();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT DeviceProvider::Register(api_devicemanager *manager)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (NULL != this->manager)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
if (NULL == manager)
|
||||
return E_POINTER;
|
||||
|
||||
hr = manager->RegisterProvider(this);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
this->manager = manager;
|
||||
manager->AddRef();
|
||||
}
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT DeviceProvider::Unregister()
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (NULL == manager)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
hr = manager->UnregisterProvider(this);
|
||||
manager->Release();
|
||||
manager = NULL;
|
||||
return hr;
|
||||
}
|
||||
|
||||
size_t DeviceProvider::IncrementActivity()
|
||||
{
|
||||
size_t a;
|
||||
|
||||
Lock();
|
||||
|
||||
activity++;
|
||||
if (1 == activity &&
|
||||
NULL != manager)
|
||||
{
|
||||
manager->SetProviderActive(this, TRUE);
|
||||
}
|
||||
|
||||
a = activity;
|
||||
|
||||
Unlock();
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
size_t DeviceProvider::DecrementActivity()
|
||||
{
|
||||
size_t a;
|
||||
|
||||
Lock();
|
||||
|
||||
if (0 != activity)
|
||||
{
|
||||
activity--;
|
||||
if (0 == activity &&
|
||||
NULL != manager)
|
||||
{
|
||||
manager->SetProviderActive(this, FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
a = activity;
|
||||
|
||||
Unlock();
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
#define CBCLASS DeviceProvider
|
||||
START_DISPATCH;
|
||||
CB(ADDREF, AddRef)
|
||||
CB(RELEASE, Release)
|
||||
CB(QUERYINTERFACE, QueryInterface)
|
||||
CB(API_BEGINDISCOVERY, BeginDiscovery)
|
||||
CB(API_CANCELDISCOVERY, CancelDiscovery)
|
||||
CB(API_GETACTIVE, GetActive)
|
||||
END_DISPATCH;
|
||||
#undef CBCLASS
|
50
Src/Plugins/Portable/pmp_android/deviceprovider.h
Normal file
50
Src/Plugins/Portable/pmp_android/deviceprovider.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
#pragma once
|
||||
|
||||
#include <wtypes.h>
|
||||
#include "../devices/ifc_deviceprovider.h"
|
||||
#include "../../Library/ml_pmp/pmp.h"
|
||||
|
||||
class DeviceProvider : public ifc_deviceprovider
|
||||
{
|
||||
protected:
|
||||
DeviceProvider();
|
||||
~DeviceProvider();
|
||||
|
||||
public:
|
||||
static HRESULT CreateInstance(DeviceProvider **instance);
|
||||
|
||||
public:
|
||||
/* Dispatchable */
|
||||
size_t AddRef();
|
||||
size_t Release();
|
||||
int QueryInterface(GUID interface_guid, void **object);
|
||||
|
||||
/* ifc_deviceprovider */
|
||||
HRESULT BeginDiscovery(api_devicemanager *manager);
|
||||
HRESULT CancelDiscovery();
|
||||
HRESULT GetActive();
|
||||
|
||||
public:
|
||||
HRESULT Register(api_devicemanager *manager);
|
||||
HRESULT Unregister();
|
||||
size_t IncrementActivity();
|
||||
size_t DecrementActivity();
|
||||
|
||||
private:
|
||||
void Lock();
|
||||
void Unlock();
|
||||
DWORD DiscoveryThread();
|
||||
friend static int DeviceProvider_DiscoveryThreadStarter(HANDLE handle, void *user_data, intptr_t id);
|
||||
|
||||
protected:
|
||||
size_t ref;
|
||||
size_t activity;
|
||||
CRITICAL_SECTION lock;
|
||||
api_devicemanager *manager;
|
||||
ENUMDRIVES enumerator;
|
||||
HANDLE readyEvent;
|
||||
BOOL cancelDiscovery;
|
||||
|
||||
protected:
|
||||
RECVS_DISPATCH;
|
||||
};
|
138
Src/Plugins/Portable/pmp_android/eject.cpp
Normal file
138
Src/Plugins/Portable/pmp_android/eject.cpp
Normal file
|
@ -0,0 +1,138 @@
|
|||
// this file almost totally copied from MSDN
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
#define LOCK_TIMEOUT 3000 // 10 Seconds
|
||||
#define LOCK_RETRIES 20
|
||||
|
||||
static HANDLE OpenVolume(TCHAR cDriveLetter)
|
||||
{
|
||||
HANDLE hVolume;
|
||||
UINT uDriveType;
|
||||
wchar_t szVolumeName[8] = {0};
|
||||
wchar_t szRootName[5] = {0};
|
||||
DWORD dwAccessFlags = 0;
|
||||
|
||||
wsprintf(szRootName, L"%c:\\", cDriveLetter);
|
||||
|
||||
uDriveType = GetDriveType(szRootName);
|
||||
switch(uDriveType) {
|
||||
case DRIVE_REMOVABLE:
|
||||
dwAccessFlags = GENERIC_READ | GENERIC_WRITE;
|
||||
break;
|
||||
case DRIVE_CDROM:
|
||||
dwAccessFlags = GENERIC_READ;
|
||||
break;
|
||||
default:
|
||||
printf("Cannot eject. Drive type is incorrect.\n");
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
wsprintf(szVolumeName, L"\\\\.\\%c:", cDriveLetter);
|
||||
|
||||
hVolume = CreateFile( szVolumeName,
|
||||
dwAccessFlags,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
0,
|
||||
NULL );
|
||||
|
||||
if (hVolume == INVALID_HANDLE_VALUE)
|
||||
printf("CreateFile error %d\n", GetLastError());
|
||||
return hVolume;
|
||||
}
|
||||
|
||||
static BOOL CloseVolume(HANDLE hVolume)
|
||||
{
|
||||
return CloseHandle(hVolume);
|
||||
}
|
||||
|
||||
static BOOL LockVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
DWORD dwSleepAmount;
|
||||
int nTryCount;
|
||||
|
||||
dwSleepAmount = LOCK_TIMEOUT / LOCK_RETRIES;
|
||||
|
||||
// Do this in a loop until a timeout period has expired
|
||||
for (nTryCount = 0; nTryCount < LOCK_RETRIES; nTryCount++) {
|
||||
if (DeviceIoControl(hVolume,
|
||||
FSCTL_LOCK_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL))
|
||||
return TRUE;
|
||||
|
||||
Sleep(dwSleepAmount);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL DismountVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
FSCTL_DISMOUNT_VOLUME,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static BOOL PreventRemovalOfVolume(HANDLE hVolume, BOOL fPreventRemoval)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
PREVENT_MEDIA_REMOVAL PMRBuffer;
|
||||
|
||||
PMRBuffer.PreventMediaRemoval = fPreventRemoval;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
IOCTL_STORAGE_MEDIA_REMOVAL,
|
||||
&PMRBuffer, sizeof(PREVENT_MEDIA_REMOVAL),
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
static int AutoEjectVolume(HANDLE hVolume)
|
||||
{
|
||||
DWORD dwBytesReturned;
|
||||
|
||||
return DeviceIoControl( hVolume,
|
||||
IOCTL_STORAGE_EJECT_MEDIA,
|
||||
NULL, 0,
|
||||
NULL, 0,
|
||||
&dwBytesReturned,
|
||||
NULL);
|
||||
}
|
||||
|
||||
BOOL EjectVolume(TCHAR cDriveLetter)
|
||||
{
|
||||
HANDLE hVolume;
|
||||
|
||||
BOOL fAutoEject = FALSE;
|
||||
|
||||
hVolume = OpenVolume(cDriveLetter);
|
||||
if (hVolume == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
// Lock and dismount the volume.
|
||||
if (LockVolume(hVolume) && DismountVolume(hVolume)) {
|
||||
// Set prevent removal to false and eject the volume.
|
||||
if (PreventRemovalOfVolume(hVolume, FALSE) && AutoEjectVolume(hVolume))
|
||||
fAutoEject = TRUE;
|
||||
}
|
||||
|
||||
// Close the volume so other processes can use the drive.
|
||||
if (!CloseVolume(hVolume))
|
||||
return FALSE;
|
||||
|
||||
if (fAutoEject) return TRUE;
|
||||
else return FALSE;
|
||||
}
|
67
Src/Plugins/Portable/pmp_android/filecopy.cpp
Normal file
67
Src/Plugins/Portable/pmp_android/filecopy.cpp
Normal file
|
@ -0,0 +1,67 @@
|
|||
#include "api.h"
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <wchar.h>
|
||||
#include "resource.h"
|
||||
#include <strsafe.h>
|
||||
|
||||
typedef struct CopyData
|
||||
{
|
||||
void * callbackContext;
|
||||
void (*callback)(void * callbackContext, wchar_t * status);
|
||||
} CopyData;
|
||||
|
||||
DWORD CALLBACK CopyToIpodProgressRoutine(LARGE_INTEGER TotalFileSize, LARGE_INTEGER TotalBytesTransferred,
|
||||
LARGE_INTEGER StreamSize, LARGE_INTEGER StreamBytesTransferred,
|
||||
DWORD dwStreamNumber,
|
||||
DWORD dwCallbackReason,
|
||||
HANDLE hSourceFile, HANDLE hDestinationFile,
|
||||
LPVOID lpData)
|
||||
{
|
||||
CopyData *inst = (CopyData *)lpData;
|
||||
if (inst && inst->callback)
|
||||
{
|
||||
wchar_t status[100] = {0};
|
||||
wchar_t langtemp[100] = {0};
|
||||
StringCbPrintf(status, sizeof(status), WASABI_API_LNGSTRINGW_BUF(IDS_TRANSFERING_PERCENT, langtemp, 100), (int)(100ULL * TotalBytesTransferred.QuadPart / (TotalFileSize.QuadPart)));
|
||||
inst->callback(inst->callbackContext,status);
|
||||
}
|
||||
return PROGRESS_CONTINUE;
|
||||
}
|
||||
|
||||
int CopyFile(const wchar_t *infile, const wchar_t *outfile, void * callbackContext, void (*callback)(void * callbackContext, wchar_t * status), int * killswitch)
|
||||
{
|
||||
wchar_t langtemp[100] = {0};
|
||||
|
||||
CopyData c;
|
||||
c.callback = callback;
|
||||
c.callbackContext = callbackContext;
|
||||
|
||||
if (CopyFileEx(infile, outfile, CopyToIpodProgressRoutine, &c, killswitch,0))
|
||||
{
|
||||
if (callback)
|
||||
{
|
||||
callback(callbackContext, WASABI_API_LNGSTRINGW_BUF(IDS_DONE, langtemp, 100));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(GetLastError())
|
||||
{
|
||||
case ERROR_REQUEST_ABORTED:
|
||||
DeleteFile(outfile);
|
||||
if (callback)
|
||||
{
|
||||
callback(callbackContext, WASABI_API_LNGSTRINGW_BUF(IDS_CANCELLED, langtemp, 100));
|
||||
}
|
||||
|
||||
default:
|
||||
if (callback)
|
||||
{
|
||||
callback(callbackContext, WASABI_API_LNGSTRINGW_BUF(IDS_TRANSFER_FAILED, langtemp, 100));
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
601
Src/Plugins/Portable/pmp_android/main.cpp
Normal file
601
Src/Plugins/Portable/pmp_android/main.cpp
Normal file
|
@ -0,0 +1,601 @@
|
|||
#include "../../Library/ml_pmp/pmp.h"
|
||||
#include "../Winamp/wa_ipc.h"
|
||||
#include <vector>
|
||||
#include "../nu/AutoWide.h"
|
||||
#include "../nu/AutoChar.h"
|
||||
#include "../nu/Alias.h"
|
||||
|
||||
#include <api/service/waServiceFactory.h>
|
||||
|
||||
#include "api.h"
|
||||
#include "resource.h"
|
||||
#include "androiddevice.h"
|
||||
#include "deviceprovider.h"
|
||||
|
||||
#include <devguid.h>
|
||||
#include <shlobj.h>
|
||||
#include <shlwapi.h>
|
||||
#include <strsafe.h>
|
||||
|
||||
#define PLUGIN_VERSION L"1.72"
|
||||
static int Init();
|
||||
static void Quit();
|
||||
static bool doRegisterForDevNotification(void);
|
||||
static intptr_t MessageProc(int msg, intptr_t param1, intptr_t param2, intptr_t param3);
|
||||
|
||||
extern PMPDevicePlugin plugin = {PMPHDR_VER,0,Init,Quit,MessageProc};
|
||||
|
||||
// start-android
|
||||
static const wchar_t *winampini;
|
||||
static std::vector<wchar_t*> blacklist;
|
||||
bool loading_devices[26] = {0,};
|
||||
|
||||
static HDEVNOTIFY hDevNotify;
|
||||
|
||||
std::vector<AndroidDevice*> devices;
|
||||
HWND config;
|
||||
|
||||
static DeviceProvider *deviceProvider = NULL;
|
||||
static UINT_PTR rescanTimer = 0;
|
||||
|
||||
static void blacklistLoad() {
|
||||
wchar_t keyname[64] = {0};
|
||||
int l = GetPrivateProfileIntW(L"pmp_android", L"blacklistnum", 0, winampini);
|
||||
for(int i=l>100?l-100:0; i<l; i++) {
|
||||
wchar_t buf[100] = {0};
|
||||
StringCchPrintfW(keyname, 64, L"blacklist-%d", i);
|
||||
GetPrivateProfileStringW(L"pmp_android", keyname, L"", buf, 100, winampini);
|
||||
if(buf[0])
|
||||
{
|
||||
blacklist.push_back(_wcsdup(buf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void blacklistSave() {
|
||||
wchar_t buf[64] = {0};
|
||||
StringCchPrintfW(buf, 64, L"%d", blacklist.size());
|
||||
WritePrivateProfileStringW(L"pmp_android", L"blacklistnum", buf, winampini);
|
||||
for(size_t i=0; i<blacklist.size(); i++)
|
||||
{
|
||||
StringCchPrintfW(buf, 64, L"blacklist-%d", i);
|
||||
WritePrivateProfileStringW(L"pmp_android", buf, (const wchar_t*)blacklist.at(i), winampini);
|
||||
}
|
||||
}
|
||||
|
||||
static wchar_t *makeBlacklistString(wchar_t drive) {
|
||||
wchar_t path[4]={drive,L":\\"};
|
||||
wchar_t name[100]=L"";
|
||||
wchar_t buf[FIELD_LENGTH]=L"";
|
||||
DWORD serial=0;
|
||||
|
||||
UINT olderrmode=SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
|
||||
GetVolumeInformation(path,name,100,&serial,NULL,NULL,NULL,0);
|
||||
|
||||
if(serial)
|
||||
{
|
||||
StringCchPrintf(buf, FIELD_LENGTH, L"s:%d",serial);
|
||||
SetErrorMode(olderrmode);
|
||||
return _wcsdup(buf);
|
||||
}
|
||||
|
||||
{
|
||||
ULARGE_INTEGER tfree={0,}, total={0,}, freeb={0,};
|
||||
GetDiskFreeSpaceEx(path, &tfree, &total, &freeb);
|
||||
StringCchPrintf(buf, FIELD_LENGTH, L"n:%s,%d,%d", name, total.HighPart, total.LowPart);
|
||||
SetErrorMode(olderrmode);
|
||||
return _wcsdup(buf);
|
||||
}
|
||||
}
|
||||
|
||||
static bool blacklistCheck(wchar_t drive)
|
||||
{
|
||||
wchar_t *s = makeBlacklistString(drive);
|
||||
if (s)
|
||||
{
|
||||
for(size_t i=0; i<blacklist.size(); i++)
|
||||
{
|
||||
if(!wcscmp(s,(wchar_t*)blacklist.at(i)))
|
||||
{
|
||||
free(s);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
free(s);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool blacklistAdd(const wchar_t drive)
|
||||
{
|
||||
wchar_t *s = makeBlacklistString(drive);
|
||||
if (s)
|
||||
{
|
||||
for(size_t i=0; i<blacklist.size(); i++)
|
||||
{
|
||||
if(!wcscmp(s,(wchar_t*)blacklist.at(i)))
|
||||
{
|
||||
free(s);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
blacklist.push_back(s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
Device_IsiPod(const wchar_t drive)
|
||||
{
|
||||
const wchar_t test[] = {drive, L":\\iPod_Control"};
|
||||
WIN32_FIND_DATAW findData;
|
||||
HANDLE file = FindFirstFileW(test, &findData);
|
||||
if (INVALID_HANDLE_VALUE != file)
|
||||
{
|
||||
FindClose(file);
|
||||
if (0 != (FILE_ATTRIBUTE_DIRECTORY & findData.dwFileAttributes))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
Device_IsAndroid(const wchar_t drive)
|
||||
{
|
||||
const wchar_t test[] = {drive, L":\\Android"};
|
||||
WIN32_FIND_DATAW findData;
|
||||
HANDLE file = FindFirstFileW(test, &findData);
|
||||
if (INVALID_HANDLE_VALUE != file)
|
||||
{
|
||||
FindClose(file);
|
||||
if (0 != (FILE_ATTRIBUTE_DIRECTORY & findData.dwFileAttributes))
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
Device_IsSizeOk(const wchar_t drive)
|
||||
{
|
||||
const wchar_t test[] = {drive, L":\\"};
|
||||
ULARGE_INTEGER total;
|
||||
|
||||
if (0 == GetDiskFreeSpaceExW(test, NULL, &total, NULL) ||
|
||||
total.HighPart == 0 && total.LowPart == 0)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static BOOL
|
||||
Device_IsOkToConnect(const wchar_t drive)
|
||||
{
|
||||
const wchar_t test[] = {drive, TEXT(":\\Winamp\\")TAG_CACHE};
|
||||
wchar_t title[128] = {0};
|
||||
wchar_t message[1024] = {0};
|
||||
int result;
|
||||
|
||||
if (FALSE != PathFileExistsW(test))
|
||||
return TRUE;
|
||||
|
||||
StringCbPrintfW(message, sizeof(message), WASABI_API_LNGSTRINGW(IDS_REMOVEABLE_DRIVE_DETECTED),
|
||||
towupper(drive));
|
||||
|
||||
WASABI_API_LNGSTRINGW_BUF(IDS_WINAMP_PMP_SUPPORT,title,ARRAYSIZE(title));
|
||||
|
||||
result = MessageBoxW(NULL, message, title,
|
||||
MB_YESNO | MB_SETFOREGROUND | MB_TOPMOST |
|
||||
MB_ICONINFORMATION);
|
||||
|
||||
if(IDNO == result)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static Nullsoft::Utility::LockGuard connect_guard;
|
||||
|
||||
static int ThreadFunc_Load(HANDLE handle, void *user_data, intptr_t id)
|
||||
{
|
||||
wchar_t drive = (wchar_t)id;
|
||||
|
||||
if (FALSE == Device_IsOkToConnect(drive))
|
||||
{
|
||||
Nullsoft::Utility::AutoLock connect_lock(connect_guard);
|
||||
blacklistAdd(drive);
|
||||
blacklistSave();
|
||||
}
|
||||
else
|
||||
{
|
||||
pmpDeviceLoading load;
|
||||
Device * d = new AndroidDevice(drive,&load);
|
||||
}
|
||||
|
||||
loading_devices[drive-'A'] = false;
|
||||
deviceProvider->DecrementActivity();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//#include <WinIoCtl.h>
|
||||
|
||||
void connectDrive(wchar_t drive, bool checkSize=true, bool checkBlacklist=true)
|
||||
{
|
||||
Nullsoft::Utility::AutoLock connect_lock(connect_guard);
|
||||
// capitalize
|
||||
if (drive >= 'a' && drive <= 'z')
|
||||
drive = drive - 32;
|
||||
|
||||
// reject invalid drive letters
|
||||
if (drive < 'A' || drive > 'Z')
|
||||
return;
|
||||
|
||||
if(checkBlacklist && blacklistCheck(drive))
|
||||
return;
|
||||
|
||||
// if device is taken already ignore
|
||||
for (std::vector<AndroidDevice*>::const_iterator e = devices.begin(); e != devices.end(); e++)
|
||||
{
|
||||
if ((*e)->drive == drive)
|
||||
return;
|
||||
}
|
||||
|
||||
if (loading_devices[drive-'A'])
|
||||
return;
|
||||
|
||||
loading_devices[drive-'A'] = true;
|
||||
|
||||
if(FALSE == checkSize || FALSE != Device_IsSizeOk(drive))
|
||||
{
|
||||
if (FALSE != Device_IsAndroid(drive) &&
|
||||
FALSE == Device_IsiPod(drive))
|
||||
{
|
||||
|
||||
deviceProvider->IncrementActivity();
|
||||
if (NULL != WASABI_API_THREADPOOL &&
|
||||
0 == WASABI_API_THREADPOOL->RunFunction(0, ThreadFunc_Load, 0,
|
||||
(int)drive, api_threadpool::FLAG_LONG_EXECUTION))
|
||||
{
|
||||
return;
|
||||
}
|
||||
deviceProvider->DecrementActivity();
|
||||
}
|
||||
}
|
||||
|
||||
loading_devices[drive-'A'] = false;
|
||||
}
|
||||
|
||||
static void autoDetectCallback(wchar_t drive,UINT type)
|
||||
{
|
||||
if(type == DRIVE_REMOVABLE)
|
||||
{
|
||||
connectDrive(drive, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// end-android
|
||||
static int Init()
|
||||
{
|
||||
WasabiInit();
|
||||
|
||||
// start-android
|
||||
winampini = (const wchar_t*)SendMessage(plugin.hwndWinampParent,WM_WA_IPC,0,IPC_GETINIFILEW);
|
||||
// need to have this initialised before we try to do anything with localisation features
|
||||
WASABI_API_START_LANG(plugin.hDllInstance,PmpAndroidLangGUID);
|
||||
// end-android
|
||||
|
||||
static wchar_t szDescription[256];
|
||||
StringCchPrintfW(szDescription, ARRAYSIZE(szDescription),
|
||||
WASABI_API_LNGSTRINGW(IDS_NULLSOFT_ANDROID_DEVICE_PLUGIN), PLUGIN_VERSION);
|
||||
plugin.description = szDescription;
|
||||
|
||||
/** load up the backlist */
|
||||
blacklistLoad();
|
||||
|
||||
if (NULL != AGAVE_API_DEVICEMANAGER &&
|
||||
NULL == deviceProvider)
|
||||
{
|
||||
if (SUCCEEDED(DeviceProvider::CreateInstance(&deviceProvider)) &&
|
||||
FAILED(deviceProvider->Register(AGAVE_API_DEVICEMANAGER)))
|
||||
{
|
||||
deviceProvider->Release();
|
||||
deviceProvider = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Our device shows up as a normal drive */
|
||||
if (NULL == deviceProvider ||
|
||||
FAILED(deviceProvider->BeginDiscovery(AGAVE_API_DEVICEMANAGER)))
|
||||
{
|
||||
SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)autoDetectCallback,PMP_IPC_ENUM_ACTIVE_DRIVES);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void Quit()
|
||||
{
|
||||
if (NULL != deviceProvider)
|
||||
{
|
||||
deviceProvider->Unregister();
|
||||
deviceProvider->Release();
|
||||
deviceProvider = NULL;
|
||||
}
|
||||
|
||||
WasabiQuit();
|
||||
UnregisterDeviceNotification(hDevNotify);
|
||||
|
||||
AndroidDevice::CloseDatabase();
|
||||
}
|
||||
|
||||
static wchar_t FirstDriveFromMask(ULONG *unitmask) {
|
||||
char i;
|
||||
ULONG adj = 0x1, mask = *unitmask;
|
||||
for(i=0; i<26; ++i) {
|
||||
if(mask & 0x1) {
|
||||
*unitmask -= adj;
|
||||
break;
|
||||
}
|
||||
adj = adj << 1;
|
||||
mask = mask >> 1;
|
||||
}
|
||||
return (i+L'A');
|
||||
}
|
||||
|
||||
static int GetNumberOfDrivesFromMask(ULONG unitmask) {
|
||||
int count = 0;
|
||||
for(int i=0; i<26; ++i)
|
||||
{
|
||||
if(unitmask & 0x1)
|
||||
count++;
|
||||
|
||||
unitmask = unitmask >> 1;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static void CALLBACK RescanOnTimer(HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime)
|
||||
{
|
||||
KillTimer(hwnd, idEvent);
|
||||
if (idEvent == rescanTimer)
|
||||
rescanTimer = 0;
|
||||
|
||||
if (NULL == deviceProvider ||
|
||||
FAILED(deviceProvider->BeginDiscovery(AGAVE_API_DEVICEMANAGER)))
|
||||
{
|
||||
PostMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(WPARAM)autoDetectCallback,PMP_IPC_ENUM_ACTIVE_DRIVES);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int wmDeviceChange(WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
UINT olderrmode=SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
if(wParam==DBT_DEVICEARRIVAL || wParam==DBT_DEVICEREMOVECOMPLETE)
|
||||
{ // something has been inserted or removed
|
||||
PDEV_BROADCAST_HDR lpdb = (PDEV_BROADCAST_HDR)lParam;
|
||||
if(lpdb->dbch_devicetype == DBT_DEVTYP_VOLUME)
|
||||
{ // its a volume
|
||||
PDEV_BROADCAST_VOLUME lpdbv = (PDEV_BROADCAST_VOLUME)lpdb;
|
||||
if((!(lpdbv->dbcv_flags & DBTF_MEDIA) && !(lpdbv->dbcv_flags & DBTF_NET)))
|
||||
{ // its not a network drive or a CD/floppy, game on!
|
||||
ULONG dbcv_unitmask = lpdbv->dbcv_unitmask;
|
||||
|
||||
// see just how many drives have been flagged on the action
|
||||
// eg one android drive could have multiple partitions that we handle
|
||||
int count = GetNumberOfDrivesFromMask(dbcv_unitmask);
|
||||
for(int j = 0; j < count; j++)
|
||||
{
|
||||
wchar_t drive = FirstDriveFromMask(&dbcv_unitmask);
|
||||
if((wParam == DBT_DEVICEARRIVAL) && !blacklistCheck(drive))
|
||||
{ // connected
|
||||
connectDrive(drive);
|
||||
//send a message as if the user just selected a drive from the combo box, this way the fields are refreshed to the correct device's settings
|
||||
SendMessage(config, WM_COMMAND,MAKEWPARAM(IDC_DRIVESELECT,CBN_SELCHANGE),0);
|
||||
}
|
||||
else
|
||||
{ // removal
|
||||
for(size_t i=0; i < devices.size(); i++)
|
||||
{
|
||||
AndroidDevice * d = (AndroidDevice*)devices.at(i);
|
||||
if(d->drive == drive)
|
||||
{
|
||||
devices.erase(devices.begin() + i);
|
||||
if(config) SendMessage(config,WM_USER,0,0); //refresh fields
|
||||
if(config) SendMessage(config,WM_COMMAND, MAKEWPARAM(IDC_DRIVESELECT,CBN_SELCHANGE),0); //update to correct device change as if the user had clicked on the combo box themself
|
||||
SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)d,PMP_IPC_DEVICEDISCONNECTED);
|
||||
delete d;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rescanTimer = SetTimer(NULL, rescanTimer, 10000, RescanOnTimer);
|
||||
}
|
||||
SetErrorMode(olderrmode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int IsDriveConnectedToPMP(wchar_t drive)
|
||||
{
|
||||
for(size_t i = 0; i < devices.size(); i++)
|
||||
{
|
||||
if(((AndroidDevice*)devices.at(i))->drive == drive)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static INT_PTR CALLBACK config_dialogProc(HWND hwndDlg, UINT uMsg, WPARAM wParam,LPARAM lParam)
|
||||
{
|
||||
switch(uMsg)
|
||||
{
|
||||
case WM_INITDIALOG:
|
||||
{
|
||||
for(wchar_t d=L'A'; d<='Z'; d++)
|
||||
{
|
||||
wchar_t drive[3] = {d,L':',0}, drv[4] = {d,L':','\\',0};
|
||||
UINT uDriveType = GetDriveType(drv);
|
||||
if(uDriveType == DRIVE_REMOVABLE || uDriveType == DRIVE_CDROM || uDriveType == DRIVE_FIXED) {
|
||||
int position = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_ADDSTRING,0,(LPARAM)drive);
|
||||
SendDlgItemMessage(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_SETITEMDATA,position,d);
|
||||
}
|
||||
}
|
||||
SendDlgItemMessage(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_SETCURSEL,0,0);
|
||||
SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_COMBO_MANUALCONNECT,CBN_SELCHANGE),0);
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
EndDialog(hwndDlg,0);
|
||||
break;
|
||||
case WM_COMMAND:
|
||||
switch(LOWORD(wParam)) {
|
||||
case IDC_COMBO_MANUALCONNECT:
|
||||
{
|
||||
if(HIWORD(wParam)==CBN_SELCHANGE) {
|
||||
int indx = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETCURSEL,0,0);
|
||||
wchar_t drive = (wchar_t)SendDlgItemMessage(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETITEMDATA,indx,0);
|
||||
if(indx >= 0)
|
||||
{
|
||||
int connected = IsDriveConnectedToPMP(drive), isblacklisted = blacklistCheck(drive);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_MANUALCONNECT), !connected && !isblacklisted);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_MANUALDISCONNECT), connected);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_MANUALBLACKLIST), TRUE);
|
||||
SetDlgItemText(hwndDlg, IDC_MANUALBLACKLIST, WASABI_API_LNGSTRINGW(isblacklisted ? IDS_UNBLACKLIST_DRIVE : IDS_BLACKLIST_DRIVE));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_MANUALCONNECT:
|
||||
{
|
||||
char titleStr[32] = {0};
|
||||
if(MessageBoxA(hwndDlg, WASABI_API_LNGSTRING(IDS_MANUAL_CONNECT_PROMPT),
|
||||
WASABI_API_LNGSTRING_BUF(IDS_WARNING,titleStr,32), MB_YESNO) == IDYES)
|
||||
{
|
||||
int indx = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETCURSEL,0,0);
|
||||
wchar_t drive = (wchar_t)SendDlgItemMessage(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETITEMDATA,indx,0);
|
||||
if(drive >= L'A' && drive <= L'Z') {
|
||||
wchar_t *bl = makeBlacklistString(drive);
|
||||
if (bl)
|
||||
{
|
||||
for(size_t i=0; i<blacklist.size(); i++)
|
||||
{
|
||||
if(!wcscmp(bl,(wchar_t*)blacklist.at(i)))
|
||||
{
|
||||
free(blacklist.at(i));
|
||||
blacklist.erase(blacklist.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(bl);
|
||||
}
|
||||
connectDrive(drive,false);
|
||||
// should do a better check here incase of failure, etc
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_MANUALCONNECT), FALSE);
|
||||
EnableWindow(GetDlgItem(hwndDlg, IDC_MANUALDISCONNECT), TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_MANUALDISCONNECT:
|
||||
{
|
||||
int indx = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETCURSEL,0,0);
|
||||
wchar_t drive = (wchar_t)SendDlgItemMessage(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETITEMDATA,indx,0);
|
||||
if(drive >= L'A' && drive <= L'Z')
|
||||
{
|
||||
for(size_t i=0; i < devices.size(); i++)
|
||||
{
|
||||
AndroidDevice * d = (AndroidDevice*)devices.at(i);
|
||||
if(d->drive == drive)
|
||||
{
|
||||
devices.erase(devices.begin() + i);
|
||||
if(config) SendMessage(config,WM_USER,0,0); //refresh fields
|
||||
if(config) SendMessage(config,WM_COMMAND, MAKEWPARAM(IDC_DRIVESELECT,CBN_SELCHANGE),0); //update to correct device change as if the user had clicked on the combo box themself
|
||||
SendMessage(plugin.hwndPortablesParent,WM_PMP_IPC,(intptr_t)d,PMP_IPC_DEVICEDISCONNECTED);
|
||||
SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_COMBO_MANUALCONNECT,CBN_SELCHANGE),0);
|
||||
delete d;
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDC_MANUALBLACKLIST:
|
||||
{
|
||||
int indx = (int)SendDlgItemMessageW(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETCURSEL,0,0);
|
||||
wchar_t drive = (wchar_t)SendDlgItemMessage(hwndDlg,IDC_COMBO_MANUALCONNECT,CB_GETITEMDATA,indx,0);
|
||||
if(drive >= L'A' && drive <= L'Z') {
|
||||
wchar_t *bl = makeBlacklistString(drive);
|
||||
if (bl)
|
||||
{
|
||||
if(!blacklistCheck(drive)) {
|
||||
blacklist.push_back(bl);
|
||||
// see if we've got a connected drive and prompt to remove it or wait till restart
|
||||
if(IsDriveConnectedToPMP(drive)) {
|
||||
wchar_t title[96] = {0};
|
||||
GetWindowText(hwndDlg, title, 96);
|
||||
if(MessageBox(hwndDlg,WASABI_API_LNGSTRINGW(IDS_DRIVE_CONNECTED_DISCONNECT_Q),title,MB_YESNO)==IDYES){
|
||||
SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_MANUALDISCONNECT,0),0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(size_t i=0; i < blacklist.size(); i++)
|
||||
{
|
||||
if(!wcscmp(bl,(wchar_t*)blacklist.at(i)))
|
||||
{
|
||||
free(blacklist.at(i));
|
||||
blacklist.erase(blacklist.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(bl);
|
||||
}
|
||||
}
|
||||
SendMessage(hwndDlg,WM_COMMAND,MAKEWPARAM(IDC_COMBO_MANUALCONNECT,CBN_SELCHANGE),0);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case IDOK:
|
||||
case IDCANCEL:
|
||||
blacklistSave();
|
||||
EndDialog(hwndDlg,0);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static intptr_t MessageProc(int msg, intptr_t param1, intptr_t param2, intptr_t param3)
|
||||
{
|
||||
switch(msg) {
|
||||
case PMP_DEVICECHANGE:
|
||||
return wmDeviceChange(param1,param2);
|
||||
case PMP_CONFIG:
|
||||
WASABI_API_DIALOGBOXW(IDD_CONFIG_GLOBAL,(HWND)param1,config_dialogProc);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) PMPDevicePlugin *winampGetPMPDevicePlugin()
|
||||
{
|
||||
return &plugin;
|
||||
}
|
||||
|
209
Src/Plugins/Portable/pmp_android/pmp_android.rc
Normal file
209
Src/Plugins/Portable/pmp_android/pmp_android.rc
Normal file
|
@ -0,0 +1,209 @@
|
|||
// 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
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PNG
|
||||
//
|
||||
|
||||
IDB_ANDROID_160 PNG "resources\\generic_android.png"
|
||||
IDR_ANDROID_ICON PNG "resources\\androidIcon.png"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_CONFIG DIALOGEX 0, 0, 264, 226
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD | WS_VISIBLE | WS_SYSMENU
|
||||
EXSTYLE WS_EX_CONTROLPARENT
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
LTEXT "File Name Format",IDC_STATIC,7,10,56,8
|
||||
EDITTEXT IDC_NAMEFORMAT,80,7,127,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Format Help",IDC_FILENAMEHELP,211,7,46,14
|
||||
LTEXT "Playlist Directory",IDC_STATIC,7,26,54,8
|
||||
EDITTEXT IDC_PLDIR,80,24,128,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Browse...",IDC_PLBROWSE,211,23,46,14
|
||||
LTEXT "Supported Formats",IDC_STATIC,7,42,62,8
|
||||
EDITTEXT IDC_SUPPORTEDFORMATS,80,40,128,14,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "Syntax Help",IDC_FORMATSHELP,211,40,46,14
|
||||
LTEXT "Delete Empty Folders",IDC_STATIC,7,55,69,8
|
||||
CONTROL "",IDC_PURGEFOLDERS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,80,56,8,8
|
||||
PUSHBUTTON "Save and Rescan",IDC_RESCAN,7,71,66,14
|
||||
PUSHBUTTON "Refresh Cache",IDC_REFRESHCACHE,79,71,66,14
|
||||
GROUPBOX "Playlist Writing Options",IDC_STATIC,7,95,250,49
|
||||
COMBOBOX IDC_PL_WRITE_COMBO,12,108,120,35,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
LTEXT "Changing how Winamp saves its playlists may improve compatability with other portable devices.",IDC_STATIC,137,104,113,34
|
||||
LTEXT "",IDC_PL_WRITE_EG,12,126,120,10
|
||||
END
|
||||
|
||||
IDD_CONFIG_GLOBAL DIALOGEX 0, 0, 196, 90
|
||||
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Android Device Support Configuration"
|
||||
FONT 8, "MS Shell Dlg", 400, 0, 0x1
|
||||
BEGIN
|
||||
GROUPBOX "Select the Drive to use from the available list below",IDC_STATIC,5,3,186,67
|
||||
COMBOBOX IDC_COMBO_MANUALCONNECT,31,17,40,242,CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "Connect Drive",IDC_MANUALCONNECT,75,17,90,13
|
||||
PUSHBUTTON "Disconnect Drive",IDC_MANUALDISCONNECT,75,34,90,13
|
||||
PUSHBUTTON "Blacklist Drive",IDC_MANUALBLACKLIST,75,51,90,13
|
||||
DEFPUSHBUTTON "Close",IDOK,75,73,45,13
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO
|
||||
BEGIN
|
||||
IDD_CONFIG, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 257
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 218
|
||||
END
|
||||
|
||||
IDD_CONFIG_GLOBAL, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 5
|
||||
RIGHTMARGIN, 191
|
||||
TOPMARGIN, 3
|
||||
BOTTOMMARGIN, 86
|
||||
END
|
||||
END
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_NULLSOFT_ANDROID_DEVICE_PLUGIN "Nullsoft Android Device Plug-in v%s"
|
||||
65535 "{EBFF6E00-39D8-45e6-B3EC-E3B07A45E6B0}"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_CANNOT_OPEN_FILE "Cannot open file"
|
||||
IDS_CANNOT_CREATE_FILE "Cannot create file"
|
||||
IDS_TRANSFERING_PERCENT "Transferring %d%%"
|
||||
IDS_CANCELLED "Cancelled"
|
||||
IDS_DONE "Done"
|
||||
IDS_TRANSFER_FAILED "Transfer failed"
|
||||
IDS_REMOVEABLE_DRIVE_DETECTED
|
||||
"Winamp has detected an Android device on %c:.\nIs this a device that you want to manage with Winamp?"
|
||||
IDS_WINAMP_PMP_SUPPORT "Winamp Portable Music Player Support"
|
||||
IDS_MANUAL_CONNECT_PROMPT
|
||||
"Manually connecting the wrong device could cause problems.\nPlease be sure that you have entered a valid Android device letter.\n\nAre you sure you wish to continue?"
|
||||
IDS_WARNING "Warning"
|
||||
IDS_LOADING_DRIVE_X "Loading Drive X:"
|
||||
IDS_FAILED_TO_EJECT_DRIVE
|
||||
"Failed to eject device. Is something else using it?"
|
||||
IDS_ERROR "Error"
|
||||
IDS_ANDROID_DRIVE_X "ANDROID Drive X:"
|
||||
IDS_TRACK_IN_USE "Track is in use - Could not delete!"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_CACHE_UPDATED "Cache updated."
|
||||
IDS_SUCCESS "Success"
|
||||
IDS_FILENAME_FORMATTING_INFO
|
||||
"You may enter a filename format string for your files.\nIt can contain \\ or / to delimit a path, and the following keywords:\n\n <Artist> - inserts the artist with the default capitalization\n <ARTIST> - inserts the artist in all uppercase\n <artist> - inserts the artist in all lowercase\n <Albumartist>/<ALBUMARTIST>/<albumartist> - inserts the album artist\n <Album>/<ALBUM>/<album> - inserts the album\n <year> - inserts the album year\n <Genre>/<GENRE>/<genre> - inserts the album genre\n <Title>/<TITLE>/<title> - inserts the track title\n <filename> - inserts the original filename (extension safe)\n <disc> - inserts the disc number\n #, ##, or ### - inserts the track number, with leading 0s if ## or ###\n\n For Example: E:\\Music\\<Artist>\\<Album>\\## - <Title>\n"
|
||||
IDS_FILENAME_FORMAT_HELP "Filename Format Help"
|
||||
IDS_SELECT_FOLDER_TO_LOAD_PLAYLISTS
|
||||
"Please select a folder to load playlists from the device."
|
||||
IDS_ERR_SELECTED_PATH_NOT_ON_DEVICE
|
||||
"Error: selected path is not on device!"
|
||||
IDS_SUPPORTED_FORMAT_INFO
|
||||
"You may enter supported extensions in the form of\nextensions separated by semicolons.\n\nFor Example: mp3;wav;wma"
|
||||
IDS_SUPPORTED_FORMAT_HELP "Supported Formats Help"
|
||||
IDS_RESCAN_COMPLETE_SAVED "Rescan complete, device settings saved."
|
||||
IDS_RESCAN_COMPLETE "Rescan complete"
|
||||
IDS_ADVANCED "Advanced"
|
||||
IDS_UNBLACKLIST_DRIVE "Un-blacklist Drive"
|
||||
IDS_BLACKLIST_DRIVE "Blacklist Drive"
|
||||
IDS_DRIVE_CONNECTED_DISCONNECT_Q
|
||||
"The Drive you have selected to blacklist is currently connected and being managed.\n\nWould you like to disconnect the Drive now or you can wait until you restart Winamp."
|
||||
IDS_SLASH_AT_START "Slash at start of paths (default)"
|
||||
IDS_DOT_AT_START "Dot at start of paths"
|
||||
END
|
||||
|
||||
STRINGTABLE
|
||||
BEGIN
|
||||
IDS_NO_SLASH_OR_DOT "No slash or dot at start"
|
||||
IDS_EG_SLASH "e.g. \\path\\to\\file.mp3"
|
||||
IDS_EG_DOT "e.g. .\\path\\to\\file.mp3"
|
||||
IDS_EG_NEITHER "e.g. path\\to\\file.mp3"
|
||||
IDS_DELAYLOAD_FAILURE "Android plug-in cannot load the database to write the cache file"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
#include "version.rc2"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
130
Src/Plugins/Portable/pmp_android/pmp_android.sln
Normal file
130
Src/Plugins/Portable/pmp_android/pmp_android.sln
Normal file
|
@ -0,0 +1,130 @@
|
|||
|
||||
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}") = "pmp_android", "pmp_android.vcxproj", "{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{57C90706-B25D-4ACA-9B33-95CDB2427C27} = {57C90706-B25D-4ACA-9B33-95CDB2427C27}
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
|
||||
{4D25C321-7F8B-424E-9899-D80A364BAF1A} = {4D25C321-7F8B-424E-9899-D80A364BAF1A}
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1} = {D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}
|
||||
{F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915} = {F1F5CD60-0D5B-4CEA-9EEB-2F87FF9AA915}
|
||||
{E105A0A2-7391-47C5-86AC-718003524C3D} = {E105A0A2-7391-47C5-86AC-718003524C3D}
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909} = {255B68B5-7EF8-45EF-A675-2D6B88147909}
|
||||
{0F9730E4-45DA-4BD2-A50A-403A4BC9751A} = {0F9730E4-45DA-4BD2-A50A-403A4BC9751A}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bfc", "..\Wasabi\bfc\bfc.vcxproj", "{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tataki", "..\tataki\tataki.vcxproj", "{255B68B5-7EF8-45EF-A675-2D6B88147909}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F} = {DABE6307-F8DD-416D-9DAC-673E2DECB73F}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nsutil", "..\nsutil\nsutil.vcxproj", "{DABE6307-F8DD-416D-9DAC-673E2DECB73F}"
|
||||
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
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Debug|x64.Build.0 = Debug|x64
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Release|Win32.Build.0 = Release|Win32
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Release|x64.ActiveCfg = Release|x64
|
||||
{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}.Release|x64.Build.0 = Release|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Debug|x64.Build.0 = Debug|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|Win32.Build.0 = Release|Win32
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|x64.ActiveCfg = Release|x64
|
||||
{D0EC862E-DDDD-4F4F-934F-B75DC9062DC1}.Release|x64.Build.0 = Release|x64
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Debug|x64.Build.0 = Debug|x64
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|Win32.Build.0 = Release|Win32
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|x64.ActiveCfg = Release|x64
|
||||
{255B68B5-7EF8-45EF-A675-2D6B88147909}.Release|x64.Build.0 = Release|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Debug|x64.Build.0 = Debug|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|Win32.Build.0 = Release|Win32
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.Release|x64.ActiveCfg = Release|x64
|
||||
{DABE6307-F8DD-416D-9DAC-673E2DECB73F}.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
|
332
Src/Plugins/Portable/pmp_android/pmp_android.vcxproj
Normal file
332
Src/Plugins/Portable/pmp_android/pmp_android.vcxproj
Normal file
|
@ -0,0 +1,332 @@
|
|||
<?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>{491665B2-6437-4D30-9AEC-DE7D1CB20E1E}</ProjectGuid>
|
||||
<RootNamespace>pmp_android</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>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
<IncludePath>$(IncludePath)</IncludePath>
|
||||
<LibraryPath>$(LibraryPath)</LibraryPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
<OutDir>$(PlatformShortName)_$(Configuration)\</OutDir>
|
||||
<IntDir>$(PlatformShortName)_$(Configuration)\</IntDir>
|
||||
</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>_WINDOWS;_UNICODE;UNICODE;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4244;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x040c</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>wsock32.lib;shlwapi.lib;fmtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalIncludeDirectories)</AdditionalLibraryDirectories>
|
||||
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
|
||||
</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>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..;..\..\..\;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_WINDOWS;_UNICODE;UNICODE;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN64;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MinimalRebuild>false</MinimalRebuild>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4244;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x040c</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>wsock32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
|
||||
</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>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..;..\..\..\;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_WINDOWS;_UNICODE;UNICODE;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4244;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x040c</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>wsock32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</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>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<FavorSizeOrSpeed>Size</FavorSizeOrSpeed>
|
||||
<AdditionalIncludeDirectories>.;..\..\..\Wasabi;..;..\..\..\;..\..\..\replicant;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<PreprocessorDefinitions>_WINDOWS;_UNICODE;UNICODE;_USRDLL;ML_ex_EXPORTS;_CRT_SECURE_NO_WARNINGS;WIN64;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<StringPooling>true</StringPooling>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<BufferSecurityCheck>true</BufferSecurityCheck>
|
||||
<TreatWChar_tAsBuiltInType>true</TreatWChar_tAsBuiltInType>
|
||||
<ForceConformanceInForLoopScope>true</ForceConformanceInForLoopScope>
|
||||
<AssemblerListingLocation>$(IntDir)</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>$(IntDir)$(TargetName).pdb</ProgramDataBaseFileName>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>None</DebugInformationFormat>
|
||||
<DisableSpecificWarnings>4244;4996;%(DisableSpecificWarnings)</DisableSpecificWarnings>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<Culture>0x040c</Culture>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>wsock32.lib;shlwapi.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||
<ProgramDatabaseFile>$(IntDir)$(TargetName).pdb</ProgramDatabaseFile>
|
||||
<MapFileName>$(IntDir)$(TargetName).map</MapFileName>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<RandomizedBaseAddress>false</RandomizedBaseAddress>
|
||||
<ImportLibrary>$(IntDir)$(TargetName).lib</ImportLibrary>
|
||||
<AdditionalLibraryDirectories>%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
|
||||
</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>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\..\General\gen_ml\ml_lib.cpp" />
|
||||
<ClCompile Include="albumart.cpp" />
|
||||
<ClCompile Include="androiddevice.cpp" />
|
||||
<ClCompile Include="androidplaylist.cpp" />
|
||||
<ClCompile Include="androidplaylistsaver.cpp" />
|
||||
<ClCompile Include="api.cpp" />
|
||||
<ClCompile Include="deviceprovider.cpp" />
|
||||
<ClCompile Include="eject.cpp" />
|
||||
<ClCompile Include="filecopy.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
<ClCompile Include="utils.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\..\General\gen_ml\ml.h" />
|
||||
<ClInclude Include="..\..\Library\ml_pmp\pmp.h" />
|
||||
<ClInclude Include="androiddevice.h" />
|
||||
<ClInclude Include="androidplaylist.h" />
|
||||
<ClInclude Include="androidplaylistsaver.h" />
|
||||
<ClInclude Include="api.h" />
|
||||
<ClInclude Include="deviceprovider.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="resources\androidIcon.png" />
|
||||
<Image Include="resources\generic_android.png" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="pmp_android.rc" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\nde\nde.vcxproj">
|
||||
<Project>{4d25c321-7f8b-424e-9899-d80a364baf1a}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\replicant\nu\nu.vcxproj">
|
||||
<Project>{f1f5cd60-0d5b-4cea-9eeb-2f87ff9aa915}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\tataki\tataki.vcxproj">
|
||||
<Project>{255b68b5-7ef8-45ef-a675-2d6b88147909}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\Wasabi\Wasabi.vcxproj">
|
||||
<Project>{3e0bfa8a-b86a-42e9-a33f-ec294f823f7f}</Project>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\WAT\WAT.vcxproj">
|
||||
<Project>{c5714908-a71f-4644-bd95-aad8ee7914da}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
91
Src/Plugins/Portable/pmp_android/pmp_android.vcxproj.filters
Normal file
91
Src/Plugins/Portable/pmp_android/pmp_android.vcxproj.filters
Normal file
|
@ -0,0 +1,91 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="albumart.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="androiddevice.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="androidplaylist.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="androidplaylistsaver.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="api.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="deviceprovider.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="eject.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="filecopy.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="utils.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\General\gen_ml\ml_lib.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="androiddevice.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="androidplaylist.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="androidplaylistsaver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="api.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="deviceprovider.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="resource.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\General\gen_ml\ml.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\Library\ml_pmp\pmp.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Image Include="resources\generic_android.png">
|
||||
<Filter>Image Files</Filter>
|
||||
</Image>
|
||||
<Image Include="resources\androidIcon.png">
|
||||
<Filter>Image Files</Filter>
|
||||
</Image>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{82d6647a-a3b9-4ade-b2cc-4a360f5ed80d}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Ressource Files">
|
||||
<UniqueIdentifier>{8731ac77-4c42-42fc-8ff8-f64922843c99}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{06318ce7-b270-4a39-833a-4ab306c760ed}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Image Files">
|
||||
<UniqueIdentifier>{d2febc64-2e0e-4a50-8994-0dcaab423352}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="pmp_android.rc">
|
||||
<Filter>Ressource Files</Filter>
|
||||
</ResourceCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
75
Src/Plugins/Portable/pmp_android/resource.h
Normal file
75
Src/Plugins/Portable/pmp_android/resource.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Visual C++ generated include file.
|
||||
// Used by pmp_android.rc
|
||||
//
|
||||
#define IDS_CANNOT_OPEN_FILE 1
|
||||
#define IDS_CANNOT_CREATE_FILE 2
|
||||
#define IDS_TRANSFERING_PERCENT 3
|
||||
#define IDS_CANCELLED 4
|
||||
#define IDS_DONE 5
|
||||
#define IDS_TRANSFER_FAILED 6
|
||||
#define IDS_REMOVEABLE_DRIVE_DETECTED 7
|
||||
#define IDS_WINAMP_PMP_SUPPORT 8
|
||||
#define IDS_MANUAL_CONNECT_PROMPT 9
|
||||
#define IDS_WARNING 10
|
||||
#define IDS_LOADING_DRIVE_X 11
|
||||
#define IDS_FAILED_TO_EJECT_DRIVE 12
|
||||
#define IDS_ERROR 13
|
||||
#define IDS_STRING14 14
|
||||
#define IDS_ANDROID_DRIVE_X 14
|
||||
#define IDS_TRACK_IN_USE 15
|
||||
#define IDS_CACHE_UPDATED 16
|
||||
#define IDS_SUCCESS 17
|
||||
#define IDS_FILENAME_FORMATTING_INFO 18
|
||||
#define IDS_FILENAME_FORMAT_HELP 19
|
||||
#define IDS_SELECT_FOLDER_TO_LOAD_PLAYLISTS 20
|
||||
#define IDS_ERR_SELECTED_PATH_NOT_ON_DEVICE 21
|
||||
#define IDS_SUPPORTED_FORMAT_INFO 22
|
||||
#define IDS_SUPPORTED_FORMAT_HELP 23
|
||||
#define IDS_RESCAN_COMPLETE_SAVED 24
|
||||
#define IDS_RESCAN_COMPLETE 25
|
||||
#define IDS_ADVANCED 26
|
||||
#define IDS_UNBLACKLIST_DRIVE 27
|
||||
#define IDS_BLACKLIST_DRIVE 28
|
||||
#define IDS_DRIVE_CONNECTED_DISCONNECT_Q 29
|
||||
#define IDS_SLASH_AT_START 30
|
||||
#define IDS_DOT_AT_START 31
|
||||
#define IDS_NO_SLASH_OR_DOT 32
|
||||
#define IDS_EG_SLASH 33
|
||||
#define IDS_EG_DOT 34
|
||||
#define IDS_STRING35 35
|
||||
#define IDS_EG_NEITHER 35
|
||||
#define IDS_DELAYLOAD_FAILURE 36
|
||||
#define IDD_CONFIG 102
|
||||
#define IDD_CONFIG_GLOBAL 105
|
||||
#define IDB_ANDROID_160 110
|
||||
#define IDB_PNG1 111
|
||||
#define IDR_ANDROID_ICON 111
|
||||
#define IDC_PLDIR 1001
|
||||
#define IDC_NAMEFORMAT 1002
|
||||
#define IDC_SUPPORTEDFORMATS 1003
|
||||
#define IDC_DRIVESELECT 1004
|
||||
#define IDC_COMBO_MANUALCONNECT 1005
|
||||
#define IDC_MANUALCONNECT 1006
|
||||
#define IDC_MANUALDISCONNECT 1007
|
||||
#define IDC_MANUALBLACKLIST 1008
|
||||
#define IDC_REFRESHCACHE 1011
|
||||
#define IDC_FILENAMEHELP 1012
|
||||
#define IDC_PLBROWSE 1013
|
||||
#define IDC_FORMATSHELP 1014
|
||||
#define IDC_RESCAN 1015
|
||||
#define IDC_PURGEFOLDERS 1016
|
||||
#define IDC_PL_WRITE_COMBO 1017
|
||||
#define IDC_PL_WRITE_EG 1018
|
||||
#define IDS_NULLSOFT_ANDROID_DEVICE_PLUGIN 65534
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 113
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1019
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
BIN
Src/Plugins/Portable/pmp_android/resources/androidIcon.png
Normal file
BIN
Src/Plugins/Portable/pmp_android/resources/androidIcon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 197 B |
BIN
Src/Plugins/Portable/pmp_android/resources/generic_android.png
Normal file
BIN
Src/Plugins/Portable/pmp_android/resources/generic_android.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
334
Src/Plugins/Portable/pmp_android/utils.cpp
Normal file
334
Src/Plugins/Portable/pmp_android/utils.cpp
Normal file
|
@ -0,0 +1,334 @@
|
|||
#include <windows.h>
|
||||
#include "../../General/gen_ml/ml.h"
|
||||
#include "../../Library/ml_pmp/pmp.h"
|
||||
#include "AndroidDevice.h"
|
||||
#include <strsafe.h>
|
||||
#include <shlwapi.h>
|
||||
|
||||
BOOL RecursiveCreateDirectory(wchar_t* buf1);
|
||||
__int64 fileSize(wchar_t * filename);
|
||||
bool supportedFormat(wchar_t * file, wchar_t * supportedFormats);
|
||||
DeviceType detectDeviceType(wchar_t drive);
|
||||
void removebadchars(wchar_t *s);
|
||||
wchar_t * FixReplacementVars(wchar_t *str, int str_size, Device * dev, songid_t song);
|
||||
|
||||
void removebadchars(wchar_t *s) {
|
||||
while (s && *s)
|
||||
{
|
||||
if (*s == L'?' || *s == L'/' || *s == L'\\' || *s == L':' || *s == L'*' || *s == L'\"' || *s == L'<' || *s == L'>' || *s == L'|')
|
||||
*s = L'_';
|
||||
s = CharNextW(s);
|
||||
}
|
||||
}
|
||||
|
||||
__int64 fileSize(wchar_t * filename)
|
||||
{
|
||||
WIN32_FIND_DATA f={0};
|
||||
HANDLE h = FindFirstFileW(filename,&f);
|
||||
if(h == INVALID_HANDLE_VALUE) return -1;
|
||||
FindClose(h);
|
||||
ULARGE_INTEGER i;
|
||||
i.HighPart = f.nFileSizeHigh;
|
||||
i.LowPart = f.nFileSizeLow;
|
||||
return i.QuadPart;
|
||||
}
|
||||
|
||||
// RecursiveCreateDirectory: creates all non-existent folders in a path
|
||||
BOOL RecursiveCreateDirectory(wchar_t* buf1) {
|
||||
wchar_t *p=buf1;
|
||||
int errors = 0;
|
||||
if (*p) {
|
||||
p = PathSkipRoot(buf1);
|
||||
if (!p) return true ;
|
||||
|
||||
wchar_t ch='c';
|
||||
while (ch) {
|
||||
while (p && *p != '\\' && *p) p = CharNext(p);
|
||||
ch = (p ? *p : 0);
|
||||
if (p) *p = 0;
|
||||
int pp = (int)wcslen(buf1)-1;
|
||||
|
||||
while(buf1[pp] == '.' || buf1[pp] == ' ' ||
|
||||
(buf1[pp] == '\\' && (buf1[pp-1] == '.' || buf1[pp-1] == ' ' || buf1[pp-1] == '/')) ||
|
||||
buf1[pp] == '/' && buf1)
|
||||
{
|
||||
if(buf1[pp] == '\\')
|
||||
{
|
||||
buf1[pp-1] = '_';
|
||||
pp -= 2;
|
||||
} else {
|
||||
buf1[pp] = '_';
|
||||
pp--;
|
||||
}
|
||||
}
|
||||
|
||||
WIN32_FIND_DATA fd = {0};
|
||||
// Avoid a "There is no disk in the drive" error box on empty removable drives
|
||||
UINT prevErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX | SEM_FAILCRITICALERRORS);
|
||||
HANDLE h = FindFirstFile(buf1,&fd);
|
||||
SetErrorMode(prevErrorMode);
|
||||
if (h == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!CreateDirectory(buf1,NULL)) errors++;
|
||||
} else {
|
||||
FindClose(h);
|
||||
if ((fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) errors++;
|
||||
}
|
||||
if (p) *p++ = ch;
|
||||
}
|
||||
}
|
||||
|
||||
return errors != 0;
|
||||
}
|
||||
|
||||
bool supportedFormat(wchar_t * file, wchar_t * supportedFormats) {
|
||||
wchar_t * ext = wcsrchr(file,'.');
|
||||
if(!ext) return false;
|
||||
ext++;
|
||||
wchar_t * p = supportedFormats;
|
||||
while(p && *p) {
|
||||
bool ret=false;
|
||||
wchar_t * np = wcschr(p,L';');
|
||||
if(np) *np = 0;
|
||||
if(!_wcsicmp(ext,p)) ret=true;
|
||||
if(np) { *np = L';'; p=np+1; }
|
||||
else return ret;
|
||||
if(ret) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// FixReplacementVars: replaces <Artist>, <Title>, <Album>, and #, ##, ##, with appropriate data
|
||||
// DOES NOT add a file extention!!
|
||||
wchar_t * fixReplacementVars(wchar_t *str, int str_size, Device * dev, songid_t song)
|
||||
{
|
||||
#define ADD_STR(x) { x(song,outp,str_size-1-(outp-str)); removebadchars(outp); while (outp && *outp) outp++; }
|
||||
#define ADD_STR_U(x) { x(song,outp,str_size-1-(outp-str)); removebadchars(outp); while (outp && *outp) { *outp=towupper(*outp); outp++; } }
|
||||
#define ADD_STR_L(x) { x(song,outp,str_size-1-(outp-str)); removebadchars(outp); while (outp && *outp) { *outp=towlower(*outp); outp++; } }
|
||||
|
||||
wchar_t tmpsrc[4096] = {0};
|
||||
lstrcpyn(tmpsrc,str,sizeof(tmpsrc)/sizeof(wchar_t)); //lstrcpyn is nice enough to make sure it's null terminated.
|
||||
|
||||
wchar_t *inp = tmpsrc;
|
||||
wchar_t *outp = str;
|
||||
int slash = 0;
|
||||
|
||||
while (inp && *inp && outp-str < str_size-2)
|
||||
{
|
||||
if (*inp == L'<')
|
||||
{
|
||||
if (!wcsncmp(inp,L"<TITLE>",7))
|
||||
{
|
||||
ADD_STR_U(dev->getTrackTitle);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<title>",7))
|
||||
{
|
||||
ADD_STR_L(dev->getTrackTitle);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<Title>",7))
|
||||
{
|
||||
ADD_STR(dev->getTrackTitle);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<ALBUM>",7))
|
||||
{
|
||||
ADD_STR_U(dev->getTrackAlbum);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<album>",7))
|
||||
{
|
||||
ADD_STR_L(dev->getTrackAlbum);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<Album>",7))
|
||||
{
|
||||
ADD_STR(dev->getTrackAlbum);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<GENRE>",7))
|
||||
{
|
||||
ADD_STR_U(dev->getTrackGenre);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<genre>",7))
|
||||
{
|
||||
ADD_STR_L(dev->getTrackGenre);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<Genre>",7))
|
||||
{
|
||||
ADD_STR(dev->getTrackGenre);
|
||||
inp+=7;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<ARTIST>",8))
|
||||
{
|
||||
ADD_STR_U(dev->getTrackArtist);
|
||||
inp+=8;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<artist>",8))
|
||||
{
|
||||
ADD_STR_L(dev->getTrackArtist);
|
||||
inp+=8;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<Artist>",8))
|
||||
{
|
||||
ADD_STR(dev->getTrackArtist);
|
||||
inp+=8;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<ALBUMARTIST>",13))
|
||||
{
|
||||
wchar_t temp[128] = {0};
|
||||
|
||||
dev->getTrackAlbumArtist(song, temp, 128);
|
||||
if (temp[0] == 0)
|
||||
dev->getTrackArtist(song, temp, 128);
|
||||
|
||||
lstrcpyn(outp,temp,str_size-1-(outp-str));
|
||||
removebadchars(outp);
|
||||
while (outp && *outp) { *outp=towupper(*outp); outp++; }
|
||||
|
||||
inp+=13;
|
||||
}
|
||||
else if (!wcsncmp(inp,L"<albumartist>",13))
|
||||
{
|
||||
wchar_t temp[128] = {0};
|
||||
|
||||
dev->getTrackAlbumArtist(song, temp, 128);
|
||||
if (temp[0] == 0)
|
||||
dev->getTrackArtist(song, temp, 128);
|
||||
|
||||
lstrcpyn(outp,temp,str_size-1-(outp-str));
|
||||
removebadchars(outp);
|
||||
while (outp && *outp) { *outp=towlower(*outp); outp++; }
|
||||
inp+=13;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<Albumartist>",13))
|
||||
{
|
||||
wchar_t temp[128] = {0};
|
||||
|
||||
dev->getTrackAlbumArtist(song, temp, 128);
|
||||
if (temp[0] == 0)
|
||||
dev->getTrackArtist(song, temp, 128);
|
||||
|
||||
lstrcpyn(outp,temp, (int)str_size-1-(outp-str));
|
||||
removebadchars(outp);
|
||||
while (outp && *outp) outp++;
|
||||
inp+=13;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<year>",6))
|
||||
{
|
||||
wchar_t year[64] = {0};
|
||||
int y = dev->getTrackYear(song);
|
||||
if (y) StringCchPrintf(year, ARRAYSIZE(year), L"%d", y);
|
||||
lstrcpyn(outp,year, (int)str_size-1-(outp-str)); while (outp && *outp) outp++;
|
||||
inp+=6;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<disc>",6))
|
||||
{
|
||||
wchar_t disc[16] = {0};
|
||||
int d = dev->getTrackDiscNum(song);
|
||||
if (d) StringCchPrintf(disc, ARRAYSIZE(disc), L"%d", d);
|
||||
lstrcpyn(outp,disc, (int)str_size-1-(outp-str)); while (outp && *outp) outp++;
|
||||
inp+=6;
|
||||
}
|
||||
else if (!_wcsnicmp(inp,L"<filename>",10))
|
||||
{
|
||||
wchar_t tfn[MAX_PATH], *ext, *fn;
|
||||
StringCchCopy(tfn,MAX_PATH,((AndroidSong*)song)->filename);
|
||||
ext = wcsrchr(tfn, L'.');
|
||||
*ext = 0; //kill extension since its added later
|
||||
fn = wcsrchr(tfn, L'\\');
|
||||
fn++;
|
||||
lstrcpyn(outp,fn, (int)str_size-1-(outp-str));
|
||||
while (outp && *outp) outp++;
|
||||
inp+=10;
|
||||
}
|
||||
else
|
||||
{
|
||||
// use this to skip over unknown tags
|
||||
while (inp && *inp && *inp != L'>') inp++;
|
||||
if (inp) inp++;
|
||||
}
|
||||
}
|
||||
else if (*inp == L'#')
|
||||
{
|
||||
int nd=0;
|
||||
wchar_t tmp[64] = {0};
|
||||
while (inp && *inp == L'#') nd++,inp++;
|
||||
int track = dev->getTrackTrackNum(song);
|
||||
if (!track)
|
||||
{
|
||||
while (inp && *inp == L' ') inp++;
|
||||
while (inp && *inp == L'\\') inp++;
|
||||
if (inp && (*inp == L'-' || *inp == L'.' || *inp == L'_')) // separator
|
||||
{
|
||||
inp++;
|
||||
while (inp && *inp == L' ') inp++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (nd > 1)
|
||||
{
|
||||
wchar_t tmp2[32] = {0};
|
||||
if (nd > 5) nd=5;
|
||||
StringCchPrintf(tmp2, ARRAYSIZE(tmp2), L"%%%02dd",nd);
|
||||
StringCchPrintf(tmp, ARRAYSIZE(tmp), tmp2,track);
|
||||
}
|
||||
else StringCchPrintf(tmp, ARRAYSIZE(tmp), L"%d",track);
|
||||
}
|
||||
lstrcpyn(outp,tmp, (int)str_size-1-(outp-str)); while (outp && *outp) outp++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (*inp == L'\\') slash += 1;
|
||||
*outp++=*inp++;
|
||||
}
|
||||
}
|
||||
|
||||
if (outp) *outp = 0;
|
||||
|
||||
// if we end up with something like U:\\\ then this
|
||||
// will set it to be just <filename> so it'll not
|
||||
// end up making a load of bad files e.g. U:\.mp3
|
||||
int out_len = lstrlen(str);
|
||||
if (out_len)
|
||||
{
|
||||
if (out_len - 2 == slash)
|
||||
{
|
||||
outp = str + 3;
|
||||
wchar_t tfn[MAX_PATH], *ext, *fn;
|
||||
StringCchCopy(tfn,MAX_PATH,((AndroidSong*)song)->filename);
|
||||
ext = wcsrchr(tfn, L'.');
|
||||
*ext = 0; //kill extension since its added later
|
||||
fn = wcsrchr(tfn, L'\\');
|
||||
fn++;
|
||||
lstrcpyn(outp,fn, (int)str_size-1-(outp-str));
|
||||
while (outp && *outp) outp++;
|
||||
if (outp) *outp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
inp=str;
|
||||
outp=str;
|
||||
wchar_t lastc=0;
|
||||
while (inp && *inp)
|
||||
{
|
||||
wchar_t ch=*inp++;
|
||||
if (ch == L'\t') ch=L' ';
|
||||
|
||||
if (ch == L' ' && (lastc == L' ' || lastc == L'\\' || lastc == L'/')) continue; // ignore space after slash, or another space
|
||||
|
||||
if ((ch == L'\\' || ch == L'/') && lastc == L' ') outp--; // if we have a space then slash, back up to write the slash where the space was
|
||||
*outp++=ch;
|
||||
lastc=ch;
|
||||
}
|
||||
if (outp) *outp=0;
|
||||
#undef ADD_STR
|
||||
#undef ADD_STR_L
|
||||
#undef ADD_STR_U
|
||||
|
||||
return str;
|
||||
}
|
39
Src/Plugins/Portable/pmp_android/version.rc2
Normal file
39
Src/Plugins/Portable/pmp_android/version.rc2
Normal file
|
@ -0,0 +1,39 @@
|
|||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
#include "../../../Winamp/buildType.h"
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,72,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 Portable Device Plug-in"
|
||||
VALUE "FileVersion", "1,72,0,0"
|
||||
VALUE "InternalName", "Nullsoft Android Device"
|
||||
VALUE "LegalCopyright", "Copyright © 2010-2023 Winamp SA"
|
||||
VALUE "LegalTrademarks", "Nullsoft and Winamp are trademarks of Winamp SA"
|
||||
VALUE "OriginalFilename", "pmp_android.dll"
|
||||
VALUE "ProductName", "Winamp"
|
||||
VALUE "ProductVersion", STR_WINAMP_PRODUCTVER
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
Loading…
Add table
Add a link
Reference in a new issue