installation_proxy.pxi 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. cdef extern from "libimobiledevice/installation_proxy.h":
  2. cdef struct instproxy_client_private:
  3. pass
  4. ctypedef instproxy_client_private *instproxy_client_t
  5. ctypedef void (*instproxy_status_cb_t) (plist.plist_t command, plist.plist_t status, void *user_data)
  6. ctypedef enum instproxy_error_t:
  7. INSTPROXY_E_SUCCESS = 0
  8. INSTPROXY_E_INVALID_ARG = -1
  9. INSTPROXY_E_PLIST_ERROR = -2
  10. INSTPROXY_E_CONN_FAILED = -3
  11. INSTPROXY_E_OP_IN_PROGRESS = -4
  12. INSTPROXY_E_OP_FAILED = -5
  13. INSTPROXY_E_UNKNOWN_ERROR = -256
  14. instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t descriptor, instproxy_client_t *client)
  15. instproxy_error_t instproxy_client_free(instproxy_client_t client)
  16. instproxy_error_t instproxy_client_get_path_for_bundle_identifier(instproxy_client_t client, const char* bundle_id, char** path)
  17. instproxy_error_t instproxy_browse(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result)
  18. instproxy_error_t instproxy_install(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
  19. instproxy_error_t instproxy_upgrade(instproxy_client_t client, char *pkg_path, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
  20. instproxy_error_t instproxy_uninstall(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
  21. instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist.plist_t client_options, plist.plist_t *result)
  22. instproxy_error_t instproxy_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
  23. instproxy_error_t instproxy_restore(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
  24. instproxy_error_t instproxy_remove_archive(instproxy_client_t client, char *appid, plist.plist_t client_options, instproxy_status_cb_t status_cb, void *user_data)
  25. cdef void instproxy_notify_cb(plist.plist_t command, plist.plist_t status, void *py_callback) with gil:
  26. (<object>py_callback)(plist.plist_t_to_node(command, False), plist.plist_t_to_node(status, False))
  27. cdef class InstallationProxyError(BaseError):
  28. def __init__(self, *args, **kwargs):
  29. self._lookup_table = {
  30. INSTPROXY_E_SUCCESS: "Success",
  31. INSTPROXY_E_INVALID_ARG: "Invalid argument",
  32. INSTPROXY_E_PLIST_ERROR: "Property list error",
  33. INSTPROXY_E_CONN_FAILED: "Connection failed",
  34. INSTPROXY_E_OP_IN_PROGRESS: "Operation in progress",
  35. INSTPROXY_E_OP_FAILED: "Operation failed",
  36. INSTPROXY_E_UNKNOWN_ERROR: "Unknown error"
  37. }
  38. BaseError.__init__(self, *args, **kwargs)
  39. cdef class InstallationProxyClient(PropertyListService):
  40. __service_name__ = "com.apple.mobile.installation_proxy"
  41. cdef instproxy_client_t _c_client
  42. def __cinit__(self, iDevice device not None, LockdownServiceDescriptor descriptor, *args, **kwargs):
  43. cdef:
  44. iDevice dev = device
  45. instproxy_error_t err
  46. err = instproxy_client_new(dev._c_dev, descriptor._c_service_descriptor, &self._c_client)
  47. self.handle_error(err)
  48. def __dealloc__(self):
  49. cdef instproxy_error_t err
  50. if self._c_client is not NULL:
  51. err = instproxy_client_free(self._c_client)
  52. self.handle_error(err)
  53. cpdef get_path_for_bundle_identifier(self, bytes bundle_id):
  54. cdef:
  55. char* c_bundle_id = bundle_id
  56. char* c_path = NULL
  57. bytes result
  58. try:
  59. self.handle_error(instproxy_client_get_path_for_bundle_identifier(self._c_client, c_bundle_id, &c_path))
  60. if c_path != NULL:
  61. result = c_path
  62. return result
  63. else:
  64. return None
  65. except BaseError, e:
  66. raise
  67. finally:
  68. free(c_path)
  69. cpdef plist.Node browse(self, object client_options):
  70. cdef:
  71. plist.Node options
  72. plist.plist_t c_options
  73. plist.plist_t c_result = NULL
  74. bint free_options = False
  75. instproxy_error_t err
  76. if isinstance(client_options, plist.Dict):
  77. options = client_options
  78. c_options = options._c_node
  79. elif isinstance(client_options, dict):
  80. c_options = plist.native_to_plist_t(client_options)
  81. free_options = True
  82. else:
  83. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  84. err = instproxy_browse(self._c_client, c_options, &c_result)
  85. try:
  86. self.handle_error(err)
  87. return plist.plist_t_to_node(c_result)
  88. except Exception, e:
  89. if c_result != NULL:
  90. plist.plist_free(c_result)
  91. raise
  92. finally:
  93. if free_options:
  94. plist.plist_free(c_options)
  95. cpdef install(self, bytes pkg_path, object client_options, object callback=None):
  96. cdef:
  97. plist.Node options
  98. plist.plist_t c_options
  99. bint free_options = False
  100. instproxy_error_t err
  101. if isinstance(client_options, plist.Dict):
  102. options = client_options
  103. c_options = options._c_node
  104. elif isinstance(client_options, dict):
  105. c_options = plist.native_to_plist_t(client_options)
  106. free_options = True
  107. else:
  108. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  109. if callback is None:
  110. err = instproxy_install(self._c_client, pkg_path, c_options, NULL, NULL)
  111. else:
  112. err = instproxy_install(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback)
  113. try:
  114. self.handle_error(err)
  115. except Exception, e:
  116. raise
  117. finally:
  118. if free_options:
  119. plist.plist_free(c_options)
  120. cpdef upgrade(self, bytes pkg_path, object client_options, object callback=None):
  121. cdef:
  122. plist.Node options
  123. plist.plist_t c_options
  124. bint free_options = False
  125. instproxy_error_t err
  126. if isinstance(client_options, plist.Dict):
  127. options = client_options
  128. c_options = options._c_node
  129. elif isinstance(client_options, dict):
  130. c_options = plist.native_to_plist_t(client_options)
  131. free_options = True
  132. else:
  133. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  134. if callback is None:
  135. err = instproxy_upgrade(self._c_client, pkg_path, c_options, NULL, NULL)
  136. else:
  137. err = instproxy_upgrade(self._c_client, pkg_path, c_options, instproxy_notify_cb, <void*>callback)
  138. try:
  139. self.handle_error(err)
  140. except Exception, e:
  141. raise
  142. finally:
  143. if free_options:
  144. plist.plist_free(c_options)
  145. cpdef uninstall(self, bytes appid, object client_options, object callback=None):
  146. cdef:
  147. plist.Node options
  148. plist.plist_t c_options
  149. instproxy_error_t err
  150. bint free_options = False
  151. if isinstance(client_options, plist.Dict):
  152. options = client_options
  153. c_options = options._c_node
  154. elif isinstance(client_options, dict):
  155. c_options = plist.native_to_plist_t(client_options)
  156. free_options = True
  157. else:
  158. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  159. if callback is None:
  160. err = instproxy_uninstall(self._c_client, appid, c_options, NULL, NULL)
  161. else:
  162. err = instproxy_uninstall(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
  163. try:
  164. self.handle_error(err)
  165. except Exception, e:
  166. raise
  167. finally:
  168. if free_options:
  169. plist.plist_free(c_options)
  170. cpdef plist.Node lookup_archives(self, object client_options):
  171. cdef:
  172. plist.Node options
  173. plist.plist_t c_options
  174. plist.plist_t c_node = NULL
  175. instproxy_error_t err
  176. bint free_options = False
  177. if isinstance(client_options, plist.Dict):
  178. options = client_options
  179. c_options = options._c_node
  180. elif isinstance(client_options, dict):
  181. c_options = plist.native_to_plist_t(client_options)
  182. free_options = True
  183. else:
  184. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  185. err = instproxy_lookup_archives(self._c_client, c_options, &c_node)
  186. try:
  187. self.handle_error(err)
  188. return plist.plist_t_to_node(c_node)
  189. except Exception, e:
  190. if c_node != NULL:
  191. plist.plist_free(c_node)
  192. raise
  193. finally:
  194. if free_options:
  195. plist.plist_free(c_options)
  196. cpdef archive(self, bytes appid, object client_options, object callback=None):
  197. cdef:
  198. plist.Node options
  199. plist.plist_t c_options
  200. bint free_options = False
  201. instproxy_error_t err
  202. if isinstance(client_options, plist.Dict):
  203. options = client_options
  204. c_options = options._c_node
  205. elif isinstance(client_options, dict):
  206. c_options = plist.native_to_plist_t(client_options)
  207. free_options = True
  208. else:
  209. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  210. if callback is None:
  211. err = instproxy_archive(self._c_client, appid, c_options, NULL, NULL)
  212. else:
  213. err = instproxy_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
  214. try:
  215. self.handle_error(err)
  216. except Exception, e:
  217. raise
  218. finally:
  219. if free_options:
  220. plist.plist_free(c_options)
  221. cpdef restore(self, bytes appid, object client_options, object callback=None):
  222. cdef:
  223. plist.Node options
  224. plist.plist_t c_options
  225. bint free_options = False
  226. instproxy_error_t err
  227. if isinstance(client_options, plist.Dict):
  228. options = client_options
  229. c_options = options._c_node
  230. elif isinstance(client_options, dict):
  231. c_options = plist.native_to_plist_t(client_options)
  232. free_options = True
  233. else:
  234. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  235. if callback is None:
  236. err = instproxy_restore(self._c_client, appid, c_options, NULL, NULL)
  237. else:
  238. err = instproxy_restore(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
  239. try:
  240. self.handle_error(err)
  241. except Exception, e:
  242. raise
  243. finally:
  244. if free_options:
  245. plist.plist_free(c_options)
  246. cpdef remove_archive(self, bytes appid, object client_options, object callback=None):
  247. cdef:
  248. plist.Node options
  249. plist.plist_t c_options
  250. bint free_options = False
  251. instproxy_error_t err
  252. if isinstance(client_options, plist.Dict):
  253. options = client_options
  254. c_options = options._c_node
  255. elif isinstance(client_options, dict):
  256. c_options = plist.native_to_plist_t(client_options)
  257. free_options = True
  258. else:
  259. raise InstallationProxyError(INSTPROXY_E_INVALID_ARG)
  260. if callback is None:
  261. err = instproxy_remove_archive(self._c_client, appid, c_options, NULL, NULL)
  262. else:
  263. err = instproxy_remove_archive(self._c_client, appid, c_options, instproxy_notify_cb, <void*>callback)
  264. try:
  265. self.handle_error(err)
  266. except Exception, e:
  267. raise
  268. finally:
  269. if free_options:
  270. plist.plist_free(c_options)
  271. cdef inline BaseError _error(self, int16_t ret):
  272. return InstallationProxyError(ret)