Fonctions de la DLL amp_in.dll

Signaler
Messages postés
2106
Date d'inscription
mercredi 21 août 2002
Statut
Contributeur
Dernière intervention
15 novembre 2020
-
Messages postés
2106
Date d'inscription
mercredi 21 août 2002
Statut
Contributeur
Dernière intervention
15 novembre 2020
-
Bonjjour tout le monde !

J'aimerais utiliser la DLL amp_in.dll dans VB6 (DLL utilisée dans mIRC pour utiliser les plugins Winamp). J'ai réussis à recupérer le nom des fonctions de la DLL mais je ne connais pas leurs paramètres. Les fonctions que j'ai trouvé sont : CurrentMusic, Queue, Info, Play, Stop, Misc, PluginManager, FlushAllPlugins et DLLInfo. La DLL est dispo ici : http://www.ircfr.com/codes/RADIOCAST-PLAYER-V2-RADIO-SHOUTCAST_41735.aspx

Je pense que cette DLL est tout a fait exploitable via VB6 mais sans connaitre les fonctions précises, rien de possible.

Ma question est donc : Comment récupérer la liste complète des fonctions ainsi que leurs paramètres ? ou si quelqu'un a directement les fonctions je suis preuneur.

D'avance, merci

[PaTaTe]

6 réponses

Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
67
dll classique => export de fonctions
utiliser depends.exe (par exemple) pour lister les fonctions exportées.

pour les parametres, pas de miracle.

mais regarde dans le code source, au niveau des $RadioCastV2.dll
Messages postés
17286
Date d'inscription
mercredi 2 janvier 2002
Statut
Modérateur
Dernière intervention
23 décembre 2019
67
Depends.exe donne bien les même 9 fonctions que tu as listé.
Messages postés
2106
Date d'inscription
mercredi 21 août 2002
Statut
Contributeur
Dernière intervention
15 novembre 2020
2
Petite avancée dans mes recherches ! Je viens de mettre la main sur une partie du code de la DLL (la partie qui nous interesse en plus)

Elle decrit les fonctions listées ci-dessus. Seulement, problème : les essais de déclarations que j'ai pu tenté ne fonctionne pas. Soit le resultat est nul soit il provoquue une opération non conforme sur oleaut32.dll.

Voici le code :

#include <windows.h>
#include <string.h>
#include "in2.h"
#include "dsp.h"
#include <mmsystem.h>

#define VERSION "1.08hack"

#define AUTHINFO \
"WA Plugin Interface DLL, v" VERSION " (c) 1999-2000 DragonZap, Hacked to mIRC 6.x+ by EmiZ"

#define WM_WA_MPEG_EOF WM_USER+2
#define MP3_PLUGIN_DESC "Nullsoft MPEG audio decoder plug-in "

#define TITLESIZE 500

#define AMPCLASS "Winamp v1.x"

// Returned error codes
#define WA_ERROR "ERROR WAE"
#define WAE_NOT_PLAYING        "0 Music is not playing"
#define WAE_PLAYING            "1 Music is currently playing"
#define WAE_BAD_FILE        "2 File could not be loaded"
#define WAE_NO_PLUGIN        "3 No matching plugin found"
#define WAE_HAVE_PLUGIN        "4 Plugin already loaded"
#define WAE_PLUGIN_VERSION    "5 Plugin is not correct version"
#define WAE_BAD_PLUGIN        "6 Plugin could not be loaded"
#define WAE_NO_OUT            "7 No output plugin loaded"
#define WAE_SYNTAX            "8 Error in request"
#define WAE_LONG_NAME        "9 Filename too long"
#define WAE_QUEUE_OOB        "10 Queue out of bounds"
#define WAE_QUEUE_EMPTY        "11 Queue is empty"
#define WAE_NO_SEEK            "12 This type of media cannot seek"
#define WAE_EXT_OOB            "13 Extension out of bounds"
#define WAE_IO                "14 I/O error"
#define WAE_INVALID_FORMAT    "15 Invalid file format"
#define WAE_USING_WINDOW    "16 Window is in use"
#define WAE_UNKNOWN            "255 Unknown error"
#define RETURNERROR(e) {\
    strcpy(data,WA_ERROR WAE_ ## e );\
    return 3;\
}

#ifdef __cplusplus
extern "C" {
#endif

struct PLUGINLIST {
    HMODULE WinampPlugin;
    In_Module *Plugin_Info;
    PLUGINLIST *Next,*Prev;
};

struct PLAYQUEUE {
    char FileName[MAX_PATH+1];
    char TitleCache[TITLESIZE];
    int SizeCache;
    PLAYQUEUE *Next,*Prev;
};

struct EQUALIZER {
    int Enabled;
    char Data[10];
    int PreAmplification;
};

EQUALIZER Equalizer = {
    0,
    {31,31,31,31,31,31,31,31,31,31},
    31
};

struct SPAWNCMD {
    char code;
    void * lpPlugin;
    char FileName[MAX_PATH+1];
};
#define WC_NOTHING            0    // Do nothing
#define WC_INPUT_INFO        1    // Spawn info dialog for specified file
#define WC_INPUT_ABOUT        2    // Spawn about box for input plugin
#define WC_INPUT_CONFIG        3    // Spawn config box for input plugin
#define WC_OUTPUT_ABOUT        4    // Spawn about box for output plugin
#define WC_OUTPUT_CONFIG    5    // Spawn config box for output plugin
#define WC_DSP_CONFIG        6    // Spawn config box for DSP plugin

char CurrentFile[MAX_PATH+1] = "";PLAYQUEUE *PQStart NULL,*PQEnd NULL,*PQCurrent = NULL;
PLUGINLIST *First NULL,*Last NULL;
PLUGINLIST * MusicPlaying = NULL;

HMODULE OutPlugin = NULL;
Out_Module *OutPluginInfo = NULL;
HMODULE Self = NULL;
BOOL AutoShuffle = false;
BOOL Looping = false;
BOOL Installed = false;
HWND hFakeAmpWindow = NULL;
HWND hMircWindow = NULL;

HHOOK hHookUninstaller = NULL;

#define WN_NONE    0    // Don't notify mIRC on song completion
#define WN_WAVE 1    /* Notify mIRC with an "on WAVEEND" when a song completes; any current
                       wave dies */
#define WN_MIDI 2   /* Notify mIRC with an "on MIDIEND" when a song completes; any current
                       midi dies */
char NotifyMethod = WN_NONE;

winampDSPHeader * lpDSPHeader = NULL;
winampDSPModule * lpDSPModule = NULL;
HMODULE DSPPlugin = NULL;

SPAWNCMD wcSpawn = {
    WC_NOTHING,
    NULL,
    ""
};

int soundVolume = 255;    // 0 to 255
int soundPan = 0;        // -128 to 128

PLAYQUEUE * InsertPrecachedQueue(char *File,char *Title,int length,PLAYQUEUE * After);
PLUGINLIST * AddInputPlugin(HMODULE PluginDLL,In_Module *Info);
PLUGINLIST * SelectInputPlugin(char * Filename,BOOL CheckURL);
BOOL RemoveInputPlugin(PLUGINLIST * Rem);
LRESULT CALLBACK AmpProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
void RemovePlayQueue(PLAYQUEUE * Die);
int CountPlayQueue();
BOOL StopMusic();
LRESULT CALLBACK AutoUninstall(int nCode,WPARAM wParam,LPARAM lParam);

HANDLE hSpawnEvent = NULL;
HANDLE hSpawnThread = NULL;

// Sends a command to the window spawner if it's not doing one already
char SendSpawnCmd(char cmd,void * plugin,char * file)
{
    char OldCmd = wcSpawn.code;
    if (OldCmd == WC_NOTHING)
    {
        if (file != NULL)
            strcpy(wcSpawn.FileName,file);
        wcSpawn.lpPlugin = plugin;

        // Set it in motion
        wcSpawn.code = cmd;

        SetEvent(hSpawnEvent);
    }
    return OldCmd;
}

DWORD WINAPI WindowSpawningThread(LPVOID lpParameter)
{
    SPAWNCMD *lpSpawn = (SPAWNCMD *)lpParameter;
    while(1)
    {
        switch(lpSpawn->code)
        {
        case WC_INPUT_INFO:
            ((In_Module *)lpSpawn->lpPlugin)->InfoBox(lpSpawn->FileName,hMircWindow);
            lpSpawn->code = WC_NOTHING;
            break;
        case WC_INPUT_ABOUT:
            ((In_Module *)lpSpawn->lpPlugin)->About(hMircWindow);
            lpSpawn->code = WC_NOTHING;
            break;
        case WC_INPUT_CONFIG:
            ((In_Module *)lpSpawn->lpPlugin)->Config(hMircWindow);
            lpSpawn->code = WC_NOTHING;
            break;
        case WC_OUTPUT_ABOUT:
            ((Out_Module *)lpSpawn->lpPlugin)->About(hMircWindow);
            lpSpawn->code = WC_NOTHING;
            break;
        case WC_OUTPUT_CONFIG:
            ((Out_Module *)lpSpawn->lpPlugin)->Config(hMircWindow);
            lpSpawn->code = WC_NOTHING;
            break;
        case WC_DSP_CONFIG:
            ((winampDSPModule *)lpSpawn->lpPlugin)->Config(
                (winampDSPModule *)lpSpawn->lpPlugin);
            lpSpawn->code = WC_NOTHING;
            break;
        }
        WaitForSingleObject(hSpawnEvent,10000);
    }
}

void SAVSAInit(int maxlatency_in_ms, int srate)
{
}

void SAVSADeInit()
{
}

void SAAddPCMData(void *PCMData, int nch, int bps, int timestamp)
{
}

int SAGetMode()
{
    return 2;
}

void SAAdd(void *data, int timestamp, int csa)
{
}

void VSAAddPCMData(void *PCMData, int nch, int bps, int timestamp)
{
}

int VSAGetMode(int *specNch, int *waveNch)
{
    return 0;
}

void VSAAdd(void *data, int timestamp)
{
}

void VSASetInfo(int nch, int srate)
{
}

    // dsp plug-in processing:
    // (filled in by winamp, called by input plug)

    // returns 1 if active (which means that the number of samples returned by dsp_dosamples
    // could be greater than went in.. Use it to estimate if you'll have enough room in the
    // output buffer
int dsp_isactive()
{
    return (lpDSPModule != NULL);
}

    // returns number of samples to output. This can be as much as twice numsamples.
    // be sure to allocate enough buffer for samples, then.
int dsp_dosamples(short int *samples, int numsamples, int bps, int nch, int srate)
{
    if (lpDSPModule != NULL)
        return lpDSPModule->ModifySamples(lpDSPModule,samples,numsamples,bps,nch,srate);
    else
        return numsamples;
}

int soundBitrate=0,soundSamplerate=0,soundStereo=0,soundSynched=0;
void SetInfo(int bitrate, int srate, int stereo, int synched)
{
    soundBitrate = bitrate;
    soundSamplerate = srate;
    soundStereo = stereo;
    soundSynched = synched;
}

// Resets the equalizer if there is music playing
void ResetEqualizer()
{
    if (MusicPlaying)
        MusicPlaying->Plugin_Info->EQSet(Equalizer.Enabled,
            Equalizer.Data,Equalizer.PreAmplification);
}

// Writes a line to a file, returns whatever WriteFile does
BOOL WriteLine(HANDLE File,char *Buf)
{
    DWORD tmp;
    BOOL Ok = WriteFile(File,Buf,strlen(Buf),&tmp,NULL);
    if (!Ok)
        return false;
    Ok = WriteFile(File,"\r\n",2,&tmp,NULL);
    return Ok;
}

// Reads a line from a file, returns TRUE if the entire line was read
int ReadLine(HANDLE File,char *Buf,int length,int *bufRead)
{
    int br = 0;
    char TheByte = 0;
    DWORD tmp;
    while(br < length)
    {
        if (!ReadFile(File,&TheByte,1,&tmp,NULL))
            return -1;
        if (tmp == 0)
        {
            if (Buf)
                Buf[br] = 0;
            if (bufRead)
                *bufRead = br;
            return 0;
        }

        if (TheByte == '\n')
        {
            // New line
            if (Buf)
                Buf[br] = 0;
            if (bufRead)
                *bufRead = br+1;
            return 0;
        }
        if (TheByte != '\r')
        {
            if (Buf)
                Buf[br] = TheByte;
            br++;
        }
    }
    if (Buf)
        Buf[br-1] = 0;
    if (bufRead)
        *bufRead = br;
    return 1;
}

// Returns a pointer to the loaded plugin's entry in the plugin list, or:
//                    NULL    // Plugin is somehow bad
#define PE_HAVE        -1        // Plugin is already loaded
#define PE_VERSION    -2        // Plugin version mismatch
PLUGINLIST * LoadInputPlugin(char *FileName)
{
    HMODULE NewPlugin = LoadLibrary(FileName);

    In_Module *Plugin_Info;
    if (NewPlugin == NULL)
        return NULL;

    PLUGINLIST *Scan = First;
    while(Scan)
    {
        if (Scan->WinampPlugin == NewPlugin)
        {
            FreeLibrary(NewPlugin);
            return (PLUGINLIST *)PE_HAVE;
        }
        Scan = Scan->Next;
    }
    FARPROC winampGetInModule2 = GetProcAddress(NewPlugin,"winampGetInModule2");
    if (winampGetInModule2 == NULL)
    {
        FreeLibrary(NewPlugin);
        return NULL;
    }
    Plugin_Info =(In_Module *)winampGetInModule2();
    if (Plugin_Info == NULL)
    {
        FreeLibrary(NewPlugin);
        return NULL;
    }

    if (Plugin_Info->version != IN_VER)
    {
        FreeLibrary(NewPlugin);
        return (PLUGINLIST *)PE_VERSION;
    }

    PLUGINLIST * Ret = AddInputPlugin(NewPlugin,Plugin_Info);

    Plugin_Info->hMainWindow = hFakeAmpWindow;
    Plugin_Info->hDllInstance = NewPlugin;
    Plugin_Info->outMod = OutPluginInfo;

    // Now we copy over all our empty functions -- the vis functions are not supported
#define BLANK_COPY(func) Plugin_Info->func = func
    BLANK_COPY(SAVSAInit);
    BLANK_COPY(SAVSADeInit);
    BLANK_COPY(SAAddPCMData);
    BLANK_COPY(SAGetMode);
    BLANK_COPY(SAAdd);
    BLANK_COPY(VSAAddPCMData);
    BLANK_COPY(VSAGetMode);
    BLANK_COPY(VSAAdd);
    BLANK_COPY(VSASetInfo);
    BLANK_COPY(dsp_isactive);
    BLANK_COPY(dsp_dosamples);
    BLANK_COPY(SetInfo);
#undef BLANK_COPY

    Plugin_Info->Init();

    return Ret;
}

Out_Module * LoadOutputPlugin(char *FileName)
{    if ((wcSpawn.code WC_OUTPUT_ABOUT) || (wcSpawn.code WC_OUTPUT_CONFIG))
        return NULL;

    HMODULE NewOutPlugin = LoadLibrary(FileName);
    Out_Module *Plugin_Info;

    if (NewOutPlugin == NULL)
        return NULL;

    FARPROC winampGetOutModule = GetProcAddress(NewOutPlugin,"winampGetOutModule");
    if (winampGetOutModule == NULL)
    {
        FreeLibrary(NewOutPlugin);
        return NULL;
    }

    Plugin_Info = (Out_Module *)winampGetOutModule();
    if (Plugin_Info == NULL)
    {
        FreeLibrary(NewOutPlugin);
        return NULL;
    }

    // Plugin version conflict
    if (Plugin_Info->version != OUT_VER)
    {
        FreeLibrary(NewOutPlugin);
        return (Out_Module *)PE_VERSION;
    }

    // If there's already an output plugin, deal with it...
    if (OutPlugin != NULL)
    {
        StopMusic();
        OutPluginInfo->Quit();
        FreeLibrary(OutPlugin);
    }
    OutPlugin = NewOutPlugin;
    OutPluginInfo = Plugin_Info;
    OutPluginInfo->hMainWindow = hFakeAmpWindow;
    OutPluginInfo->hDllInstance = NewOutPlugin;
    OutPluginInfo->Init();

    // Go through any existing input plugins and point them to the new output plugin
    PLUGINLIST * Current = First;
    while(Current)
    {
        Current->Plugin_Info->outMod = OutPluginInfo;
        Current->Plugin_Info->hMainWindow = hFakeAmpWindow; // Just in case
        Current = Current->Next;
    }

    return Plugin_Info;
}

int LoadDSPPlugin(char *FileName,int which)
{
    // It's ok to change DSP during playback, but not without first unloading
    // the existing one
    if ((DSPPlugin) || (lpDSPModule) || (lpDSPHeader))
        return PE_HAVE;

    HMODULE hNewDSP = LoadLibrary(FileName);
    if (!hNewDSP)
        return 0;

    FARPROC winampDSPGetHeader2 = GetProcAddress(hNewDSP,"winampDSPGetHeader2");
    if (!winampDSPGetHeader2)
    {
        FreeLibrary(hNewDSP);
        return 0;
    }
   
    winampDSPHeader * NewDSPHeader = (winampDSPHeader *)winampDSPGetHeader2();
    if ((!NewDSPHeader) || (NewDSPHeader->version != DSP_HDRVER))
    {
        FreeLibrary(hNewDSP);
        return PE_VERSION;
    }

    winampDSPModule * NewDSPModule = NewDSPHeader->getModule(which);

    if (!NewDSPModule)
    {
        FreeLibrary(hNewDSP);
        return 0;
    }

    NewDSPModule->hDllInstance = hNewDSP;
    // NewDSPModule->hwndParent = hFakeAmpWindow;

    /*    Why did I do this? That way the DSP window will stay in the foreground
        in front of mIRC. */
    NewDSPModule->hwndParent = hMircWindow;

    if (NewDSPModule->Init(NewDSPModule))
    {
        FreeLibrary(hNewDSP);
        return 0;
    }

    // Insert new DSP module info
    DSPPlugin = hNewDSP;
    lpDSPHeader = NewDSPHeader;

    // Insert new DSP module
    lpDSPModule = NewDSPModule;

    return 1;
}

void UnloadDSPPlugin()
{
    winampDSPModule * OldModule = lpDSPModule;
    lpDSPModule = NULL;
    if (OldModule)       
        OldModule->Quit(OldModule);
    lpDSPHeader = NULL;
    if (DSPPlugin)
    {
        FreeLibrary(DSPPlugin);
        DSPPlugin = NULL;
    }
}

// Pass true to pause, returns true on success
BOOL PauseMusic(BOOL SetOn)
{
    if (MusicPlaying)
    {
        if (SetOn)
        {
            if (!MusicPlaying->Plugin_Info->IsPaused())
            {
                MusicPlaying->Plugin_Info->Pause();
                return true;
            }
        }
        else
            if (MusicPlaying->Plugin_Info->IsPaused())
            {
                MusicPlaying->Plugin_Info->UnPause();
                return true;
            }
    }
    return false;
}

// Plays a specified file, returns 0 on success
// -1 -- File not found
// -2 -- Output plugin not loaded
// -3 -- Correct plugin could not be found
// -4 -- Music is already playing
// -5 -- Some other error

int PlayMusic(char *Name)
{
    if(strlen(Name) > MAX_PATH)
        return -5;
    if (MusicPlaying)
        return -4;
    if (!OutPlugin)
    {
        PQCurrent = NULL;
        return -2;
    }
    char FileTitle[TITLESIZE];
    char AmpTitle[TITLESIZE+12];
    int SampleRate;
    OutPluginInfo->SetVolume(soundVolume);
    OutPluginInfo->SetPan(soundPan);

    // Find the correct plugin
    PLUGINLIST * Correct = SelectInputPlugin(Name,1);
    if (Correct == NULL)
    {
        PQCurrent = NULL;
        return -3;
    }
    Correct->Plugin_Info->GetFileInfo(Name,FileTitle,&SampleRate);
    strcpy(AmpTitle,"1. ");
    strcat(AmpTitle,FileTitle);
    strcat(AmpTitle," - Winamp");
    SendMessage(hFakeAmpWindow,WM_SETTEXT,0,(long)AmpTitle);
    int Playing = Correct->Plugin_Info->Play(Name);
    switch(Playing)
    {
    case 0:
    {
        char *lpszIgnore;
        if(!GetFullPathName(Name,MAX_PATH,CurrentFile,&lpszIgnore))
            strcpy(CurrentFile,Name);
        MusicPlaying = Correct;
        ResetEqualizer();
        return 0;
    }
    case -1:
        PQCurrent = NULL;
        return -1;
    default:
        PQCurrent = NULL;
        return -5;
    }
}

// Stops the music, returns true if music was playing
BOOL StopMusic()
{
    if (MusicPlaying)
    {
        MusicPlaying->Plugin_Info->Stop();
        MusicPlaying = NULL;
        return true;
    }
    return false;
}

// What do you think?
void ShufflePlayQueue()
{
    // First, count the queue entries
    int qCount = CountPlayQueue();

    // Ok, our algorithm is simple -- select a random number from 1 to qCount...
    // ...find that entry...
    // ...move it to the end, decrease qCount, and repeat until qCount is 0...

    // Random number seed
    srand((int)(hMircWindow) * GetTickCount());
    while(qCount > 0)
    {
        PLAYQUEUE * Current = PQStart;
        int randNum = rand() % qCount;
        int scanList = 0;
        while(scanList < randNum)
        {
            scanList++;
            Current = Current->Next;
        }

        // This is the one we're moving to the end.
        if (Current->Prev == NULL)
            PQStart = Current->Next;
        if (Current->Next == NULL)
            PQEnd = Current->Prev;
        if (Current->Next)
            Current->Next->Prev = Current->Prev;
        if (Current->Prev)
            Current->Prev->Next = Current->Next;

        // And reattach it to the end
        Current->Next = NULL;
        Current->Prev = PQEnd;
        if (PQStart == NULL)
            PQStart = Current;
        if (PQEnd != NULL)
            PQEnd->Next = Current;
        PQEnd = Current;

        qCount--;
    }
}

void ClearPlayQueue()
{
    if (PQCurrent != NULL)
        StopMusic();
    while(PQStart)
        RemovePlayQueue(PQStart);
    PQCurrent = NULL;
}

#define QE_OK        0
#define QE_OOB        -1
#define QE_INVALID    -2

// Selects an item from the queue based on "Which"
int LastQueueRequest = 1;

int SelectQueueItem(const char *Which,LPVOID *Result)
{
    if ((Which[0] < '0') || (Which[0] > '9'))
    {
        // It's not a number, so check it for other strings
        char * WE = strchr(Which,' ');
        int WordSize = 0;
        if (WE == NULL)
            WordSize = strlen(Which);
        else
            WordSize = WE - Which;
        if (!strnicmp(Which,"current",WordSize))
        {
            // Current queue pointer
            *Result = (LPVOID)PQCurrent;
            return (PQCurrent == NULL ? QE_OOB : QE_OK);
        }
        if (!strnicmp(Which,"next",WordSize))
        {
            if (PQCurrent == NULL)
            {
                *Result = (LPVOID)PQStart;
                return QE_OOB;
            }
            *Result = (LPVOID)PQCurrent->Next;
            return (PQCurrent->Next == NULL ? QE_OOB : QE_OK);
        }
        if (!strnicmp(Which,"previous",WordSize))
        {
            if (PQCurrent == NULL)
            {
                *Result = NULL;
                return QE_OOB;
            }
            *Result = (LPVOID)PQCurrent->Prev;
            return (PQCurrent->Prev == NULL ? QE_OOB : QE_OK);
        }
        if (!strnicmp(Which,"last",WordSize))
        {
            *Result = (LPVOID)PQEnd;
            return (PQEnd == NULL ? QE_OOB : QE_OK);
        }
        return QE_INVALID;
    }
    unsigned int WhichQueue = atoi(Which);
    if (WhichQueue < 1)
    {
        *Result = (LPVOID)PQStart;
        return QE_OOB;
    }
    unsigned int ScanQueue = 1;
    PLAYQUEUE * FindQueue = PQStart;
    while((FindQueue) && (ScanQueue < WhichQueue))
    {
        ScanQueue++;
        FindQueue = FindQueue->Next;
    }
   
    if (FindQueue == NULL)
    {
        *Result = (LPVOID)PQEnd;
        return QE_OOB;
    }
    *Result = (LPVOID)FindQueue;
    return QE_OK;
}

int CountPlayQueue()
{
    PLAYQUEUE *Current = PQStart;
    int Count = 0;
    while(Current)
    {
        Count++;
        Current = Current->Next;
    }
    return Count;
}

// Simple. Uninstallation.
void UninstallThisDLL()
{

    StopMusic();
   
    ClearPlayQueue();

    if (hSpawnThread)
        TerminateThread(hSpawnThread,0);

    UnloadDSPPlugin();

    while(First)
        RemoveInputPlugin(First);

    if(OutPluginInfo)
    {
        OutPluginInfo->Quit();
        OutPluginInfo = NULL;
    }

    if(OutPlugin)
    {
        FreeLibrary(OutPlugin);
        OutPlugin = NULL;
    }

    Installed = 0;
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpvReserved)
{   
    Self = hinstDLL;

    switch(fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        {
            WNDCLASS AmpClass;
            memset(&AmpClass,0,sizeof(WNDCLASS));
            AmpClass.lpszClassName = AMPCLASS;
            AmpClass.hInstance = Self;
            AmpClass.lpfnWndProc = AmpProc;
            RegisterClass(&AmpClass);

        }
        break;
    case DLL_PROCESS_DETACH:
        if (hSpawnEvent)
            CloseHandle(hSpawnEvent);

        if (hHookUninstaller != NULL)
            UnhookWindowsHookEx(hHookUninstaller);

        // Unregister the window class
        UnregisterClass("Winamp v1.x",Self);

        break;
    }
    return 1;
}

BOOL StayLoaded(HWND hMircWin)
{
    char MyName[MAX_PATH];
    if (!Installed)
    {
        // Reload library
        GetModuleFileName(Self,MyName,MAX_PATH);
        LoadLibrary(MyName);

        if (!hFakeAmpWindow)
            hFakeAmpWindow = CreateWindow(
                AMPCLASS,
                "WinAmp 2.5e",
                WS_CAPTION,
                0,0,
                200,200,
                hMircWindow,
                NULL,
                Self,
                NULL);       

        hMircWindow = hMircWin;

        hSpawnEvent = CreateEvent(NULL,false,false,NULL);

        DWORD dwThreadId;
        hSpawnThread = CreateThread(NULL,0,WindowSpawningThread,&wcSpawn,0,&dwThreadId);

        hHookUninstaller = SetWindowsHookEx(WH_CALLWNDPROC,AutoUninstall,Self,GetCurrentThreadId());

        Installed = 1;
        return 1;
    }
    return 0;
}

PLUGINLIST * AddInputPlugin(HMODULE PluginDLL,In_Module *Info)
{
    PLUGINLIST * NewPlugin = new PLUGINLIST;
    if (NewPlugin == NULL)
        return NULL;
    NewPlugin->WinampPlugin = PluginDLL;
    NewPlugin->Plugin_Info = Info;
    NewPlugin->Next = NULL;

    if (First == NULL)
    {
        First = NewPlugin;
        NewPlugin->Prev = NULL;
    }
    else {
        NewPlugin->Prev = Last;
        Last->Next = NewPlugin;
    }
    Last = NewPlugin;
    return NewPlugin;
}

// Insert a file into the play queue, after "After" if it is not NULL
PLAYQUEUE * InsertPlayQueue(char *File,PLAYQUEUE * After)
{
    int length;
    char FileName[MAX_PATH+1];
    char Title[TITLESIZE];
    char *tmp;
    if(!GetFullPathName(File,MAX_PATH,FileName,&tmp))
        strcpy(FileName,File);
    PLUGINLIST *InPlugin = SelectInputPlugin(File,true);
    if (InPlugin)
        InPlugin->Plugin_Info->GetFileInfo(File,Title,&length);
    else
        strcpy(Title,File);
    return InsertPrecachedQueue(FileName,Title,length,After);
}

PLAYQUEUE * InsertPrecachedQueue(char *File,char *Title,int length,PLAYQUEUE * After)
{
    if (strlen(File) > MAX_PATH)
        return NULL;
    PLAYQUEUE * NewQueue = new PLAYQUEUE;
    if (!NewQueue)
        return NULL;
    if (After)
    {
        NewQueue->Next = After->Next;
        NewQueue->Prev = After;
        if (After->Next)
            After->Next->Prev = NewQueue;
        else
            PQEnd = NewQueue;
        After->Next = NewQueue;
    }
    else
    {
        // Insert first
        NewQueue->Prev = NULL;
        NewQueue->Next = PQStart;
        if (PQStart)
            PQStart->Prev = NewQueue;
        if (NewQueue->Next == NULL)
            PQEnd = NewQueue;
        PQStart = NewQueue;
    }
    strcpy(NewQueue->FileName,File);
    strcpy(NewQueue->TitleCache,Title);
    NewQueue->SizeCache = length;
    return NewQueue;
}

// Remove a file from the playqueue
void RemovePlayQueue(PLAYQUEUE * Die)
{
    if (Die->Prev == NULL)
        PQStart = Die->Next;
    if (Die->Next == NULL)
        PQEnd = Die->Prev;
    if (Die->Next)
        Die->Next->Prev = Die->Prev;
    if (Die->Prev)
        Die->Prev->Next = Die->Next;

    bool WasCurrent = false;
    if (PQCurrent == Die)
    {
        PQCurrent = Die->Next;
       
        WasCurrent = true;
    }
    // Move to the next music
    if (MusicPlaying && WasCurrent)
    {
        BOOL Paused = (MusicPlaying->Plugin_Info->IsPaused() != 0);
        StopMusic();
        if (PQCurrent)
        {
            PlayMusic(Die->Next->FileName);
            PauseMusic(Paused);
        }
    }
    delete Die;
}

// Finds the number of the specified input plugin, or 0 if not found
int FindInputPluginNumber(In_Module *Which)
{
    int pNum = 0;
    PLUGINLIST *Current = First;
    while(Current)
    {
        pNum++;
        if (Which == Current->Plugin_Info)
            return pNum;
        Current = Current->Next;
    }
    return 0;
}

PLUGINLIST * PickNumberedInputPlugin(char *Which)
{
    int PNumber = atoi(Which);
    if (PNumber < 1)
        return NULL;
    int PScan = 1;
    PLUGINLIST *Current = First;
    while(Current && (PScan < PNumber))
    {
        PScan++;
        Current = Current->Next;
    }
    return Current;
}

// Selects a plugin based on the filename extension and whatever
PLUGINLIST * SelectInputPlugin(char * FileName,BOOL CheckURL)
{
    PLUGINLIST * Current = First;

    // Check URL-like filenames first
    if (CheckURL)
        while(Current)
        {
            if (Current->Plugin_Info->IsOurFile(FileName))
                return Current;
            Current = Current->Next;
        }

    // Now check by extension
    Current = First;
    while(Current)
    {
        // Scan the characters
        const char * Extensions = Current->Plugin_Info->FileExtensions;

        // We'll want to skip every other
        int ExtLen;
        while((ExtLen = strlen(Extensions)) != 0)
        {
            // Scan for ;
            for(int x=0;x<ExtLen;x++)
                if (Extensions[x] == ';')
                {
                    ExtLen = x;
                    break;
                }

            int NameLen = strlen(FileName);
            if ((NameLen > ExtLen) &&
                (!strnicmp(FileName + NameLen - ExtLen,Extensions,ExtLen)) &&
                (FileName[NameLen-ExtLen-1] == '.'))
                    return Current;
            if (Extensions[ExtLen] != ';')
            {
                Extensions += ExtLen + 1;
                Extensions += strlen(Extensions) + 1;
            }
            else
                Extensions += ExtLen + 1;
        }

        Current = Current->Next;
    }

    // When all else fails, use the MP3 plugin
    if (CheckURL)
    {
        unsigned int DescLen = strlen(MP3_PLUGIN_DESC);
        Current = First;
        while(Current)
        {
            if (!strnicmp(MP3_PLUGIN_DESC,Current->Plugin_Info->description,DescLen))
                return Current;
            Current = Current->Next;
        }
    }
    return NULL;
}

BOOL RemoveInputPlugin(PLUGINLIST * Rem)
{
    if (Rem == NULL)
        return 0;
    if (Rem == First)
        First = Rem->Next;
    if (Rem == Last)
        Last = Rem->Prev;
    if (Rem->Prev != NULL)
        Rem->Prev->Next = Rem->Next;
    if (Rem->Next != NULL)
        Rem->Next->Prev = Rem->Prev;
    Rem->Plugin_Info->Quit();
    FreeLibrary(Rem->WinampPlugin);
    delete Rem;
    return 1;
}

LRESULT CALLBACK AutoUninstall(int nCode,WPARAM wParam,LPARAM lParam)
{
    if (nCode < 0)
        return CallNextHookEx(hHookUninstaller,nCode,wParam,lParam);
    CWPSTRUCT * msg = (CWPSTRUCT *)lParam;
    if ((msg->message WM_DESTROY) && (msg->hwnd hMircWindow))
        DestroyWindow(hFakeAmpWindow);
   
    return CallNextHookEx(hHookUninstaller,nCode,wParam,lParam);
}

LRESULT CALLBACK AmpProc(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam)
{
    switch(Msg)
    {
    case WM_DESTROY:
        hFakeAmpWindow = NULL;
       
        UninstallThisDLL();
        break;
    case WM_USER:
        switch(lParam)
        {
        case 104:
            // Play test -- return 0 if not playing, 1 if playing
            if (MusicPlaying)
                return 1;
            return 0;
        case 0x190:
            // Other play test -- return 1 if using the queue, not sure
            // what it's really supposed to be, but seems to work.
            if (PQCurrent)
                return 1;
        }
        break;
    case WM_WA_MPEG_EOF:
        // The current song has ended...
        StopMusic();

        // Let mIRC know; pretend it's a midi finishing
        char DevID[100];
        switch(NotifyMethod)
        {
        case WN_MIDI:
            mciSendString("close mircmidi",NULL,0,hMircWindow);
            mciSendString("open sequencer alias mircmidi",DevID,99,hMircWindow);
            PostMessage(hMircWindow,MM_MCINOTIFY,MCI_NOTIFY_SUCCESSFUL,atoi(DevID));
            break;
        case WN_WAVE:
            mciSendString("close mircwave",NULL,0,hMircWindow);
            mciSendString("open waveaudio alias mircwave",DevID,99,hMircWindow);
            PostMessage(hMircWindow,MM_MCINOTIFY,MCI_NOTIFY_SUCCESSFUL,atoi(DevID));
            break;
        }
        if (PQCurrent != NULL)
        {
            PQCurrent = PQCurrent->Next;
            if (AutoShuffle && !PQCurrent)
                ShufflePlayQueue();
            if (Looping && !PQCurrent)
                PQCurrent = PQStart;
            if (PQCurrent)
                PlayMusic(PQCurrent->FileName);
        }
        break;
    default:
        return DefWindowProc(hWnd,Msg,wParam,lParam);
    }
    return 0;
}

int FAR PASCAL CurrentMusic(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
{
    if (!stricmp(data,"status"))
    {
        if (!MusicPlaying)
            strcpy(data,"OK stopped");
        else if (MusicPlaying->Plugin_Info->IsPaused())
            strcpy(data,"OK paused");
        else
            strcpy(data,"OK playing");
        return 3;
    }
    if (!MusicPlaying)
        RETURNERROR(NOT_PLAYING);
    if (!stricmp(data,"pause"))
    {
        if (!PauseMusic(true))
            RETURNERROR(NOT_PLAYING);
        strcpy(data,"OK paused");
        return 3;
    }
    else if (!stricmp(data,"unpause"))
    {
        if (!PauseMusic(false))
            RETURNERROR(PLAYING);
        strcpy(data,"OK unpaused");
        return 3;
    }
    else if (!stricmp(data,"title"))
    {
        int tmp;
        strcpy(data,"OK ");
        MusicPlaying->Plugin_Info->GetFileInfo("",data+3,&tmp);
        return 3;
    }
    else if (!stricmp(data,"filename"))
    {
        strcpy(data,"OK ");
        strcpy(data+3,CurrentFile);
        return 3;
    }
    else if (!stricmp(data,"position"))
    {
        strcpy(data,"OK ");
        itoa(MusicPlaying->Plugin_Info->GetOutputTime(),data+3,10);
        return 3;
    }
    else if (!stricmp(data,"length"))
    {
        strcpy(data,"OK ");
        itoa(MusicPlaying->Plugin_Info->GetLength(),data+3,10);
        return 3;
    }
    else if (!strnicmp(data,"seek ",5))
    {
        if (!MusicPlaying->Plugin_Info->is_seekable)
            RETURNERROR(NO_SEEK);
        MusicPlaying->Plugin_Info->SetOutputTime(atoi(strchr(data,' ')+1));
        strcpy(data,"OK seeked");
        return 3;
    }
    else if (!stricmp(data,"bitrate"))
    {
        strcpy(data,"OK ");
        itoa(soundBitrate,data+3,10);
        return 3;
    }
    else if (!stricmp(data,"samplerate"))
    {
        strcpy(data,"OK ");
        itoa(soundSamplerate,data+3,10);
        return 3;
    }
    else if (!stricmp(data,"stereo"))
    {
        strcpy(data,"OK ");
        itoa(soundStereo,data+3,10);
        return 3;
    }
    else if (!stricmp(data,"synched"))
    {
        strcpy(data,"OK ");
        strcpy(data+3,(soundSynched ? "yes" : "no"));
        return 3;
    }
    else if (!stricmp(data,"info"))
    {
        if (SendSpawnCmd(WC_INPUT_INFO,MusicPlaying->Plugin_Info,CurrentFile) !=
            WC_NOTHING)
            RETURNERROR(USING_WINDOW);
        strcpy(data,"OK infobox");
        return 3;
    }
    RETURNERROR(SYNTAX);
}

int FAR PASCAL PluginManager(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
{
    StayLoaded(mWnd);

    char * Space = strchr(data,' ');
    if (!stricmp(data,"inputcount"))
    {
        int InputPluginCount = 0;
        PLUGINLIST * Current = First;
        while(Current)
        {
            InputPluginCount++;
            Current = Current->Next;
        }
        strcpy(data,"OK ");
        itoa(InputPluginCount,data+3,10);
        return 3;
    }
    else if (!strnicmp(data,"uinfo ",6))
    {
        // Retrieve info on unloaded plugin
// Base plugin types
#define PI_OUTPUT    0x00
#define PI_INPUT    0x01
#define PI_DSP        0x02
#define PI_VIS        0x03    // Unused

#define PI_ALL        0x07    // Combines all previous

// Subfunction info types
#define PI_S_NAME        0x00    // Plugin description
#define PI_S_MODNAME    0x08    // Plugin module description
#define PI_S_VERSION    0x10    // Plugin version
#define PI_S_MODCOUNT    0x18    // Module count
#define PI_S_ID            0x20    // Output module ID

#define PI_S_ALL        0xF8    // Combines all previous

        char InfoType =0;
        Space++;
        if (!strnicmp(Space,"output ",7))
            InfoType = PI_OUTPUT;
        else if (!strnicmp(Space,"input ",6))
            InfoType = PI_INPUT;
        else if (!strnicmp(Space,"dsp ",4))
            InfoType = PI_DSP;
/*        else if (!strnicmp(Space,"vis ",4))
            InfoType = PI_VIS;*/
        else
            RETURNERROR(SYNTAX);

        Space = strchr(Space,' ')+1;    // No need for NULL checking, we know it's there
        if (!strnicmp(Space,"name ",5))
            InfoType |= PI_S_NAME;
        else if (!strnicmp(Space,"modname ",8))
            InfoType |= PI_S_MODNAME;
        else if (!strnicmp(Space,"version ",8))
            InfoType |= PI_S_VERSION;
        else if (!strnicmp(Space,"modcount ",9))
            InfoType |= PI_S_MODCOUNT;
        else if (!strnicmp(Space,"id ",3))
            InfoType |= PI_S_ID;
        else
            RETURNERROR(SYNTAX);

        // Point Space to the filename
        Space = strchr(Space,' ')+1;
        int WhichMod = -1;

        // Extra processing when a number is required
        if ((InfoType & PI_S_ALL) == PI_S_MODNAME)
        {
            if ((*Space < '0') || (*Space > '9'))
                RETURNERROR(SYNTAX);
            WhichMod = atoi(Space);
            Space = strchr(Space,' ');
            if (Space == NULL)
                RETURNERROR(SYNTAX);
            Space++;
        }

        // Check for valid pairings
        switch(InfoType)
        {
        case PI_OUTPUT | PI_S_NAME:
        case PI_OUTPUT | PI_S_VERSION:
        case PI_OUTPUT | PI_S_ID:
        case PI_INPUT | PI_S_NAME:
        case PI_INPUT | PI_S_VERSION:
        case PI_DSP | PI_S_NAME:
        case PI_DSP | PI_S_MODNAME:
        case PI_DSP | PI_S_VERSION:
        case PI_DSP | PI_S_MODCOUNT:
            break;
        default:
            RETURNERROR(SYNTAX);
        }
       
        HMODULE hInfoPlugin = LoadLibrary(Space);
        if (!hInfoPlugin)
            RETURNERROR(NO_PLUGIN);
        switch(InfoType & PI_ALL)
        {
        case PI_OUTPUT:
            {
            FARPROC winampGetOutModule = GetProcAddress(hInfoPlugin,"winampGetOutModule");
            if (winampGetOutModule == NULL)
            {
                FreeLibrary(hInfoPlugin);
                RETURNERROR(BAD_PLUGIN)
            }

            Out_Module * Plugin_Info = (Out_Module *)winampGetOutModule();
            if (Plugin_Info == NULL)
            {
                FreeLibrary(hInfoPlugin);
                RETURNERROR(BAD_PLUGIN);
            }

            if ((InfoType & PI_S_ALL) == PI_S_VERSION)
            {
                strcpy(data,"OK ");
                itoa(Plugin_Info->version,data+3,16);

                // Insert hex point
                int slen = strlen(data);
                for(int mv=slen+1;mv>slen-1;mv--)
                    data[mv] = data[mv-1];
                data[slen-1] = '.';
                return 3;
            }
            // Plugin version conflict
            if (Plugin_Info->version != OUT_VER)
            {
                FreeLibrary(hInfoPlugin);
                RETURNERROR(PLUGIN_VERSION);
            }
            switch(InfoType & PI_S_ALL)
            {
            case PI_S_NAME:
                strcpy(data,"OK ");
                strcpy(data+3,Plugin_Info->description);
                break;
            case PI_S_ID:
                strcpy(data,"OK ");
                itoa(Plugin_Info->id,data+3,10);
                break;
            }

            }
            break;
        case PI_INPUT:
            {
                FARPROC winampGetInModule2 = GetProcAddress(hInfoPlugin,"winampGetInModule2");
                if (winampGetInModule2 == NULL)
                {
                    FreeLibrary(hInfoPlugin);
                    RETURNERROR(BAD_PLUGIN);
                }
                In_Module * Plugin_Info =(In_Module *)winampGetInModule2();
                if (Plugin_Info == NULL)
                {
                    FreeLibrary(hInfoPlugin);
                    RETURNERROR(BAD_PLUGIN);
                }
                if ((InfoType & PI_S_ALL) == PI_S_VERSION)
                {
                    strcpy(data,"OK ");
                    itoa(Plugin_Info->version,data+3,16);

                    // Insert hex point
                    int slen = strlen(data);
                    for(int mv=slen+1;mv>slen-2;mv--)
                        data[mv] = data[mv-1];
                    data[slen-2] = '.';
                    return 3;
                }
                if (Plugin_Info->version != IN_VER)
                {
                    FreeLibrary(hInfoPlugin);
                    RETURNERROR(PLUGIN_VERSION);
                }
                switch(InfoType & PI_S_ALL)
                {
                case PI_S_NAME:
                    strcpy(data,"OK ");
                    strcpy(data+3,Plugin_Info->description);
                    break;
                }
            }
            break;
        case PI_DSP:
            {
            FARPROC winampDSPGetHeader2 = GetProcAddress(hInfoPlugin,"winampDSPGetHeader2");
            if (!winampDSPGetHeader2)
            {
                FreeLibrary(hInfoPlugin);
                RETURNERROR(BAD_PLUGIN);
            }
            winampDSPHeader * DspCHeader = (winampDSPHeader *)winampDSPGetHeader2();
            if (!DspCHeader)
            {
                FreeLibrary(hInfoPlugin);
                RETURNERROR(BAD_PLUGIN);
            }
            if ((InfoType & PI_S_ALL) == PI_S_VERSION)
            {
                strcpy(data,"OK ");
                itoa(DspCHeader->version,data+3,16);

                // Insert hex point
                int slen = strlen(data);
                for(int mv=slen+1;mv>slen-1;mv--)
                    data[mv] = data[mv-1];
                data[slen-1] = '.';
                return 3;
            }
            if (DspCHeader->version != DSP_HDRVER)
            {
                FreeLibrary(hInfoPlugin);
                RETURNERROR(PLUGIN_VERSION);
            }
            switch(InfoType & PI_S_ALL)
            {
            case PI_S_NAME:
                strcpy(data,"OK ");
                strcpy(data+3,DspCHeader->description);
                break;
            case PI_S_MODNAME:
                {
                winampDSPModule * DSPModule = DspCHeader->getModule(WhichMod-1);

                if (!DSPModule)
                {
                    FreeLibrary(hInfoPlugin);
                    RETURNERROR(BAD_PLUGIN);
                }
                strcpy(data,"OK ");
                strcpy(data+3,DSPModule->description);
                }
                break;
            case PI_S_MODCOUNT:
                {
                int count = 0;
                while(DspCHeader->getModule(count))
                    count++;
       
                strcpy(data,"OK ");
                itoa(count,data+3,10);
                }
                break;
            }
            break;
            }
        }
        FreeLibrary(hInfoPlugin);
        return 3;
    }
    else if (!strnicmp(data,"load ",5))
    {
        char *PluginFile = strchr(Space+1,' ');
        if (PluginFile == NULL)
            RETURNERROR(SYNTAX);
        PluginFile++;
        // What type of plugin are we loading?
        if (!strnicmp(Space+1,"input ",6))
        {
            // Input plugin
            PLUGINLIST * NewPlugin;
            switch((int)(NewPlugin = LoadInputPlugin(PluginFile)))
            {
            case 0:
                RETURNERROR(BAD_PLUGIN);
            case PE_HAVE:
                RETURNERROR(HAVE_PLUGIN);
            case PE_VERSION:
                RETURNERROR(PLUGIN_VERSION);
            }
            strcpy(data,"OK ");
            strcpy(data+3,NewPlugin->Plugin_Info->description);
            return 3;
        }
        else if (!strnicmp(Space+1,"output ",7))
        {            if ((wcSpawn.code WC_OUTPUT_CONFIG) || (wcSpawn.code WC_OUTPUT_ABOUT))
                RETURNERROR(USING_WINDOW);

            // Output plugin
            Out_Module * OutPlugin = LoadOutputPlugin(PluginFile);
            switch((int)OutPlugin)
            {
            case 0:
                RETURNERROR(BAD_PLUGIN);
            case PE_VERSION:
                RETURNERROR(PLUGIN_VERSION);
            }
            strcpy(data,"OK ");
            strcpy(data+3,OutPlugin->description);
            return 3;
        }
        else if (!strnicmp(Space+1,"dsp ",4))
        {
            if (wcSpawn.code == WC_DSP_CONFIG)
                RETURNERROR(USING_WINDOW);

            // Get number
            char * NumWhich = strchr(Space+1,' ')+1;
            char * FName = strchr(NumWhich,' ');
            if (!FName)
                RETURNERROR(SYNTAX);
            FName++;
            switch(LoadDSPPlugin(FName,atoi(NumWhich)-1))
            {
            case 0:
                RETURNERROR(BAD_PLUGIN);
            case PE_HAVE:
                RETURNERROR(HAVE_PLUGIN);
            case PE_VERSION:
                RETURNERROR(PLUGIN_VERSION);
            }
            strcpy(data,"OK ");
            strcpy(data+3,lpDSPModule->description);
            return 3;
        }
    }
    else if (!stricmp(data,"unload dsp"))
    {
        if (wcSpawn.code == WC_DSP_CONFIG)
            RETURNERROR(USING_WINDOW);
        UnloadDSPPlugin();
        strcpy(data,"OK unloaded");
        return 3;
    }
    else if (!strnicmp(data,"about ",6))
    {
        // About box
        if (!stricmp(Space+1,"output"))
        {
            if (!OutPluginInfo)
                RETURNERROR(NO_PLUGIN);
            if (SendSpawnCmd(WC_OUTPUT_ABOUT,OutPluginInfo,NULL) != WC_NOTHING)
                RETURNERROR(USING_WINDOW);
           
            strcpy(data,"OK about");
            return 3;
        }
        else
        {
            PLUGINLIST * Which = PickNumberedInputPlugin(Space+1);
            if (!Which)
                RETURNERROR(NO_PLUGIN);
            if (SendSpawnCmd(WC_INPUT_ABOUT,Which->Plugin_Info,NULL) != WC_NOTHING)
                RETURNERROR(USING_WINDOW);
            strcpy(data,"OK about");
            return 3;
        }
    }
    else if (!strnicmp(data,"config ",7))
    {
        // Config box
        if (!stricmp(Space+1,"output"))
        {
            if (!OutPluginInfo)
                RETURNERROR(NO_PLUGIN);
            if (SendSpawnCmd(WC_OUTPUT_CONFIG,OutPluginInfo,NULL) != WC_NOTHING)
                RETURNERROR(USING_WINDOW);
            strcpy(data,"OK config");
            return 3;
        }
        else if (!stricmp(Space+1,"dsp"))
        {
            if (!lpDSPModule)
                RETURNERROR(NO_PLUGIN);
            if (SendSpawnCmd(WC_DSP_CONFIG,lpDSPModule,NULL) != WC_NOTHING)
                RETURNERROR(USING_WINDOW);
            strcpy(data,"OK config");
            return 3;
        }
        else
        {
            PLUGINLIST * Which = PickNumberedInputPlugin(Space+1);
            if (!Which)
                RETURNERROR(NO_PLUGIN);
            if (SendSpawnCmd(WC_INPUT_CONFIG,Which->Plugin_Info,NULL) != WC_NOTHING)
                RETURNERROR(USING_WINDOW);
            strcpy(data,"OK config");
            return 3;
        }
    }
    else if (!strnicmp(data,"description ",12))
    {
        // Retrieve description
        if (!stricmp(Space+1,"output"))
        {
            if (!OutPluginInfo)
                RETURNERROR(NO_PLUGIN);
            strcpy(data,"OK ");
            strcpy(data+3,OutPluginInfo->description);
            return 3;
        }
        else if (!stricmp(Space+1,"dsp"))
        {
            if (!lpDSPHeader)
                RETURNERROR(NO_PLUGIN);

            strcpy(data,"OK ");
            strcpy(data+3,lpDSPHeader->description);
            return 3;
        }
        else if (!stricmp(Space+1,"dspmod"))
        {
            if (!lpDSPModule)
                RETURNERROR(NO_PLUGIN);

            strcpy(data,"OK ");
            strcpy(data+3,lpDSPModule->description);
            return 3;
        }
        else
        {
            PLUGINLIST * Which = PickNumberedInputPlugin(Space+1);
            if (!Which)
                RETURNERROR(NO_PLUGIN);
            strcpy(data,"OK ");
            strcpy(data+3,Which->Plugin_Info->description);
            return 3;
        }
    }
    else if (!strnicmp(data,"typecount ",10))
    {
        PLUGINLIST *Which = PickNumberedInputPlugin(Space+1);
        if (!Which)
            RETURNERROR(NO_PLUGIN);

        // Scan the type list
        char *TypeList = Which->Plugin_Info->FileExtensions;
        int Count = 0;
        while(*TypeList)
        {
            Count++;
            TypeList += strlen(TypeList)+1;
            TypeList += strlen(TypeList)+1;
        }

        strcpy(data,"OK ");
        itoa(Count,data+3,10);
        return 3;
    }
    else if (!strnicmp(data,"typelist ",9))
    {
        // Get a list of types -- takes 2 numbers
        PLUGINLIST *Which = PickNumberedInputPlugin(Space+1);

        char *TypeNum = strchr(Space+1,' ');
        if (TypeNum == NULL)
            RETURNERROR(SYNTAX);

        TypeNum++;
        int WantType = atoi(TypeNum);
        if (WantType < 1)
            RETURNERROR(EXT_OOB);

        char *TypeList = Which->Plugin_Info->FileExtensions;
        int Count = 1;
        while(*TypeList && (Count < WantType))
        {
            Count++;
            TypeList += strlen(TypeList)+1;
            TypeList += strlen(TypeList)+1;
        }
        if (!*TypeList)
            RETURNERROR(EXT_OOB);
        strcpy(data,"OK ");
        strcpy(data+3,TypeList);
        return 3;
    }
    else if (!strnicmp(data,"typedesc ",9))
    {
        // Get a description of types -- takes 2 numbers
        PLUGINLIST *Which = PickNumberedInputPlugin(Space+1);

        char *TypeNum = strchr(Space+1,' ');
        if (TypeNum == NULL)
            RETURNERROR(SYNTAX);

        TypeNum++;
        int WantType = atoi(TypeNum);
        if (WantType < 1)
            RETURNERROR(EXT_OOB);

        char *TypeList = Which->Plugin_Info->FileExtensions;
        int Count = 1;
        while(*TypeList && (Count < WantType))
        {
            Count++;
            TypeList += strlen(TypeList)+1;
            TypeList += strlen(TypeList)+1;
        }
        if (!*TypeList)
            RETURNERROR(EXT_OOB);
        TypeList += strlen(TypeList)+1;
        strcpy(data,"OK ");
        strcpy(data+3,TypeList);
        return 3;
    }
    else if (!strnicmp(data,"alltypes ",9))
    {
        // Returns all the types of a specific plugin
        PLUGINLIST *Which = PickNumberedInputPlugin(Space+1);
        if (!Which)
            RETURNERROR(NO_PLUGIN);
        strcpy(data,"OK ");
        char *TypeList = Which->Plugin_Info->FileExtensions;
        while(*TypeList)
        {
            if (*(data+3))
                strcat(data+3,";");
            strcat(data+3,TypeList);
            TypeList += strlen(TypeList)+1;
            TypeList += strlen(TypeList)+1;
        }
        return 3;
    }
    else if (!stricmp(data,"alltypes"))
    {
        // Returns all the types of all plugins
        PLUGINLIST *Current = First;
        strcpy(data,"OK ");
        while(Current)
        {
            char *TypeList = Current->Plugin_Info->FileExtensions;
            while(*TypeList)
            {
                if (*(data+3))
                    strcat(data+3,";");
                strcat(data+3,TypeList);
                TypeList += strlen(TypeList)+1;
                TypeList += strlen(TypeList)+1;
            }
            Current = Current->Next;
        }
        return 3;
    }
    RETURNERROR(SYNTAX);
}

// For the time being, uses only the first loaded plugin
int FAR PASCAL Queue(HWND mWnd, HWND aWnd, char *data, char *parms, BOOL show, BOOL nopause)
{
    StayLoaded(mWnd);

    char *Space = strchr(data,' ');
    PLAYQUEUE * Target=NULL;
    if (!strnicmp(data,"add ",4))
    {
        char * FileName = data + 4;
        if (strlen(FileName) > MAX_PATH)
            RETURNERROR(LONG_NAME);
        if (!InsertPlayQueue(FileName,PQEnd))
            RETURNERROR(UNKNOWN);
        strcpy(data,"OK added");
        return 3;

    }
    else if (!stricmp(data,"count"))
    {
        strcpy(data,"OK ");
        itoa(CountPlayQueue(),data+3,10);
        return 3;
    }
    else if (!strnicmp(data,"insert ",7))
    {
        switch(SelectQueueItem(Space+1,(LPVOID *)&Target))
        {
        case QE_INVALID:
            RETURNERROR(SYNTAX);
        case QE_OOB:
        case QE_OK:
            char * FileName = strchr(Space+1,' ');
            if (FileName == NULL)
                RETURNERROR(SYNTAX);
            FileName++;
            if (Target != NULL)
                Target = Target->Prev;
            if (!InsertPlayQueue(FileName,Target))
                RETURNERROR(UNKNOWN);
            strcpy(data,"OK added");
            return 3;
        }
    }
    else if (!strnicmp(data,"remove ",7))
    {
        switch(SelectQueueItem(Space+1,(LPVOID *)&Target))
        {
        case QE_OK:
            RemovePlayQueue(Target);
            strcpy(data,"OK removed");
            return 3;
        case QE_OOB:
            RETURNERROR(QUEUE_OOB);
        case QE_INVALID:
            RETURNE
Messages postés
2106
Date d'inscription
mercredi 21 août 2002
Statut
Contributeur
Dernière intervention
15 novembre 2020
2
Il apparait que l'affichage du contenu de mon post précédent soit "corrommpu" avec FireFox. Avec Internet Explorer : aucun soucis :)

[PaTaTe]
Messages postés
2106
Date d'inscription
mercredi 21 août 2002
Statut
Contributeur
Dernière intervention
15 novembre 2020
2
Personne ne peut m'aider ? :(

[PaTaTe]
Messages postés
2106
Date d'inscription
mercredi 21 août 2002
Statut
Contributeur
Dernière intervention
15 novembre 2020
2
Apparemment personne n'est intéressé par le sujet :(

Si quelqu'un a une piste qu'il parle ^^