Subversion Repositories WoWGM

Rev

Rev 31 | Rev 34 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3 tristanc 1
#include "pch.h"
2
#pragma hdrstop
3
 
4
#include "ConsoleClient.h"
5
#include <Os/W32/OsFile.h>
6
 
32 tristanc 7
 
3 tristanc 8
/****************************************************************************
9
*
31 tristanc 10
*   Client memory addresses
3 tristanc 11
*
12
***/
13
 
32 tristanc 14
#define  CONSOLECOMMANDDESTROY  0x007685C0
3 tristanc 15
 
16
 
31 tristanc 17
/****************************************************************************
18
*
19
*   Client symbol pointers
20
*
21
***/
22
 
23
void (*ConsoleCommandDestroyPtr)() = *(void(*)())CONSOLECOMMANDDESTROY;
24
 
25
 
26
/****************************************************************************
27
*
32 tristanc 28
*   Private
31 tristanc 29
*
30
***/
31
 
32
static char s_fileName[260] = {};
33
 
3 tristanc 34
//===========================================================================
31 tristanc 35
void ConsoleCommandDestroy () {
3 tristanc 36
	// Remove the function trampoline
37
	DETOUR_INIT;
38
	DETOUR_DETACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
39
	DETOUR_COMMIT;
40
 
32 tristanc 41
	// Unregister our own commands
3 tristanc 42
	ConsoleCommandUnregister("new");
43
	ConsoleCommandUnregister("run");
44
	ConsoleCommandUnregister("end");
21 tristanc 45
	ConsoleCommandUnregister("ver");
3 tristanc 46
 
32 tristanc 47
	// Call the original function to handle clean-up
3 tristanc 48
	ConsoleCommandDestroyPtr();
49
}
50
 
31 tristanc 51
//===========================================================================
32 tristanc 52
BOOL ValidateFileName (char const* fileName) {
31 tristanc 53
  if (fileName && *fileName) {
54
    if (strstr(fileName,"..") || strstr(fileName,"\\")) {
55
      ConsoleWrite("File Name cannot contain '\\' or '..'",ERROR_COLOR);
56
      return FALSE;
57
    }
3 tristanc 58
 
32 tristanc 59
    char const* fileExtension = strrchr(fileName,'.');
31 tristanc 60
    if (fileExtension&& *fileExtension) {
61
      if (_strcmpi(fileExtension,".wtf")) {
62
        ConsoleWrite("Only '.wtf' extensions are allowed",ERROR_COLOR);
63
        return FALSE;
64
      }
65
    }
66
    return TRUE;
67
  }
3 tristanc 68
 
31 tristanc 69
  return FALSE;
3 tristanc 70
}
71
 
72
//===========================================================================
31 tristanc 73
BOOL CreateWTFFilePath (char* filePath, unsigned int size) {
11 tristanc 74
	char buffer[FILENAME_MAX] = {};
3 tristanc 75
 
76
	if (filePath && *filePath && size != 0) {
11 tristanc 77
		SStrCopy(buffer,"WTF\\",FILENAME_MAX);
78
		strncat_s(buffer,filePath,FILENAME_MAX);
3 tristanc 79
 
80
		char* extension = strrchr(filePath,'.');
81
		if (extension && *extension) {
82
			if (_strcmpi(extension,".wtf")) {
83
				ConsoleWrite("File must have '.wtf' extension",ERROR_COLOR);
84
				return FALSE;
85
			}
86
		}
87
		else {
11 tristanc 88
			strncat_s(buffer,".wtf",FILENAME_MAX);
3 tristanc 89
		}
11 tristanc 90
		SStrCopy(filePath,buffer,FILENAME_MAX);
3 tristanc 91
		return TRUE;
92
	}
31 tristanc 93
 
3 tristanc 94
	return FALSE;
95
}
96
 
97
 
98
/****************************************************************************
99
*
31 tristanc 100
*   Command definitions
3 tristanc 101
*
102
***/
103
 
104
//===========================================================================
32 tristanc 105
BOOL ConsoleCommand_CreateExec (char const* cmd, char const* arguments) {
31 tristanc 106
	if (ValidateFileName(arguments)) {
11 tristanc 107
		char folder[FILENAME_MAX] = {};
108
		char filePath[FILENAME_MAX] = {};
3 tristanc 109
 
11 tristanc 110
		SStrCopy(s_fileName,arguments,FILENAME_MAX);
111
		SStrCopy(filePath,s_fileName,FILENAME_MAX);
3 tristanc 112
 
11 tristanc 113
		if (CreateWTFFilePath(filePath,FILENAME_MAX)) {
3 tristanc 114
			if (OsFileExists(filePath)) {
115
				ConsoleWrite("File exists are you sure you want to Overwrite Y / N ? ",WARNING_COLOR);
116
				g_ExecCreateMode = EM_PROMPTOVERWRITE;
117
			}
118
			else {
11 tristanc 119
				SStrCopy(folder,filePath,FILENAME_MAX);
3 tristanc 120
 
121
				char* dirName = strrchr(folder,'\\');
122
				if (dirName)
123
					*dirName = 0;
124
 
125
				if (OsDirectoryExists(folder)) {
126
					g_ExecCreateMode = EM_RECORDING;
127
					ConsoleWrite("Begin Typing the commands",ECHO_COLOR);
128
				}
129
				else {
32 tristanc 130
					g_ExecCreateMode = EM_NOTACTIVE;
3 tristanc 131
					ConsoleWrite("Error! WTF folder does not exist.",ERROR_COLOR);
132
				}
133
			}
134
		}
135
	}
32 tristanc 136
 
31 tristanc 137
	return FALSE;
3 tristanc 138
}
139
 
140
//===========================================================================
32 tristanc 141
BOOL ConsoleCommand_CloseExec (char const* cmd, char const* arguments) {
31 tristanc 142
	BOOL result = FALSE;
32 tristanc 143
 
3 tristanc 144
	if (g_ExecCreateMode < EM_APPEND || g_ExecCreateMode > EM_WRITEFILE)
145
	{
146
		ConsoleWrite("You must type 'new' 'filename' to begin creating an Exec file",WARNING_COLOR);
147
		result = TRUE;
148
	}
149
	else
150
	{
11 tristanc 151
		char filePath[FILENAME_MAX] = {};
152
		SStrCopy(filePath, s_fileName, FILENAME_MAX);
3 tristanc 153
 
32 tristanc 154
		if (CreateWTFFilePath(filePath, FILENAME_MAX)) {
3 tristanc 155
			HANDLE hFile = OsCreateFile(filePath,FILE_ALL_ACCESS,0,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,(HANDLE)0x3F3F3F3F);
156
			if (hFile == INVALID_HANDLE_VALUE)
157
				ConsoleWrite("Error trying to create the file.",ERROR_COLOR);
32 tristanc 158
			else {
3 tristanc 159
				if (g_ExecCreateMode == EM_APPEND)
160
					OsSetFilePointer(hFile,CREATE_ALWAYS,0i64);
161
 
162
				DWORD count = 0;
11 tristanc 163
				DWORD bufLen = SStrLen(g_ExecBuffer);
3 tristanc 164
				COLOR_T color;
165
				const char *str;
32 tristanc 166
 
3 tristanc 167
				OsWriteFile(hFile,g_ExecBuffer,bufLen,&count);
32 tristanc 168
 
169
				if (count) {
3 tristanc 170
					color = ECHO_COLOR;
171
					str = "File written successfully";
172
				}
32 tristanc 173
				else {
3 tristanc 174
					color = ERROR_COLOR;
175
					str = "Error Writing ExecFile";
176
				}
32 tristanc 177
 
3 tristanc 178
				ConsoleWrite(str,color);
179
				OsCloseFile(hFile);
180
			}
181
		}
32 tristanc 182
 
3 tristanc 183
		g_ExecCreateMode = EM_NOTACTIVE;
184
		memset(g_ExecBuffer,'\0',sizeof(g_ExecBuffer));
185
		result = TRUE;
186
	}
31 tristanc 187
 
3 tristanc 188
	return result;
189
}
190
 
191
//===========================================================================
32 tristanc 192
BOOL ConsoleCommand_RunExec (char const* command, char const* arguments) {
31 tristanc 193
	BOOL result = FALSE;
11 tristanc 194
	char filename[FILENAME_MAX] = { '\0' };
195
	char tmp[FILENAME_MAX] = { '\0' };
3 tristanc 196
	char lineBuffer[128] = { '\0' };
197
	char param1[32] = { '\0' };
198
	DWORD bytes;
32 tristanc 199
	int verbose = 0;
3 tristanc 200
 
32 tristanc 201
	if (sscanf_s(arguments, "%260s %32s", filename, sizeof(filename), param1, sizeof(param1)) != 0) {
3 tristanc 202
		if (!_strcmpi(param1, "verbose"))
203
			verbose = 1;
32 tristanc 204
 
3 tristanc 205
		result = CreateWTFFilePath(filename, 260u);
32 tristanc 206
		if (result) {
3 tristanc 207
			HANDLE hFile = OsCreateFile(filename, GENERIC_READ, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
208
			DWORD fileSize = GetFileSize(hFile, NULL);
32 tristanc 209
 
210
			char* readData = (char *)calloc(1, fileSize+1);
211
			if (!readData) {
3 tristanc 212
				ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
32 tristanc 213
				return FALSE;
3 tristanc 214
			}
32 tristanc 215
 
216
			if (OsReadFile(hFile, readData, fileSize, &bytes)) {
217
				char* bufferPtr = (char *)calloc(1, bytes+1);
218
				if (!bufferPtr) {
3 tristanc 219
					ConsoleWriteA("ConsoleCommand_RunExec, Line %d: call to calloc() failed", ERROR_COLOR, __LINE__);
32 tristanc 220
					return FALSE;
3 tristanc 221
				}
32 tristanc 222
 
3 tristanc 223
				memcpy((void*)bufferPtr, readData, bytes);
32 tristanc 224
 
225
				if (bufferPtr) {
226
					char* token = 0;
227
					char* nextToken = 0;
228
 
3 tristanc 229
					token = strtok_s(bufferPtr, "\r\n", &nextToken);
32 tristanc 230
					if (token) {
231
						do {
11 tristanc 232
							SStrCopy(lineBuffer, token, 128u);
32 tristanc 233
 
234
							if (lineBuffer[0]) {
235
								if (verbose) {
11 tristanc 236
									_snprintf(tmp, FILENAME_MAX, "Executing ->%s", lineBuffer);
3 tristanc 237
									ConsoleWrite(tmp, ECHO_COLOR);
238
								}
32 tristanc 239
 
3 tristanc 240
								ConsoleCommandExecute(lineBuffer, 0);
241
							}
32 tristanc 242
 
3 tristanc 243
							token = strtok_s(NULL, "\r\n", &nextToken);
244
						} while (token && *token);
245
					}
246
					else
32 tristanc 247
						result = FALSE;
248
 
3 tristanc 249
					free((void*)bufferPtr);
250
				}
251
				else
32 tristanc 252
					result = FALSE;
3 tristanc 253
			}
32 tristanc 254
			else {
3 tristanc 255
				if (*command)
11 tristanc 256
					_snprintf(tmp, FILENAME_MAX, "Unable to load file %s", filename);
3 tristanc 257
				else
11 tristanc 258
					_snprintf(tmp, FILENAME_MAX, "Unknown command: %s", arguments);
32 tristanc 259
 
3 tristanc 260
				ConsoleWrite(tmp, ERROR_COLOR);
32 tristanc 261
				result = FALSE;
3 tristanc 262
			}
32 tristanc 263
 
3 tristanc 264
			OsCloseFile(hFile);
265
			free(readData);
266
		}
267
	}
32 tristanc 268
	else {
3 tristanc 269
		ConsoleWrite("Invalid number of parameters", ERROR_COLOR);
270
		ConsoleCommandWriteHelp(command);
271
	}
31 tristanc 272
 
3 tristanc 273
	return result;
274
}
275
 
21 tristanc 276
//===========================================================================
277
BOOL ConsoleCommand_Ver (LPCSTR command, LPCSTR args) {
278
#ifdef NDEBUG
279
	ConsoleWriteA("WoW [Release] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
280
#else
281
	ConsoleWriteA("WoW [Debug] Build 12340 (%s)", DEFAULT_COLOR, __DATE__);
282
#endif
283
	return TRUE;
284
}
3 tristanc 285
 
21 tristanc 286
 
3 tristanc 287
/****************************************************************************
288
*
32 tristanc 289
*   External
3 tristanc 290
*
291
***/
292
 
293
//===========================================================================
31 tristanc 294
void ConsoleCommandInitialize () {
3 tristanc 295
	DETOUR_INIT;
296
	DETOUR_ATTACH(ConsoleCommandDestroyPtr,ConsoleCommandDestroy);
297
	DETOUR_COMMIT;
298
 
21 tristanc 299
	ConsoleCommandUnregister("ver");
32 tristanc 300
	ConsoleCommandRegister("ver",ConsoleCommand_Ver,DEFAULT,NOHELP);
3 tristanc 301
	ConsoleCommandRegister("new",ConsoleCommand_CreateExec,CONSOLE,"[File Name] starts recording a new script");
302
	ConsoleCommandRegister("run",ConsoleCommand_RunExec,CONSOLE,"[File Name] Runs a wtf file from the WTF folder");
303
	ConsoleCommandRegister("end",ConsoleCommand_CloseExec,CONSOLE,"Stops recording script");
304
}
32 tristanc 305