#include #include #include #include #include #include "Daodan.h" #include "Daodan_Utility.h" #include "Flatline_Net.h" #pragma comment(lib, "wininet.lib") #define DAODAN_BUILD 3 int file_exists(const char *fname) { FILE *file; if (file = fopen(fname, "r")) { fclose(file); return 1; } return 0; } void DDr_StartupNetworkError() { int errorno = WSAGetLastError(); char Message[1024]; FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_MAX_WIDTH_MASK, NULL, errorno, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR) Message, 1024, NULL); DDrStartupMessage(Message); #ifdef _DEBUG MessageBox(0, Message, "", 0); #endif } char* DDr_HttpGet( char* host, char* path ) { #define chunkSize 8192 char* file = 0; char tempRaw[chunkSize] = {0}; char* rawData = 0; char* filePtr; char* sizePtr; int rawLen = 0; int tempLen = 0; char getString[255]; sockaddr_in UpdateAddr = {0}; int UpdateSocket; hostent* host_info = 0; struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; sprintf(getString, "GET %s HTTP/1.0\r\n" "User-Agent: Daodan DLL Updater\r\n" "Host: %s\r\n" "\r\n" , path, host ); host_info = gethostbyname(host); if(!host_info) { DDr_StartupNetworkError(); return 0; } UpdateAddr.sin_port = htons(80); UpdateAddr.sin_family = AF_INET; UpdateAddr.sin_addr.S_un.S_addr = *(ULONG*)host_info->h_addr_list[0]; UpdateSocket = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP) ; if(UpdateSocket <= 0) { DDrStartupMessage("Could not create socket"); DDr_StartupNetworkError(); return 0; } //Set timeout to five seconds. setsockopt(UpdateSocket, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof tv); if (connect(UpdateSocket, (struct sockaddr *) &UpdateAddr, sizeof(sockaddr_in)) < 0) { closesocket( UpdateSocket ); DDr_StartupNetworkError(); return 0; } send( UpdateSocket, getString, strlen(getString), 0 ); while((tempLen = recv( UpdateSocket, tempRaw, chunkSize, 0 )) > 0) { rawLen += tempLen; rawData = (char*)realloc( rawData, rawLen + 1 ); if(rawData == 0) { closesocket( UpdateSocket ); return 0; } memcpy( rawData + rawLen - tempLen, tempRaw, tempLen ); } closesocket( UpdateSocket ); if(tempLen < 0) { return 0; } //check for complete header filePtr = strstr( rawData, "\r\n\r\n" ) + 4; //get the data size sizePtr = strstr( rawData, "Content-Length:") + strlen("Content-Length:"); //check for correct status code if(filePtr > 4 && sizePtr && !strncmp("HTTP/1.0 200 OK", rawData, 15)) { int fileSize = atoi(sizePtr); file = (char*)malloc( fileSize + sizeof(int) + 1); if(file) { *(int *)file = fileSize; memcpy( file + 4, filePtr, fileSize ); file[fileSize + sizeof(int)] = 0; } } else { if(sizePtr && filePtr) *(filePtr + atoi(sizePtr)) = 0; #ifdef _DEBUG MessageBox( 0, rawData, "", 0); #endif DDrStartupMessage("HTML Error!"); DDrStartupMessage( rawData ); } free( rawData ); return file; #undef chunkSize } int DDr_CheckForUpdates(int argc, char* argv[]) { int version = 0; char* fileGet; char args[8191] = {0}; int i; WSADATA wsaData; for(i = 1; i < argc; i++) { if(!stricmp(argv[i], "-noupdate")) return 1; strcat( args, " "); strcat( args, argv[i] ); } //Start network stuff if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { DDrStartupMessage("WSA initalization failed"); return 0; } DDrStartupMessage("net started using WSA version %d.%d", LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); fileGet = DDr_HttpGet( "gumby.oni2.net", "/daodan/version.txt" ); if(fileGet && *(int*)fileGet) { version = atoi(fileGet + sizeof(int)); } free( fileGet ); if(version > DAODAN_BUILD) { FILE* dllFile; char pName[8191] = {0}; int returnval = 0; STARTUPINFO siStartupInfo; PROCESS_INFORMATION piProcessInfo; memset(&siStartupInfo, 0, sizeof(siStartupInfo)); memset(&piProcessInfo, 0, sizeof(piProcessInfo)); siStartupInfo.cb = sizeof(siStartupInfo); DDrStartupMessage("Update for the Daodan DLL is avaliable..."); returnval = MessageBox( NULL, "An update for the Daodan DLL is avaiable! Would you like to download it?", "Daodan DLL Alert", MB_YESNO); if( returnval != IDYES) return 1; MessageBox( NULL, "Update downloading, please do not reopen Oni, it will open itself.\nPress OK to continue", "Daodan DLL Alert", 0); fileGet = DDr_HttpGet( "gumby.oni2.net", "/daodan/binkw32.dll" ); if(!(fileGet && *(int*)fileGet)) { free(fileGet); return 0; } //Remove the old file remove( "binkw32.dll.bak" ); rename( "binkw32.dll", "binkw32.dll.bak" ); //rename failed! if(file_exists("binkw32.dll")) return; //write the new file dllFile = fopen( "binkw32.dll", "wb" ); if(dllFile == NULL ) { rename( "binkw32.dll.bak", "binkw32.dll" ); return 0; } fwrite( fileGet + 4, *(int *)fileGet, 1, dllFile ); fclose( dllFile ); free(fileGet); //Restart Oni! GetModuleFileName(NULL, pName, 8191 ); //GetProcessImageFileName() //GetProcessImageFileName( 0, pName, 8191 ); CreateProcess(pName, args, 0, 0, 0, 0, 0, 0,&siStartupInfo,&piProcessInfo); exit(0); } return 1; }