ns.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. #include <stdio.h>
  2. #include <stdbool.h>
  3. #include <switch.h>
  4. #include "nx/ns.h"
  5. #include "util/log.h"
  6. Service NS_APP_SERV = {0};
  7. Result __ns_get_application_service(void)
  8. {
  9. if (hosversionBefore(3, 0, 0))
  10. return smGetService(&NS_APP_SERV, "ns:am");
  11. else
  12. return nsGetApplicationManagerInterface(&NS_APP_SERV);
  13. }
  14. bool init_ns(void)
  15. {
  16. if (R_FAILED(nsInitialize())) return false;
  17. if (R_FAILED(__ns_get_application_service())) return false;
  18. return true;
  19. }
  20. void exit_ns(void)
  21. {
  22. serviceClose(&NS_APP_SERV);
  23. nsExit();
  24. }
  25. int64_t ns_get_storage_total_size(NcmStorageId storage_id)
  26. {
  27. int64_t size = 0;
  28. if (R_FAILED(nsGetTotalSpaceSize(storage_id, &size)))
  29. write_log("failed to get ns total storage size\n");
  30. return size;
  31. }
  32. int64_t ns_get_storage_free_space(NcmStorageId storage_id)
  33. {
  34. int64_t size = 0;
  35. if (R_FAILED(nsGetFreeSpaceSize(storage_id, &size)))
  36. write_log("failed to get ns total free space\n");
  37. return size;
  38. }
  39. int32_t ns_list_app_record(NsApplicationRecord *out, int32_t count, int32_t offset)
  40. {
  41. int32_t out_count = 0;
  42. if (R_FAILED(nsListApplicationRecord(out, count, offset, &out_count)))
  43. write_log("failed to list app records\n");
  44. return out_count;
  45. }
  46. int32_t ns_list_app_cnmt_status(NsApplicationContentMetaStatus *out, int32_t count, uint64_t app_id)
  47. {
  48. int32_t out_count = 0;
  49. if (R_FAILED(nsListApplicationContentMetaStatus(app_id, 0, out, count, &out_count)))
  50. write_log("failed to list cnmt status\n");
  51. return out_count;
  52. }
  53. size_t ns_get_app_control_data(NsApplicationControlData *out, uint64_t app_id)
  54. {
  55. size_t out_size = 0;
  56. Result rc = nsGetApplicationControlData(NsApplicationControlSource_Storage, app_id, out, sizeof(NsApplicationControlData), &out_size);
  57. if (R_FAILED(rc))
  58. write_log("failed to get app control data with app_id: %lu\n", app_id);
  59. return out_size;
  60. }
  61. int32_t ns_get_app_delivery_info(NsApplicationDeliveryInfo *out, int32_t count, uint64_t app_id, uint32_t attr)
  62. {
  63. int32_t out_count = 0;
  64. if (!hosversionAtLeast(4, 0, 0))
  65. return out_count;
  66. if (R_FAILED(nsGetApplicationDeliveryInfo(out, count, app_id, attr, &out_count)))
  67. write_log("failed to get app delivery info\n");
  68. if (out_count != count)
  69. write_log("ns_get_app_delivery_info missmatch: got %d, expected %d\n", out_count, count);
  70. return out_count;
  71. }
  72. bool ns_check_app_delivery_info(const NsApplicationDeliveryInfo *info)
  73. {
  74. bool res = false;
  75. if (!hosversionAtLeast(4, 0, 0))
  76. return res;
  77. if (R_FAILED(nsHasAllContentsToDeliver(info, 1, &res)))
  78. write_log("failed to check for valid app delivery info\n");
  79. return res;
  80. }
  81. int32_t ns_compare_app_delivery_info(const NsApplicationDeliveryInfo *info0, const NsApplicationDeliveryInfo *info1)
  82. {
  83. int32_t res = -1;
  84. if (!hosversionAtLeast(4, 0, 0))
  85. return res;
  86. if (R_FAILED(nsCompareApplicationDeliveryInfo(info0, 1, info1, 1, &res)))
  87. write_log("failed to compare app delivery infos\n");
  88. return res;
  89. }
  90. bool ns_check_if_can_deliver_app_info(NsApplicationDeliveryInfo *info0, int32_t count0, NsApplicationDeliveryInfo *info1)
  91. {
  92. bool res = false;
  93. if (!hosversionAtLeast(4, 0, 0))
  94. return res;
  95. if (R_FAILED(nsCanDeliverApplication(info0, count0, info1, 1, &res)))
  96. write_log("failed to check if app info can be delivered\n");
  97. return res;
  98. }
  99. int32_t ns_list_content_meta_key(NcmContentMetaKey *meta, NsApplicationDeliveryInfo *info)
  100. {
  101. int32_t total_out = 0;
  102. if (!hosversionAtLeast(4, 0, 0))
  103. return total_out;
  104. if (R_FAILED(nsListContentMetaKeyToDeliverApplication(meta, 1, 0, info, 1, &total_out)))
  105. write_log("failed to list content meta key\n");
  106. return total_out;
  107. }
  108. int32_t ns_count_application_record(uint64_t app_id)
  109. {
  110. int32_t count = 0;
  111. Result rc = serviceDispatchInOut(&NS_APP_SERV, 1, app_id, count, SfOutHandleAttr_None);
  112. if (R_FAILED(rc))
  113. write_log("failed to count application records\n");
  114. return count;
  115. }
  116. bool ns_is_any_application_redundent(void)
  117. {
  118. Result rc = 0;
  119. bool ret = false;
  120. if (R_FAILED(rc))
  121. {
  122. write_log("failed %s %s\n", __func__, R_DESCRIPTION(rc));
  123. return false;
  124. }
  125. return ret;
  126. }
  127. Result ns_delete_application_entity(uint64_t app_id)
  128. {
  129. Result rc = nsDeleteApplicationEntity(app_id);
  130. if (R_FAILED(rc))
  131. write_log("failed to delete application entity\n");
  132. return rc;
  133. }
  134. Result ns_delete_application_completely(uint64_t app_id)
  135. {
  136. Result rc = nsDeleteApplicationCompletely(app_id);
  137. if (R_FAILED(rc))
  138. write_log("failed to delete application completely\n");
  139. return rc;
  140. }
  141. bool ns_is_application_moveable(uint64_t app_id, NcmStorageId storage_id)
  142. {
  143. bool can_move = false;
  144. if (R_FAILED(nsIsApplicationEntityMovable(app_id, storage_id, &can_move)))
  145. write_log("failed to check if application %lu is moveable to storage_id %u\n", app_id, storage_id);
  146. return can_move;
  147. }
  148. Result ns_move_application(uint64_t app_id, NcmStorageId storage_id)
  149. {
  150. Result rc = nsMoveApplicationEntity(app_id, storage_id);
  151. if (R_FAILED(rc))
  152. write_log("failed to move application %lu to storage_id %u\n", app_id, storage_id);
  153. return rc;
  154. }
  155. NsApplicationOccupiedSize ns_get_application_occupied_size(uint64_t app_id)
  156. {
  157. NsApplicationOccupiedSize size = {0};
  158. Result rc = nsCalculateApplicationOccupiedSize(app_id, &size);
  159. if (R_FAILED(rc))
  160. write_log("failed to delete application record\n");
  161. return size;
  162. }
  163. bool ns_push_application_record(uint64_t app_id, const NcmContentStorageRecord *records, uint32_t count)
  164. {
  165. const struct
  166. {
  167. uint8_t last_modified_event;
  168. uint8_t padding[0x7];
  169. uint64_t app_id;
  170. } in = { NsApplicationRecordType_Installed, {0}, app_id };
  171. Result rc = serviceDispatchIn(&NS_APP_SERV, 16, in,
  172. .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
  173. .buffers = { { records, sizeof(NcmContentStorageRecord) * count } });
  174. if (R_FAILED(rc))
  175. {
  176. write_log("failed to push application record\n");
  177. return false;
  178. }
  179. return true;
  180. }
  181. bool ns_list_application_record_content_meta(uint64_t offset, uint64_t app_id, NcmContentStorageRecord *records, uint32_t count)
  182. {
  183. const struct
  184. {
  185. uint64_t offset;
  186. uint64_t app_id;
  187. } in = { offset, app_id };
  188. uint32_t out = 0;
  189. Result rc = serviceDispatchInOut(&NS_APP_SERV, 17, in, out,
  190. .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
  191. .buffers = { { records, sizeof(NcmContentStorageRecord) * count } });
  192. if (R_FAILED(rc))
  193. {
  194. write_log("failed to list app cnmt\n");
  195. return false;
  196. }
  197. return true;
  198. }
  199. bool ns_delete_application_record(uint64_t app_id)
  200. {
  201. Result rc = serviceDispatchIn(&NS_APP_SERV, 27, app_id, SfOutHandleAttr_None);
  202. if (R_FAILED(rc))
  203. {
  204. write_log("failed to delete application record\n");
  205. }
  206. return true;
  207. }
  208. int32_t ns_count_application_content_meta(uint64_t app_id)
  209. {
  210. int32_t count = 0;
  211. Result rc = nsCountApplicationContentMeta(app_id, &count);
  212. if (rc == 0x410) // not an error. Just means no cnmt found.
  213. {
  214. return 0;
  215. }
  216. if (R_FAILED(rc))
  217. {
  218. write_log("failed to count app cnmt\n");
  219. return 0;
  220. }
  221. return count;
  222. }
  223. //Result ncm_get_latest_key
  224. bool ns_application_overwrite_previous_entity(uint64_t id)
  225. {
  226. if (!id)
  227. {
  228. write_log("missing params in ns_application_pverwrite_previous_entity\n");
  229. return false;
  230. }
  231. Result rc = nsDeleteApplicationEntity(id); // this func wraps around ncmContentMetaDatabaseRemove.
  232. if (R_FAILED(rc))
  233. {
  234. write_log("failed to delete application_entity\n");
  235. return false;
  236. }
  237. return true;
  238. }
  239. #include <string.h>
  240. bool ns_get_gamecard_info(gamecard_info_t *info)
  241. {
  242. struct
  243. {
  244. uint8_t d[0x10];
  245. } out = {0};
  246. Result rc = serviceDispatchOut(&NS_APP_SERV, 46, out);
  247. if (R_FAILED(rc))
  248. {
  249. write_log("Failed to get gamecard info\n");
  250. return false;
  251. }
  252. memcpy(info, &out, 0x10);
  253. return true;
  254. }
  255. bool ns_has_application_record(uint64_t app_id) //5.0.0
  256. {
  257. bool has_record = false;
  258. //910
  259. // or
  260. // ReadOnlyApplicationRecordInterface.
  261. // 0.
  262. return has_record;
  263. }
  264. bool ns_get_application_record(NcmContentStorageRecord *record_out)
  265. {
  266. if (!hosversionAtLeast(2, 0, 0))
  267. return false;
  268. struct
  269. {
  270. uint8_t d[0x18];
  271. } out = {0};
  272. Result rc = serviceDispatchOut(&NS_APP_SERV, 900, out);
  273. if (R_FAILED(rc))
  274. {
  275. write_log("Failed to get gamecard info\n");
  276. return false;
  277. }
  278. memcpy(record_out, &out, sizeof(out));
  279. return true;
  280. }