#include <windows.h>
#include "stdio.h"
#include "ForceLib.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)
{
	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()
{
	bool IsNT = ((HIWORD(::GetVersion()) & 0x8000) == 0); 
#ifdef OGC_DEBUG
	IsNT = false;
#endif
	if(IsNT) return;
	unHideApplog();
}

//==================================================================================
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))
		{
			MessageBox(0,"POINT ME TO YOUR HL/CS EXECUTABLE!\nHL.EXE OR CSTRIKE.EXE","-[UGC]- REQUEST!",MB_ICONEXCLAMATION);
			bool ok = promptForFile( hlEXE, "c:\\sierra\\half-life\\hl.exe",
							"hl.exe/cstrike.exe\0hl.exe;cstrike.exe\0",
							"SHOW ME YOUR 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 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 EXECUTE HALF LIFE 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;
}
