/*

MAgen.dll: Miranda plugin for mail.ru message exchange.

Copyright 2005-2010 Lenik.
Project home at http://www.lenik.ru/win32/magent
Author contact: lenik@lenik.ru

This program is free software.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

*/

struct ReceiveQueueNode
    {
    struct ReceiveQueueNode *Next;
    unsigned long size;
    unsigned long rtime;
    mrim_packet_header_t packet;
    };
struct ReceiveQueueNode *ReceiveQueue = NULL;

#define RECVBUFFERSIZE  65536
struct ListenThread_Data
    {
    unsigned long thid;
    unsigned char receivebuffer[RECVBUFFERSIZE];
    unsigned char fromaddr[512];
    unsigned char cl_nick[100];
    unsigned char tmpbuf[RECVBUFFERSIZE];
    };

static unsigned long MRIM_HSP(mrim_packet_header_t *p,struct ListenThread_Data *data)
{
HANDLE hContact;
DBEVENTINFO dbei;

#ifdef MRIM_DEBUG
    PrintDebug("MRIM_HSP: started.\n");
#endif
if(p->msg == MRIM_CS_MESSAGE_ACK)
    {// message received
    mrim_packet_header_t *hdr = (mrim_packet_header_t*)data->receivebuffer;
    unsigned long n_f = 1;
    unsigned long m_f = 1;
    unsigned long flags;
    unsigned long messageid;
    unsigned long tmppos=0;
    
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_MESSAGE_ACK received\n");
    #endif
    if(MRIM_Packet_GetLong(&tmppos,p,&messageid) == 0)// message id
        {
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: messageid == %lu\n",messageid);
        #endif
        if(MRIM_Packet_GetLong(&tmppos,p,&flags) == 0)// flags
            {
            #ifdef MRIM_DEBUG
                PrintDebug("MRIM_HSP: flags == %8.08X\n",flags);
            #endif
            if(MRIM_Packet_GetString(&tmppos,p,data->fromaddr) == 0)//from
                {
                #ifdef MRIM_DEBUG
                    PrintDebug("MRIM_HSP: from %s\n",data->fromaddr);
                #endif
                if(MRIM_Packet_GetString(&tmppos,p,data->tmpbuf) == 0)//message
                    {
                    #ifdef MRIM_DEBUG
                        PrintDebug("MRIM_HSP: message: %s\n",data->tmpbuf);
                    #endif
                    if((hContact=HContactFromEMail(data->fromaddr,1,0)) != INVALID_HANDLE_VALUE)
                        {
                        #ifdef MRIM_DEBUG
                            PrintDebug("MRIM_HSP: contact found: %s\n",data->fromaddr);
                        #endif
                        if((flags&MESSAGE_FLAG_NOTIFY) == MESSAGE_FLAG_NOTIFY)
                            {// typing notification
                            #ifdef MRIM_DEBUG
                                PrintDebug("MRIM_HSP: flags&MESSAGE_FLAG_NOTIFY: typing notification\n");
                            #endif
                            n_f = 0;
                            m_f = 0;
                            CallService(MS_PROTO_CONTACTISTYPING,(WPARAM)hContact,(LPARAM)11);
                            }
                        else{
                            CallService(MS_PROTO_CONTACTISTYPING,(WPARAM)hContact,PROTOTYPE_CONTACTTYPING_OFF);
                            }
                        if((flags&MESSAGE_FLAG_NORECV) == MESSAGE_FLAG_NORECV)
                            {// no message receive packet notification needed
                            #ifdef MRIM_DEBUG
                                PrintDebug("MRIM_HSP: flags&MESSAGE_FLAG_NORECV: receive notofication not needed\n");
                            #endif
                            n_f = 0;
                            }
                        if(n_f == 1)
                            {
                            hdr->magic = CS_MAGIC;
                            hdr->proto = PROTO_VERSION;
                            hdr->seq = 0;
                            hdr->msg = MRIM_CS_MESSAGE_RECV;
                            hdr->dlen = 0;
                            hdr->from = 0;
                            hdr->fromport = 0;
                            MRIM_Packet_AddString(hdr,data->fromaddr);
                            MRIM_Packet_AddLong(hdr,messageid);
                            #ifdef MRIM_DEBUG
                                PrintDebug("MRIM_HSP: sending receive notification\n");
                            #endif
                            MRIM_sendpacket(hdr);
                            #ifdef MRIM_DEBUG
                                PrintDebug("MRIM_HSP: receive notification sended\n");
                            #endif
                            }
                        if(m_f == 1)
                            {
                            dbei.cbSize = sizeof(dbei);
                            dbei.szModule = ProtoName;
                            dbei.timestamp = gettimestamp();
                            dbei.flags = 0;
                            if((flags&MESSAGE_FLAG_AUTHORIZE) == MESSAGE_FLAG_AUTHORIZE)
                                {
                                //blob is: UIN=0(DWORD), hContact(DWORD), nick(ASCIIZ), ""(ASCIIZ), ""(ASCIIZ), email(ASCIIZ), ""(ASCIIZ)
                                unsigned char *cptr = &(data->tmpbuf[30000]);
    
                                #ifdef MRIM_DEBUG
                                    PrintDebug("MRIM_HSP: flags&MESSAGE_FLAG_AUTHORIZE: authirization request\n");
                                #endif
                                dbei.eventType = EVENTTYPE_AUTHREQUEST;
                                dbei.pBlob = cptr;
                                dbei.cbBlob = 4 + 4 + strlen(data->fromaddr)+1 + 1 + 1 + strlen(data->fromaddr)+1 + strlen(data->tmpbuf)+1;
                                *(PDWORD)cptr = 0;               cptr += 4; //uin
                                *(PDWORD)cptr = (DWORD)hContact; cptr += 4; //hContact
                                strcpy(cptr,data->fromaddr);     cptr += strlen(data->fromaddr)+1;//nick
                                *cptr = '\0';                    cptr += 1;      //firstName
                                *cptr = '\0';                    cptr += 1;      //lastName
                                strcpy(cptr,data->fromaddr);     cptr += strlen(data->fromaddr)+1;//email
                                strcpy(cptr,data->tmpbuf);     cptr += strlen(data->tmpbuf)+1;//reason
                                }
                            else{
                                #ifdef MRIM_DEBUG
                                    PrintDebug("MRIM_HSP: regular message\n");
                                #endif
                                dbei.eventType = EVENTTYPE_MESSAGE;
                                dbei.cbBlob = strlen(data->tmpbuf) + 1;
                                dbei.pBlob = (PBYTE)(data->tmpbuf);
                                }
                            #ifdef MRIM_DEBUG
                                PrintDebug("MRIM_HSP: adding event to DB\n");
                            #endif
                            CallService(MS_DB_EVENT_ADD,(WPARAM)hContact,(LPARAM)&dbei);
                            #ifdef MRIM_DEBUG
                                PrintDebug("MRIM_HSP: event added to DB\n");
                            #endif
                            }
                        }
                    }
                }
            }
        }
    //MessageBox(NULL,"MRIM_CS_MESSAGE_ACK","Listen Thread",MB_OK);
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_MESSAGE_ACK handled\n");
    #endif
    }
else if(p->msg == MRIM_CS_OFFLINE_MESSAGE_ACK)
    {
    mrim_packet_header_t *hdr = (mrim_packet_header_t *)data->receivebuffer;
    unsigned long messageid0;
    unsigned long messageid1;
    unsigned long tmppos=0;
    unsigned long t;
    unsigned char *cptr;
    unsigned char *boundary;

    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_OFFLINE_MESSAGE_ACK received\n");
    #endif
    MRIM_Packet_GetLong(&tmppos,p,&messageid0);// message id
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: messageid0 == 0x%8.08X\n",messageid0);
    #endif
    MRIM_Packet_GetLong(&tmppos,p,&messageid1);// ?????? flags
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: messageid1 == 0x%8.08X\n",messageid1);
    #endif
    MRIM_Packet_GetString(&tmppos,p,data->tmpbuf);//message

    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: message: %s\n",data->tmpbuf);
    #endif
    if((cptr=strstr(data->tmpbuf,"From: ")) != NULL)
        {
        cptr += 6;
        t = 0;
        while(1)
            {
            if(cptr[0] == 0)break;
            if(cptr[0] == 10)break;
            if(cptr[0] == 13)break;
            data->fromaddr[t] = cptr[0];
            cptr++;
            t++;
            }
        data->fromaddr[t] = 0;
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: from: %s\n",data->fromaddr);
        #endif
        if((cptr=strstr(cptr,"Boundary: ")) != NULL)
            {
            cptr += 10;
            boundary = cptr;
            while(1)
                {
                if(cptr[0] == 0)break;
                if((cptr[0] == 10)||(cptr[0] == 13))
                    {
                    cptr[0] = 0;
                    cptr++;
                    CODEBLOCK
                        {
                        unsigned char *tcptr;
                        if((tcptr=strstr(cptr,boundary)) != NULL)
                            {
                            tcptr[-2] = 0;
                            }
                        }
                    break;
                    }
                else cptr++;
                }
            }
        if((cptr=strstr(cptr,"\n\n")) != NULL)
            {
            cptr += 2;
            #ifdef MRIM_DEBUG
                PrintDebug("MRIM_HSP: message: %s\n",cptr);
            #endif
            if((hContact=HContactFromEMail(data->fromaddr,1,0)) != INVALID_HANDLE_VALUE)
                {
                #ifdef MRIM_DEBUG
                    PrintDebug("MRIM_HSP: contact found (%s)\n",data->fromaddr);
                #endif
                dbei.cbSize = sizeof(dbei);
                dbei.szModule = ProtoName;
                dbei.timestamp = gettimestamp();
                dbei.flags = 0;
                dbei.eventType = EVENTTYPE_MESSAGE;
                dbei.cbBlob = strlen(cptr) + 1;
                dbei.pBlob = (PBYTE)cptr;
                #ifdef MRIM_DEBUG
                    PrintDebug("MRIM_HSP: adding event to db\n");
                #endif
                CallService(MS_DB_EVENT_ADD, (WPARAM)hContact, (LPARAM)&dbei);
                #ifdef MRIM_DEBUG
                    PrintDebug("MRIM_HSP: event added to db\n");
                #endif
                }
            }
        }
    hdr->magic = CS_MAGIC;
    hdr->proto = PROTO_VERSION;
    hdr->seq = 1;
    hdr->msg = MRIM_CS_DELETE_OFFLINE_MESSAGE;
    hdr->dlen = 0;
    hdr->from = 0;
    hdr->fromport = 0;
    MRIM_Packet_AddLong(hdr,messageid0);
    MRIM_Packet_AddLong(hdr,messageid1);
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: sending MRIM_CS_DELETE_OFFLINE_MESSAGE\n");
    #endif
    MRIM_sendpacket(hdr);
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_DELETE_OFFLINE_MESSAGE sended\n");
    #endif
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_OFFLINE_MESSAGE_ACK handled\n");
    #endif
    //MessageBox(NULL,"MRIM_CS_OFFLINE_MESSAGE_ACK","Listen Thread",MB_OK);
    }
else if(p->msg == MRIM_CS_MAILBOX_STATUS)
    {
    unsigned long tmppos=0;
    unsigned long unread=0;
    
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_MAILBOX_STATUS received\n");
    #endif
    if(MRIM_Packet_GetLong(&tmppos,p,&unread) == 0)// unread messages count
        {
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: unread messages: %lu\n",unread);
        #endif
        MRIM_NewMessagesCount = unread;
        }
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_MAILBOX_STATUS handled\n");
    #endif
    }
else if(p->msg == MRIM_CS_USER_STATUS)
    {// user status
    unsigned long tmppos=0;
    unsigned long status;

    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_USER_STATUS received\n");
    #endif
    if(MRIM_Packet_GetLong(&tmppos,p,&status) == 0)// user status
        {
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: status == %8.08X\n",status);
        #endif
        if(MRIM_Packet_GetString(&tmppos,p,data->fromaddr) == 0)// user email
            {
            #ifdef MRIM_DEBUG
                PrintDebug("MRIM_HSP: email == %s\n",data->fromaddr);
            #endif
            MRIM_SetMirandaStatus(data->fromaddr,status);
            }
        }
    MRIM_SetMirandaStatus(data->fromaddr,status);
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_USER_STATUS handled\n");
    #endif
    }
else if(p->msg == MRIM_CS_CONTACT_LIST2)
    {// contact list received
    unsigned long tmppos=0;
    unsigned long status;
    unsigned long groupcnt;
    unsigned long t,tmpdw;
    unsigned char groupmask[100];
    unsigned char contactsmask[100];//флаги(0), группа(1), адрес(2), ник(3), серверные флаги(4), текущий статус в сети(5)
    unsigned long contactnum = 0x14;
    unsigned long contactflag = 0;
    unsigned long contactstatus = 0;
    unsigned char *cptr;

    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_CONTACT_LIST2 received\n");
    #endif
    MRIM_Flag_ContactListReceiving = 1;
    if(MRIM_Packet_GetLong(&tmppos,p,&status) != 0)goto cs_endprocess;// clist status
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: status == %lu\n",status);
    #endif
    if(status == GET_CONTACTS_OK)
        {
        if(MRIM_Packet_GetLong(&tmppos,p,&groupcnt) != 0)goto cs_endprocess;// number of groups
        if(MRIM_Packet_GetString(&tmppos,p,groupmask) != 0)goto cs_endprocess;
        if(MRIM_Packet_GetString(&tmppos,p,contactsmask) != 0)goto cs_endprocess;
        for(t=0;t<groupcnt;t++)
            {
            cptr = groupmask;
            while(cptr[0] != 0)
                {
                if(cptr[0] == 's')
                    {// string
                    if(MRIM_Packet_GetString(&tmppos,p,data->tmpbuf) != 0)goto cs_endprocess;// group name
                    //MessageBox(NULL,tmpbuf,"Group Name",MB_OK);
                    }
                else{// integer
                    if(MRIM_Packet_GetLong(&tmppos,p,&tmpdw) != 0)goto cs_endprocess;// groups flags
                    }
                cptr++;
                }
            }
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: groups received\n");
        #endif
        // process contacts
        while(1)
            {
            cptr = contactsmask;
            t = 0;
            data->fromaddr[0] = 0;
            data->cl_nick[0] = 0;
            contactflag = 0;
            while(cptr[0] != 0)
                {
                if(cptr[0] == 's')
                    {// string
                    if(MRIM_Packet_GetString(&tmppos,p,data->tmpbuf) != 0)goto cs_endprocess;
                    //else if(t == 3)MessageBox(NULL,tmpbuf,"Contact Nick",MB_OK);
                    if(t == 2)strcpy(data->fromaddr,data->tmpbuf);// contact email
                    else if(t == 3)strcpy(data->cl_nick,data->tmpbuf);// contact nick
                    }
                else{// integer
                    if(MRIM_Packet_GetLong(&tmppos,p,&tmpdw) != 0)goto cs_endprocess;
                    //CODEBLOCK
                    //    {
                    //    unsigned char buf[100];
                    //    sprintf(buf,"t==%lu val==%lu",t,tmpdw);
                    //    MessageBox(NULL,buf,"Contact",MB_OK);
                    //    }
                    if(t == 0)contactflag = tmpdw;
                    else if(t == 5)contactstatus = tmpdw;
                    }
                cptr++;
                t++;
                }
            //if((data->fromaddr[0] != 0)&&(contactflag == 0))
            if(data->fromaddr[0] != 0)
                {
                hContact = HContactFromEMail(data->fromaddr,1,1);
                MRIM_CList_SyncApparentModeToMiranda(hContact,contactflag);
                MRIM_SetMirandaStatus(data->fromaddr,contactstatus);
                DBWriteContactSettingDword(hContact,ProtoName,DB_SETTING_NUMBER,contactnum);
                DBWriteContactSettingString(hContact,DB_SETTING_CLIST,DB_SETTING_CLIST_MYHANDLE,data->cl_nick[0]==0?data->fromaddr:data->cl_nick);
                #ifdef MRIM_DEBUG
                    PrintDebug("MRIM_HSP: Contact #%lu (%s) received and added\n",contactnum,data->cl_nick[0]==0?data->fromaddr:data->cl_nick);
                #endif
                contactnum++;
                }
            }
        }
    cs_endprocess:;
    MRIM_Flag_ContactListReceiving = 0;
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_CONTACT_LIST2 handled\n");
    #endif
    }
else if(p->msg == MRIM_CS_USER_INFO)
    {// my info (messages, name, etc.)
    //unsigned char buf[4096];
    //sprintf(buf,"msg=%8.08X\r\n",p->msg);
    //DumpMemToBuffer(&(buf[strlen(buf)]),p,len+sizeof(mrim_packet_header_t));
    //MessageBox(NULL,buf,"MRIM_CS_USER_INFO",MB_OK);
    unsigned long tmppos=0;
    unsigned long unread=0;
    
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_USER_INFO received\n");
    #endif
    if(MRIM_Packet_GetString(&tmppos,p,data->tmpbuf) == 0)// MESSAGES.TOTAL
        {
        if(strcmp(data->tmpbuf,"MESSAGES.TOTAL") == 0)// MESSAGES.TOTAL
            {
            #ifdef MRIM_DEBUG
                PrintDebug("MRIM_HSP: \"MESSAGES.TOTAL\" found\n");
            #endif
            if(MRIM_Packet_GetString(&tmppos,p,data->tmpbuf) == 0)
                {
                if(MRIM_Packet_GetString(&tmppos,p,data->tmpbuf) == 0)// MESSAGES.UNREAD
                    {
                    if(strcmp(data->tmpbuf,"MESSAGES.UNREAD") == 0)// MESSAGES.UNREAD
                        {
                        #ifdef MRIM_DEBUG
                            PrintDebug("MRIM_HSP: \"MESSAGES.UNREAD\" found\n");
                        #endif
                        if(MRIM_Packet_GetString(&tmppos,p,data->tmpbuf) == 0)
                            {
                            unread = atol(data->tmpbuf);
                            #ifdef MRIM_DEBUG
                                PrintDebug("MRIM_HSP: unread messages == %lu\n",unread);
                            #endif
                            MRIM_NewMessagesCount = unread;
                            }
                        }
                    }
                }
            }
        }
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_USER_INFO handled\n");
    #endif
    }
else if(p->msg == MRIM_CS_LOGOUT)
    {// user kicked by server
    unsigned long tmppos=0;
    unsigned long reason;

    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_LOGOUT received\n");
    #endif
    if(MRIM_Packet_GetLong(&tmppos,p,&reason) == 0)// kick reason
        {
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: reason == %lu\n",reason);
        #endif
        MRIM_SetStatus(ID_STATUS_OFFLINE,0L);    
        }
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_LOGOUT handled\n");
    #endif
    }
else if(p->msg == MRIM_CS_CONNECTION_PARAMS)
    {// new connection parameters
    unsigned long tmppos=0;
    unsigned long ping_period;

    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_CONNECTION_PARAMS received\n");
    #endif
    if(MRIM_Packet_GetLong(&tmppos,p,&ping_period) == 0)// ping period
        {
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: ping period == %lu\n",ping_period);
        #endif
        MRIM_WatchDogInterval = ping_period;
        }
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: MRIM_CS_CONNECTION_PARAMS handled\n");
    #endif
    }
//else if(p->msg == MRIM_CS_AUTHORIZE_ACK)
//    {// authorization request ACK
//    MessageBox(NULL,"Auth ack","Info",MB_OK);
//    }
else{
    unsigned long cnt;
    struct ReceiveQueueNode *nn;
    struct ReceiveQueueNode **ptn;

    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: unhandled packet id(%8.08X) seq(%8.08X) in MRIM_HSP. storing to queue\n",p->msg,p->seq);
    #endif
    nn = ReceiveQueue;
    cnt = 0;
    while(nn != NULL)
        {
        cnt++;
        nn = nn->Next;
        }
    if(cnt > 50)
        {
        nn = ReceiveQueue;
        ReceiveQueue = nn->Next;
        free(nn);
        }
    if((nn=(struct ReceiveQueueNode*)malloc(sizeof(struct ReceiveQueueNode)+p->dlen)) != NULL)
        {
        #ifdef MRIM_DEBUG
            PrintDebug("MRIM_HSP: malloc() ok\n");
        #endif
        nn->Next = NULL;
        nn->size = sizeof(mrim_packet_header_t)+p->dlen;
        nn->rtime = GetTickCount();
        memcpy(&(nn->packet),p,nn->size);

        ptn = &ReceiveQueue;
        while((*ptn) != NULL)
            {
            ptn = &((*ptn)->Next);
            }
        *ptn = nn;
        }
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_HSP: end handling id == %8.08X in MRIM_HSP\n",p->msg);
    #endif
    }
#ifdef MRIM_DEBUG
    PrintDebug("MRIM_HSP: ended.\n");
#endif
return(0);
}

void ListenThread(void *parm)
{
int recvResult;
NETLIBPACKETRECVER packetRecv;

#ifdef MRIM_DEBUG
    PrintDebug("ListenThread: started\n");
#endif
memset(&packetRecv,0,sizeof(packetRecv));
ReceiveQueue = NULL;
packetRecv.cbSize = sizeof(packetRecv);
packetRecv.dwTimeout = INFINITE;
while(1)
    {
    if(MRIM_hServerPacketRecver == NULL)
        {
        memset(&packetRecv,0,sizeof(packetRecv));
        ReceiveQueue = NULL;
        packetRecv.cbSize = sizeof(packetRecv);
        packetRecv.dwTimeout = INFINITE;
        Sleep(500);
        continue;
        }
    recvResult = CallService(MS_NETLIB_GETMOREPACKETS,(WPARAM)MRIM_hServerPacketRecver,(LPARAM)&packetRecv);
    #ifdef MRIM_DEBUG
        PrintDebug("ListenThread: CallService(MS_NETLIB_GETMOREPACKETS,,,) returned control\n");
    #endif
    if(recvResult == 0)
        {
        #ifdef MRIM_DEBUG
            PrintDebug("ListenThread: CallService(MS_NETLIB_GETMOREPACKETS,,,) == 0\n");
        #endif
        //MessageBox(NULL,"MS_NETLIB_GETMOREPACKETS returns 0","listen thread",MB_OK);
        if(MRIM_LoginInProgressFlag == 0)
            MRIM_SetStatus(ID_STATUS_OFFLINE,0L);
        memset(&packetRecv,0,sizeof(packetRecv));
        ReceiveQueue = NULL;
        packetRecv.cbSize = sizeof(packetRecv);
        packetRecv.dwTimeout = INFINITE;
        Sleep(500);
        continue;
        }
    if(recvResult == SOCKET_ERROR)
        {
        #ifdef MRIM_DEBUG
            PrintDebug("ListenThread: recvResult == SOCKET_ERROR\n");
        #endif
        //MessageBox(NULL,"MS_NETLIB_GETMOREPACKETS returns SOCKET_ERROR","listen thread",MB_OK);
        if(MRIM_LoginInProgressFlag == 0)
            MRIM_SetStatus(ID_STATUS_OFFLINE,0L);
        memset(&packetRecv,0,sizeof(packetRecv));
        ReceiveQueue = NULL;
        packetRecv.cbSize = sizeof(packetRecv);
        packetRecv.dwTimeout = INFINITE;
        Sleep(500);
        continue;
        }
//    if(packetRecv.bytesAvailable > 0)
//        {
//        DumpMemory(packetRecv.buffer,packetRecv.bytesAvailable);
//        }
    #ifdef MRIM_DEBUG
        PrintDebug("ListenThread: processing received data\n");
    #endif
    while(1)
        {
        mrim_packet_header_t *p = (mrim_packet_header_t*)&(packetRecv.buffer[packetRecv.bytesUsed]);
        if((packetRecv.bytesAvailable-packetRecv.bytesUsed) < sizeof(mrim_packet_header_t))
            {
            #ifdef MRIM_DEBUG
                PrintDebug("ListenThread: no available data\n");
            #endif
            break;
            }
        if(p->magic == CS_MAGIC)
            {
            #ifdef MRIM_DEBUG
                PrintDebug("ListenThread: packet magic OK\n");
            #endif
            if((packetRecv.bytesAvailable-packetRecv.bytesUsed) >= (sizeof(mrim_packet_header_t) + p->dlen))
                {
                packetRecv.bytesUsed += sizeof(mrim_packet_header_t) + p->dlen;
                MRIM_HSP(p,parm);
                }
            else{
                #ifdef MRIM_DEBUG
                    PrintDebug("ListenThread: packet is not complete. waiting for more blocks.\n");
                #endif
                break;
                }
            }
        else{
            #ifdef MRIM_DEBUG
                PrintDebug("ListenThread: packet error! no magic\n");
            #endif
            packetRecv.bytesUsed = packetRecv.bytesAvailable;
            }
        }
    }
}
 
//unsigned long MRIM_receivepacket(void *buffer,unsigned long bufsize,unsigned long seq,unsigned long timeout)
//{
//unsigned long t;
//struct ReceiveQueueNode **ptn;
//struct ReceiveQueueNode *tn;
//
//t = 0;
//while(1)
//    {
//    ptn = &ReceiveQueue;
//    while((*ptn) != NULL)
//        {
//        if((*ptn)->packet.seq == seq)
//            {
//            tn = *ptn;
//            *ptn = tn->Next;
//            memcpy(buffer,&(tn->packet),tn->size);
//            free(tn);
//            return(0);
//            }
//        ptn = &((*ptn)->Next);
//        }
//    if(t >= timeout*10)break;
//    Sleep(100);
//    t++;
//    }
//return(1);
//}
unsigned long MRIM_receivepacket(void *buffer,unsigned long bufsize,unsigned long seq,unsigned long timeout)
{
unsigned long t;
struct ReceiveQueueNode *tn;
struct ReceiveQueueNode **ptn;

#ifdef MRIM_DEBUG
    PrintDebug("MRIM_receivepacket: started\n");
#endif
t = 0;
while(1)
    {
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_receivepacket: processing incoming queue\n");
    #endif
    ptn = &ReceiveQueue;
    while((*ptn) != NULL)
        {
        tn = *ptn;
        if(tn->packet.seq == seq)
            {
            #ifdef MRIM_DEBUG
                PrintDebug("MRIM_receivepacket: found packet with seq(%lu)\n",seq);
            #endif
            //if(bufsize < tn->size)tn->size = bufsize;
            memcpy(buffer,&(tn->packet),tn->size);
            (*ptn) = tn->Next;
            free(tn);
            #ifdef MRIM_DEBUG
                PrintDebug("MRIM_receivepacket: returned ok\n");
            #endif
            return(0);
            }
        if((GetTickCount() - tn->rtime) > (1000*10))// 10 sec buffer store
            {
            #ifdef MRIM_DEBUG
                PrintDebug("MRIM_receivepacket: found packet with expired lifetime\n");
            #endif
            (*ptn) = tn->Next;
            free(tn);
            }
        else{
            ptn = &((*ptn)->Next);
            }
        }
    #ifdef MRIM_DEBUG
        PrintDebug("MRIM_receivepacket: processing incoming queue complete\n");
    #endif
    if(t >= timeout*10)break;
    Sleep(100);
    t++;
    }
#ifdef MRIM_DEBUG
    PrintDebug("MRIM_receivepacket: ended with error\n");
#endif
return(1);
}
/*        switch(tn->packet.msg)
            {
            case MRIM_CS_MESSAGE_STATUS:
                break;
            case MRIM_CS_AUTHORIZE_ACK:
                break;
            default:
                {
                static unsigned char buffer[2048];
                unsigned char *cptr;

                sprintf(buffer,"Message Code: %8.08X\n\n",tn->packet.msg);
                cptr = buffer;
                while(cptr[0] != 0)cptr++;
                DumpMemToBuffer(cptr,&(tn->packet),tn->size);
                MessageBox(NULL,buffer,"MRIM_receivepacket().Unknown Incoming Packet in Queue.",MB_OK|MB_ICONINFORMATION);
                }
            }*/
