diff -r 7602d7fb60d9 -r 026da5437111 core/smn_filesystem.cpp --- a/core/smn_filesystem.cpp Fri Jul 11 06:51:21 2008 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,963 +0,0 @@ -/** - * vim: set ts=4 : - * ============================================================================= - * SourceMod - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved. - * ============================================================================= - * - * This program is free software; you can redistribute it and/or modify it under - * the terms of the GNU General Public License, version 3.0, as published by the - * Free Software Foundation. - * - * 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, see . - * - * As a special exception, AlliedModders LLC gives you permission to link the - * code of this program (as well as its derivative works) to "Half-Life 2," the - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software - * by the Valve Corporation. You must obey the GNU General Public License in - * all respects for all other code used. Additionally, AlliedModders LLC grants - * this exception to all derivative works. AlliedModders LLC defines further - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), - * or . - * - * Version: $Id$ - */ - -#include -#include "sm_globals.h" -#include "HandleSys.h" -#include "LibrarySys.h" -#include "sm_stringutil.h" -#include "Logger.h" -#include "PluginSys.h" -#include "sourcemm_api.h" -#include "ForwardSys.h" - -SH_DECL_HOOK1_void(IVEngineServer, LogPrint, SH_NOATTRIB, false, const char *); - -HandleType_t g_FileType; -HandleType_t g_DirType; -IChangeableForward *g_pLogHook = NULL; - -class FileNatives : - public SMGlobalClass, - public IHandleTypeDispatch, - public IPluginsListener -{ -public: - FileNatives() - { - m_bIsLoggingHooked = false; - } - virtual void OnSourceModAllInitialized() - { - g_FileType = g_HandleSys.CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL); - g_DirType = g_HandleSys.CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL); - g_pLogHook = g_Forwards.CreateForwardEx(NULL, ET_Hook, 1, NULL, Param_String); - g_PluginSys.AddPluginsListener(this); - } - virtual void OnSourceModShutdown() - { - g_PluginSys.RemovePluginsListener(this); - if (m_bIsLoggingHooked) - { - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false); - m_bIsLoggingHooked = false; - } - g_Forwards.ReleaseForward(g_pLogHook); - g_HandleSys.RemoveType(g_DirType, g_pCoreIdent); - g_HandleSys.RemoveType(g_FileType, g_pCoreIdent); - g_DirType = 0; - g_FileType = 0; - } - virtual void OnHandleDestroy(HandleType_t type, void *object) - { - if (type == g_FileType) - { - FILE *fp = (FILE *)object; - fclose(fp); - } - else if (type == g_DirType) - { - IDirectory *pDir = (IDirectory *)object; - g_LibSys.CloseDirectory(pDir); - } - } - virtual void OnPluginDestroyed(IPlugin *plugin) - { - if (m_bIsLoggingHooked && g_pLogHook->GetFunctionCount() == 0) - { - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false); - m_bIsLoggingHooked = false; - } - } - virtual void AddLogHook(IPluginFunction *pFunc) - { - if (!m_bIsLoggingHooked) - { - SH_ADD_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false); - m_bIsLoggingHooked = true; - } - - g_pLogHook->AddFunction(pFunc); - } - virtual void RemoveLogHook(IPluginFunction *pFunc) - { - g_pLogHook->RemoveFunction(pFunc); - - if (m_bIsLoggingHooked && g_pLogHook->GetFunctionCount() == 0) - { - SH_REMOVE_HOOK_MEMFUNC(IVEngineServer, LogPrint, engine, this, &FileNatives::LogPrint, false); - m_bIsLoggingHooked = false; - } - } - virtual void LogPrint(const char *msg) - { - cell_t result; - - result = 0; - - g_in_game_log_hook = true; - g_pLogHook->PushString(msg); - g_pLogHook->Execute(&result); - g_in_game_log_hook = false; - - if (result >= Pl_Handled) - { - RETURN_META(MRES_SUPERCEDE); - } - } -private: - bool m_bIsLoggingHooked; -} s_FileNatives; - -static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params) -{ - char *path; - int err; - if ((err=pContext->LocalToString(params[1], &path)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path); - - IDirectory *pDir = g_LibSys.OpenDirectory(realpath); - if (!pDir) - { - return 0; - } - - return g_HandleSys.CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL); -} - -static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - IDirectory *pDir; - HandleError herr; - HandleSecurity sec; - int err; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, &sec, (void **)&pDir)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - if (!pDir->MoreFiles()) - { - return false; - } - - cell_t *filetype; - if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - if (pDir->IsEntryDirectory()) - { - *filetype = 1; - } else if (pDir->IsEntryFile()) { - *filetype = 2; - } else { - *filetype = 0; - } - - const char *path = pDir->GetEntryName(); - if ((err=pContext->StringToLocalUTF8(params[2], params[3], path, NULL)) - != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - pDir->NextEntry(); - - return true; -} - -static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params) -{ - char *name, *mode; - int err; - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - if ((err=pContext->LocalToString(params[2], &mode)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); - - FILE *pFile = fopen(realpath, mode); - if (!pFile) - { - return 0; - } - - return g_HandleSys.CreateHandle(g_FileType, pFile, pContext->GetIdentity(), g_pCoreIdent, NULL); -} - -static cell_t sm_DeleteFile(IPluginContext *pContext, const cell_t *params) -{ - char *name; - int err; - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); - - return (unlink(realpath)) ? 0 : 1; -} - -static cell_t sm_ReadFileLine(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - int err; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - char *buf; - if ((err=pContext->LocalToString(params[2], &buf)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - if (fgets(buf, params[3], pFile) == NULL) - { - return 0; - } - - return 1; -} - -static cell_t sm_IsEndOfFile(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - return (feof(pFile)) ? 1 : 0; -} - -static cell_t sm_FileSeek(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - fseek(pFile, params[2], params[3]); - - return 1; -} - -static cell_t sm_FilePosition(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - return ftell(pFile); -} - -static cell_t sm_FileExists(IPluginContext *pContext, const cell_t *params) -{ - char *name; - int err; - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - if (params[0] >= 2 && params[2] == 1) - { - return basefilesystem->FileExists(name) ? 1 : 0; - } - - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); -#ifdef PLATFORM_WINDOWS - struct _stat s; - if (_stat(realpath, &s) != 0) - { - return 0; - } - if (s.st_mode & S_IFREG) - { - return 1; - } - return 0; -#elif defined PLATFORM_POSIX - struct stat s; - if (stat(realpath, &s) != 0) - { - return 0; - } - if (S_ISREG(s.st_mode)) - { - return 1; - } - return 0; -#endif -} - -static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params) -{ - char *newpath, *oldpath; - int err; - if ((err=pContext->LocalToString(params[1], &newpath)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - if ((err=pContext->LocalToString(params[2], &oldpath)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - char new_realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, new_realpath, sizeof(new_realpath), "%s", newpath); - char old_realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, old_realpath, sizeof(old_realpath), "%s", oldpath); - -#ifdef PLATFORM_WINDOWS - return (MoveFileA(old_realpath, new_realpath)) ? 1 : 0; -#elif defined PLATFORM_POSIX - return (rename(old_realpath, new_realpath)) ? 0 : 1; -#endif -} - -static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params) -{ - char *name; - int err; - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); -#ifdef PLATFORM_WINDOWS - struct _stat s; - if (_stat(realpath, &s) != 0) - { - return 0; - } - if (s.st_mode & S_IFDIR) - { - return 1; - } - return 0; -#elif defined PLATFORM_POSIX - struct stat s; - if (stat(realpath, &s) != 0) - { - return 0; - } - if (S_ISDIR(s.st_mode)) - { - return 1; - } - return 0; -#endif -} - -static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params) -{ - char *name; - int err; - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return -1; - } - - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); -#ifdef PLATFORM_WINDOWS - struct _stat s; - if (_stat(realpath, &s) != 0) - { - return -1; - } - if (s.st_mode & S_IFREG) - { - return static_cast(s.st_size); - } - return -1; -#elif defined PLATFORM_POSIX - struct stat s; - if (stat(realpath, &s) != 0) - { - return -1; - } - if (S_ISREG(s.st_mode)) - { - return static_cast(s.st_size); - } - return -1; -#endif -} - -static cell_t sm_RemoveDir(IPluginContext *pContext, const cell_t *params) -{ - char *name; - int err; - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); - - return (rmdir(realpath)) ? 0 : 1; -} - -static cell_t sm_WriteFileLine(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - char *fmt; - int err; - if ((err=pContext->LocalToString(params[2], &fmt)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - char buffer[2048]; - int arg = 3; - atcprintf(buffer, sizeof(buffer), fmt, pContext, params, &arg); - fprintf(pFile, "%s\n", buffer); - - return 1; -} - -static cell_t sm_FlushFile(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - return (fflush(pFile) == 0) ? 1 : 0; -} - -static cell_t sm_BuildPath(IPluginContext *pContext, const cell_t *params) -{ - char path[PLATFORM_MAX_PATH], *fmt, *buffer; - int arg = 5; - pContext->LocalToString(params[2], &buffer); - pContext->LocalToString(params[4], &fmt); - - atcprintf(path, sizeof(path), fmt, pContext, params, &arg); - - return g_SourceMod.BuildPath(Path_SM_Rel, buffer, params[3], "%s", path); -} - -static cell_t sm_LogToGame(IPluginContext *pContext, const cell_t *params) -{ - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - - char buffer[1024]; - size_t len = g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - return 0; - } - - if (len >= sizeof(buffer)-2) - { - buffer[1022] = '\n'; - buffer[1023] = '\0'; - } else { - buffer[len++] = '\n'; - buffer[len] = '\0'; - } - - Engine_LogPrintWrapper(buffer); - - return 1; -} - -static cell_t sm_LogMessage(IPluginContext *pContext, const cell_t *params) -{ - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - - char buffer[1024]; - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - return 0; - } - - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext()); - g_Logger.LogMessage("[%s] %s", pPlugin->GetFilename(), buffer); - - return 1; -} - -static cell_t sm_LogError(IPluginContext *pContext, const cell_t *params) -{ - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - - char buffer[1024]; - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 1); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - return 0; - } - - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext()); - g_Logger.LogError("[%s] %s", pPlugin->GetFilename(), buffer); - - return 1; -} - -static cell_t sm_GetFileTime(IPluginContext *pContext, const cell_t *params) -{ - char *name; - int err; - if ((err=pContext->LocalToString(params[1], &name)) != SP_ERROR_NONE) - { - pContext->ThrowNativeErrorEx(err, NULL); - return 0; - } - - time_t time_val; - char realpath[PLATFORM_MAX_PATH]; - g_SourceMod.BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name); - - if (!g_LibSys.FileTime(realpath, (FileTimeType)params[2], &time_val)) - { - return -1; - } - - return (cell_t)time_val; -} - -static cell_t sm_LogToOpenFile(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - char buffer[2048]; - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - return 0; - } - - CPlugin *pPlugin = g_PluginSys.GetPluginByCtx(pContext->GetContext()); - g_Logger.LogToOpenFile(pFile, "[%s] %s", pPlugin->GetFilename(), buffer); - - return 1; -} - -static cell_t sm_LogToOpenFileEx(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec; - FILE *pFile; - - sec.pOwner = NULL; - sec.pIdentity = g_pCoreIdent; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - char buffer[2048]; - g_SourceMod.SetGlobalTarget(SOURCEMOD_SERVER_LANGUAGE); - g_SourceMod.FormatString(buffer, sizeof(buffer), pContext, params, 2); - - if (pContext->GetLastNativeError() != SP_ERROR_NONE) - { - return 0; - } - - g_Logger.LogToOpenFile(pFile, "%s", buffer); - - return 1; -} - -static cell_t sm_ReadFile(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - FILE *pFile; - size_t read = 0; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - if (params[4] != 1 && params[4] != 2 && params[4] != 4) - { - return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); - } - - cell_t *data; - pContext->LocalToPhysAddr(params[2], &data); - - if (params[4] == 4) - { - read = fread(data, sizeof(cell_t), params[3], pFile); - } - else if (params[4] == 2) - { - int16_t val; - for (cell_t i = 0; i < params[3]; i++) - { - if (fread(&val, sizeof(int16_t), 1, pFile) != 1) - { - break; - } - data[read++] = val; - } - } - else if (params[4] == 1) - { - int8_t val; - for (cell_t i = 0; i < params[3]; i++) - { - if (fread(&val, sizeof(int8_t), 1, pFile) != 1) - { - break; - } - data[read++] = val; - } - } - - if (read != (size_t)params[3] && ferror(pFile) != 0) - { - return -1; - } - - return read; -} - -static cell_t sm_ReadFileString(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - FILE *pFile; - cell_t num_read = 0; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - char *buffer; - pContext->LocalToString(params[2], &buffer); - - char val; - while (1) - { - /* If we're in stop mode, break as soon as the buffer is full. */ - if (params[4] && (params[3] == 0 || num_read >= params[3] - 1)) - { - break; - } - if (fread(&val, sizeof(val), 1, pFile) != 1) - { - if (ferror(pFile)) - { - return -1; - } - break; - } - if (val == '\0') - { - break; - } - if (params[3] > 0 && num_read < params[3] - 1) - { - buffer[num_read++] = val; - } - } - - if (params[3] > 0) - { - buffer[num_read] = '\0'; - } - - return num_read; -} - -static cell_t sm_WriteFile(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - FILE *pFile; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - cell_t *data; - pContext->LocalToPhysAddr(params[2], &data); - - if (params[4] != 1 && params[4] != 2 && params[4] != 4) - { - return pContext->ThrowNativeError("Invalid size specifier (%d is not 1, 2, or 4)", params[4]); - } - - /* :NOTE: This really isn't compatible with big endian but we will never have to worry about that. */ - - if (params[4] == 4) - { - if (fwrite(data, sizeof(cell_t), params[3], pFile) != (size_t)params[3]) - { - return 0; - } - } - else if (params[4] == 2) - { - for (cell_t i = 0; i < params[3]; i++) - { - if (fwrite(&data[i], sizeof(int16_t), 1, pFile) != 1) - { - return 0; - } - } - } - else if (params[4] == 1) - { - for (cell_t i = 0; i < params[3]; i++) - { - if (fwrite(&data[i], sizeof(int8_t), 1, pFile) != 1) - { - return 0; - } - } - } - - return 1; -} - -static cell_t sm_WriteFileString(IPluginContext *pContext, const cell_t *params) -{ - Handle_t hndl = static_cast(params[1]); - HandleError herr; - HandleSecurity sec(pContext->GetIdentity(), g_pCoreIdent); - FILE *pFile; - - if ((herr=g_HandleSys.ReadHandle(hndl, g_FileType, &sec, (void **)&pFile)) - != HandleError_None) - { - return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr); - } - - char *buffer; - pContext->LocalToString(params[2], &buffer); - - size_t len = strlen(buffer); - - if (params[3]) - { - len++; - } - - return (fwrite(buffer, sizeof(char), len, pFile) == len) ? 1 : 0; -} - -static cell_t sm_AddGameLogHook(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunction; - - if ((pFunction=pContext->GetFunctionById(params[1])) == NULL) - { - return pContext->ThrowNativeError("Function id %x is invalid", params[1]); - } - - s_FileNatives.AddLogHook(pFunction); - - return 1; -} - -static cell_t sm_RemoveGameLogHook(IPluginContext *pContext, const cell_t *params) -{ - IPluginFunction *pFunction; - - if ((pFunction=pContext->GetFunctionById(params[1])) == NULL) - { - return pContext->ThrowNativeError("Function id %x is invalid", params[1]); - } - - s_FileNatives.RemoveLogHook(pFunction); - - return 1; -} - -REGISTER_NATIVES(filesystem) -{ - {"OpenDirectory", sm_OpenDirectory}, - {"ReadDirEntry", sm_ReadDirEntry}, - {"OpenFile", sm_OpenFile}, - {"DeleteFile", sm_DeleteFile}, - {"ReadFileLine", sm_ReadFileLine}, - {"IsEndOfFile", sm_IsEndOfFile}, - {"FileSeek", sm_FileSeek}, - {"FilePosition", sm_FilePosition}, - {"FileExists", sm_FileExists}, - {"RenameFile", sm_RenameFile}, - {"DirExists", sm_DirExists}, - {"FileSize", sm_FileSize}, - {"RemoveDir", sm_RemoveDir}, - {"WriteFileLine", sm_WriteFileLine}, - {"BuildPath", sm_BuildPath}, - {"LogToGame", sm_LogToGame}, - {"LogMessage", sm_LogMessage}, - {"LogError", sm_LogError}, - {"FlushFile", sm_FlushFile}, - {"GetFileTime", sm_GetFileTime}, - {"LogToOpenFile", sm_LogToOpenFile}, - {"LogToOpenFileEx", sm_LogToOpenFileEx}, - {"ReadFile", sm_ReadFile}, - {"ReadFileString", sm_ReadFileString}, - {"WriteFile", sm_WriteFile}, - {"WriteFileString", sm_WriteFileString}, - {"AddGameLogHook", sm_AddGameLogHook}, - {"RemoveGameLogHook", sm_RemoveGameLogHook}, - {NULL, NULL}, -};