/*
* [U]NITED [G]AMING [C]HEATS
*
* Copyright (c) ADVANCED   2001-2002
* Copyright (c) LIQUID     2001-2002
* Copyright (c) ZERO       2001-2002
* Copyright (c) ZOOLABUS   2001-2002
* 
* 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., 675 Mass Ave, Cambridge, MA 02139, USA.
* 
* GNU license doesn't cover Engine directory.
* Content of Engine directory is copyrighted (c) 1999, 2000, by Valve LLC
* and it is licensed under Valve's proprietary license (see original HL SDK).
*/

#include <windows.h>
#include "stdio.h"
#include "ForceLib.h"
#include "ugc.h"

#pragma pack(1)

HINSTANCE mainInstance;

bool fileExists(const char* filename)
{
	WIN32_FIND_DATA finddata;
	HANDLE handle = FindFirstFile(filename,&finddata);
	return (handle!=INVALID_HANDLE_VALUE);
}

#undef OGC_DEBUG

//==============================================================================
bool promptForFile( char* retFile, const char* tip, char* filter, char* title, bool save, HWND hWnd )
{
              OPENFILENAME ofn;
              memset(&ofn, 0, sizeof(OPENFILENAME));
              ofn.lStructSize = sizeof(OPENFILENAME);
              ofn.hwndOwner = hWnd;
              ofn.hInstance = mainInstance;
              ofn.nFilterIndex = 1;
              ofn.lpstrFile = retFile;
              ofn.nMaxFile = 256;
              ofn.lpstrInitialDir = tip;
              //====
              ofn.lpstrFilter = filter;
              ofn.lpstrTitle  = title;

              strcpy( retFile, tip );

              bool status;
              if( save )
              {
                  ofn.Flags = OFN_OVERWRITEPROMPT;
                  status =  (GetSaveFileName(&ofn)!=0);
              } else
              {
                  ofn.Flags = OFN_FILEMUSTEXIST;
                  status = (GetOpenFileName(&ofn)!=0);
              }
              return status;
}

STARTUPINFO          SI;
PROCESS_INFORMATION  PI;

//==================================================================================
bool isApplogAlreadyDisabled()
{
	HKEY  l_hKey;
    DWORD l_UseProfile;
    DWORD l_dwBufLen = 4;

    DWORD l_ret = RegOpenKeyEx(
		HKEY_LOCAL_MACHINE,
		"Software\\Microsoft\\Windows\\CurrentVersion\\Applets\\Defrag\\AppStartParams",
		0,KEY_QUERY_VALUE, &l_hKey);
	if(l_ret!=ERROR_SUCCESS) { RegCloseKey(l_hKey); return false; }

	l_ret = RegQueryValueEx(l_hKey,"UseProfile",NULL,NULL,(LPBYTE)&l_UseProfile,&l_dwBufLen);
	if(l_ret!=ERROR_SUCCESS) { RegCloseKey(l_hKey); return false; }

	RegCloseKey(l_hKey);
	return (l_UseProfile==0);
}

//==================================================================================
bool isOnWindowsDrive(char* file)
{
	// check for windows drive = hl drive
	char windir[400];
	GetWindowsDirectory(windir,390);
	if( file[1]==':' && windir[1]==':' && tolower(file[0])==tolower(windir[0]) ) return true;
	else return false;
}

//==================================================================================
void unHideApplog()
{
	char applogdir[400];
	GetWindowsDirectory(applogdir,390);
	strcat(applogdir,"\\Applog");
	SetFileAttributes( applogdir, FILE_ATTRIBUTE_NORMAL );
}

////==================================================================================
void applogFix()
{
	// check for NT
	bool IsNT = ((HIWORD(::GetVersion()) & 0x8000) == 0); 
#ifdef OGC_DEBUG
	IsNT = false;
#endif
	if(IsNT) return;

}

//==================================================================================
void removeTrailingCRLF(char* a)
{
	while(a[strlen(a)-1]=='\x0D' || a[strlen(a)-1]=='\x0A' ) a[strlen(a)-1]=0;
}


//==================================================================================
int WINAPI WinMain(HINSTANCE hInstance,
				   HINSTANCE hPrevInstance,
				   LPSTR lpCmdLine,
				   int nShowCmd)
{
	mainInstance = hInstance;
 
	char hookEXE  [400] = ""; 
	char hookDLL  [400] = ""; 
	char hookINI  [400] = "";
	char hlCmdLine[400] = "";
	char hlEXE    [400] = "";
	
	GetModuleFileName(0,hookEXE,390); 
	int  len = strlen(hookEXE);
	strcpy(hookDLL,hookEXE); 
	strcpy(hookINI,hookEXE); 
	hookDLL[len-3]='d';hookDLL[len-2]='l';hookDLL[len-1]='l';
	hookINI[len-3]='i';hookINI[len-2]='n';hookINI[len-1]='i';

	#ifndef OGC_DEBUG
	if( !fileExists(hookDLL) ) {
		MessageBox(0,hookDLL,"-[UGC]- DLL NOT FOUND!",MB_ICONERROR|MB_TOPMOST);
		return 1;
	}
	#endif

	bool success = false;
	do{
		FILE* file = fopen(hookINI,"r");
		if(file)
		{
			fgets(hlEXE    ,390,file);hlEXE[398]=0;     removeTrailingCRLF(hlEXE);
			fclose(file);
		}

		if(!fileExists(hlEXE))
		{
			if(!GetHLCSPath(hlEXE))
			{
				MessageBox(0,"WE COULD NOT FIND YOUR HL/CS EXECUTABLE,\nHL.EXE OR CSTRIKE.EXE","-[UGC]- REQUEST",MB_ICONEXCLAMATION);
				bool ok = promptForFile( hlEXE, "c:\\sierra\\counter-strike\\cstrike.exe",
								"hl.exe or cstrike.exe\0hl.exe;cstrike.exe\0",
								"HL/CS DIRECTORY", false, 0);
				if(!ok) { return 0; }
			}
			
			file = fopen(hookINI,"w");
			if(file)
			{
				fprintf(file,"%s\x0D\x0A",hlEXE);
				fclose(file);
			} else {
				MessageBox(0,hookINI,"-[UGC]- WRITE ERROR",0); 
				break;
			}
			if(fileExists(hlEXE)) success = true;
		}
		else
		{
			success = true;
		}

	} while(!success);

	if( !strcmpi(hlEXE,hookEXE) )
	{
		MessageBox(0,"CANNOT EXECUTE HL/CS PROGRAM!","-[UGC]- ERROR",MB_ICONEXCLAMATION);
		DeleteFile(hookINI);
		return 1;
	}

	#ifndef OGC_DEBUG
	if( isOnWindowsDrive(hlEXE) ) applogFix();
	#else
	applogFix();
	#endif
	
	if(!strstr(lpCmdLine,"-game")) strcpy(hlCmdLine," -game cstrike -console ");
	strcat(hlCmdLine,lpCmdLine);

	ZeroMemory(&SI,sizeof(STARTUPINFO));
	ZeroMemory(&PI,sizeof(PROCESS_INFORMATION));
	SI.cb = sizeof(STARTUPINFO);

	char hlDir[400];
	strcpy(hlDir,hlEXE);
	char* pos = hlDir+strlen(hlDir);
	while(pos>=hlDir && *pos!='\\') --pos;
	*pos = 0;
	char* hlBaseFileName = pos+1;
	SetCurrentDirectory(hlDir);
	
	if (!CreateProcess(hlBaseFileName,hlCmdLine,NULL,NULL,FALSE,CREATE_SUSPENDED,NULL,NULL,&SI,&PI))
	{
		MessageBox(0,"CANNOT CREATE THE HL/CS PROCESS!","-[UGC]- ERROR",MB_ICONERROR|MB_TOPMOST);
		return -1;
	}
	
	if (!ForceLibrary(hookDLL,&PI))
	{
		MessageBox(0,"HOOK INJECTION FAILED!","-[UGC]- ERROR",MB_ICONERROR|MB_TOPMOST);
		TerminateProcess(PI.hProcess,-1);
		return -1;
	}

	ResumeThread(PI.hThread);

	CloseHandle(PI.hProcess);
	CloseHandle(PI.hThread);
	return 0;
}

//==================================================================================
bool GetHLCSPath(char *szHLCSPath)
{
	HKEY p_hKey;
	DWORD p_dwBufLen = 400;
	char tmpstr[500] = "";
	bool hlfound = true;

	DWORD p_ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
		"Software\\Sierra OnLine\\Setup\\HALFLIFE", 0, KEY_QUERY_VALUE, &p_hKey);
	if(p_ret!=ERROR_SUCCESS)
	{
		RegCloseKey(p_hKey);
		hlfound = false;
	}
	if(!hlfound)
	{
		p_ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
			"Software\\Sierra OnLine\\Setup\\CSTRIKE", 0, KEY_QUERY_VALUE, &p_hKey);
		if(p_ret!=ERROR_SUCCESS)
		{
			RegCloseKey(p_hKey);
			MessageBox(0,"GetHLCSPath() - OpenKey\n"
						 "HL/CS IS NOT INSTALLED!",LDR_ERR,MB_ICONERROR|MB_TOPMOST);
			return false;
		}
	}

	p_ret = RegQueryValueEx(p_hKey,"DIRECTORY",NULL,NULL,(unsigned char*)szHLCSPath,&p_dwBufLen);
	if(p_ret!=ERROR_SUCCESS)
	{
		RegCloseKey(p_hKey);
		MessageBox(0,"GetHLCSPath() - QueryValue\n"
					 "CANNOT FIND HL/CS DIRECTORY!",LDR_ERR,MB_ICONERROR|MB_TOPMOST);
		return false;
	}
	RegCloseKey(p_hKey);

	if(hlfound) strcat(szHLCSPath, "\\hl.exe");
	else strcat(szHLCSPath, "\\cstrike.exe");
	sprintf(tmpstr,"HL/CS EXECUTABLE WAS FOUND IN,\n\n%s",szHLCSPath);
	if(MessageBox(0,tmpstr,LDR_REQ,MB_YESNO|MB_ICONQUESTION) == IDYES) return true;
	else return false;
}
