diff --git a/nx/include/switch/services/fs.h b/nx/include/switch/services/fs.h index ce2341b5..18ee3f02 100644 --- a/nx/include/switch/services/fs.h +++ b/nx/include/switch/services/fs.h @@ -139,6 +139,16 @@ typedef enum FsSaveDataType_CacheStorage = 5, ///< [3.0.0+] } FsSaveDataType; +typedef enum { + FsGameCardAttribute_AutoBoot = (1 << 0), ///< Causes the cartridge to automatically start on bootup + FsGameCardAttribute_ForceError = (1 << 1), ///< Causes NS to throw an error on attempt to load the cartridge + FsGameCardAttribute_Repair = (1 << 2), ///< Indicates that this gamecard is a repair tool. +} FsGameCardAttribute; + +typedef struct { + u32 value; +} FsGameCardHandle; + Result fsInitialize(void); void fsExit(void); @@ -242,4 +252,7 @@ void fsEventNotifierClose(FsEventNotifier* e); // IDeviceOperator Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out); +Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out); +Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out); +Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out); void fsDeviceOperatorClose(FsDeviceOperator* d); diff --git a/nx/include/switch/services/gpio.h b/nx/include/switch/services/gpio.h index 271582f2..45402a72 100644 --- a/nx/include/switch/services/gpio.h +++ b/nx/include/switch/services/gpio.h @@ -37,4 +37,4 @@ Result gpioPadSetDirection(GpioPadSession *p, GpioDirection dir); Result gpioPadGetDirection(GpioPadSession *p, GpioDirection *out); Result gpioPadSetValue(GpioPadSession *p, GpioValue val); Result gpioPadGetValue(GpioPadSession *p, GpioValue *out); -void gpioPadClose(GpioPadSession *p); \ No newline at end of file +void gpioPadClose(GpioPadSession *p); diff --git a/nx/include/switch/services/i2c.h b/nx/include/switch/services/i2c.h index d112f982..29847c78 100644 --- a/nx/include/switch/services/i2c.h +++ b/nx/include/switch/services/i2c.h @@ -29,4 +29,4 @@ void i2cExit(void); Result i2cOpenSession(I2cSession *out, I2cDevice dev); Result i2csessionSendAuto(I2cSession *s, void *buf, size_t size, I2cTransactionOption option); -void i2csessionClose(I2cSession *s); \ No newline at end of file +void i2csessionClose(I2cSession *s); diff --git a/nx/source/services/bpc.c b/nx/source/services/bpc.c index 22c8d8e5..15e31992 100644 --- a/nx/source/services/bpc.c +++ b/nx/source/services/bpc.c @@ -127,4 +127,4 @@ Result bpcGetSleepButtonState(BpcSleepButtonState *out) { } return rc; -} \ No newline at end of file +} diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index 5ef5a941..d84e1eff 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -1589,7 +1589,7 @@ void fsEventNotifierClose(FsEventNotifier* e) { } // IDeviceOperator -Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out) { +static Result _fsDeviceOperatorCheckInserted(FsDeviceOperator* d, u32 cmd_id, bool* out) { IpcCommand c; ipcInitialize(&c); @@ -1601,7 +1601,7 @@ Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out) { raw = serviceIpcPrepareHeader(&d->s, &c, sizeof(*raw)); raw->magic = SFCI_MAGIC; - raw->cmd_id = 0; + raw->cmd_id = cmd_id; Result rc = serviceIpcDispatch(&d->s); @@ -1626,6 +1626,90 @@ Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out) { return rc; } +Result fsDeviceOperatorIsSdCardInserted(FsDeviceOperator* d, bool* out) { + return _fsDeviceOperatorCheckInserted(d, 0, out); +} + +Result fsDeviceOperatorIsGameCardInserted(FsDeviceOperator* d, bool* out) { + return _fsDeviceOperatorCheckInserted(d, 200, out); +} + +Result fsDeviceOperatorGetGameCardHandle(FsDeviceOperator* d, FsGameCardHandle* out) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + } *raw; + + raw = serviceIpcPrepareHeader(&d->s, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 202; + + Result rc = serviceIpcDispatch(&d->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + u32 handle; + } *resp; + + serviceIpcParse(&d->s, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + out->value = resp->handle; + } + } + + return rc; +} + +Result fsDeviceOperatorGetGameCardAttribute(FsDeviceOperator* d, const FsGameCardHandle* handle, u8 *out) { + IpcCommand c; + ipcInitialize(&c); + + struct { + u64 magic; + u64 cmd_id; + u32 handle; + } *raw; + + raw = serviceIpcPrepareHeader(&d->s, &c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 205; + raw->handle = handle->value; + + Result rc = serviceIpcDispatch(&d->s); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + struct { + u64 magic; + u64 result; + u8 attr; + } *resp; + + serviceIpcParse(&d->s, &r, sizeof(*resp)); + resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc)) { + *out = resp->attr; + } + } + + return rc; +} + void fsDeviceOperatorClose(FsDeviceOperator* d) { serviceClose(&d->s); } diff --git a/nx/source/services/set.c b/nx/source/services/set.c index a2d08d60..7d67d5c7 100644 --- a/nx/source/services/set.c +++ b/nx/source/services/set.c @@ -685,4 +685,4 @@ Result setsysGetFatalDirtyFlags(u64 *flags_0, u64 *flags_1) { } return rc; -} \ No newline at end of file +}