My Project
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Modules
srv.c
Go to the documentation of this file.
1 /*
2  srv.c _ Service manager.
3 */
4 
5 #include <string.h>
6 #include <3ds.h>
7 
8 
9 /*
10  The homebrew loader can choose to supply a list of service handles that have
11  been "stolen" from other processes that have been compromised. This allows us
12  to access services that are normally restricted from the current process.
13 
14  For every service requested by the application, we shall first check if the
15  list given to us contains the requested service and if so use it. If we don't
16  find the service in that list, we ask the service manager and hope for the
17  best.
18  */
19 
20 typedef struct {
22 
23  struct {
24  char name[8];
26  } services[];
28 
30 
31 static Handle g_srv_handle = 0;
32 
33 
34 static int __name_cmp(const char* a, const char* b) {
35  u32 i;
36 
37  for(i=0; i<8; i++) {
38  if(a[i] != b[i])
39  return 1;
40  if(a[i] == '\0')
41  return 0;
42  }
43 
44  return 0;
45 }
46 
47 Handle __get_handle_from_list(const char* name) {
48  if((u32)__service_ptr == 0)
49  return 0;
50 
51  u32 i, num = __service_ptr->num;
52 
53  for(i=0; i<num; i++) {
54  if(__name_cmp(__service_ptr->services[i].name, name) == 0)
55  return __service_ptr->services[i].handle;
56  }
57 
58  return 0;
59 }
60 
62  if((u32)__service_ptr == 0)
63  return;
64 
65  u32 i, num = __service_ptr->num;
66 
67  for(i=0; i<num; i++)
68  svcCloseHandle(__service_ptr->services[i].handle);
69 
70  __service_ptr->num = 0;
71 }
72 
74 {
75  Result rc = 0;
76 
77  if((rc = svcConnectToPort(&g_srv_handle, "srv:")))return rc;
78 
79  if((rc = srvRegisterClient())) {
80  svcCloseHandle(g_srv_handle);
81  g_srv_handle = 0;
82  }
83 
84  return rc;
85 }
86 
88 {
89  if(g_srv_handle != 0)svcCloseHandle(g_srv_handle);
90 
91  g_srv_handle = 0;
92  return 0;
93 }
94 
96 {
97  Result rc = 0;
98 
99  u32* cmdbuf = getThreadCommandBuffer();
100 
101  cmdbuf[0] = 0x10002;
102  cmdbuf[1] = 0x20;
103 
104  if((rc = svcSendSyncRequest(g_srv_handle)))return rc;
105 
106  return cmdbuf[1];
107 }
108 
109 Result srvGetServiceHandle(Handle* out, const char* name)
110 {
111  Result rc = 0;
112 
113  /* Look in service-list given to us by loader. If we find find a match,
114  we return it. */
115  Handle h = __get_handle_from_list(name);
116 
117  if(h != 0) {
118  return svcDuplicateHandle(out, h);
119  }
120 
121  /* Normal request to service manager. */
122  u32* cmdbuf = getThreadCommandBuffer();
123  cmdbuf[0] = 0x50100;
124  strcpy((char*) &cmdbuf[1], name);
125  cmdbuf[3] = strlen(name);
126  cmdbuf[4] = 0x0;
127 
128  if((rc = svcSendSyncRequest(g_srv_handle)))return rc;
129 
130  *out = cmdbuf[3];
131  return cmdbuf[1];
132 }
133 
134 // Old srv:pm interface, will only work on systems where srv:pm was a port (<7.X)
136 {
137  Result rc = 0;
138 
139  if((rc = svcConnectToPort(&g_srv_handle, "srv:pm")))return rc;
140 
141  if((rc = srvRegisterClient())) {
142  svcCloseHandle(g_srv_handle);
143  g_srv_handle = 0;
144  }
145 
146  return rc;
147 }
148 
149 Result srvRegisterProcess(u32 procid, u32 count, void *serviceaccesscontrol)
150 {
151  Result rc = 0;
152 
153  u32 *cmdbuf = getThreadCommandBuffer();
154 
155  cmdbuf[0] = 0x04030082; // <7.x
156  cmdbuf[1] = procid;
157  cmdbuf[2] = count;
158  cmdbuf[3] = (count << 16) | 2;
159  cmdbuf[4] = (u32)serviceaccesscontrol;
160 
161  if((rc = svcSendSyncRequest(g_srv_handle))) return rc;
162 
163  return cmdbuf[1];
164 }
165 
167 {
168  Result rc = 0;
169 
170  u32 *cmdbuf = getThreadCommandBuffer();
171 
172  cmdbuf[0] = 0x04040040; // <7.x
173  cmdbuf[1] = procid;
174 
175  if((rc = svcSendSyncRequest(g_srv_handle))) return rc;
176 
177  return cmdbuf[1];
178 }
s32 Result
Definition: types.h:42
s32 svcCloseHandle(Handle handle)
Result srvInit()
Definition: srv.c:73
service_list_t * __service_ptr
u32 Handle
Definition: types.h:41
u32 * getThreadCommandBuffer(void)
Handle __get_handle_from_list(const char *name)
Definition: srv.c:47
uint32_t u32
Definition: types.h:23
Result srvRegisterClient()
Definition: srv.c:95
Handle handle
Definition: srv.c:25
Result srvExit()
Definition: srv.c:87
Result srvGetServiceHandle(Handle *out, const char *name)
Definition: srv.c:109
Result srvRegisterProcess(u32 procid, u32 count, void *serviceaccesscontrol)
Definition: srv.c:149
u32 num
Definition: srv.c:21
s32 svcConnectToPort(volatile Handle *out, const char *portName)
char name[8]
Definition: srv.c:24
s32 svcSendSyncRequest(Handle session)
Result srvUnregisterProcess(u32 procid)
Definition: srv.c:166
void __destroy_handle_list(void)
Definition: srv.c:61
struct service_list_t::@1 services[]
Result srvPmInit()
Definition: srv.c:135
s32 svcDuplicateHandle(Handle *out, Handle original)