17 u16 pointer_buffer_size;
21 SfBufferAttr_In =
BIT(0),
22 SfBufferAttr_Out =
BIT(1),
23 SfBufferAttr_HipcMapAlias =
BIT(2),
24 SfBufferAttr_HipcPointer =
BIT(3),
25 SfBufferAttr_FixedSize =
BIT(4),
26 SfBufferAttr_HipcAutoSelect =
BIT(5),
27 SfBufferAttr_HipcMapTransferAllowsNonSecure =
BIT(6),
28 SfBufferAttr_HipcMapTransferAllowsNonDevice =
BIT(7),
47 typedef enum SfOutHandleAttr {
48 SfOutHandleAttr_None = 0,
49 SfOutHandleAttr_HipcCopy = 1,
50 SfOutHandleAttr_HipcMove = 2,
54 SfOutHandleAttr attr0;
55 SfOutHandleAttr attr1;
56 SfOutHandleAttr attr2;
57 SfOutHandleAttr attr3;
58 SfOutHandleAttr attr4;
59 SfOutHandleAttr attr5;
60 SfOutHandleAttr attr6;
61 SfOutHandleAttr attr7;
141 s->pointer_buffer_size = 0;
142 cmifQueryPointerBufferSize(h, &s->pointer_buffer_size);
157 s->pointer_buffer_size = parent->pointer_buffer_size;
171 if (object_id != 0) {
172 s->session = parent->session;
174 s->object_id = object_id;
175 s->pointer_buffer_size = parent->pointer_buffer_size;
185 #define serviceAssumeDomain(_s) do { \
186 if (!(_s)->object_id) \
187 __builtin_unreachable(); \
196 #if defined(NX_SERVICE_ASSUME_NON_DOMAIN)
198 __builtin_unreachable();
201 if (s->own_handle || s->object_id) {
202 cmifMakeCloseRequest(
armGetTls(), s->own_handle ? 0 : s->object_id);
217 #if defined(NX_SERVICE_ASSUME_NON_DOMAIN)
219 __builtin_unreachable();
223 out_s->own_handle = 1;
224 out_s->object_id = s->object_id;
225 out_s->pointer_buffer_size = s->pointer_buffer_size;
226 return cmifCloneCurrentObject(s->session, &out_s->session);
237 #if defined(NX_SERVICE_ASSUME_NON_DOMAIN)
239 __builtin_unreachable();
243 out_s->own_handle = 1;
244 out_s->object_id = s->object_id;
245 out_s->pointer_buffer_size = s->pointer_buffer_size;
246 return cmifCloneCurrentObjectEx(s->session, tag, &out_s->session);
256 if (!s->own_handle) {
258 Result rc = cmifCloneCurrentObjectEx(s->session, 0, &s->session);
264 return cmifConvertCurrentObjectToDomain(s->session, &s->object_id);
270 const bool is_in = (attr & SfBufferAttr_In) != 0;
271 const bool is_out = (attr & SfBufferAttr_Out) != 0;
273 if (attr & SfBufferAttr_HipcAutoSelect) {
275 fmt->num_in_auto_buffers ++;
277 fmt->num_out_auto_buffers ++;
278 }
else if (attr & SfBufferAttr_HipcPointer) {
280 fmt->num_in_pointers ++;
282 if (attr & SfBufferAttr_FixedSize)
283 fmt->num_out_fixed_pointers ++;
285 fmt->num_out_pointers ++;
287 }
else if (attr & SfBufferAttr_HipcMapAlias) {
289 fmt->num_inout_buffers ++;
291 fmt->num_in_buffers ++;
293 fmt->num_out_buffers ++;
300 const bool is_in = (attr & SfBufferAttr_In);
301 const bool is_out = (attr & SfBufferAttr_Out);
303 if (attr & SfBufferAttr_HipcAutoSelect) {
304 HipcBufferMode mode = HipcBufferMode_Normal;
305 if (attr & SfBufferAttr_HipcMapTransferAllowsNonSecure)
306 mode = HipcBufferMode_NonSecure;
307 if (attr & SfBufferAttr_HipcMapTransferAllowsNonDevice)
308 mode = HipcBufferMode_NonDevice;
310 cmifRequestInAutoBuffer(req, buf->ptr, buf->size, mode);
312 cmifRequestOutAutoBuffer(req, (
void*)buf->ptr, buf->size, mode);
313 }
else if (attr & SfBufferAttr_HipcPointer) {
315 cmifRequestInPointer(req, buf->ptr, buf->size);
317 if (attr & SfBufferAttr_FixedSize)
318 cmifRequestOutFixedPointer(req, (
void*)buf->ptr, buf->size);
320 cmifRequestOutPointer(req, (
void*)buf->ptr, buf->size);
322 }
else if (attr & SfBufferAttr_HipcMapAlias) {
323 HipcBufferMode mode = HipcBufferMode_Normal;
324 if (attr & SfBufferAttr_HipcMapTransferAllowsNonSecure)
325 mode = HipcBufferMode_NonSecure;
326 if (attr & SfBufferAttr_HipcMapTransferAllowsNonDevice)
327 mode = HipcBufferMode_NonDevice;
330 cmifRequestInOutBuffer(req, (
void*)buf->ptr, buf->size, mode);
332 cmifRequestInBuffer(req, buf->ptr, buf->size, mode);
334 cmifRequestOutBuffer(req, (
void*)buf->ptr, buf->size, mode);
341 u32 num_objects,
const Service*
const* objects,
344 #if defined(NX_SERVICE_ASSUME_NON_DOMAIN)
346 __builtin_unreachable();
350 fmt.object_id = s->object_id;
351 fmt.request_id = request_id;
352 fmt.context = context;
353 fmt.data_size = data_size;
354 fmt.server_pointer_size = s->pointer_buffer_size;
355 fmt.num_objects = num_objects;
356 fmt.num_handles = num_handles;
357 fmt.send_pid = send_pid;
359 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr0);
360 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr1);
361 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr2);
362 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr3);
363 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr4);
364 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr5);
365 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr6);
366 _serviceRequestFormatProcessBuffer(&fmt, buffer_attrs.attr7);
371 for (
u32 i = 0; i < num_objects; i ++)
372 cmifRequestObject(&req, objects[i]->object_id);
374 for (
u32 i = 0; i < num_handles; i ++)
375 cmifRequestHandle(&req, handles[i]);
377 _serviceRequestProcessBuffer(&req, &buffers[0], buffer_attrs.attr0);
378 _serviceRequestProcessBuffer(&req, &buffers[1], buffer_attrs.attr1);
379 _serviceRequestProcessBuffer(&req, &buffers[2], buffer_attrs.attr2);
380 _serviceRequestProcessBuffer(&req, &buffers[3], buffer_attrs.attr3);
381 _serviceRequestProcessBuffer(&req, &buffers[4], buffer_attrs.attr4);
382 _serviceRequestProcessBuffer(&req, &buffers[5], buffer_attrs.attr5);
383 _serviceRequestProcessBuffer(&req, &buffers[6], buffer_attrs.attr6);
384 _serviceRequestProcessBuffer(&req, &buffers[7], buffer_attrs.attr7);
393 case SfOutHandleAttr_None:
395 case SfOutHandleAttr_HipcCopy:
396 *out = cmifResponseGetCopyHandle(res);
398 case SfOutHandleAttr_HipcMove:
399 *out = cmifResponseGetMoveHandle(res);
409 #if defined(NX_SERVICE_ASSUME_NON_DOMAIN)
411 __builtin_unreachable();
415 bool is_domain = s->object_id != 0;
421 *out_data = res.data;
423 for (
u32 i = 0; i < num_out_objects; i ++) {
430 _serviceResponseGetHandle(&res, out_handle_attrs.attr0, &out_handles[0]);
431 _serviceResponseGetHandle(&res, out_handle_attrs.attr1, &out_handles[1]);
432 _serviceResponseGetHandle(&res, out_handle_attrs.attr2, &out_handles[2]);
433 _serviceResponseGetHandle(&res, out_handle_attrs.attr3, &out_handles[3]);
434 _serviceResponseGetHandle(&res, out_handle_attrs.attr4, &out_handles[4]);
435 _serviceResponseGetHandle(&res, out_handle_attrs.attr5, &out_handles[5]);
436 _serviceResponseGetHandle(&res, out_handle_attrs.attr6, &out_handles[6]);
437 _serviceResponseGetHandle(&res, out_handle_attrs.attr7, &out_handles[7]);
444 const void* in_data,
u32 in_data_size,
445 void* out_data,
u32 out_data_size,
452 void* in = serviceMakeRequest(&srv, request_id, disp.context,
453 in_data_size, disp.in_send_pid,
454 disp.buffer_attrs, disp.buffers,
455 disp.in_num_objects, disp.in_objects,
456 disp.in_num_handles, disp.in_handles);
459 __builtin_memcpy(in, in_data, in_data_size);
464 rc = serviceParseResponse(&srv,
466 disp.out_num_objects, disp.out_objects,
467 disp.out_handle_attrs, disp.out_handles);
470 __builtin_memcpy(out_data, out, out_data_size);
476 #define serviceDispatch(_s,_rid,...) \
477 serviceDispatchImpl((_s),(_rid),NULL,0,NULL,0,(SfDispatchParams){ __VA_ARGS__ })
479 #define serviceDispatchIn(_s,_rid,_in,...) \
480 serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ })
482 #define serviceDispatchOut(_s,_rid,_out,...) \
483 serviceDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
485 #define serviceDispatchInOut(_s,_rid,_in,_out,...) \
486 serviceDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
Common Message Interface Framework protocol.
Horizon Inter-Process Communication protocol.
#define R_FAILED(res)
Checks whether a result code indicates failure.
Definition: result.h:12
#define R_SUCCEEDED(res)
Checks whether a result code indicates success.
Definition: result.h:10
static bool serviceIsOverride(Service *s)
Returns whether a service is overriden in the homebrew environment.
Definition: service.h:100
static Result serviceClone(Service *s, Service *out_s)
Clones a service.
Definition: service.h:215
static bool serviceIsDomainSubservice(Service *s)
Returns whether a service is a domain subservice.
Definition: service.h:118
static Result serviceCloneEx(Service *s, u32 tag, Service *out_s)
Clones a service with a session manager tag.
Definition: service.h:235
static void serviceCreateNonDomainSubservice(Service *s, Service *parent, Handle h)
Creates a non-domain subservice object from a parent service.
Definition: service.h:151
static Result serviceConvertToDomain(Service *s)
Converts a regular service to a domain.
Definition: service.h:254
static bool serviceIsActive(Service *s)
Returns whether a service has been initialized.
Definition: service.h:91
static void serviceCreateDomainSubservice(Service *s, Service *parent, u32 object_id)
Creates a domain subservice object from a parent service.
Definition: service.h:169
static bool serviceIsDomain(Service *s)
Returns whether a service is a domain.
Definition: service.h:109
static u32 serviceGetObjectId(Service *s)
For a domain/domain subservice, return the associated object ID.
Definition: service.h:127
static void serviceClose(Service *s)
Closes a service.
Definition: service.h:194
static void serviceCreate(Service *s, Handle h)
Creates a service object from an IPC session handle.
Definition: service.h:136
Service object structure.
Definition: service.h:13
Result svcCloseHandle(Handle handle)
Closes a handle, decrementing the reference count of the corresponding kernel object.
Result svcSendSyncRequest(Handle session)
Sends an IPC synchronization request to a session.
static void * armGetTls(void)
Gets the thread local storage buffer.
Definition: tls.h:14
#define NX_INLINE
Flags a function as (always) inline.
Definition: types.h:86
#define BIT(n)
Creates a bitmask from a bit number.
Definition: types.h:54
#define INVALID_HANDLE
Invalid handle.
Definition: types.h:96
u32 Handle
Kernel object handle.
Definition: types.h:43
uint16_t u16
16-bit unsigned integer.
Definition: types.h:20
u32 Result
Function error code result type.
Definition: types.h:44
#define NX_CONSTEXPR
Flags a function as constexpr in C++14 and above; or as (always) inline otherwise.
Definition: types.h:92
uint32_t u32
32-bit unsigned integer.
Definition: types.h:21