/* * Plugin of miranda IM(ICQ) for Communicating with users of the XFire Network. * * Copyright (C) 2010 by * dufte * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * 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. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * * Based on J. Lawler - BaseProtocol * Herbert Poul/Beat Wolf - xfirelib * * Miranda ICQ: the free icq client for MS Windows * Copyright (C) 2000-2008 Richard Hughes, Roland Rabien & Tristan Van de Vreede * */ #include "stdafx.h" #include #include "tools.h" #include "xdebug.h" extern HANDLE hNetlib; //convert buf to hexstring /*char* tohex(unsigned char*buf,int size) { static char buffer[1024*10]=""; strcpy(buffer,""); for(int i=0;i-1) { char *temp=new char[strlen(src)+strlen(rep)+1]; strcpy(temp,src); *(temp+pos)=0; strcat(temp,rep); strcat(temp,(src+pos+strlen(find))); strcpy(src,temp); delete temp; return TRUE; } return FALSE; } /* popup darstellen */ int displayPopup(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType,HICON hicon) { static signed char bUsePopups = -1; static BOOL bIconsNotLoaded = TRUE; static HICON hicNotify = NULL, hicWarning = NULL, hicError = NULL; if ((uType & MB_TYPEMASK) == MB_OK) { POPUPDATA ppd = { 0 }; ppd.lchIcon = hicon; if (bIconsNotLoaded) { hicNotify = Skin_GetIcon("popup_notify"); hicWarning = Skin_GetIcon("popup_warning"); hicError = Skin_GetIcon("popup_error"); bIconsNotLoaded = FALSE; } lstrcpynA(ppd.lpzContactName, lpCaption, sizeof(ppd.lpzContactName)); lstrcpynA(ppd.lpzText, lpText, sizeof(ppd.lpzText)); if ((uType & MB_ICONMASK) == MB_ICONSTOP) { ppd.lchIcon = hicError; ppd.colorBack = RGB(191,0,0); ppd.colorText = RGB(255,245,225); } else if ((uType & MB_ICONMASK) == MB_ICONWARNING) { ppd.lchIcon = hicWarning; ppd.colorBack = RGB(210,210,150); ppd.colorText = RGB(0,0,0); } else { ppd.lchIcon = hicNotify; ppd.colorBack = RGB(230,230,230); ppd.colorText = RGB(0,0,0); } PUAddPopup(&ppd); } return IDOK; } char*menuitemtext(char*mtext) { static char temp[256]=""; int anz=0; int j=0; if (!mtext) return NULL; int size=strlen(mtext); if (!size || size>255) return mtext; //alle & zeichen zählen for(int i=0;i> 8); #else _asm { mov ax,data rol ax,8 mov data,ax } return data; #endif } //simple und hoffetnlich schnelle teamspeakdetection BOOL FindTeamSpeak(DWORD*pid,int*vid) { BOOL found=FALSE; if (pid==NULL) return FALSE; HANDLE hSnapShot = CreateToolhelp32Snapshot ( TH32CS_SNAPALL, 0); PROCESSENTRY32* processInfo = new PROCESSENTRY32; processInfo->dwSize = sizeof ( PROCESSENTRY32); // XFireLog("Scanning for voiceprograms..."); while ( Process32Next ( hSnapShot,processInfo ) != FALSE) { if (processInfo->th32ProcessID!=0) { int size=_tcslen(processInfo->szExeFile); if (size==13) { if ((processInfo->szExeFile[0]=='T'||processInfo->szExeFile[0]=='t')&& processInfo->szExeFile[1]=='e'&& processInfo->szExeFile[2]=='a'&& processInfo->szExeFile[3]=='m'&& processInfo->szExeFile[4]=='S'&& processInfo->szExeFile[5]=='p'&& processInfo->szExeFile[6]=='e'&& processInfo->szExeFile[7]=='a'&& processInfo->szExeFile[8]=='k') { *pid=processInfo->th32ProcessID; found=TRUE; *vid=32; break; } } else if (size==12) { if ((processInfo->szExeFile[0]=='V'||processInfo->szExeFile[0]=='v')&& processInfo->szExeFile[1]=='e'&& processInfo->szExeFile[2]=='n'&& processInfo->szExeFile[3]=='t'&& processInfo->szExeFile[4]=='r'&& processInfo->szExeFile[5]=='i'&& processInfo->szExeFile[6]=='l'&& processInfo->szExeFile[7]=='o') { *pid=processInfo->th32ProcessID; found=TRUE; *vid=33; break; } } else if (size==10) { if ((processInfo->szExeFile[0]=='m'||processInfo->szExeFile[0]=='M')&& processInfo->szExeFile[1]=='u'&& processInfo->szExeFile[2]=='m'&& processInfo->szExeFile[3]=='b'&& processInfo->szExeFile[4]=='l'&& processInfo->szExeFile[5]=='e') { *pid=processInfo->th32ProcessID; found=TRUE; *vid=34; break; } } } } CloseHandle ( hSnapShot); return found; } #include #define maxuppackets 4 //funktion liefer ip/port einer verbindung BOOL GetServerIPPort(DWORD pid,char*localaddrr,unsigned long localaddr,char*ip1,char*ip2,char*ip3,char*ip4,long*port) { static std::vector localport; static const int hdrInclude = 1; static int lastip=0; static int lastport=0; static int lastpid=0; //DUMP("***Suche IP/Port***",""); if (pid!=lastpid) { lastip=lastport=0; lastpid=pid; } DWORD size=0; MIB_UDPTABLE_OWNER_PID * ptab=NULL; GetExtendedUdpTable(NULL, &size, FALSE, AF_INET, UDP_TABLE_OWNER_PID, 0); ptab=(MIB_UDPTABLE_OWNER_PID*)malloc(size); int ret = GetExtendedUdpTable(ptab, &size, FALSE, AF_INET, UDP_TABLE_OWNER_PID, 0); //alle grad geöffnet updverb nach der pid vom spiel suchen, um an den port ranzukommen if (ret==NO_ERROR) { BOOL notfound=TRUE; for(unsigned int i=0;idwNumEntries;i++) { if (ptab->table[i].dwOwningPid==pid) //spiel gefunden { localport.push_back(ptab->table[i].dwLocalPort); //DUMP("Localport: %d",ptab->table[i].dwLocalPort); //localport=; //port wird gesichert //break; //wir brauchen nicht mehr suchen notfound=FALSE; } } if (notfound) //kein port gefunden { //DUMP("Kein Localport gefunden",""); XFireLog("no local port found"); return FALSE; //dann erstmal schluss } } else { XFireLog("GetExtendedUdpTable error!"); return FALSE; } if (ptab) delete ptab; //speicher frei machn //socker erstellen SOCKET s; s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); if (s==INVALID_SOCKET) { //DUMP("Kann Rawsocket nicht erstellen. Error: %d",WSAGetLastError()); XFireLog("unable to create raw socket %d",WSAGetLastError()); closesocket(s); return FALSE; } static struct sockaddr_in msockaddr; memset(&msockaddr,0,sizeof(msockaddr)); msockaddr.sin_addr.s_addr = localaddr; msockaddr.sin_family = AF_INET; msockaddr.sin_port = 0; //socket an nw binden if (bind(s, (sockaddr *)&msockaddr, sizeof(msockaddr)) == SOCKET_ERROR) { //DUMP("Kann Rawsocket nicht binden. Error: %d",WSAGetLastError()); XFireLog("unable to bind raw socket %d",WSAGetLastError()); closesocket(s); return FALSE; } //wir wollen alles was da reinkommt haben static int I = 1; static DWORD b; if (WSAIoctl(s, _WSAIOW(IOC_VENDOR,1), &I, sizeof(I), NULL, NULL, &b, NULL, NULL) == SOCKET_ERROR) { //DUMP("IOCTL Error",""); /*closesocket(s); return FALSE;*/ XFireLog("IOCTL error %d",WSAGetLastError()); //unter bestimmten umständen schlägt es hier fehl, dann lass trotzdem ip weiter erkennen } //socket soll timeout auswerfen, wenn nix kommt, damit der gamethread nicht hängt //DUMP("timeout>>>",""); static int timeout=200; if (setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout) == SOCKET_ERROR)) { XFireLog("setsockopt(SO_RCVTIMEO) error %d",WSAGetLastError()); } //updstruct, nur mit wichtigen sachen struct mpacket { unsigned char ipv; char dmp[11]; //dummy //srcip, serverip unsigned char ip1; unsigned char ip2; unsigned char ip3; unsigned char ip4; //unsere nw unsigned int ipdst; char temp[1024]; }; struct mpacket2 { unsigned char ipv; char dmp[11]; //dummy //srcip, serverip unsigned long srcip; //server ip unsigned char ip1; unsigned char ip2; unsigned char ip3; unsigned char ip4; char temp[1024]; }; struct udp { //srcport u_short srcport; //dstport u_short dstport; }; mpacket temp={0}; //empfamngsbuffer udp * temp2; char * temp3; mpacket2 * temp4; for (int I=0;Idstport); //DUMP("== %d",localport.at(i)); if (temp2->dstport==localport.at(i)/*FIX: für XP SP3 ->*/&&temp4->srcip!=localaddr) //ist das ziel des packets, gleich dem port des spiels { *port=r(temp2->srcport); //ja dann serverdaten an gamethread übermitteln *ip1=temp.ip1; *ip2=temp.ip2; *ip3=temp.ip3; *ip4=temp.ip4; closesocket(s); //socket zumachn //DUMP("SourceIP %d",temp4->srcip); //DUMP("SourcePort %d",temp2->srcport); if (lastip!=temp4->srcip||temp2->srcport!=lastport) { lastport=temp2->srcport; //fixed port wechsel, damit dieser auch mitgetielt wird, wenn zb vorher nur serverinfos angefordert wurden lastip=temp4->srcip; closesocket(s); //DUMP("IP gefunden",""); XFireLog("got ip!"); return TRUE; } XFireLog("no serverip found!"); return FALSE; } /* else if (temp4->srcip==localaddr && temp2->srcport==localport.at(i)) //gesendete gamepackets { *port=r(temp2->dstport); //ja dann serverdaten an gamethread übermitteln *ip1=temp4->ip1; *ip2=temp4->ip2; *ip3=temp4->ip3; *ip4=temp4->ip4; closesocket(s); //socket zumachn return TRUE; }*/ } } else if (msize==SOCKET_ERROR) { XFireLog("recv() error %d",WSAGetLastError()); } } closesocket(s); //socket zumachn lastip=0; lastport=0; return TRUE; } //funktion liefert ip/port einer verbindung, dupliziert für teamspeak/ventrilo, wegen static vals //TODO: eventuell umbauen, damit es für beide genutzt werden kann BOOL GetServerIPPort2(DWORD pid,char*localaddrr,unsigned long localaddr,char*ip1,char*ip2,char*ip3,char*ip4,long*port) { static std::vector localport; static const int hdrInclude = 1; static int lastip=0; static int lastpid=0; static int lastport=0; if (pid!=lastpid) { lastip=lastport=0; lastpid=pid; } DWORD size=0; MIB_UDPTABLE_OWNER_PID * ptab=NULL; GetExtendedUdpTable(NULL, &size, FALSE, AF_INET, UDP_TABLE_OWNER_PID, 0); ptab=(MIB_UDPTABLE_OWNER_PID*)malloc(size); int ret = GetExtendedUdpTable(ptab, &size, FALSE, AF_INET, UDP_TABLE_OWNER_PID, 0); //alle grad geöffnet updverb nach der pid vom spiel suchen, um an den port ranzukommen if (ret==NO_ERROR) { BOOL notfound=TRUE; for(unsigned int i=0;idwNumEntries;i++) { if (ptab->table[i].dwOwningPid==pid) //spiel gefunden { localport.push_back(ptab->table[i].dwLocalPort); //localport=; //port wird gesichert //break; //wir brauchen nicht mehr suchen notfound=FALSE; } } if (notfound) //kein port gefunden { if (lastip!=0) { lastip=0; lastport=0; return TRUE; } return FALSE; //dann erstmal schluss } } else return FALSE; if (ptab) delete ptab; //speicher frei machn //socker erstellen SOCKET s; s = socket(AF_INET, SOCK_RAW, IPPROTO_UDP); static struct sockaddr_in msockaddr; memset(&msockaddr,0,sizeof(msockaddr)); msockaddr.sin_addr.s_addr = localaddr; msockaddr.sin_family = AF_INET; msockaddr.sin_port = 0; //socket an nw binden if (bind(s, (sockaddr *)&msockaddr, sizeof(msockaddr)) == SOCKET_ERROR) { closesocket(s); return FALSE; } //wir wollen alles was da reinkommt haben static int I = 1; DWORD b; if (WSAIoctl(s, _WSAIOW(IOC_VENDOR,1), &I, sizeof(I), NULL, NULL, &b, NULL, NULL) == SOCKET_ERROR) { /*closesocket(s); return FALSE;*/ //unter bestimmten umständen schlägt es hier fehl, dann lass trotzdem ip weiter erkennen } //socket soll timeout auswerfen, wenn nix kommt, damit der gamethread nicht hängt //DUMP("timeout>>>",""); static int timeout=200; setsockopt(s, SOL_SOCKET, SO_RCVTIMEO,(char*)&timeout, sizeof(timeout)); //updstruct, nur mit wichtigen sachen struct mpacket { unsigned char ipv; char dmp[11]; //dummy //srcip, serverip unsigned char ip1; unsigned char ip2; unsigned char ip3; unsigned char ip4; //unsere nw unsigned int ipdst; char temp[1024]; }; struct mpacket2 { unsigned char ipv; char dmp[11]; //dummy //srcip, serverip unsigned long srcip; //server ip unsigned char ip1; unsigned char ip2; unsigned char ip3; unsigned char ip4; char temp[1024]; }; struct udp { //srcport u_short srcport; //dstport u_short dstport; }; mpacket temp={0}; //empfamngsbuffer udp * temp2; char * temp3; mpacket2 * temp4; for (int I=0;Idstport==localport.at(i)/*FIX: für XP SP3 ->*/&&temp4->srcip!=localaddr) //ist das ziel des packets, gleich dem port des spiels { *port=r(temp2->srcport); //ja dann serverdaten an gamethread übermitteln *ip1=temp.ip1; *ip2=temp.ip2; *ip3=temp.ip3; *ip4=temp.ip4; closesocket(s); //socket zumachn if (lastip!=temp4->srcip||temp2->srcport!=lastport) { lastport=temp2->srcport; //fixed port wechsel, damit dieser auch mitgetielt wird, wenn zb vorher nur serverinfos angefordert wurden lastip=temp4->srcip; return TRUE; } return FALSE; } /* else if (temp4->srcip==localaddr && temp2->srcport==localport.at(i)) //gesendete gamepackets { *port=r(temp2->dstport); //ja dann serverdaten an gamethread übermitteln *ip1=temp4->ip1; *ip2=temp4->ip2; *ip3=temp4->ip3; *ip4=temp4->ip4; closesocket(s); //socket zumachn return TRUE; }*/ } } closesocket(s); //socket zumachn lastip=0; lastport=0; return TRUE; } char * getItem(char * string,char delim,int count) { static char item[255]; char i=0; while(*string!='\0'&&count>0) { if (*string==delim) { item[i]=0; i=0; count--; string++; } else { item[i]=*string; i++; string++; } } if (*string=='\0') item[i]=0; if (count>1) item[0]=0; for(unsigned int i=0;iProcessParameters,UserPool,sizeof(PROCESS_PARAMETERS),NULL); proc_params = (PPROCESS_PARAMETERS)UserPool; ULONG uSize = 0; LPVOID pBaseAddress = NULL; uSize = proc_params->CommandLine.Length; pBaseAddress = proc_params->CommandLine.Buffer; //keine commandline?! if (uSize==0||pBaseAddress==NULL) { LocalFree(UserPool); return FALSE; } buffer=(WCHAR*)new char[uSize]; rc = _ZwReadVirtualMemory(hProcess, pBaseAddress, buffer, uSize, NULL); //in ansi umwandeln int correctsize=WideCharToMultiByte(CP_OEMCP, 0, buffer, -1, NULL, 0, NULL, NULL); if (correctsize==0) { LocalFree(UserPool); return FALSE; } buffer2=new char[correctsize]; WideCharToMultiByte(CP_OEMCP, 0, buffer, -1, buffer2,correctsize,NULL,NULL); buffer2[correctsize-1]=0; for(unsigned int i=0;iresultCode); if (nlhrReply->resultCode != 200) { CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); return FALSE; } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); } else return FALSE; return TRUE; } BOOL GetWWWContent2(char*address,char*filename,BOOL dontoverwrite,char**tobuf,unsigned int* size) { if (dontoverwrite==TRUE) { if (GetFileAttributesA(filename)!=0xFFFFFFFF) { Netlib_Logf(hNetlib,"%s already exists, no overwrite.",filename); return TRUE; } } Netlib_Logf(hNetlib,"Download Url %s ...",address); //netlib request NETLIBHTTPREQUEST nlhr={0},*nlhrReply; nlhr.cbSize = sizeof(nlhr); nlhr.requestType= REQUEST_GET; nlhr.flags = NLHRF_NODUMP|NLHRF_GENERATEHOST|NLHRF_SMARTAUTHHEADER; nlhr.szUrl = address; nlhrReply=(NETLIBHTTPREQUEST*)CallService(MS_NETLIB_HTTPTRANSACTION,(WPARAM)hNetlib,(LPARAM)&nlhr); if (nlhrReply) { //nicht auf dem server if (nlhrReply->resultCode != 200) { Netlib_Logf(hNetlib,"Bad statuscode: %d",nlhrReply->resultCode); CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); return FALSE; } //keine daten für mich else if (nlhrReply->dataLength < 1 || nlhrReply->pData == NULL) { Netlib_Logf(hNetlib,"No data received."); CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); return FALSE; } else { if (tobuf==NULL) { FILE * f = fopen(filename,"wb"); if (f==NULL) { Netlib_Logf(hNetlib,"Cannot open %s for binary write mode.",filename); CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); return FALSE; } fwrite(nlhrReply->pData,nlhrReply->dataLength,1,f); fclose(f); } else { if (*tobuf==NULL) { *tobuf=new char[nlhrReply->dataLength+1]; memcpy_s(*tobuf,nlhrReply->dataLength,nlhrReply->pData,nlhrReply->dataLength); //0 terminieren (*tobuf)[nlhrReply->dataLength]=0; //größe zurückliefern, wenn gewollt if (size) *size=nlhrReply->dataLength+1; } } } CallService(MS_NETLIB_FREEHTTPREQUESTSTRUCT,0,(LPARAM)nlhrReply); } else { Netlib_Logf(hNetlib,"No valid Netlib Request.",filename); return FALSE; } return TRUE; } //eigener www downloader, da winet exceptions erzeugt BOOL GetWWWContent(char*host,char* request,char*filename,BOOL dontoverwrite) { char add[1024]="http://"; strcat(add,host); strcat(add,request); return GetWWWContent2(add,filename,dontoverwrite); } unsigned int getfilesize(char*path) { FILE * f = NULL; f=fopen(path,"rb"); if (f==NULL) return 0; fseek (f, 0, SEEK_END); int size=ftell (f); fclose (f); return size; } //funktion soll erst in der userini suchen, danach in der xfire_games.ini DWORD xfire_GetPrivateProfileString(__in LPCSTR lpAppName, __in LPCSTR lpKeyName, __in LPCSTR lpDefault, __out LPSTR lpReturnedString, __in DWORD nSize, __in LPCSTR lpFileName) { //xfire_games.ini int size=strlen(lpFileName); if (size>15) { char*file=(char*)lpFileName; int ret=0; *(file+size-14)='u'; *(file+size-13)='s'; *(file+size-12)='e'; *(file+size-11)='r'; ret = GetPrivateProfileStringA( lpAppName,lpKeyName,lpDefault,lpReturnedString,nSize,lpFileName); if (ret) { return ret; } else { *(file+size-14)='f'; *(file+size-13)='i'; *(file+size-12)='r'; *(file+size-11)='e'; return GetPrivateProfileStringA( lpAppName,lpKeyName,lpDefault,lpReturnedString,nSize,lpFileName); } } return GetPrivateProfileStringA( lpAppName,lpKeyName,lpDefault,lpReturnedString,nSize,lpFileName); } BOOL mySleep(int ms,HANDLE evt) { switch(WaitForSingleObject(evt,ms)) { case WAIT_TIMEOUT: return FALSE; case WAIT_ABANDONED: //MessageBoxA(NULL,"Abbruch","Abbruch",0); return TRUE; default: return TRUE; } return FALSE; }