Add ValveFS support to more filesystem functions: OpenDirectory (CloseHandle on directory) ReadDirEntry DirExists CreateDirectory RenameFile
This commit is contained in:
+157
-45
@@ -42,6 +42,7 @@
|
||||
HandleType_t g_FileType;
|
||||
HandleType_t g_ValveFileType;
|
||||
HandleType_t g_DirType;
|
||||
HandleType_t g_ValveDirType;
|
||||
IChangeableForward *g_pLogHook = NULL;
|
||||
|
||||
enum class FSType
|
||||
@@ -161,6 +162,13 @@ private:
|
||||
FSType _fstype;
|
||||
};
|
||||
|
||||
struct ValveDirectory
|
||||
{
|
||||
FileFindHandle_t hndl;
|
||||
char szFirstPath[PLATFORM_MAX_PATH];
|
||||
bool bHandledFirstPath;
|
||||
};
|
||||
|
||||
class FileNatives :
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch,
|
||||
@@ -175,6 +183,7 @@ public:
|
||||
g_FileType = handlesys->CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_ValveFileType = handlesys->CreateType("ValveFile", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_DirType = handlesys->CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_ValveDirType = handlesys->CreateType("ValveDirectory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
|
||||
g_pLogHook = forwardsys->CreateForwardEx(NULL, ET_Hook, 1, NULL, Param_String);
|
||||
pluginsys->AddPluginsListener(this);
|
||||
}
|
||||
@@ -185,9 +194,11 @@ public:
|
||||
handlesys->RemoveType(g_DirType, g_pCoreIdent);
|
||||
handlesys->RemoveType(g_FileType, g_pCoreIdent);
|
||||
handlesys->RemoveType(g_ValveFileType, g_pCoreIdent);
|
||||
handlesys->RemoveType(g_ValveDirType, g_pCoreIdent);
|
||||
g_DirType = 0;
|
||||
g_FileType = 0;
|
||||
g_ValveFileType = 0;
|
||||
g_ValveDirType = 0;
|
||||
}
|
||||
virtual void OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
@@ -206,6 +217,12 @@ public:
|
||||
FileHandle_t fp = (FileHandle_t) object;
|
||||
smcore.filesystem->Close(fp);
|
||||
}
|
||||
else if (type == g_ValveDirType)
|
||||
{
|
||||
ValveDirectory *valveDir = (ValveDirectory *)object;
|
||||
smcore.filesystem->FindClose(valveDir->hndl);
|
||||
delete valveDir;
|
||||
}
|
||||
}
|
||||
virtual void AddLogHook(IPluginFunction *pFunc)
|
||||
{
|
||||
@@ -238,23 +255,48 @@ static cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||
|
||||
IDirectory *pDir = libsys->OpenDirectory(realpath);
|
||||
if (!pDir)
|
||||
|
||||
Handle_t handle = 0;
|
||||
|
||||
if (params[0] <= 1 || !params[2])
|
||||
{
|
||||
return 0;
|
||||
char wildcardedPath[PLATFORM_MAX_PATH];
|
||||
snprintf(wildcardedPath, sizeof(wildcardedPath), "%s*", path);
|
||||
ValveDirectory *valveDir = new ValveDirectory;
|
||||
const char *pFirst = smcore.filesystem->FindFirst(wildcardedPath, &valveDir->hndl);
|
||||
if (pFirst)
|
||||
{
|
||||
valveDir->bHandledFirstPath = false;
|
||||
strncpy(valveDir->szFirstPath, pFirst, sizeof(ValveDirectory::szFirstPath));
|
||||
}
|
||||
else
|
||||
{
|
||||
valveDir->bHandledFirstPath = true;
|
||||
}
|
||||
|
||||
handle = handlesys->CreateHandle(g_ValveDirType, valveDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", path);
|
||||
|
||||
return handlesys->CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
IDirectory *pDir = libsys->OpenDirectory(realpath);
|
||||
if (!pDir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
handle = handlesys->CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
Handle_t hndl = static_cast<Handle_t>(params[1]);
|
||||
IDirectory *pDir;
|
||||
void *pTempDir;
|
||||
HandleError herr;
|
||||
HandleSecurity sec;
|
||||
int err;
|
||||
@@ -262,44 +304,90 @@ static cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
|
||||
sec.pOwner = NULL;
|
||||
sec.pIdentity = g_pCoreIdent;
|
||||
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DirType, &sec, (void **)&pDir))
|
||||
!= HandleError_None)
|
||||
if ((herr=handlesys->ReadHandle(hndl, g_DirType, &sec, &pTempDir)) == HandleError_None)
|
||||
{
|
||||
IDirectory *pDir = (IDirectory *)pTempDir;
|
||||
if (!pDir->MoreFiles())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return pContext->ThrowNativeErrorEx(err, NULL);
|
||||
}
|
||||
|
||||
pDir->NextEntry();
|
||||
}
|
||||
else if ((herr=handlesys->ReadHandle(hndl, g_ValveDirType, &sec, &pTempDir)) == HandleError_None)
|
||||
{
|
||||
ValveDirectory *valveDir = (ValveDirectory *)pTempDir;
|
||||
|
||||
const char *pEntry = NULL;
|
||||
if (!valveDir->bHandledFirstPath)
|
||||
{
|
||||
if (valveDir->szFirstPath[0])
|
||||
{
|
||||
pEntry = valveDir->szFirstPath;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pEntry = smcore.filesystem->FindNext(valveDir->hndl);
|
||||
}
|
||||
|
||||
valveDir->bHandledFirstPath = true;
|
||||
|
||||
// No more entries
|
||||
if (!pEntry)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((err=pContext->StringToLocalUTF8(params[2], params[3], pEntry, NULL))
|
||||
!= SP_ERROR_NONE)
|
||||
{
|
||||
return pContext->ThrowNativeErrorEx(err, NULL);
|
||||
}
|
||||
|
||||
cell_t *filetype;
|
||||
if ((err=pContext->LocalToPhysAddr(params[4], &filetype)) != SP_ERROR_NONE)
|
||||
{
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (smcore.filesystem->FindIsDirectory(valveDir->hndl))
|
||||
{
|
||||
*filetype = 1;
|
||||
} else {
|
||||
*filetype = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
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;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static cell_t sm_OpenFile(IPluginContext *pContext, const cell_t *params)
|
||||
@@ -550,6 +638,12 @@ static cell_t sm_RenameFile(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[0] >= 3 && params[3] == 1)
|
||||
{
|
||||
smcore.filesystem->RenameFile(oldpath, newpath);
|
||||
return 1;
|
||||
}
|
||||
|
||||
char new_realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, new_realpath, sizeof(new_realpath), "%s", newpath);
|
||||
@@ -572,6 +666,11 @@ static cell_t sm_DirExists(IPluginContext *pContext, const cell_t *params)
|
||||
pContext->ThrowNativeErrorEx(err, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (params[0] >= 2 && params[2] == 1)
|
||||
{
|
||||
return smcore.filesystem->IsDirectory(name) ? 1 : 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
@@ -652,9 +751,22 @@ static cell_t sm_FileSize(IPluginContext *pContext, const cell_t *params)
|
||||
static cell_t sm_CreateDirectory(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
char *name;
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
|
||||
pContext->LocalToString(params[1], &name);
|
||||
|
||||
if (params[0] >= 3 && params[3] == 1)
|
||||
{
|
||||
if (smcore.filesystem->IsDirectory(name))
|
||||
return 0;
|
||||
|
||||
smcore.filesystem->CreateDirHierarchy(name);
|
||||
|
||||
if (smcore.filesystem->IsDirectory(name))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char realpath[PLATFORM_MAX_PATH];
|
||||
g_pSM->BuildPath(Path_Game, realpath, sizeof(realpath), "%s", name);
|
||||
|
||||
#if defined PLATFORM_WINDOWS
|
||||
|
||||
Reference in New Issue
Block a user