diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index 4f276c014..c14b54194 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -261,16 +261,124 @@ typedef enum { FsGameCardPartition_Logo = 3, ///< [4.0.0+] } FsGameCardPartition; +typedef enum { + FsMmcPartition_UserData = 0, + FsMmcPartition_BootPartition1 = 1, + FsMmcPartition_BootPartition2 = 2, +} FsMmcPartition; + +typedef enum { + FsGameCardClockRate_ClockRate25MHz = 25, + FsGameCardClockRate_ClockRate50MHz = 50, +} FsGameCardClockRate; + +typedef enum { + FsGameCardSize_Size1GB = 1, + FsGameCardSize_Size2GB = 2, + FsGameCardSize_Size4GB = 4, + FsGameCardSize_Size8GB = 8, + FsGameCardSize_Size16GB = 16, + FsGameCardSize_Size32GB = 32, +} FsGameCardSize; + +typedef enum { + FsGameCardCompatibilityType_Global = 0, + FsGameCardCompatibilityType_China = 1, +} FsGameCardCompatibilityType; + +typedef enum { + FsSdCardSpeedMode_Identification = 0, + FsSdCardSpeedMode_DefaultSpeed = 1, + FsSdCardSpeedMode_HighSpeed = 2, + FsSdCardSpeedMode_Sdr12 = 3, + FsSdCardSpeedMode_Sdr25 = 4, + FsSdCardSpeedMode_Sdr50 = 5, + FsSdCardSpeedMode_Sdr104 = 6, + FsSdCardSpeedMode_Ddr50 = 7, + FsSdCardSpeedMode_Unknown = 8, +} FsSdCardSpeedMode; + +typedef enum { + FsMmcSpeedMode_Identification = 0, + FsMmcSpeedMode_LegacySpeed = 1, + FsMmcSpeedMode_HighSpeed = 2, + FsMmcSpeedMode_Hs200 = 3, + FsMmcSpeedMode_Hs400 = 4, + FsMmcSpeedMode_Unknown = 5, +} FsMmcSpeedMode; + +typedef enum { + FsSpeedEmulationMode_None = 0, + FsSpeedEmulationMode_Faster = 1, + FsSpeedEmulationMode_Slower = 2, + FsSpeedEmulationMode_Random = 3, +} FsSpeedEmulationMode; + +typedef enum { + FsSimulatingDeviceType_Mmc = 0, + FsSimulatingDeviceType_SdCard = 1, + FsSimulatingDeviceType_GameCard = 2, +} FsSimulatingDeviceType; + +typedef enum { + FsSimulatingDeviceDetectionMode_NoSimulation = 0, + FsSimulatingDeviceDetectionMode_DeviceAttached = 1, + FsSimulatingDeviceDetectionMode_DeviceRemoved = 2, +} FsSimulatingDeviceDetectionMode; + +typedef enum { + FsSimulatingDeviceAccessFailureEventType_None = 0, + FsSimulatingDeviceAccessFailureEventType_AccessTimeoutFailure = 1, + FsSimulatingDeviceAccessFailureEventType_AccessFailure = 2, + FsSimulatingDeviceAccessFailureEventType_DataCorruption = 3, +} FsSimulatingDeviceAccessFailureEventType; + +typedef enum { + FsSimulatingDeviceTargetOperation_Read = 1, + FsSimulatingDeviceTargetOperation_Write = 2, +} FsSimulatingDeviceTargetOperation; + typedef struct { u32 value; } FsGameCardHandle; typedef struct { u32 version; - u8 pad[0x4]; + u32 reserved; u64 id; } FsGameCardUpdatePartitionInfo; +typedef struct { + u8 data[0x200]; +} FsGameCardRmaInformation; + +typedef struct { + u32 id1; + u32 id2; + u32 id3; +} FsGameCardIdSet; + +typedef struct { + u8 data[0xC]; +} FsHostControllerStatus; + +typedef struct { + u8 data[0x8]; +} FsSdmmcConnectionStatus; + +typedef enum { + FsSdCardActivationMode_Normal = 0, ///< Normal activation mode. + FsSdCardActivationMode_Override = 1, ///< Override activation mode. +} FsSdCardActivationMode; + +typedef struct { + FsSimulatingDeviceType device_type; + FsSimulatingDeviceDetectionMode detection_mode; + FsSimulatingDeviceAccessFailureEventType access_failure_event; + FsSimulatingDeviceTargetOperation target_operation; + u32 access_failure_result; +} FsDeviceSimulationEvent; + typedef struct { u32 aes_ctr_key_type; ///< Contains bitflags describing how data is AES encrypted. u32 speed_emulation_type; ///< Contains bitflags describing how data is emulated. @@ -386,6 +494,18 @@ typedef struct { u32 num_read_write_error_corrections; } FsStorageErrorInfo; +/// FsGameCardErrorInfo +typedef struct { + u16 game_card_crc_error_count; + u16 reserved1; + u16 asic_crc_error_count; + u16 reserved2; + u16 refresh_count; + u16 reserved3; + u16 read_retry_count; + u16 timeout_retry_error_count; +} FsGameCardErrorInfo; + /// FatFatError typedef struct { s32 error; @@ -432,7 +552,7 @@ typedef struct { FatFatSafeInfo bis_system_fat_safe_info; FatFatSafeInfo bis_user_fat_safe_info; - u8 reserved[0x18]; + u8 reserved[0x98]; } FsFileSystemProxyErrorInfo; /// FsMemoryReportInfo @@ -455,29 +575,22 @@ typedef struct { /// FsGameCardErrorReportInfo typedef struct { - u16 game_card_crc_error_num; - u16 reserved1; - u16 asic_crc_error_num; - u16 reserved2; - u16 refresh_num; - u16 reserved3; - u16 retry_limit_out_num; - u16 timeout_retry_num; + FsGameCardErrorInfo error_info; u16 asic_reinitialize_failure_detail; u16 insertion_count; u16 removal_count; - u16 asic_reinitialize_num; - u32 initialize_count; - u16 asic_reinitialize_failure_num; - u16 awaken_failure_num; - u16 reserved4; - u16 refresh_succeeded_count; + u16 asic_reinitialize_count; + u32 asic_initialize_count; + u16 asic_reinitialize_failure_count; + u16 awaken_failure_count; + u16 reserved1; + u16 refresh_count; u32 last_read_error_page_address; u32 last_read_error_page_count; u32 awaken_count; u32 read_count_from_insert; u32 read_count_from_awaken; - u8 reserved5[8]; + u8 reserved2[8]; } FsGameCardErrorReportInfo; /// Initialize fsp-srv. Used automatically during app startup. @@ -672,22 +785,60 @@ void fsEventNotifierClose(FsEventNotifier* e); // IDeviceOperator Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out); Result fsDeviceOperatorGetSdCardSpeedMode(FsDeviceOperator* d, s64* out); -Result fsDeviceOperatorGetSdCardCid(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size); +Result fsDeviceOperatorGetSdCardCid(FsDeviceOperator* d, void* dst, size_t size); Result fsDeviceOperatorGetSdCardUserAreaSize(FsDeviceOperator* d, s64* out); Result fsDeviceOperatorGetSdCardProtectedAreaSize(FsDeviceOperator* d, s64* out); -Result fsDeviceOperatorGetAndClearSdCardErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t dst_size, s64 size); -Result fsDeviceOperatorGetMmcCid(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size); +Result fsDeviceOperatorGetAndClearSdCardErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t size); +Result fsDeviceOperatorGetSdCardHostControllerStatus(FsDeviceOperator* d, FsHostControllerStatus* out); ///< [17.0.0+] +Result fsDeviceOperatorSetSdCardActivationMode(FsDeviceOperator* d, FsSdCardActivationMode mode); ///< [20.0.0+] +Result fsDeviceOperatorTryGetSdCardInfo(FsDeviceOperator* d, void* out, size_t size); ///< [20.0.0+] +Result fsDeviceOperatorGetMmcCid(FsDeviceOperator* d, void* dst, size_t size); Result fsDeviceOperatorGetMmcSpeedMode(FsDeviceOperator* d, s64* out); +Result fsDeviceOperatorEraseMmc(FsDeviceOperator* d, FsMmcPartition partition); +Result fsDeviceOperatorGetMmcPartitionSize(FsDeviceOperator* d, FsMmcPartition partition, s64* out); Result fsDeviceOperatorGetMmcPatrolCount(FsDeviceOperator* d, u32* out); -Result fsDeviceOperatorGetAndClearMmcErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t dst_size, s64 size); -Result fsDeviceOperatorGetMmcExtendedCsd(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size); +Result fsDeviceOperatorGetAndClearMmcErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t size); +Result fsDeviceOperatorGetMmcExtendedCsd(FsDeviceOperator* d, void* dst, size_t size); +Result fsDeviceOperatorSuspendMmcPatrol(FsDeviceOperator* d); ///< [4.0.0+] +Result fsDeviceOperatorResumeMmcPatrol(FsDeviceOperator* d); ///< [4.0.0+] +Result fsDeviceOperatorEraseMmcWithRange(FsDeviceOperator* d, FsMmcPartition partition, u64 offset, u64 size); ///< [17.0.0+] +Result fsDeviceOperatorMarkBeforeEraseMmcPartitionUserData(FsDeviceOperator* d); ///< [20.0.0+] +Result fsDeviceOperatorCheckAfterEraseMmcPartitionUserData(FsDeviceOperator* d); ///< [20.0.0+] Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out); +Result fsDeviceOperatorEraseGameCard(FsDeviceOperator* d, FsGameCardSize size, u64 normal_area_size); Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out); Result fsDeviceOperatorGetGameCardUpdatePartitionInfo(FsDeviceOperator* d, const FsGameCardHandle* handle, FsGameCardUpdatePartitionInfo* out); +Result fsDeviceOperatorFinalizeGameCardDriver(FsDeviceOperator* d); Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out); -Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size); -Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size); +Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t size, s64* out_size); +Result fsDeviceOperatorGetGameCardAsicInfo(FsDeviceOperator* d, const void* fw, size_t fw_size, FsGameCardRmaInformation* rma); +Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, FsGameCardIdSet* dst); +Result fsDeviceOperatorWriteToGameCardDirectly(FsDeviceOperator* d, void* dst, size_t size, s64 offset); +Result fsDeviceOperatorSetVerifyWriteEnableFlag(FsDeviceOperator* d, bool flag); +Result fsDeviceOperatorGetGameCardImageHash(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t size); +Result fsDeviceOperatorGetGameCardDeviceIdForProdCard(FsDeviceOperator* d, const void* card_header, size_t card_header_size, void* dst, size_t dst_size); ///< [2.0.0+] +Result fsDeviceOperatorEraseAndWriteParamDirectly(FsDeviceOperator* d, const void* buf, size_t size); ///< [2.0.0+] +Result fsDeviceOperatorReadParamDirectly(FsDeviceOperator* d, void* dst, size_t size); ///< [2.0.0+] +Result fsDeviceOperatorForceEraseGameCard(FsDeviceOperator* d); ///< [2.0.0+] +Result fsDeviceOperatorGetGameCardErrorInfo(FsDeviceOperator* d, FsGameCardErrorInfo* out); ///< [2.0.0+] Result fsDeviceOperatorGetGameCardErrorReportInfo(FsDeviceOperator* d, FsGameCardErrorReportInfo* out); -Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size); +Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_t size); Result fsDeviceOperatorChallengeCardExistence(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, void* seed, size_t seed_size, void* value, size_t value_size); +Result fsDeviceOperatorGetGameCardCompatibilityType(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out); ///< [9.0.0+] +Result fsDeviceOperatorGetGameCardAsicCertificate(FsDeviceOperator* d, void* dst, size_t size); ///< [17.0.0+] +Result fsDeviceOperatorGetGameCardCardHeader(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t size); ///< [18.0.0+] +Result fsDeviceOperatorSetGameCardSessionCreationDelay(FsDeviceOperator* d, bool flag0, bool flag1, u32 delay); ///< [19.0.0+] +Result fsDeviceOperatorGetGameCardApplicationIdList(FsDeviceOperator* d, const FsGameCardHandle* handle, u64* buf, size_t size, u16* out_count); ///< [19.0.0+] +Result fsDeviceOperatorRegisterGameCardConfigurationData(FsDeviceOperator* d, const void* buf, size_t size); ///< [20.0.0+] +Result fsDeviceOperatorGetGameCardDetailedErrorReportInfo(FsDeviceOperator* d, void* out, size_t size); ///< [20.0.0+] +Result fsDeviceOperatorSetSpeedEmulationMode(FsDeviceOperator* d, FsSpeedEmulationMode mode); +Result fsDeviceOperatorGetSpeedEmulationMode(FsDeviceOperator* d, FsSpeedEmulationMode* out); +Result fsDeviceOperatorSetApplicationStorageSpeed(FsDeviceOperator* d, s32 speed); ///< [18.0.0+] +Result fsDeviceOperatorSetGameCardClockRateForSpeedEmulation(FsDeviceOperator* d, s32 clock_rate); ///< [20.0.0+] +Result fsDeviceOperatorClearGameCardClockRateForSpeedEmulation(FsDeviceOperator* d); ///< [20.0.0+] +Result fsDeviceOperatorSuspendSdmmcControl(FsDeviceOperator* d); ///< [5.0.0+] +Result fsDeviceOperatorResumeSdmmcControl(FsDeviceOperator* d); ///< [5.0.0+] +Result fsDeviceOperatorGetSdmmcConnectionStatus(FsDeviceOperator* d, u32 input, FsSdmmcConnectionStatus* out); ///< [6.0.0+] +Result fsDeviceOperatorSetDeviceSimulationEvent(FsDeviceOperator* d, const FsDeviceSimulationEvent* event); ///< [6.0.0+] +Result fsDeviceOperatorClearDeviceSimulationEvent(FsDeviceOperator* d, FsSimulatingDeviceType device_type); ///< [6.0.0+] void fsDeviceOperatorClose(FsDeviceOperator* d); diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index 227396824..b2ca7badd 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -620,7 +620,23 @@ Result fsGetAndClearErrorInfo(FsFileSystemProxyErrorInfo *out) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _fsObjectDispatchOut(&g_fsSrv, 800, *out); + if (hosversionAtLeast(21,0,0)) { + return _fsObjectDispatch(&g_fsSrv, 800, + .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_FixedSize | SfBufferAttr_Out }, + .buffers = { { out, sizeof(*out) } }, + ); + } else { + struct { + u8 data[0x80]; + } tmp = {}; + + Result rc = _fsObjectDispatchOut(&g_fsSrv, 800, tmp); + if (R_SUCCEEDED(rc)) { + memset(out, 0, sizeof(*out)); + memcpy(out, &tmp, sizeof(tmp)); + } + return rc; + } } Result fsGetContentStorageInfoIndex(s32 *out) { @@ -661,7 +677,7 @@ Result fsGetProgramIndexForAccessLog(u32 *out_program_index, u32 *out_program_co u32 count; } out; - Result rc = _fsObjectDispatchOut(&g_fsSrv, 1007, out); + Result rc = _fsObjectDispatchOut(&g_fsSrv, 1011, out); if (R_SUCCEEDED(rc)) { if (out_program_index) *out_program_index = out.index; if (out_program_count) *out_program_count = out.count; @@ -933,7 +949,8 @@ Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void * if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _fsObjectDispatchIn(&fs->s, 15, query_id, + u32 tmp = query_id; + return _fsObjectDispatchIn(&fs->s, 15, tmp, .buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In | SfBufferAttr_HipcMapTransferAllowsNonSecure, @@ -1150,15 +1167,16 @@ void fsEventNotifierClose(FsEventNotifier* e) { // IDeviceOperator //----------------------------------------------------------------------------- -static Result _fsCmdGetAndClearStorageErrorInfo(Service *srv, FsStorageErrorInfo* out_sei, s64 *out_log_size, void *dst, size_t dst_size, s64 size, u32 cmd_id) { +static Result _fsCmdGetAndClearStorageErrorInfo(Service *srv, FsStorageErrorInfo* out_sei, s64 *out_log_size, void *dst, size_t size, u32 cmd_id) { struct { FsStorageErrorInfo error_info; s64 log_size; } out; - Result rc = _fsObjectDispatchInOut(srv, cmd_id, size, out, + s64 in = (s64)size; + Result rc = _fsObjectDispatchInOut(srv, cmd_id, in, out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { dst, dst_size } }, + .buffers = { { dst, size } }, ); if (R_SUCCEEDED(rc)) { @@ -1169,6 +1187,14 @@ static Result _fsCmdGetAndClearStorageErrorInfo(Service *srv, FsStorageErrorInfo return rc; } +static Result _fsCmdInSizeInBuffer(Service* srv, const void* src, size_t size, u32 cmd_id) { + s64 in = (s64)size; + return _fsObjectDispatchIn(srv, cmd_id, in, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, + .buffers = { { src, size } }, + ); +} + Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out) { return _fsCmdNoInOutBool(&d->s, out, 0); } @@ -1177,10 +1203,10 @@ Result fsDeviceOperatorGetSdCardSpeedMode(FsDeviceOperator* d, s64* out) { return _fsCmdNoInOutS64(&d->s, out, 1); } -Result fsDeviceOperatorGetSdCardCid(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) { +Result fsDeviceOperatorGetSdCardCid(FsDeviceOperator* d, void* dst, size_t size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _fsCmdInSizeOutBuffer(&d->s, dst, dst_size, size, 2); + return _fsCmdInSizeOutBuffer(&d->s, dst, size, (s64)size, 2); } Result fsDeviceOperatorGetSdCardUserAreaSize(FsDeviceOperator* d, s64* out) { @@ -1195,42 +1221,119 @@ Result fsDeviceOperatorGetSdCardProtectedAreaSize(FsDeviceOperator* d, s64* out) return _fsCmdNoInOutS64(&d->s, out, 4); } -Result fsDeviceOperatorGetAndClearSdCardErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t dst_size, s64 size) { +Result fsDeviceOperatorGetAndClearSdCardErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _fsCmdGetAndClearStorageErrorInfo(&d->s, out, out_log_size, dst, dst_size, size, 5); + return _fsCmdGetAndClearStorageErrorInfo(&d->s, out, out_log_size, dst, size, 5); +} + +Result fsDeviceOperatorGetSdCardHostControllerStatus(FsDeviceOperator* d, FsHostControllerStatus* out) { + if (hosversionBefore(17,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsObjectDispatchOut(&d->s, 6, *out); } -Result fsDeviceOperatorGetMmcCid(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) { - return _fsCmdInSizeOutBuffer(&d->s, dst, dst_size, size, 100); +Result fsDeviceOperatorSetSdCardActivationMode(FsDeviceOperator* d, FsSdCardActivationMode mode) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + u8 tmp = mode; + return _fsObjectDispatchIn(&d->s, 7, tmp); +} + +Result fsDeviceOperatorTryGetSdCardInfo(FsDeviceOperator* d, void* out, size_t size) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdInSizeOutBuffer(&d->s, out, size, (s64)size, 8); +} + +Result fsDeviceOperatorGetMmcCid(FsDeviceOperator* d, void* dst, size_t size) { + return _fsCmdInSizeOutBuffer(&d->s, dst, size, (s64)size, 100); } Result fsDeviceOperatorGetMmcSpeedMode(FsDeviceOperator* d, s64* out) { return _fsCmdNoInOutS64(&d->s, out, 101); } +Result fsDeviceOperatorEraseMmc(FsDeviceOperator* d, FsMmcPartition partition) { + u32 tmp = partition; + return _fsObjectDispatchIn(&d->s, 110, tmp); +} + +Result fsDeviceOperatorGetMmcPartitionSize(FsDeviceOperator* d, FsMmcPartition partition, s64* out) { + u32 tmp = partition; + return _fsObjectDispatchInOut(&d->s, 111, tmp, *out); +} + Result fsDeviceOperatorGetMmcPatrolCount(FsDeviceOperator* d, u32* out) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); return _fsCmdNoInOutU32(&d->s, out, 112); } -Result fsDeviceOperatorGetAndClearMmcErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t dst_size, s64 size) { +Result fsDeviceOperatorGetAndClearMmcErrorInfo(FsDeviceOperator* d, FsStorageErrorInfo* out, s64 *out_log_size, void *dst, size_t size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _fsCmdGetAndClearStorageErrorInfo(&d->s, out, out_log_size, dst, dst_size, size, 113); + return _fsCmdGetAndClearStorageErrorInfo(&d->s, out, out_log_size, dst, size, 113); } -Result fsDeviceOperatorGetMmcExtendedCsd(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) { +Result fsDeviceOperatorGetMmcExtendedCsd(FsDeviceOperator* d, void* dst, size_t size) { if (hosversionBefore(2,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _fsCmdInSizeOutBuffer(&d->s, dst, dst_size, size, 114); + return _fsCmdInSizeOutBuffer(&d->s, dst, size, (s64)size, 114); +} + +Result fsDeviceOperatorSuspendMmcPatrol(FsDeviceOperator* d) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 115); +} + +Result fsDeviceOperatorResumeMmcPatrol(FsDeviceOperator* d) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 116); +} + +Result fsDeviceOperatorEraseMmcWithRange(FsDeviceOperator* d, FsMmcPartition partition, u64 offset, u64 size) { + if (hosversionBefore(17,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + const struct { + u32 partition; + u32 pad; + u64 offset; + u64 size; + } in = { partition, 0, offset, size }; + + return _fsObjectDispatchIn(&d->s, 117, in); +} + +Result fsDeviceOperatorMarkBeforeEraseMmcPartitionUserData(FsDeviceOperator* d) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 118); +} + +Result fsDeviceOperatorCheckAfterEraseMmcPartitionUserData(FsDeviceOperator* d) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 119); } Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out) { return _fsCmdNoInOutBool(&d->s, out, 200); } +Result fsDeviceOperatorEraseGameCard(FsDeviceOperator* d, FsGameCardSize size, u64 normal_area_size) { + const struct { + u32 size; + u32 pad; + u64 normal_area_size; + } in = { size, 0, normal_area_size }; + + return _fsObjectDispatchIn(&d->s, 201, in); +} + Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out) { return _fsObjectDispatchOut(&d->s, 202, *out); } @@ -1239,28 +1342,32 @@ Result fsDeviceOperatorGetGameCardUpdatePartitionInfo(FsDeviceOperator* d, const return _fsObjectDispatchInOut(&d->s, 203, *handle, *out); } +Result fsDeviceOperatorFinalizeGameCardDriver(FsDeviceOperator* d) { + return _fsCmdNoIO(&d->s, 204); +} + Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out) { return _fsObjectDispatchInOut(&d->s, 205, *handle, *out); } -Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, s64* out_size, s64 size) { +Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t size, s64* out_size) { const struct { - FsGameCardHandle handle; s64 buffer_size; - } in = { *handle, size }; + FsGameCardHandle handle; + u32 pad; + } in = { (s64)size, *handle, 0 }; - // Assume old gamecard certificate size on pre-19.0.0 s64 os = 0x200; Result rc; if (hosversionAtLeast(19,0,0)) { rc = _fsObjectDispatchInOut(&d->s, 206, in, os, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { dst, dst_size } }); + .buffers = { { dst, size } }); } else { rc = _fsObjectDispatchIn(&d->s, 206, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { dst, dst_size } }); + .buffers = { { dst, size } }); } if (R_SUCCEEDED(rc)) @@ -1269,8 +1376,101 @@ Result fsDeviceOperatorGetGameCardDeviceCertificate(FsDeviceOperator* d, const F return rc; } -Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) { - return _fsCmdInSizeOutBuffer(&d->s, dst, dst_size, size, 208); +Result fsDeviceOperatorGetGameCardAsicInfo(FsDeviceOperator* d, const void* fw, size_t fw_size, FsGameCardRmaInformation* rma) { + const struct { + s64 fw_buffer_size; + s64 rma_info_size; + } in = { (s64)fw_size, (s64)sizeof(*rma) }; + + return _fsObjectDispatchIn(&d->s, 207, in, + .buffer_attrs = { + SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, + SfBufferAttr_HipcMapAlias | SfBufferAttr_In, + }, + .buffers = { + { rma, sizeof(*rma) }, + { fw, fw_size }, + }, + ); +} + +Result fsDeviceOperatorGetGameCardIdSet(FsDeviceOperator* d, FsGameCardIdSet* dst) { + return _fsCmdInSizeOutBuffer(&d->s, dst, sizeof(*dst), (s64)sizeof(*dst), 208); +} + +Result fsDeviceOperatorWriteToGameCardDirectly(FsDeviceOperator* d, void* dst, size_t size, s64 offset) { + const struct { + s64 offset; + s64 buffer_size; + } in = { offset, (s64)size }; + + return _fsObjectDispatchIn(&d->s, 209, in, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { dst, size } }, + ); +} + +Result fsDeviceOperatorSetVerifyWriteEnableFlag(FsDeviceOperator* d, bool flag) { + u8 tmp = flag; + return _fsObjectDispatchIn(&d->s, 210, tmp); +} + +Result fsDeviceOperatorGetGameCardImageHash(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t size) { + const struct { + s64 buffer_size; + FsGameCardHandle handle; + u32 pad; + } in = { (s64)size, *handle, 0 }; + + return _fsObjectDispatchIn(&d->s, 211, in, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { dst, size } }, + ); +} + +Result fsDeviceOperatorGetGameCardDeviceIdForProdCard(FsDeviceOperator* d, const void* card_header, size_t card_header_size, void* dst, size_t dst_size) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + const struct { + s64 card_header_buffer_size; + s64 buffer_size; + } in = { (s64)card_header_size, (s64)dst_size }; + + return _fsObjectDispatchIn(&d->s, 212, in, + .buffer_attrs = { + SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, + SfBufferAttr_HipcMapAlias | SfBufferAttr_In, + }, + .buffers = { + { dst, dst_size }, + { card_header, card_header_size }, + }, + ); +} + +Result fsDeviceOperatorEraseAndWriteParamDirectly(FsDeviceOperator* d, const void* buf, size_t size) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdInSizeInBuffer(&d->s, buf, size, 213); +} + +Result fsDeviceOperatorReadParamDirectly(FsDeviceOperator* d, void* dst, size_t size) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdInSizeOutBuffer(&d->s, dst, size, (s64)size, 214); +} + +Result fsDeviceOperatorForceEraseGameCard(FsDeviceOperator* d) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 215); +} + +Result fsDeviceOperatorGetGameCardErrorInfo(FsDeviceOperator* d, FsGameCardErrorInfo* out) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsObjectDispatchOut(&d->s, 216, *out); } Result fsDeviceOperatorGetGameCardErrorReportInfo(FsDeviceOperator* d, FsGameCardErrorReportInfo* out) { @@ -1279,10 +1479,10 @@ Result fsDeviceOperatorGetGameCardErrorReportInfo(FsDeviceOperator* d, FsGameCar return _fsObjectDispatchOut(&d->s, 217, *out); } -Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_t dst_size, s64 size) { +Result fsDeviceOperatorGetGameCardDeviceId(FsDeviceOperator* d, void* dst, size_t size) { if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return _fsCmdInSizeOutBuffer(&d->s, dst, dst_size, size, 218); + return _fsCmdInSizeOutBuffer(&d->s, dst, size, (s64)size, 218); } Result fsDeviceOperatorChallengeCardExistence(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t dst_size, void* seed, size_t seed_size, void* value, size_t value_size) { @@ -1303,6 +1503,145 @@ Result fsDeviceOperatorChallengeCardExistence(FsDeviceOperator* d, const FsGameC ); } +Result fsDeviceOperatorGetGameCardCompatibilityType(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out) { + if (hosversionBefore(9,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsObjectDispatchInOut(&d->s, 220, *handle, *out); +} + +Result fsDeviceOperatorGetGameCardAsicCertificate(FsDeviceOperator* d, void* dst, size_t size) { + if (hosversionBefore(17,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdInSizeOutBuffer(&d->s, dst, size, (s64)size, 221); +} + +Result fsDeviceOperatorGetGameCardCardHeader(FsDeviceOperator* d, const FsGameCardHandle* handle, void* dst, size_t size) { + if (hosversionBefore(18,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + const struct { + s64 buffer_size; + FsGameCardHandle handle; + u32 pad; + } in = { (s64)size, *handle, 0 }; + + return _fsObjectDispatchIn(&d->s, 222, in, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { dst, size } }, + ); +} + +Result fsDeviceOperatorSetGameCardSessionCreationDelay(FsDeviceOperator* d, bool flag0, bool flag1, u32 delay) { + if (hosversionBefore(19,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + const struct { + u8 flag0; + u8 flag1; + u8 pad[2]; + u32 delay; + } in = { flag0, flag1, {0}, delay }; + + return _fsObjectDispatchIn(&d->s, 223, in); +} + +Result fsDeviceOperatorGetGameCardApplicationIdList(FsDeviceOperator* d, const FsGameCardHandle* handle, u64* buf, size_t size, u16* out_count) { + if (hosversionBefore(19,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + const struct { + s64 buffer_size; + FsGameCardHandle handle; + u32 pad; + } in = { (s64)size, *handle, 0 }; + + return _fsObjectDispatchInOut(&d->s, 224, in, *out_count, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { buf, size } }, + ); +} + +Result fsDeviceOperatorRegisterGameCardConfigurationData(FsDeviceOperator* d, const void* buf, size_t size) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + s64 in = (s64)size; + return _fsObjectDispatchIn(&d->s, 225, in, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, + .buffers = { { buf, size } }, + ); +} + +Result fsDeviceOperatorGetGameCardDetailedErrorReportInfo(FsDeviceOperator* d, void* out, size_t size) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + s64 in = (s64)size; + return _fsObjectDispatchIn(&d->s, 226, in, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { out, size } }, + ); +} + +Result fsDeviceOperatorSetSpeedEmulationMode(FsDeviceOperator* d, FsSpeedEmulationMode mode) { + u32 tmp = mode; + return _fsObjectDispatchIn(&d->s, 300, tmp); +} + +Result fsDeviceOperatorGetSpeedEmulationMode(FsDeviceOperator* d, FsSpeedEmulationMode* out) { + u32 tmp=0; + Result rc = _fsObjectDispatchOut(&d->s, 301, tmp); + if (R_SUCCEEDED(rc) && out) *out = (FsSpeedEmulationMode)tmp; + return rc; +} + +Result fsDeviceOperatorSetApplicationStorageSpeed(FsDeviceOperator* d, s32 speed) { + if (hosversionBefore(18,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsObjectDispatchIn(&d->s, 302, speed); +} + +Result fsDeviceOperatorSetGameCardClockRateForSpeedEmulation(FsDeviceOperator* d, s32 clock_rate) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsObjectDispatchIn(&d->s, 303, clock_rate); +} + +Result fsDeviceOperatorClearGameCardClockRateForSpeedEmulation(FsDeviceOperator* d) { + if (hosversionBefore(20,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 304); +} + +Result fsDeviceOperatorSuspendSdmmcControl(FsDeviceOperator* d) { + if (hosversionBefore(5,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 400); +} + +Result fsDeviceOperatorResumeSdmmcControl(FsDeviceOperator* d) { + if (hosversionBefore(5,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsCmdNoIO(&d->s, 401); +} + +Result fsDeviceOperatorGetSdmmcConnectionStatus(FsDeviceOperator* d, u32 input, FsSdmmcConnectionStatus* out) { + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsObjectDispatchInOut(&d->s, 402, input, *out); +} + +Result fsDeviceOperatorSetDeviceSimulationEvent(FsDeviceOperator* d, const FsDeviceSimulationEvent* event) { + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _fsObjectDispatchIn(&d->s, 500, *event); +} + +Result fsDeviceOperatorClearDeviceSimulationEvent(FsDeviceOperator* d, FsSimulatingDeviceType device_type) { + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + u32 tmp = device_type; + return _fsObjectDispatchIn(&d->s, 501, tmp); +} + void fsDeviceOperatorClose(FsDeviceOperator* d) { _fsObjectClose(&d->s); }