diff --git a/nx/include/switch/sf/service.h b/nx/include/switch/sf/service.h index 971468f62..3bb0ffc6d 100644 --- a/nx/include/switch/sf/service.h +++ b/nx/include/switch/sf/service.h @@ -473,14 +473,23 @@ NX_INLINE Result serviceDispatchImpl( return rc; } +#define serviceMacroDetectIsSameType(a, b) __builtin_types_compatible_p(typeof(a), typeof(b)) +#define serviceMacroDetectIsPointerOrArray(p) (__builtin_classify_type(p) == 5) +#define serviceMacroDecay(p) (&*__builtin_choose_expr(serviceMacroDetectIsPointerOrArray(p), p, NULL)) +#define serviceMacroDetectIsPointer(p) serviceMacroDetectIsSameType(p, serviceMacroDecay(p)) + #define serviceDispatch(_s,_rid,...) \ serviceDispatchImpl((_s),(_rid),NULL,0,NULL,0,(SfDispatchParams){ __VA_ARGS__ }) #define serviceDispatchIn(_s,_rid,_in,...) \ - serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ }) + ({ _Static_assert(!(serviceMacroDetectIsPointer(_in))); \ + serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ }); }) #define serviceDispatchOut(_s,_rid,_out,...) \ - serviceDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }) + ({ _Static_assert(!(serviceMacroDetectIsPointer(_out))); \ + serviceDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }); }) #define serviceDispatchInOut(_s,_rid,_in,_out,...) \ - serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }) + ({ _Static_assert(!(serviceMacroDetectIsPointer(_in))); \ + _Static_assert(!(serviceMacroDetectIsPointer(_out))); \ + serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }); }) diff --git a/nx/source/services/capsc.c b/nx/source/services/capsc.c index 508936f14..062e49fe7 100644 --- a/nx/source/services/capsc.c +++ b/nx/source/services/capsc.c @@ -109,7 +109,7 @@ Result capscGenerateApplicationAlbumEntry(CapsApplicationAlbumEntry *appEntry, c Result capscSaveAlbumScreenShotFile(const CapsAlbumFileId *file_id, const void* buffer, u64 buffer_size) { if (hosversionBefore(2,0,0) || hosversionAtLeast(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchIn(&g_capscSrv, 2201, file_id, + return serviceDispatchIn(&g_capscSrv, 2201, *file_id, .buffer_attrs = { SfBufferAttr_HipcMapTransferAllowsNonSecure | SfBufferAttr_HipcMapAlias | SfBufferAttr_In }, .buffers = { { buffer, buffer_size }, }, ); diff --git a/nx/source/services/fs.c b/nx/source/services/fs.c index 9be5b9d01..0ac231742 100644 --- a/nx/source/services/fs.c +++ b/nx/source/services/fs.c @@ -60,13 +60,17 @@ NX_INLINE Result _fsObjectDispatchImpl( _fsObjectDispatchImpl((_s),(_rid),NULL,0,NULL,0,(SfDispatchParams){ __VA_ARGS__ }) #define _fsObjectDispatchIn(_s,_rid,_in,...) \ - _fsObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ }) + ({ _Static_assert(!(serviceMacroDetectIsPointer(_in))); \ + _fsObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ }); }) #define _fsObjectDispatchOut(_s,_rid,_out,...) \ - _fsObjectDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }) + ({ _Static_assert(!(serviceMacroDetectIsPointer(_out))); \ + _fsObjectDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }); }) #define _fsObjectDispatchInOut(_s,_rid,_in,_out,...) \ - _fsObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }) + ({ _Static_assert(!(serviceMacroDetectIsPointer(_in))); \ + _Static_assert(!(serviceMacroDetectIsPointer(_out))); \ + _fsObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ }); }) NX_GENERATE_SERVICE_GUARD(fs); diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index 8476de48c..d57ac199a 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -1503,7 +1503,7 @@ Result nsCompareApplicationDeliveryInfo(const NsApplicationDeliveryInfo *info0, Service srv={0}; Result rc = nsGetApplicationManagerInterface(&srv); - if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2005, out, + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2005, *out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In, @@ -1710,7 +1710,7 @@ Result nsCompareSystemDeliveryInfo(const NsSystemDeliveryInfo *info0, const NsSy Service srv={0}; Result rc = nsGetApplicationManagerInterface(&srv); - if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2015, out, + if (R_SUCCEEDED(rc)) rc = serviceDispatchOut(&srv, 2015, *out, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In, SfBufferAttr_HipcMapAlias | SfBufferAttr_In,