From 1b610070f51777ed43ebdba277a3886e3de4d959 Mon Sep 17 00:00:00 2001 From: yellows8 Date: Thu, 10 Oct 2019 21:06:14 -0400 Subject: [PATCH] pdmqry: Updated for new-ipc and updated for using AccountUid. Renamed pdmqryGetUserPlayedApplications to pdmqryQueryRecentlyPlayedApplication. Renamed pdmqryGetUserAccountEvent to pdmqryGetRecentlyPlayedApplicationUpdateEvent. Minor param name adjustment. --- nx/include/switch/services/pdm.h | 25 +- nx/source/services/pdm.c | 402 ++++++------------------------- 2 files changed, 84 insertions(+), 343 deletions(-) diff --git a/nx/include/switch/services/pdm.h b/nx/include/switch/services/pdm.h index 9c0253b2..4fb8847d 100644 --- a/nx/include/switch/services/pdm.h +++ b/nx/include/switch/services/pdm.h @@ -6,7 +6,8 @@ */ #pragma once #include "../types.h" -#include "../services/sm.h" +#include "../sf/service.h" +#include "../services/acc.h" #include "../kernel/event.h" /// PlayEventType @@ -132,7 +133,7 @@ typedef struct { /// AccountEvent typedef struct { - union { u128 userID; } PACKED; ///< userID. + AccountUid userID; ///< \ref AccountUid u32 entryindex; ///< Entry index. u8 pad[4]; ///< Padding. u64 timestampUser; ///< See PdmPlayEvent::timestampUser. @@ -182,10 +183,10 @@ Result pdmqryQueryPlayStatisticsByApplicationId(u64 titleID, PdmPlayStatistics * /** * @brief Gets \ref PdmPlayStatistics for the specified titleID and account userID. * @param[in] titleID Application titleID. - * @param[in] userID Account userID. + * @param[in] userID \ref AccountUid * @param[out] stats \ref PdmPlayStatistics */ -Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 titleID, u128 userID, PdmPlayStatistics *stats); +Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 titleID, AccountUid *userID, PdmPlayStatistics *stats); /** * @brief Gets \ref PdmLastPlayTime for the specified titles. @@ -226,39 +227,39 @@ Result pdmqryQueryAccountEvent(u32 entryindex, PdmAccountEvent *events, s32 coun * @brief Gets a list of \ref PdmAccountPlayEvent. * @note Only available with [4.0.0+]. * @param[in] entryindex Start entry index. - * @param[in] userID Account userID. + * @param[in] userID \ref AccountUid * @param[out] events Output \ref PdmAccountPlayEvent array. * @param[in] count Max entries in the output array. * @param[out] total_out Total output entries. */ -Result pdmqryQueryAccountPlayEvent(u32 entryindex, u128 userID, PdmAccountPlayEvent *events, s32 count, s32 *total_out); +Result pdmqryQueryAccountPlayEvent(u32 entryindex, AccountUid *userID, PdmAccountPlayEvent *events, s32 count, s32 *total_out); /** * @brief Gets range fields which can then be used with \ref pdmqryQueryAccountPlayEvent. - * @param[in] userID Account userID. + * @param[in] userID \ref AccountUid * @param[out] total_entries Total entries. * @param[out] start_entryindex Start entry index. * @param[out] end_entryindex End entry index. */ -Result pdmqryGetAvailableAccountPlayEventRange(u128 userID, u32 *total_entries, u32 *start_entryindex, u32 *end_entryindex); +Result pdmqryGetAvailableAccountPlayEventRange(AccountUid *userID, u32 *total_entries, u32 *start_entryindex, u32 *end_entryindex); /** * @brief Gets a list of titles played by the specified user. * @note Only available with [6.0.0+]. - * @param[in] userID Account userID. + * @param[in] userID \ref AccountUid * @param[out] titleIDs Output titleID array. * @param[in] count Max entries in the output array. * @param[out] total_out Total output entries. */ -Result pdmqryGetUserPlayedApplications(u128 userID, u64 *titleIDs, size_t count, u32 *total_out); +Result pdmqryQueryRecentlyPlayedApplication(AccountUid *userID, u64 *titleIDs, size_t count, u32 *total_out); /** * @brief Gets an Event which is signaled when logging a new \ref PdmPlayEvent which would be available via \ref pdmqryQueryAccountEvent, where PdmPlayEvent::eventData::account::type is 0. * @note Only available with [6.0.0+]. * @note The Event must be closed by the user once finished with it. - * @param[out] event_out Output Event with autoclear=false. + * @param[out] out_event Output Event with autoclear=false. */ -Result pdmqryGetUserAccountEvent(Event* event_out); +Result pdmqryGetRecentlyPlayedApplicationUpdateEvent(Event* out_event); /** * @brief Helper function which converts a Play timestamp from the Pdm*Event structs to POSIX. diff --git a/nx/source/services/pdm.c b/nx/source/services/pdm.c index fac7823d..e9db6f2f 100644 --- a/nx/source/services/pdm.c +++ b/nx/source/services/pdm.c @@ -1,193 +1,75 @@ +#define NX_SERVICE_ASSUME_NON_DOMAIN +#include "service_guard.h" #include -#include "types.h" -#include "result.h" -#include "arm/atomics.h" -#include "kernel/ipc.h" #include "kernel/event.h" -#include "services/sm.h" #include "services/pdm.h" +#include "services/acc.h" #include "runtime/hosversion.h" static Service g_pdmqrySrv; -static u64 g_pdmqryRefCnt; -Result pdmqryInitialize(void) { - atomicIncrement64(&g_pdmqryRefCnt); +NX_GENERATE_SERVICE_GUARD(pdmqry); - if (serviceIsActive(&g_pdmqrySrv)) - return 0; - - Result rc = smGetService(&g_pdmqrySrv, "pdm:qry"); - - if (R_FAILED(rc)) pdmqryExit(); - - return rc; +Result _pdmqryInitialize(void) { + return smGetService(&g_pdmqrySrv, "pdm:qry"); } -void pdmqryExit(void) { - if (atomicDecrement64(&g_pdmqryRefCnt) == 0) - serviceClose(&g_pdmqrySrv); +void _pdmqryCleanup(void) { + serviceClose(&g_pdmqrySrv); } Service* pdmqryGetServiceSession(void) { return &g_pdmqrySrv; } -static Result _pdmqryQueryEvent(u64 cmd_id, u32 entryindex, void* events, size_t entrysize, s32 count, s32 *total_out) { - IpcCommand c; - ipcInitialize(&c); +static Result _pdmCmdGetEvent(Service* srv, Event* out_event, bool autoclear, u32 cmd_id) { + Handle event = INVALID_HANDLE; + Result rc = serviceDispatch(srv, cmd_id, + .out_handle_attrs = { SfOutHandleAttr_HipcCopy }, + .out_handles = &event, + ); - ipcAddRecvBuffer(&c, events, count*entrysize, BufferType_Normal); - - struct { - u64 magic; - u64 cmd_id; - u32 entryindex; - } *raw; - - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = cmd_id; - raw->entryindex = entryindex; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - s32 total_out; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && total_out) *total_out = resp->total_out; - } + if (R_SUCCEEDED(rc)) + eventLoadRemote(out_event, event, autoclear); return rc; } +static Result _pdmqryQueryEvent(u32 cmd_id, u32 entryindex, void* events, size_t entrysize, s32 count, s32 *total_out) { + return serviceDispatchInOut(&g_pdmqrySrv, cmd_id, entryindex, *total_out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { events, count*entrysize } }, + ); +} + Result pdmqryQueryApplicationEvent(u32 entryindex, PdmApplicationEvent *events, s32 count, s32 *total_out) { return _pdmqryQueryEvent(0, entryindex, events, sizeof(PdmApplicationEvent), count, total_out); } Result pdmqryQueryPlayStatisticsByApplicationId(u64 titleID, PdmPlayStatistics *stats) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; - u64 titleID; - } *raw; - - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 4; - raw->titleID = titleID; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - PdmPlayStatistics stats; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && stats) memcpy(stats, &resp->stats, sizeof(resp->stats)); - } - - return rc; + return serviceDispatchInOut(&g_pdmqrySrv, 4, titleID, *stats); } -Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 titleID, u128 userID, PdmPlayStatistics *stats) { - IpcCommand c; - ipcInitialize(&c); - - struct { - u64 magic; - u64 cmd_id; +Result pdmqryQueryPlayStatisticsByApplicationIdAndUserAccountId(u64 titleID, AccountUid *userID, PdmPlayStatistics *stats) { + const struct { u64 titleID; - union { u128 userID; } PACKED; - } *raw; + AccountUid userID; + } in = { titleID, *userID }; - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 5; - raw->titleID = titleID; - raw->userID = userID; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - PdmPlayStatistics stats; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && stats) memcpy(stats, &resp->stats, sizeof(resp->stats)); - } - - return rc; + return serviceDispatchInOut(&g_pdmqrySrv, 5, in, *stats); } Result pdmqryQueryLastPlayTime(PdmLastPlayTime *playtimes, const u64 *titleIDs, s32 count, s32 *total_out) { - IpcCommand c; - ipcInitialize(&c); - - ipcAddSendBuffer(&c, titleIDs, count*sizeof(u64), BufferType_Normal); - ipcAddRecvBuffer(&c, playtimes, count*sizeof(PdmLastPlayTime), BufferType_Normal); - - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 7; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - s32 total_out; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && total_out) *total_out = resp->total_out; - } - - return rc; + return serviceDispatchOut(&g_pdmqrySrv, 7, *total_out, + .buffer_attrs = { + SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, + SfBufferAttr_HipcMapAlias | SfBufferAttr_In, + }, + .buffers = { + { playtimes, count*sizeof(PdmLastPlayTime) }, + { titleIDs, count*sizeof(u64) }, + }, + ); } Result pdmqryQueryPlayEvent(u32 entryindex, PdmPlayEvent *events, s32 count, s32 *total_out) { @@ -195,41 +77,18 @@ Result pdmqryQueryPlayEvent(u32 entryindex, PdmPlayEvent *events, s32 count, s32 } Result pdmqryGetAvailablePlayEventRange(u32 *total_entries, u32 *start_entryindex, u32 *end_entryindex) { - IpcCommand c; - ipcInitialize(&c); - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 9; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); + u32 total_entries; + u32 start_entryindex; + u32 end_entryindex; + } out; + Result rc = serviceDispatchOut(&g_pdmqrySrv, 9, out); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u32 total_entries; - u32 start_entryindex; - u32 end_entryindex; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries; - if (R_SUCCEEDED(rc) && start_entryindex) *start_entryindex = resp->start_entryindex; - if (R_SUCCEEDED(rc) && end_entryindex) *end_entryindex = resp->end_entryindex; + if (total_entries) *total_entries = out.total_entries; + if (start_entryindex) *start_entryindex = out.start_entryindex; + if (end_entryindex) *end_entryindex = out.end_entryindex; } - return rc; } @@ -237,173 +96,54 @@ Result pdmqryQueryAccountEvent(u32 entryindex, PdmAccountEvent *events, s32 coun return _pdmqryQueryEvent(10, entryindex, events, sizeof(PdmAccountEvent), count, total_out); } -Result pdmqryQueryAccountPlayEvent(u32 entryindex, u128 userID, PdmAccountPlayEvent *events, s32 count, s32 *total_out) { - IpcCommand c; - ipcInitialize(&c); - +Result pdmqryQueryAccountPlayEvent(u32 entryindex, AccountUid *userID, PdmAccountPlayEvent *events, s32 count, s32 *total_out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - ipcAddRecvBuffer(&c, events, count*sizeof(PdmAccountPlayEvent), BufferType_Normal); - - struct { - u64 magic; - u64 cmd_id; + const struct { u32 entryindex; - u32 pad; - union { u128 userID; } PACKED; - } *raw; + AccountUid userID; + } in = { entryindex, *userID }; - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 11; - raw->entryindex = entryindex; - raw->userID = userID; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - s32 total_out; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && total_out) *total_out = resp->total_out; - } - - return rc; + return serviceDispatchInOut(&g_pdmqrySrv, 11, in, *total_out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { events, count*sizeof(PdmAccountPlayEvent) } }, + ); } -Result pdmqryGetAvailableAccountPlayEventRange(u128 userID, u32 *total_entries, u32 *start_entryindex, u32 *end_entryindex) { - IpcCommand c; - ipcInitialize(&c); - +Result pdmqryGetAvailableAccountPlayEventRange(AccountUid *userID, u32 *total_entries, u32 *start_entryindex, u32 *end_entryindex) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); struct { - u64 magic; - u64 cmd_id; - u128 userID; - } *raw; - - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 12; - raw->userID = userID; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); + u32 total_entries; + u32 start_entryindex; + u32 end_entryindex; + } out; + Result rc = serviceDispatchInOut(&g_pdmqrySrv, 12, *userID, out); if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u32 total_entries; - u32 start_entryindex; - u32 end_entryindex; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries; - if (R_SUCCEEDED(rc) && start_entryindex) *start_entryindex = resp->start_entryindex; - if (R_SUCCEEDED(rc) && end_entryindex) *end_entryindex = resp->end_entryindex; + if (total_entries) *total_entries = out.total_entries; + if (start_entryindex) *start_entryindex = out.start_entryindex; + if (end_entryindex) *end_entryindex = out.end_entryindex; } - return rc; } -Result pdmqryGetUserPlayedApplications(u128 userID, u64 *titleIDs, size_t count, u32 *total_out) { - IpcCommand c; - ipcInitialize(&c); - +Result pdmqryQueryRecentlyPlayedApplication(AccountUid *userID, u64 *titleIDs, size_t count, u32 *total_out) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - ipcAddRecvBuffer(&c, titleIDs, count*sizeof(u64), BufferType_Normal); - - struct { - u64 magic; - u64 cmd_id; - u128 userID; - } *raw; - - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 14; - raw->userID = userID; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - u32 total_out; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc) && total_out) *total_out = resp->total_out; - } - - return rc; + return serviceDispatchInOut(&g_pdmqrySrv, 14, *userID, *total_out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { titleIDs, count*sizeof(u64) } }, + ); } -Result pdmqryGetUserAccountEvent(Event* event_out) { - IpcCommand c; - ipcInitialize(&c); - +Result pdmqryGetRecentlyPlayedApplicationUpdateEvent(Event* out_event) { if (hosversionBefore(6,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - struct { - u64 magic; - u64 cmd_id; - } *raw; - - raw = serviceIpcPrepareHeader(&g_pdmqrySrv, &c, sizeof(*raw)); - - raw->magic = SFCI_MAGIC; - raw->cmd_id = 15; - - Result rc = serviceIpcDispatch(&g_pdmqrySrv); - - if (R_SUCCEEDED(rc)) { - IpcParsedCommand r; - struct { - u64 magic; - u64 result; - } *resp; - - serviceIpcParse(&g_pdmqrySrv, &r, sizeof(*resp)); - resp = r.Raw; - - rc = resp->result; - - if (R_SUCCEEDED(rc)) { - eventLoadRemote(event_out, r.Handles[0], false); - } - } - - return rc; + return _pdmCmdGetEvent(&g_pdmqrySrv, out_event, false, 15); }