add in WHB helpers for PCFS/HFIO

this mirrors the SD helpers but for Host File I/O, and PCFS when
interacting with devkits. Most of these functions are pretty much
beat for beat the same as the SD functions, the only real difference
is the introduction of Well Known Host Directories which are the
recommended way of referencing several 'PATHs' that a developer would
commonly use without needing to hardcode paths.
This commit is contained in:
Cynthia
2026-01-28 05:38:47 +00:00
parent afa43f676d
commit 82e0ccfbd7
2 changed files with 195 additions and 0 deletions

View File

@@ -0,0 +1,73 @@
#pragma once
#include <wut.h>
/**
* \defgroup whb_hfio Host I/O access
* \ingroup whb
* @{
*/
#ifdef __cplusplus
extern "C" {
#endif
typedef enum WHBWellKnownHostDirectory
{
//! A way to quickly reference the emulated MLC directory on a attached host
//! pc.
//!
//! You should prefer to use this for compatability (as it will be the same
//! across systems, even with separate paths), and it will usually be fewer
//! characters meaning the actual path can be used by more of the important
//! stuff.
WHB_MLC_HOST_DIRECTORY = 0,
//! A way to quickly reference the emulated SLC directory on a attached host
//! pc.
//!
//! You should prefer to use this for compatability (as it will be the same
//! across systems, even with separate paths), and it will usually be fewer
//! characters meaning the actual path can be used by more of the important
//! stuff.
WHB_SLC_HOST_DIRECTORY = 1,
//! A way to quickly reference the emulated directory of the 'optical disc'
//! on a attached host pc.
//!
//! You should prefer to use this for compatability (as it will be the same
//! across systems, even with separate paths), and it will usually be fewer
//! characters meaning the actual path can be used by more of the important
//! stuff.
WHB_DISC_HOST_DIRECTORY = 2,
//! A way to quickly reference the emulated directory of the current titles
//! save directory.
//!
//! You should prefer to use this for compatability (as it will be the same
//! across systems, even with separate paths), and it will usually be fewer
//! characters meaning the actual path can be used by more of the important
//! stuff.
WHB_SAVE_HOST_DIRECTORY = 3,
//! A way to quickly reference an attached network drive of the host pc.
//!
//! You should prefer to use this for compatability (as it will be the same
//! across systems, even with separate paths), and it will usually be fewer
//! characters meaning the actual path can be used by more of the important
//! stuff.
WHB_NETWORK_DRIVE_HOST_DIRECTORY = 4,
} WHBWellKnownHostDirectory;
BOOL
WHBMountHostFileIO();
char *
WHBGetHostFileIOMountPath();
char *
WHBPathForWellKnownHostDirectory(WHBWellKnownHostDirectory directory);
BOOL
WHBUnmountHostFileIO();
#ifdef __cplusplus
}
#endif
/** @} */

122
libraries/libwhb/src/hfio.c Normal file
View File

@@ -0,0 +1,122 @@
#include <coreinit/filesystem.h>
#include <coreinit/memdefaultheap.h>
#include <string.h>
#include <whb/hfio.h>
#include <whb/log.h>
static BOOL
sHFIOMounted = FALSE;
static char
sHFIOMountPath[128] = {0};
static FSClient
sHFIOClient;
BOOL
WHBMountHostFileIO()
{
FSCmdBlock cmd;
FSMountSource mountSource;
FSStatus result;
if (sHFIOMounted) {
return TRUE;
}
FSInit();
result = FSAddClient(&sHFIOClient, FS_ERROR_FLAG_ALL);
if (result != FS_STATUS_OK) {
WHBLogPrintf("%s: FSAddClient error %d", __FUNCTION__, result);
return FALSE;
}
FSInitCmdBlock(&cmd);
result = FSGetMountSource(&sHFIOClient, &cmd, FS_MOUNT_SOURCE_HFIO, &mountSource, FS_ERROR_FLAG_ALL);
if (result < 0) {
WHBLogPrintf("%s: FSGetMountSource error %d", __FUNCTION__, result);
goto fail;
}
result = FSMount(&sHFIOClient, &cmd, &mountSource, sHFIOMountPath, sizeof(sHFIOMountPath), FS_ERROR_FLAG_ALL);
if (result < 0) {
WHBLogPrintf("%s: FSMount error %d", __FUNCTION__, result);
goto fail;
}
sHFIOMounted = TRUE;
return TRUE;
fail:
FSDelClient(&sHFIOClient, FS_ERROR_FLAG_ALL);
return FALSE;
}
char *
WHBGetHostFileIOMountPath()
{
return sHFIOMountPath;
}
char *
WHBPathForWellKnownHostDirectory(WHBWellKnownHostDirectory directory)
{
// The host path is 128 bytes, and the maximum we can append is 15 bytes, for a final size of 143.
char *finalPath = (char *)MEMAllocFromDefaultHeap(143);
if (finalPath == NULL) {
return NULL;
}
// Ensure we get a NULL terminator, mimic calloc.
memset(finalPath, 0, 143);
strcat(finalPath, sHFIOMountPath);
strcat(finalPath, "/");
switch (directory) {
case WHB_MLC_HOST_DIRECTORY:
strcat(finalPath, "%MLC_EMU_DIR");
break;
case WHB_SLC_HOST_DIRECTORY:
strcat(finalPath, "%SLC_EMU_DIR");
break;
case WHB_DISC_HOST_DIRECTORY:
strcat(finalPath, "%DISC_EMU_DIR");
break;
case WHB_SAVE_HOST_DIRECTORY:
strcat(finalPath, "%SAVE_EMU_DIR");
break;
case WHB_NETWORK_DRIVE_HOST_DIRECTORY:
strcat(finalPath, "%NETWORK");
break;
}
return finalPath;
}
BOOL
WHBUnmountHostFileIO()
{
FSCmdBlock cmd;
FSStatus result;
if (!sHFIOMounted) {
return TRUE;
}
FSInitCmdBlock(&cmd);
result = FSUnmount(&sHFIOClient, &cmd, sHFIOMountPath, FS_ERROR_FLAG_ALL);
if (result < 0) {
WHBLogPrintf("%s: FSUnmount error %d", __FUNCTION__, result);
return FALSE;
}
result = FSDelClient(&sHFIOClient, FS_ERROR_FLAG_ALL);
if (result < 0) {
WHBLogPrintf("%s: FSDelClient error %d", __FUNCTION__, result);
return FALSE;
}
sHFIOMounted = FALSE;
return TRUE;
}