mirror of
https://github.com/switchbrew/libnx.git
synced 2025-07-03 10:02:14 +02:00
make friends service a domain
This commit is contained in:
parent
e11e5a2cd4
commit
b5a45d6742
@ -12,12 +12,12 @@
|
|||||||
#include "../sf/service.h"
|
#include "../sf/service.h"
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
FriendServiceType_User = 0, ///< Initializes friend:u
|
FriendsServiceType_User = 0, ///< Initializes friend:u
|
||||||
FriendServiceType_Viewer = 1, ///< Initializes friend:v
|
FriendsServiceType_Viewer = 1, ///< Initializes friend:v
|
||||||
FriendServiceType_Manager = 2, ///< Initializes friend:m
|
FriendsServiceType_Manager = 2, ///< Initializes friend:m
|
||||||
FriendServiceType_System = 3, ///< Initializes friend:s
|
FriendsServiceType_System = 3, ///< Initializes friend:s
|
||||||
FriendServiceType_Administrator = 4 ///< Initializes friend:a
|
FriendsServiceType_Administrator = 4 ///< Initializes friend:a
|
||||||
} FriendServiceType;
|
} FriendsServiceType;
|
||||||
|
|
||||||
/// InAppScreenName
|
/// InAppScreenName
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -49,10 +49,10 @@ typedef struct {
|
|||||||
char friend_code[0x20]; ///< Friend Code
|
char friend_code[0x20]; ///< Friend Code
|
||||||
u64 friend_code_next_issuable_time; ///< Unknown
|
u64 friend_code_next_issuable_time; ///< Unknown
|
||||||
char extra[0x7C8]; ///< Extra
|
char extra[0x7C8]; ///< Extra
|
||||||
} FriendUserSetting;
|
} FriendsUserSetting;
|
||||||
|
|
||||||
/// Initialize friends
|
/// Initialize friends
|
||||||
Result friendsInitialize(FriendServiceType service_type);
|
Result friendsInitialize(FriendsServiceType service_type);
|
||||||
|
|
||||||
/// Exit friends
|
/// Exit friends
|
||||||
void friendsExit(void);
|
void friendsExit(void);
|
||||||
@ -64,11 +64,11 @@ Service* friendsGetServiceSession(void);
|
|||||||
Service* friendsGetServiceSession_IFriendsService(void);
|
Service* friendsGetServiceSession_IFriendsService(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets the \ref FriendUserSetting details
|
* @brief Gets the \ref FriendsUserSetting details
|
||||||
* @param[in] uid \ref User AccountUid.
|
* @param[in] uid \ref User AccountUid.
|
||||||
* @param[out] user_setting \ref FriendUserSetting
|
* @param[out] user_setting \ref FriendsUserSetting
|
||||||
*/
|
*/
|
||||||
Result friendsGetUserSetting(AccountUid uid, FriendUserSetting *user_setting);
|
Result friendsGetUserSetting(AccountUid uid, FriendsUserSetting *user_setting);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Gets an Event which is signaled when data is available with \ref friendsTryPopFriendInvitationNotificationInfo.
|
* @brief Gets an Event which is signaled when data is available with \ref friendsTryPopFriendInvitationNotificationInfo.
|
||||||
|
@ -1,62 +1,125 @@
|
|||||||
#include "service_guard.h"
|
#include "service_guard.h"
|
||||||
|
#include "sf/sessionmgr.h"
|
||||||
#include "services/friends.h"
|
#include "services/friends.h"
|
||||||
|
|
||||||
static FriendServiceType g_friendsServiceType;
|
static FriendsServiceType g_friendsServiceType;
|
||||||
|
|
||||||
static Service g_friendSrv;
|
static Service g_friendsSrv;
|
||||||
static Service g_friendsIFriendService;
|
static Service g_friendsIFriendService;
|
||||||
|
|
||||||
NX_GENERATE_SERVICE_GUARD_PARAMS(friends, (FriendServiceType service_type), (service_type));
|
static SessionMgr g_friendsSessionMgr;
|
||||||
|
|
||||||
Result _friendsInitialize(FriendServiceType service_type) {
|
NX_GENERATE_SERVICE_GUARD_PARAMS(friends, (FriendsServiceType service_type), (service_type));
|
||||||
|
|
||||||
|
NX_INLINE bool _friendsObjectIsChild(Service* s) {
|
||||||
|
return s->session == g_friendsSrv.session;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void _friendsObjectClose(Service* s) {
|
||||||
|
if (!_friendsObjectIsChild(s)) {
|
||||||
|
serviceClose(s);
|
||||||
|
} else {
|
||||||
|
int slot = sessionmgrAttachClient(&g_friendsSessionMgr);
|
||||||
|
uint32_t object_id = serviceGetObjectId(s);
|
||||||
|
|
||||||
|
serviceAssumeDomain(s);
|
||||||
|
cmifMakeCloseRequest(armGetTls(), object_id);
|
||||||
|
svcSendSyncRequest(sessionmgrGetClientSession(&g_friendsSessionMgr, slot));
|
||||||
|
sessionmgrDetachClient(&g_friendsSessionMgr, slot);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NX_INLINE Result _friendsObjectDispatchImpl(Service* s, u32 request_id,
|
||||||
|
const void * in_data, u32 in_data_size,
|
||||||
|
void * out_data, u32 out_data_size,
|
||||||
|
SfDispatchParams disp)
|
||||||
|
{
|
||||||
|
int slot = -1;
|
||||||
|
if (_friendsObjectIsChild(s)) {
|
||||||
|
slot = sessionmgrAttachClient(&g_friendsSessionMgr);
|
||||||
|
if (slot < 0)
|
||||||
|
__builtin_unreachable();
|
||||||
|
disp.target_session = sessionmgrGetClientSession(&g_friendsSessionMgr, slot);
|
||||||
|
serviceAssumeDomain(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
Result rc = serviceDispatchImpl(s, request_id, in_data, in_data_size, out_data, out_data_size, disp);
|
||||||
|
|
||||||
|
if (slot >= 0)
|
||||||
|
sessionmgrDetachClient(&g_friendsSessionMgr, slot);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _friendsObjectDispatch(_s,_rid,...) \
|
||||||
|
_friendsObjectDispatchImpl((_s),(_rid),NULL,0,NULL,0,(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
#define _friendsObjectDispatchIn(_s,_rid,_in,...) \
|
||||||
|
_friendsObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),NULL,0,(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
#define _friendsObjectDispatchOut(_s,_rid,_out,...) \
|
||||||
|
_friendsObjectDispatchImpl((_s),(_rid),NULL,0,&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
#define _friendsObjectDispatchInOut(_s,_rid,_in,_out,...) \
|
||||||
|
_friendsObjectDispatchImpl((_s),(_rid),&(_in),sizeof(_in),&(_out),sizeof(_out),(SfDispatchParams){ __VA_ARGS__ })
|
||||||
|
|
||||||
|
Result _friendsInitialize(FriendsServiceType service_type) {
|
||||||
Result rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
Result rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
|
||||||
|
|
||||||
g_friendsServiceType = service_type;
|
g_friendsServiceType = service_type;
|
||||||
|
|
||||||
switch (g_friendsServiceType) {
|
switch (g_friendsServiceType) {
|
||||||
case FriendServiceType_User:
|
case FriendsServiceType_User:
|
||||||
rc = smGetService(&g_friendSrv, "friend:u");
|
rc = smGetService(&g_friendsSrv, "friend:u");
|
||||||
break;
|
break;
|
||||||
case FriendServiceType_Administrator:
|
case FriendsServiceType_Administrator:
|
||||||
rc = smGetService(&g_friendSrv, "friend:a");
|
rc = smGetService(&g_friendsSrv, "friend:a");
|
||||||
break;
|
break;
|
||||||
case FriendServiceType_Manager:
|
case FriendsServiceType_Manager:
|
||||||
rc = smGetService(&g_friendSrv, "friend:m");
|
rc = smGetService(&g_friendsSrv, "friend:m");
|
||||||
break;
|
break;
|
||||||
case FriendServiceType_Viewer:
|
case FriendsServiceType_Viewer:
|
||||||
rc = smGetService(&g_friendSrv, "friend:v");
|
rc = smGetService(&g_friendsSrv, "friend:v");
|
||||||
break;
|
break;
|
||||||
case FriendServiceType_System:
|
case FriendsServiceType_System:
|
||||||
rc = smGetService(&g_friendSrv, "friend:s");
|
rc = smGetService(&g_friendsSrv, "friend:s");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = serviceDispatch(&g_friendSrv, 0,
|
if (R_SUCCEEDED(rc))
|
||||||
.out_num_objects = 1,
|
rc = serviceConvertToDomain(&g_friendsSrv);
|
||||||
.out_objects = &g_friendsIFriendService,
|
|
||||||
);
|
if (R_SUCCEEDED(rc))
|
||||||
|
rc = sessionmgrCreate(&g_friendsSessionMgr, g_friendsSrv.session, 0x5);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
rc = _friendsObjectDispatch(&g_friendsSrv, 0,
|
||||||
|
.out_num_objects = 1,
|
||||||
|
.out_objects = &g_friendsIFriendService
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _friendsCleanup(void) {
|
void _friendsCleanup(void) {
|
||||||
serviceClose(&g_friendsIFriendService);
|
sessionmgrClose(&g_friendsSessionMgr);
|
||||||
serviceClose(&g_friendSrv);
|
_friendsObjectClose(&g_friendsIFriendService);
|
||||||
|
serviceClose(&g_friendsSrv);
|
||||||
}
|
}
|
||||||
|
|
||||||
Service* friendsGetServiceSession(void) {
|
Service* friendsGetServiceSession(void) {
|
||||||
return &g_friendSrv;
|
return &g_friendsSrv;
|
||||||
}
|
}
|
||||||
|
|
||||||
Service* friendsGetServiceSession_IFriendsService(void)
|
Service* friendsGetServiceSession_IFriendsService(void) {
|
||||||
{
|
|
||||||
return &g_friendsIFriendService;
|
return &g_friendsIFriendService;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result friendsGetUserSetting(AccountUid uid, FriendUserSetting *user_setting) {
|
Result friendsGetUserSetting(AccountUid uid, FriendsUserSetting *user_setting) {
|
||||||
return serviceDispatchIn(&g_friendsIFriendService, 20800, uid,
|
return _friendsObjectDispatchIn(&g_friendsIFriendService, 20800, uid,
|
||||||
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize },
|
.buffer_attrs = { SfBufferAttr_HipcPointer | SfBufferAttr_Out | SfBufferAttr_FixedSize },
|
||||||
.buffers = { { user_setting, sizeof(FriendUserSetting) } }
|
.buffers = { { user_setting, sizeof(FriendsUserSetting) } }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user