<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://www.3dbrew.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tekito256</id>
	<title>3dbrew - User contributions [en]</title>
	<link rel="self" type="application/atom+xml" href="https://www.3dbrew.org/w/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Tekito256"/>
	<link rel="alternate" type="text/html" href="https://www.3dbrew.org/wiki/Special:Contributions/Tekito256"/>
	<updated>2026-04-15T20:11:41Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.43.1</generator>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=IPC&amp;diff=22420</id>
		<title>IPC</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=IPC&amp;diff=22420"/>
		<updated>2023-10-21T07:33:02Z</updated>

		<summary type="html">&lt;p&gt;Tekito256: Fix source code missing&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The 3DS software stack follows a server/client architecture, where common functionality is provided by global server processes through interfaces called &#039;&#039;ports&#039;&#039; and &#039;&#039;services&#039;&#039;. Applications can access this functionality by creating &#039;&#039;sessions&#039;&#039; to the provided services. Technically, this is implemented using &#039;&#039;interprocess communication&#039;&#039; (IPC).&lt;br /&gt;
&lt;br /&gt;
== Concepts ==&lt;br /&gt;
&lt;br /&gt;
=== Sessions ===&lt;br /&gt;
&lt;br /&gt;
Sessions are communication channels consisting of a client and server, through which data can be exchanged in the form of a request and response, respectively. Through sessions, the standard [[#Command Structure|IPC command protocol]] is implemented. Clients use their client session handle to send IPC commands to the server using svcSendSyncRequest, while servers use svcReplyAndReceive to reply. Client sessions can&#039;t be used with svcReplyAndReceive. In both cases, the kernel takes care of transferring IPC command data from the [[Thread Local Storage]] of the sending thread to the TLS of the receiving thread. Sessions can be created through svcCreateSession, which provides the caller with the client and server handles.&lt;br /&gt;
&lt;br /&gt;
Sessions are used in their raw form to implement [[FS:OpenFile|file handles]]. In this case, fs-module creates a raw session using svcCreateSession, and provides the &amp;quot;fs:USER&amp;quot; client with the resulting client session handle, keeping the server session handle for its own use. These sessions expose their [[Filesystem services#File service|own set of IPC commands]] which act on the file that was opened through fs:USER.&lt;br /&gt;
&lt;br /&gt;
=== Ports ===&lt;br /&gt;
&lt;br /&gt;
Ports are interfaces for managing multiple client sessions to the same high-level server. Ports are created through svcCreatePort, and can be global or private. A global port is created by passing a name for the port to svcCreatePort. Clients can start IPC sessions to global ports by connecting to the port using svcConnectToPort, passing the desired port name. If the port is private, it is not possible to create a session through svcConnectToPort - sessions can only be created if one has a handle to the port itself, obtained from the call to svcCreatePort. When a client wishes to connect to a port (i.e. create a session), the server must accept the new session using svcAcceptSession. The kernel notifies the server whenever a new session is incoming via the server&#039;s port handle. The server can wait for this notification through svcWaitSynchronization or svcReplyAndReceive.&lt;br /&gt;
&lt;br /&gt;
The two global ports usually found on retail are &amp;quot;srv:&amp;quot; ([[Services|service manager]]) and &amp;quot;err:f&amp;quot; ([[ErrDisp]]).&lt;br /&gt;
&lt;br /&gt;
=== Services ===&lt;br /&gt;
&lt;br /&gt;
Services are an abstraction of ports that are managed by service manager. Services cannot be connected to through svcConnectToPort, as the underlying port is a private port. The service name is instead entirely handled by service manager, and the kernel is not aware of it. Clients are instead expected to open a session to a service using the &amp;quot;srv:&amp;quot; port command [[SRV:GetServiceHandle|GetServiceHandle]]. The client process must pass an access permission check for each service (by name) that it attempts to request a session with. These permissions are granted in the &amp;quot;service access control&amp;quot; of the title&#039;s [[NCCH/Extended Header#ARM11 Local System Capabilities|extended header]]. A service is registered with service manager using the command [[SRV:RegisterService|RegisterService]].&lt;br /&gt;
&lt;br /&gt;
Internally, service manager creates services by creating a private port which it associates with the desired service name. The resulting server port handle is returned in the RegisterService response, for the server&#039;s own use (see ports). To create sessions to a service on behalf of a client, service manager uses svcCreateSessionToPort, passing the client port handle it obtained when creating the port, to the kernel. Service manager then returns the resulting session handle to the client in the GetServiceHandle response.&lt;br /&gt;
&lt;br /&gt;
The majority of 3DS inter-process communication is implemented as services.&lt;br /&gt;
&lt;br /&gt;
=== Shared Memory ===&lt;br /&gt;
&lt;br /&gt;
Communication through port/service requests and replies may incur a big bottleneck when exchanging large amounts of data because the kernel needs to transfer the data between the two involved processes. There is hence a complementary feature to share the same physical memory between two processes. For this purpose, one process needs to create a block of shared memory using svcCreateMemoryBlock such that the other process can map it into its own virtual memory address space using svcMapMemoryBlock. The memory block handle for the latter is provided using a regular IPC command.&lt;br /&gt;
&lt;br /&gt;
Many services use shared memory as a secondary command interface (e.g. [[GSP_Shared_Memory|GSP]]), the processing of which is triggered through an IPC request (cf. [[GSPGPU:TriggerCmdReqQueue]]).&lt;br /&gt;
&lt;br /&gt;
== Message Structure ==&lt;br /&gt;
&lt;br /&gt;
IPC requests are written to the [[Thread Local Storage]] at offset 0x80 and submitted using [[SVC|svcSendSyncRequest]]. If the kernel was able to dispatch the request, the server reply will be written to TLS+0x80 before svcSendSyncRequest returns. By convention, the second word of the response data is an error code (or 0 on success). IPC requests and IPC replies follow the same structure.&lt;br /&gt;
&lt;br /&gt;
Every IPC message starts with a u32 header code. Parameters (if any) are written following this header. There are &amp;quot;normal parameters&amp;quot;, which are fixed-size words, and there are &amp;quot;translate parameters&amp;quot;, which are of flexible size and each of which begins with a header. The entire command has the following structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Word&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0&lt;br /&gt;
| 1&lt;br /&gt;
| Header code&lt;br /&gt;
|-&lt;br /&gt;
| 1&lt;br /&gt;
| x&lt;br /&gt;
| Normal parameters&lt;br /&gt;
|-&lt;br /&gt;
| 1+x&lt;br /&gt;
| y&lt;br /&gt;
| Translate parameters&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The IPC message header has the following structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Bits&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0-5&lt;br /&gt;
| Total size in words of the translate parameters (=y). Note that this is in general different from the number of translate parameters&lt;br /&gt;
|-&lt;br /&gt;
| 6-11&lt;br /&gt;
| Number of normal parameters (=x)&lt;br /&gt;
|-&lt;br /&gt;
| 12-15&lt;br /&gt;
| Unused&lt;br /&gt;
|-&lt;br /&gt;
| 16-31&lt;br /&gt;
| Command ID&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When calling svcSendSyncRequest, the command id specifies a function specific to the target service to call. When calling svcReplyAndReceive, the command ID is generally ignored. However if it&#039;s 0xffff (and 0 is passed for the reply target handle), the kernel will omit the IPC reply and just wait for incoming IPC requests.&lt;br /&gt;
&lt;br /&gt;
Each translate parameter starts with a translation descriptor:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Bits&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 1-3&lt;br /&gt;
| Translation type&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Translate parameters are modified/translated transparently by the kernel. They are used to transfer handles/buffers between the different processes.&lt;br /&gt;
&lt;br /&gt;
The type of parameter is described by the bits 1-3 in the translation descriptor. Parameter types accepted for sending by the kernel are: 0, 1, 2, 5, 6, 7. &lt;br /&gt;
&lt;br /&gt;
For replies, only 0, 1, 5, 6, 7 are allowed. In other words any type 2 fields must be zeroed before calling svcReplyAndReceive on the server-side. For replies, type 0, 1, and 2 are ignored. Types 5, 6, and 7 do something with the mem pointer upon reply. The type 0 descriptor can be used to ignore parameters. The number of parameters covered by a type-0 descriptor is (desc &amp;gt;&amp;gt; 26) + 1.&lt;br /&gt;
&lt;br /&gt;
=== Handle Translation ===&lt;br /&gt;
&lt;br /&gt;
Translation type 0 is used to send handles across processes. The corresponding translation descriptor has the following structure:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Bits&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 4&lt;br /&gt;
| If set, the handles are closed for the caller. Interaction with bit5 unknown.&lt;br /&gt;
|-&lt;br /&gt;
| 5&lt;br /&gt;
| If set, the following handles are replaced by the process ID. Otherwise, translate each handle between client and server.&lt;br /&gt;
|-&lt;br /&gt;
| 26-31&lt;br /&gt;
| Number of handles following this descriptor (minus one).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Usage examples:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; width=&amp;quot;300&amp;quot; |  Usual form&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00000000 &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; ((num_handles-1)&amp;lt;&amp;lt;26)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;handle 0&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;handle 1&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
| Copies the given KHandles to the receiving process, i.e. creating new handles in the target process while keeping around the ones of the source process. When a handle value is 0x0, value 0x0 is written to the destination cmdbuf without doing any actual handle-transfer.&lt;br /&gt;
|-&lt;br /&gt;
| 0x00000010 &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; ((num_handles-1)&amp;lt;&amp;lt;26)&lt;br /&gt;
&lt;br /&gt;
&amp;lt;handle 0&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;handle 1&amp;gt;&lt;br /&gt;
...&lt;br /&gt;
| Moves the given KHandles to the receiving process, i.e. creating new handles in the target process and closing the ones of the source process. When a handle value is 0x0, value 0x0 is written to the destination cmdbuf without doing any actual handle-transfer.&lt;br /&gt;
|-&lt;br /&gt;
| 0x00000020&lt;br /&gt;
&amp;lt;placeholder&amp;gt;&lt;br /&gt;
| Let kernel set value to calling process ProcessID.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Static Buffer Translation ===&lt;br /&gt;
&lt;br /&gt;
Each thread may set up up to 16 static buffer descriptors in their [[Thread Local Storage]] at offset 0x180. These contain information about buffers in the thread&#039;s memory space that may be used for information exchange for communication with other processes. In particular, a static buffer descriptor encodes the address and size of a buffer.&lt;br /&gt;
&lt;br /&gt;
Using IPC requests, data can be transferred from any location in the source process to one of the static buffers set up in the target process. This is done using a translation descriptor of type 1, which is followed by a pointer to the source data. The translation descriptor has the following structure:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Bits&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 1-3&lt;br /&gt;
| Translation type (characteristically 1)&lt;br /&gt;
|-&lt;br /&gt;
| 10-13&lt;br /&gt;
| Static buffer index of the receiving process &lt;br /&gt;
|-&lt;br /&gt;
| 14-31&lt;br /&gt;
| Size in bytes of the transferred data. Specifying an amount larger than the target static buffer will result in a kernelpanic. &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
When encountering such a translation descriptor, the kernel will look up the static buffer address and size corresponding to the given index and (if the buffer can hold the requested amount of data) will copy the data to the specified location.&lt;br /&gt;
&lt;br /&gt;
Note that the translation descriptor and static buffer descriptor share the same layout. However, it is unknown whether the kernel ever reads fields other than the buffer address and size when dealing with static buffer descriptors.&lt;br /&gt;
&lt;br /&gt;
Usage examples:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; width=&amp;quot;300&amp;quot; |  Usual form&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00000002 &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (size&amp;lt;&amp;lt;14) &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (static_buffer_id&amp;lt;&amp;lt;10)&lt;br /&gt;
&amp;lt;ptr&amp;gt;&lt;br /&gt;
| The corresponding value contains a ptr to a buffer of said size, that should be copied to an already set-up buffer in destination process at [[Thread Local Storage]] offset 0x180 + static_buffer_id*8. The static_buffer_id is only 4 bits, making it possible for at most up to 16 buffers in total per thread.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Buffer Mapping Translation ===&lt;br /&gt;
&lt;br /&gt;
The IPC subsystem can temporarily map a whole buffer of the sender&#039;s memory into the receiver&#039;s memory space. This is useful for large buffers, for which the overhead of copying static buffer data around would be too expensive.&lt;br /&gt;
&lt;br /&gt;
This kind of translation is enabled by setting bit3 in the translation descriptor. The other two bits of what&#039;s documented as the translation type above are used to specify buffer access permissions of the source process.&lt;br /&gt;
&lt;br /&gt;
Buffers will get mapped at virtual address 0x04000000+ in the destination process. When this translation descriptor is submitted to the kernel through svcReplyAndReceive, the given buffer will be unmapped from the sending process(otherwise the buffer will be left mapped after the cmd-reply is finished). Regardless of the descriptor used here, the MMU-table entries for the source-process(from svcSendSyncRequest) buffers are not changed: memory permissions are left at the original while commands are being processed. The memory permissions for buffers at 0x04000000+ is always RW-, regardless of the actual memory permissions for the source-process buffer. Bitmask 0xFFF(low 12-bits) of the start address of each buffer for 0x04000000+ is the same as bitmask 0xFFF from the source-process buffer address.&lt;br /&gt;
&lt;br /&gt;
The buffer address written into the destination cmdbuf by the kernel with svcSendSyncRequest is the allocated 0x04000000+ buffer. When doing the same with svcSendSyncRequest, the buffer address is the same one from the source cmdbuf(0x04000000+).&lt;br /&gt;
&lt;br /&gt;
The first and last pages of the buffer at 0x04000000+ are allocated under the BASE memregion(with data being copied to/from the original source-process buffer as needed), with the rest being mapped to the original buffer physmem. When the source-process buffer is 0x1000-byte aligned, the first page for 0x04000000+ is mapped directly into the original buffer physmem instead of allocating BASE memory(likewise for the last page when the buffer size is 0x1000-byte aligned).&lt;br /&gt;
&lt;br /&gt;
Each buffer at 0x04000000+ has 1 page of unmapped memory before and after the mapped memory, used for separating each buffer. Hence, the first buffer&#039;s page at 0x04000000+ is always mapped starting at 0x04001000 not 0x04000000.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Bits&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 1-2&lt;br /&gt;
| Access permission flags for the source process: 1=read-only, 2=write-only, 3=read/write. Specifying 0 will cause a kernel panic.&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| Characteristically 1 for this translation type.&lt;br /&gt;
|-&lt;br /&gt;
| 4-31&lt;br /&gt;
| Size in bytes of the shared memory block.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Usage examples:&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; width=&amp;quot;300&amp;quot; |  Usual form&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00000008&lt;br /&gt;
| This command will cause a kernel panic.&lt;br /&gt;
|-&lt;br /&gt;
| &amp;lt;nowiki&amp;gt;0x0000000A | (size&amp;lt;&amp;lt;4)&amp;lt;/nowiki&amp;gt;&lt;br /&gt;
&amp;lt;ptr&amp;gt;&lt;br /&gt;
| The corresponding value contains a ptr to a buffer of said size. The buffer specified by the source process must have read permission(tested on hardware with a read-only buffer). Used for input buffers.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0000000C &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (size&amp;lt;&amp;lt;4)&lt;br /&gt;
&amp;lt;ptr&amp;gt;&lt;br /&gt;
| The corresponding value contains a ptr to a buffer of said size. The buffer specified by the source process must have write permission. Used for output buffers. In the destination process with the buffer mapped at 0x04000000+, that buffer has same content as the buffer from the source buffer(like descriptor 0x0000000A). When handling command requests this is handled the same way as 0x0000000A, besides the descriptor type written into the dst cmdbuf and memory permissions.&lt;br /&gt;
|-&lt;br /&gt;
| 0x0000000E &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (size&amp;lt;&amp;lt;4)&lt;br /&gt;
&amp;lt;ptr&amp;gt;&lt;br /&gt;
| The corresponding value contains a ptr to a buffer of said size. The buffer specified by the source process must have read permission during cmd-request handling(write permission is checked during cmd-reply handling for the original buffer). This isn&#039;t known to be used by any processes. When handling command requests this is handled the same way as 0x0000000A, and for handling command replies this is handled the same way as 0x0000000C(besides the descriptor type written into the dst cmdbuf for both of these).&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Usage Examples for other Translation Types ===&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Type&lt;br /&gt;
! scope=&amp;quot;col&amp;quot; width=&amp;quot;300&amp;quot; |  Usual form&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 2&lt;br /&gt;
| 0x00000004 &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (size&amp;lt;&amp;lt;8) &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (static_buffer_id&amp;lt;&amp;lt;4)&lt;br /&gt;
&amp;lt;ptr&amp;gt;&lt;br /&gt;
| This is typically used for RW buffers over PXI, but any process can use this. The address written to the destination cmd-buf is a phys-addr for a table located in the corresponding static buffer of the receiving process (which must be provided by the latter, otherwise the kernel dereferences NULL). Each static buffer needs to be page-aligned and musn&#039;t exceed a page&#039;s length (kernelpanic otherwise). This table contains the phys-addrs for the actual data, the array entries have the following format: {u32 *datachunk_physaddr, u32 datachunk_bytesize}.&lt;br /&gt;
|-&lt;br /&gt;
| 3&lt;br /&gt;
| 0x00000006 &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (size&amp;lt;&amp;lt;8) &amp;lt;nowiki&amp;gt;|&amp;lt;/nowiki&amp;gt; (static_buffer_id&amp;lt;&amp;lt;4)&lt;br /&gt;
&amp;lt;ptr&amp;gt;&lt;br /&gt;
| Same as above except for read-only buffer. Prior(?) to the kernel version which implemented memory-permission checking for PXI buffers, this was unused and hence triggered a kernelpanic.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== SVCs ==&lt;br /&gt;
&lt;br /&gt;
=== svcReplyAndReceive ===&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Signature:&#039;&#039;&#039;&lt;br /&gt;
 Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget)&lt;br /&gt;
&lt;br /&gt;
In a single operation, sends a IPC reply and waits for a new request. &amp;lt;code&amp;gt;handles&amp;lt;/code&amp;gt; should be a pointer to an array of &amp;lt;code&amp;gt;handleCount&amp;lt;/code&amp;gt; handles.&amp;lt;sup&amp;gt;TODO: Are only port/session handles supported?&amp;lt;/sup&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;replyTarget&amp;lt;/code&amp;gt; should contain a handle to the session to send the reply to. (This is usually the session from which we received the previous request.)&lt;br /&gt;
If &amp;lt;code&amp;gt;replyTarget&amp;lt;/code&amp;gt; is 0, no reply and the call will simply wait for an incoming event.&amp;lt;sup&amp;gt;TODO: It doesn&#039;t seem like the 0xFFFF0000 command id mentioned in the above sections is necessary, but needs confirmation.&amp;lt;/sup&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Upon returning, &amp;lt;code&amp;gt;index&amp;lt;/code&amp;gt; will contain an index into &amp;lt;code&amp;gt;handles&amp;lt;/code&amp;gt; specifying which object changed state.&lt;br /&gt;
If it&#039;s a server port endpoint, it means that there is a new incoming connection on that port which should be accepted using svcAcceptSession.&lt;br /&gt;
If it&#039;s a server session endpoint it means that we received a request from that session and should process and then reply to it by calling svcReplyAndReceive again with &amp;lt;code&amp;gt;replyTarget&amp;lt;/code&amp;gt; set to that session&#039;s handle.&lt;br /&gt;
&lt;br /&gt;
An example of a server svcReplyAndReceive loop is:&lt;br /&gt;
&lt;br /&gt;
 #define MAX_CLIENTS 4&lt;br /&gt;
 Handle server_port = ...;&lt;br /&gt;
 s32 requesting_index;&lt;br /&gt;
 Handle handles[1 + MAX_CLIENTS] = { server_port };&lt;br /&gt;
 s32 connected_clients = 0;&lt;br /&gt;
 Handle reply_target = 0;&lt;br /&gt;
 &lt;br /&gt;
 while (true) {&lt;br /&gt;
     Result res = svcReplyAndReceive(&amp;amp;requesting_index, handles, 1 + connected_clients, reply_target);&lt;br /&gt;
 &lt;br /&gt;
     if (res == 0xC920181A) {&lt;br /&gt;
         // Session was closed by remote&lt;br /&gt;
         // TODO: Handle disconnects&lt;br /&gt;
         reply_target = 0;&lt;br /&gt;
         continue;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     if (requesting_index == 0) {&lt;br /&gt;
         // New connection in server_port&lt;br /&gt;
         ASSERT(connected_client &amp;lt; MAX_CLIENTS);&lt;br /&gt;
         svcAcceptSession(&amp;amp;handles[1 + connected_clients++], server_port);&lt;br /&gt;
         reply_target = 0;&lt;br /&gt;
         continue;&lt;br /&gt;
     }&lt;br /&gt;
 &lt;br /&gt;
     reply_target = handles[requesting_index];&lt;br /&gt;
 &lt;br /&gt;
     // Handle command here and write reply to command buffer&lt;br /&gt;
 }&lt;/div&gt;</summary>
		<author><name>Tekito256</name></author>
	</entry>
	<entry>
		<id>https://www.3dbrew.org/w/index.php?title=Extdata&amp;diff=21798</id>
		<title>Extdata</title>
		<link rel="alternate" type="text/html" href="https://www.3dbrew.org/w/index.php?title=Extdata&amp;diff=21798"/>
		<updated>2022-01-19T11:03:17Z</updated>

		<summary type="html">&lt;p&gt;Tekito256: add jpn title&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;This page describes the format and encryption of extdata, &amp;amp;quot;extra data&amp;amp;quot; stored on SD card and NAND, at:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;nand/data/&amp;amp;lt;ID&amp;amp;gt;/extdata/&amp;amp;lt;ExtdataID-High&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
* &amp;lt;code&amp;gt;sdmc/Nintendo 3DS/&amp;amp;lt;ID0&amp;amp;gt;/&amp;amp;lt;ID1&amp;amp;gt;/extdata/&amp;amp;lt;ExtdataID-High&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ExtdataID-High is always 00000000 for SD, and always 00048000 for NAND. Regular apps can only mount SD extdata using the same extdataID which is stored in the CXI exheader. Therefore, regular apps which have the exheader extdataID set to zero can&#039;t use extdata. This restriction doesn&#039;t apply for shared extdata with extdataID high bitmask 0x48000 stored on NAND. System apps with a certain access right can mount arbitrary extdata. All NAND extdata is shared extdata, while all SD extdata is normal extdata.&lt;br /&gt;
&lt;br /&gt;
All data in this page is little-endian. All &amp;amp;quot;unused / padding&amp;amp;quot; fields can contain uninitialized data unless otherwise specified.&lt;br /&gt;
&lt;br /&gt;
= Format =&lt;br /&gt;
&lt;br /&gt;
To avoid confusion, the terms &#039;&#039;&#039;device directory / file&#039;&#039;&#039; and &#039;&#039;&#039;virtual directory / file&#039;&#039;&#039; are used with the following meanings:&lt;br /&gt;
&lt;br /&gt;
* &#039;&#039;&#039;Device directory / file&#039;&#039;&#039; are the real directory / file stored on SD / NAND that can be seen under path &amp;lt;code&amp;gt;nand/data/&amp;amp;lt;ID&amp;amp;gt;/extdata/&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;sdmc/Nintendo 3DS/&amp;amp;lt;ID0&amp;amp;gt;/&amp;amp;lt;ID1&amp;amp;gt;/extdata/&amp;lt;/code&amp;gt;.&lt;br /&gt;
* &#039;&#039;&#039;Virtual directory / file&#039;&#039;&#039; are directory / file stored inside extdata virtual file system, which can be seen by applications in the mounted extdata archives.&lt;br /&gt;
&lt;br /&gt;
An extdata consists of several device directories and files, which forms a file system consisting of multiple virtual directories and files.&lt;br /&gt;
&lt;br /&gt;
An extdata with ID &amp;lt;code&amp;gt;ExtdataId&amp;lt;/code&amp;gt; has the following device files:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;.../extdata/&amp;amp;lt;ExtdataID-High&amp;amp;gt;/&amp;amp;lt;ExtdataId-Low&amp;amp;gt;/Quota.dat&amp;lt;/code&amp;gt; (optional)&lt;br /&gt;
* &amp;lt;code&amp;gt;.../extdata/&amp;amp;lt;ExtdataID-High&amp;amp;gt;/&amp;amp;lt;ExtdataId-Low&amp;amp;gt;/&amp;amp;lt;SubDirID&amp;amp;gt;/&amp;amp;lt;SubFileID&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Note:&lt;br /&gt;
&lt;br /&gt;
* All device files are [[DISA and DIFF|DIFF containers]]. &#039;&#039;&#039;All format description below is about the inner content of the containers&#039;&#039;&#039;. Please unwrap these files first according to the DIFF format description before reading them using the extdata format description below.&lt;br /&gt;
* &amp;lt;code&amp;gt;Quota.dat&amp;lt;/code&amp;gt; is only observed existing for NAND shared extdata.&lt;br /&gt;
* &amp;lt;code&amp;gt;&amp;amp;lt;SubDirID&amp;amp;gt;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;amp;lt;SubFileID&amp;amp;gt;&amp;lt;/code&amp;gt; are 8-digit hex strings.&lt;br /&gt;
* Device file with &amp;lt;code&amp;gt;SubDirID = SubFileID = 00000000&amp;lt;/code&amp;gt; doesn&#039;t exist. Other ID combinations can exists.&lt;br /&gt;
* Device file with &amp;lt;code&amp;gt;SubDirID = 00000000&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;SubFileID = 00000001&amp;lt;/code&amp;gt; is the VSXE metadata file and must exist.&lt;br /&gt;
* Other files, besides &amp;lt;code&amp;gt;Quota.dat&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;00000000/00000001&amp;lt;/code&amp;gt;, are normal sub files, are these device files one-to-one correspond to virtual files. They contain raw virtual file data in the DIFF inner content.&lt;br /&gt;
* &amp;lt;code&amp;gt;SubDirID = 00000000&amp;lt;/code&amp;gt; is usually the only one device directory that can be seen. See [[#Device Directory Capacity]] for more information.&lt;br /&gt;
&lt;br /&gt;
== Quota File ==&lt;br /&gt;
&lt;br /&gt;
The inner data of &amp;lt;code&amp;gt;Quota.dat&amp;lt;/code&amp;gt; is 0x48 bytes with the following format. The file seems to limit the extdata total size.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
! Offset&lt;br /&gt;
! Length&lt;br /&gt;
! Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x00&lt;br /&gt;
| 4&lt;br /&gt;
| Magic &amp;amp;quot;QUOT&amp;amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
| 0x04&lt;br /&gt;
| 4&lt;br /&gt;
| Magic 0x30000&lt;br /&gt;
|-&lt;br /&gt;
| 0x08&lt;br /&gt;
| 4&lt;br /&gt;
| 0x1000, block size&lt;br /&gt;
|-&lt;br /&gt;
| 0x0C&lt;br /&gt;
| 4&lt;br /&gt;
| Always 126. Probably device directory capacity. See the [[#Device Directory Capacity]] more information.&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0?&lt;br /&gt;
|-&lt;br /&gt;
| 0x14&lt;br /&gt;
| 4&lt;br /&gt;
| Max number of blocks&lt;br /&gt;
|-&lt;br /&gt;
| 0x18&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0? &lt;br /&gt;
|-&lt;br /&gt;
| 0x1C&lt;br /&gt;
| 4&lt;br /&gt;
| Free blocks remained&lt;br /&gt;
|-&lt;br /&gt;
| 0x20&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0? &lt;br /&gt;
|-&lt;br /&gt;
| 0x24&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0? &lt;br /&gt;
|-&lt;br /&gt;
| 0x28&lt;br /&gt;
| 4&lt;br /&gt;
| Free blocks remained + (blocks occupied by the recently mounted file, specified by the ID below (0 if recently deleted))&lt;br /&gt;
|-&lt;br /&gt;
| 0x2C&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0? &lt;br /&gt;
|-&lt;br /&gt;
| 0x30&lt;br /&gt;
| 4&lt;br /&gt;
| ID of most recently mounted file. Same as the one in [[Inner_FAT#Filesystem Header]]&lt;br /&gt;
|-&lt;br /&gt;
| 0x34&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0?&lt;br /&gt;
|-&lt;br /&gt;
| 0x38&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0?&lt;br /&gt;
|-&lt;br /&gt;
| 0x3C&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0?&lt;br /&gt;
|-&lt;br /&gt;
| 0x40&lt;br /&gt;
| 4&lt;br /&gt;
| Size in bytes of most recently mounted file (device file size). 0 if recently deleted&lt;br /&gt;
|-&lt;br /&gt;
| 0x44&lt;br /&gt;
| 4&lt;br /&gt;
| Always 0?&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== Device Directory Capacity ==&lt;br /&gt;
&lt;br /&gt;
A device directory in an extdata (a &amp;lt;code&amp;gt;&amp;amp;lt;SubDirID&amp;amp;gt;&amp;lt;/code&amp;gt; directory) seems to have a maximum number of device files it can contain. For SD extdata, this maximum number seems to be hard-coded as 126. For NAND extdata, the number is probably indicated by a field in Quota.dat, which is, again, always 126 as observed. 3DS FS tries to put all device files in the device directory &amp;lt;code&amp;gt;00000000&amp;lt;/code&amp;gt; if possible, and only when more than 126 files needed to add, a second device directory &amp;lt;code&amp;gt;00000001&amp;lt;/code&amp;gt; and so on are created. However, few extdata have such amount of files to store, so the behavior lacks of use cases to confirm.&lt;br /&gt;
&lt;br /&gt;
The number 126 is probably from some kind of other capacity of 128 with &amp;lt;code&amp;gt;&amp;amp;quot;.&amp;amp;quot;&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;&amp;amp;quot;..&amp;amp;quot;&amp;lt;/code&amp;gt; entries reserved. It is theorized that this is to keep a FAT directory table, with 0x20 bytes for each entry, in one 0x1000 cluster. The motivation is unclear.&lt;br /&gt;
&lt;br /&gt;
== VSXE Filesystem ==&lt;br /&gt;
&lt;br /&gt;
This is one variant of the [[Inner FAT|FAT filesystem]]. Please refer to its page for the description of the filesystem. In general, device file &amp;lt;code&amp;gt;00000000/00000001&amp;lt;/code&amp;gt; contains the metadata of the filesystem, while other device files (except for the Quota file) contains normal sub-files&lt;br /&gt;
&lt;br /&gt;
Each non-dummy file entry corresponds to a device file. The path to the device file is generated by the following computation:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;// See previous section about this capacity&lt;br /&gt;
const uint32_t device_dir_capacity = 126;&lt;br /&gt;
&lt;br /&gt;
// entry index is the index in the file entry table, with the first dummy entry as&lt;br /&gt;
// index = 0, which is never used for a real file.&lt;br /&gt;
// file_index = 1 is reserved for the VSXE Filesystem Metadata itself, so real files&lt;br /&gt;
// started from file_index = 2.&lt;br /&gt;
uint32_t file_index = entry_index + 1;&lt;br /&gt;
&lt;br /&gt;
uint32_t SubDirID = file_index / device_dir_capacity;&lt;br /&gt;
uint32_t SubFileID = file_index % pdevice_dir_capacity;&lt;br /&gt;
&lt;br /&gt;
char extdata_path[...]; // &amp;amp;quot;.../extdata/&amp;amp;lt;ExtdataID-High&amp;amp;gt;/&amp;amp;lt;ExtdataId-Low&amp;amp;gt;&amp;amp;quot;&lt;br /&gt;
char device_path[...]; // output path&lt;br /&gt;
sprintf(device_path, &amp;amp;quot;%s/%08x/%08x&amp;amp;quot;, extdata_path, SubDirID, SubFileID);&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
When mounting extdata, the unique identifier is used to match the ID stored in subfile&#039;s [[DISA and DIFF#DIFF header|DIFF header]]. If the ID doesn&#039;t match, mounting will fail.&lt;br /&gt;
&lt;br /&gt;
== Virtual File System Structure ==&lt;br /&gt;
&lt;br /&gt;
When extdata is created, these are &#039;&#039;always&#039;&#039; created regardless of whether the title actually uses them.&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/icon&amp;lt;/code&amp;gt; This virtual file contains the extdata icon displayed in data management. This icon can only be written to by titles when creating extdata, titles would have to recreate extdata to change the icon. This file can&#039;t be read directly, instead it is read via FS:ReadExtSaveDataIcon.&lt;br /&gt;
* &amp;lt;code&amp;gt;/user/&amp;lt;/code&amp;gt; This virtual directory contains the title&#039;s actual extdata files.&lt;br /&gt;
* &amp;lt;code&amp;gt;/boss/&amp;lt;/code&amp;gt; This virtual directory can contain SpotPass content. SpotPass content can only be downloaded to this &amp;lt;code&amp;gt;/boss&amp;lt;/code&amp;gt; virtual directory.&lt;br /&gt;
&lt;br /&gt;
User extdata and SpotPass extdata use separate mount points at &amp;lt;code&amp;gt;/user&amp;lt;/code&amp;gt; and &amp;lt;code&amp;gt;/boss&amp;lt;/code&amp;gt;. Therefore one mount can&#039;t access the other virtual directory, and also can&#039;t access &amp;lt;code&amp;gt;/icon&amp;lt;/code&amp;gt;.(The title&#039;s SpotPass extdata can be mounted by the title itself, if it uses SpotPass)&lt;br /&gt;
&lt;br /&gt;
Other optional but notable directories include:&lt;br /&gt;
&lt;br /&gt;
* &amp;lt;code&amp;gt;/user/ExBanner&amp;lt;/code&amp;gt; This virtual directory can optionally store extended banners. When this is available, this banner is displayed instead of the CXI ExeFS banner. &amp;lt;code&amp;gt;COMMON.bin&amp;lt;/code&amp;gt; stores the common exbanner, while &amp;lt;code&amp;gt;&amp;amp;lt;regionlang_code&amp;amp;gt;.bin&amp;lt;/code&amp;gt; stores an optional separate region/language specific banner.(regionlang_code can be &amp;amp;quot;JPN_JP&amp;amp;quot;, &amp;amp;quot;USA_EN&amp;amp;quot;, etc)&lt;br /&gt;
&lt;br /&gt;
== SD Extdata ==&lt;br /&gt;
Usually the ExtdataID low is in the format &#039;00&amp;lt;Unique ID&amp;gt;&#039;&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! JPN ExtdataID&lt;br /&gt;
! USA ExtdataID&lt;br /&gt;
! EUR ExtdataID&lt;br /&gt;
! Description&lt;br /&gt;
! Extdata images&lt;br /&gt;
|-&lt;br /&gt;
| 00000082&lt;br /&gt;
| 0000008f&lt;br /&gt;
| 00000098&lt;br /&gt;
| [[Home Menu]] extdata, this contains home-menu savedata and cached icons for applications.&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00000200&lt;br /&gt;
| 00000210&lt;br /&gt;
| 00000220&lt;br /&gt;
| [[System_Settings|System Settings]] extdata added with [[2.0.0-2]].&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00000207&lt;br /&gt;
| 00000217&lt;br /&gt;
| 00000227&lt;br /&gt;
| [[Mii Maker]], contains an ExBanner&lt;br /&gt;
| [https://dl.dropbox.com/u/20520664/extdata00000217.zip cleartext]&lt;br /&gt;
|-&lt;br /&gt;
| 00000208&lt;br /&gt;
| 00000218&lt;br /&gt;
| 00000228&lt;br /&gt;
| Streetpass Mii Plaza&lt;br /&gt;
| 11 mb big!&lt;br /&gt;
|-&lt;br /&gt;
| 00000209&lt;br /&gt;
| 00000219&lt;br /&gt;
| 00000229&lt;br /&gt;
| [[eShop]], contains store music in AAC format.&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0000020b&lt;br /&gt;
| 0000021b&lt;br /&gt;
| 0000022b&lt;br /&gt;
| Nintendo Zone&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0000020d&lt;br /&gt;
| 0000021d&lt;br /&gt;
| 0000022d&lt;br /&gt;
| Face Raiders, likely contains an ExBanner&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 000002cc&lt;br /&gt;
| 000002cd&lt;br /&gt;
| 000002ce&lt;br /&gt;
| [[Home Menu]] theme&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 000004aa&lt;br /&gt;
| 000004ab&lt;br /&gt;
| Nintendo Video Extra Data&lt;br /&gt;
This is where the video files are stored, and [[Nintendo_Video|includes]] the thumbnail, the description, and possibly some checksum info in each video file stored in the extdata images. There are always 9 files within the subdirectory &amp;quot;00000000&amp;quot; of this folder, even without any videos downloaded. The files are &amp;quot;00000001&amp;quot; - &amp;quot;00000009&amp;quot;, and &amp;quot;00000003&amp;quot; - &amp;quot;00000008&amp;quot; have the same filesize of 50.7 MB. It is possible to restore the older videos by overwriting all the files within this directory. Provided of course you have made a backup of the files before hand, by copying all the files within this directory to your computer. As far I&#039;m aware its not possible to mix and match the files in order to get certain videos in one grouping, ie. having all 3 Zelda orchestral recordings in one group of 4 Nintendo videos.&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
|00000306&lt;br /&gt;
|00000308&lt;br /&gt;
|00000307&lt;br /&gt;
|Mario Kart 7&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| 0000030b&lt;br /&gt;
| 0000030d&lt;br /&gt;
| 0000030c&lt;br /&gt;
| Nintendogs + Cats&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00000326&lt;br /&gt;
| 00000326&lt;br /&gt;
| 00000326&lt;br /&gt;
| Pokédex 3D&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00000305&lt;br /&gt;
| 0000032d&lt;br /&gt;
| 0000033c&lt;br /&gt;
| Super Street Fighter IV 3D&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00000328&lt;br /&gt;
| 00000358&lt;br /&gt;
| 0000033b&lt;br /&gt;
| Ridge Racer 3D&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 0000034d&lt;br /&gt;
| 00000402&lt;br /&gt;
| Samurai Warriors Chronicles&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 0000034f&lt;br /&gt;
| 0000038a&lt;br /&gt;
| Dead or Alive Dimensions&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00000481&lt;br /&gt;
| N/A&lt;br /&gt;
| N/A&lt;br /&gt;
| Monster Hunter Tri G (Download-Quests)&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 00000517&lt;br /&gt;
| 00000518&lt;br /&gt;
| Swapnote&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0000055d&lt;br /&gt;
| 0000055d&lt;br /&gt;
| 0000055d&lt;br /&gt;
| Pokémon X&amp;lt;br&amp;gt;Pokémon Y&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 00000725&lt;br /&gt;
| 00000724&lt;br /&gt;
| Ambassador Certificate&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 000007af&lt;br /&gt;
| New Super Mario Bros. 2&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 00000863&lt;br /&gt;
| 00000864&lt;br /&gt;
| Animal Crossing: New Leaf&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 00000a85&lt;br /&gt;
| 00000a86&lt;br /&gt;
| Professor Layton and the Miracle Mask&amp;lt;br&amp;gt;Professor Layton and the Azran Legacy&lt;br /&gt;
German Version ExtdataID is 00000a87&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00000b4f&lt;br /&gt;
| Fullblox / Crashmo&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00000ba9&lt;br /&gt;
| Pokémon Mystery Dungeon: Gates to Infinity&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00000c24&lt;br /&gt;
| Denpa men&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00000c73&lt;br /&gt;
| 00000c73&lt;br /&gt;
| 00000c73&lt;br /&gt;
| Save Data Transfer Tool&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00000d9a&lt;br /&gt;
| Donkey Kong Country™&amp;lt;br&amp;gt;Returns 3D: Trailer&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00000ea6&lt;br /&gt;
| Etrian Odyssey IV&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 00000edf&lt;br /&gt;
| 00000ee0&lt;br /&gt;
| Super Smash Bros. for Nintendo 3DS&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 00000f14&lt;br /&gt;
| 00000f1e&lt;br /&gt;
| Phoenix Wright: Ace Attorney - Dual Destinies&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| 00001007&lt;br /&gt;
| 00001005&lt;br /&gt;
| Professor Layton vs Phoenix Wright: Ace Attorney&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00001062&lt;br /&gt;
| Nintendo Pocket Football Club&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 0000111c&lt;br /&gt;
| Yoshi&#039;s New Island&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00001131&lt;br /&gt;
| Fantasy Life&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 000011c5&lt;br /&gt;
| 000011c5&lt;br /&gt;
| 000011c5&lt;br /&gt;
| Pokémon Omega Ruby&amp;lt;br&amp;gt;Pokémon Alpha Sapphire&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 000012ca&lt;br /&gt;
| Mario vs. Donkey Kong: Tipping Stars&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00001499&lt;br /&gt;
| Korg DSN-12&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 000014f2&lt;br /&gt;
| Animal Crossing: Happy Home Designer&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 000014d1&lt;br /&gt;
| 000014d1&lt;br /&gt;
| 000014d1&lt;br /&gt;
| [[Home Menu]] badge&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00001632&lt;br /&gt;
| Fullblox / Stretchmo&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00001646&lt;br /&gt;
| Pokémon Rumble World&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 00001648&lt;br /&gt;
| 00001648&lt;br /&gt;
| 00001648&lt;br /&gt;
| Pokémon Sun&amp;lt;br&amp;gt;Pokémon Moon&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 0000165c&lt;br /&gt;
| 0000165c&lt;br /&gt;
| 0000165c&lt;br /&gt;
| [[Home Menu]] saved theme layouts&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| 000016C6&lt;br /&gt;
| ?&lt;br /&gt;
| 00001678&lt;br /&gt;
| Yo-kai Watch&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 000018fa&lt;br /&gt;
| Phoenix Wright: Ace Attorney - Spirit of Justice&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 0000198f&lt;br /&gt;
| Animal Crossing: New Leaf - Welcome amiibo&lt;br /&gt;
|&lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00001a05&lt;br /&gt;
| Super Mario Maker&lt;br /&gt;
| &lt;br /&gt;
|-&lt;br /&gt;
| ?&lt;br /&gt;
| ?&lt;br /&gt;
| 00001a2e&lt;br /&gt;
| Swapdoodle&lt;br /&gt;
| &lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
== NAND Shared Extdata ==&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  ExtdataID&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0xe0000000&lt;br /&gt;
| Home Menu attempts to open this archive during boot, if [[FS:OpenArchive]] doesn&#039;t return an error Home Menu seems to then launch the [[System Transfer]] application. Home Menu doesn&#039;t actually use this archive at all except for checking whether it exists.&lt;br /&gt;
|-&lt;br /&gt;
|  0xf0000001&lt;br /&gt;
|  NAND JPEG/MPO files and phtcache.bin from the camera application are stored here. This also contains UploadData.dat.&lt;br /&gt;
|-&lt;br /&gt;
|  0xf0000002&lt;br /&gt;
|  NAND M4A files from the sound application are stored here&lt;br /&gt;
|-&lt;br /&gt;
|  0xf0000009&lt;br /&gt;
|  Used for [[BOSS_Services|SpotPass]] content storage for [[News_Services|notifications]].&lt;br /&gt;
|-&lt;br /&gt;
|  0xf000000b&lt;br /&gt;
|  Contains idb.dat, idbt.dat, gamecoin.dat, ubll.lst, CFL_DB.dat, and CFL_OldDB.dat. These files contain cleartext [[Mii_Maker|Miis]] and some data relating (including cached ICN data) to Play/Usage Records.&lt;br /&gt;
|-&lt;br /&gt;
|  0xf000000c&lt;br /&gt;
|  Contains bashotorya.dat and bashotorya2.dat.&lt;br /&gt;
|-&lt;br /&gt;
|  0xf000000d&lt;br /&gt;
|  Home Menu SpotPass content data [[BOSS_Services|storage]].&lt;br /&gt;
|-&lt;br /&gt;
|  0xf000000e&lt;br /&gt;
|  Contains [[VersionList|versionlist.dat]], used by Home Menu for the software update notification added with [[7.0.0-13]].&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==== Shared Extdata 0xf000000b gamecoin.dat ====&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!  Offset&lt;br /&gt;
!  Size&lt;br /&gt;
!  Description&lt;br /&gt;
|-&lt;br /&gt;
| 0x0&lt;br /&gt;
| 0x4&lt;br /&gt;
| Magic number: 0x4F00&lt;br /&gt;
|-&lt;br /&gt;
| 0x4&lt;br /&gt;
| 0x2&lt;br /&gt;
| Total Play Coins&lt;br /&gt;
|-&lt;br /&gt;
| 0x6&lt;br /&gt;
| 0x2&lt;br /&gt;
| Total Play Coins obtained on the date stored below. When the below date does not match the current date, this field is reset to zero, then the date(and other fields) are updated. Once this value is &amp;gt;=10, no more Play Coins can be obtained until the current date changes.&lt;br /&gt;
|-&lt;br /&gt;
| 0x8&lt;br /&gt;
| 0x4&lt;br /&gt;
| Total step [[PTM:GetTotalStepCount|count]] at the time a new Play Coin was obtained.&lt;br /&gt;
|-&lt;br /&gt;
| 0xC&lt;br /&gt;
| 0x4&lt;br /&gt;
| Step count for the day the last Play Coin was obtained, for that day&#039;s step count(same as the step count displayed by home-menu when this file was updated).&lt;br /&gt;
|-&lt;br /&gt;
| 0x10&lt;br /&gt;
| 0x2&lt;br /&gt;
| Year&lt;br /&gt;
|-&lt;br /&gt;
| 0x12&lt;br /&gt;
| 0x1&lt;br /&gt;
| Month&lt;br /&gt;
|-&lt;br /&gt;
| 0x13&lt;br /&gt;
| 0x1&lt;br /&gt;
| Day&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
The above date stores the last time new Play Coin(s) were obtained. The contents of this file is updated by home-menu. [[PTM:GetTotalStepCount]] is not checked constantly, after home-menu boot this is only checked when waking from sleep-mode. Each time home-menu updates the contents of this file, home-menu will set the Play Coin total to 300 if it&#039;s higher than the 300 Play Coin limit.&lt;br /&gt;
&lt;br /&gt;
[[Home Menu]] loads this file / opens this archive during [[Home Menu|startup]]. When accessing this file fails, like when the file/archive is corrupted(or at least on older system-versions), the result is a brick due to Home Menu using [[SVC|svcBreak]]. [[User:Yellows8|Yellows8]] bricked a 3DS this way due to corruption via invalid [[FSFile:Write]] flush flags. When opening this extdata archive(0xf000000b) fails, Home Menu executes svcBreak.&lt;br /&gt;
&lt;br /&gt;
==== Shared Extdata 0xf000000b ubll.lst ====&lt;br /&gt;
List of blocked users.&lt;br /&gt;
&lt;br /&gt;
Empty space is filled with 0xC-long sequences of 00 00 ... 07&lt;br /&gt;
&lt;br /&gt;
=== Tools ===&lt;br /&gt;
&lt;br /&gt;
* [https://github.com/wwylele/3ds-save-tool 3ds-save-tool] - Extract/verifies extdata&lt;/div&gt;</summary>
		<author><name>Tekito256</name></author>
	</entry>
</feed>