TMA services: Difference between revisions

No edit summary
Initial protocol stuff, HostIO, and Env as of ~1.0
Line 306: Line 306:
Takes no input, returns an s32 "Priority".
Takes no input, returns an s32 "Priority".


= Protocol (gen1) =
== PacketHeader ==
{| class="wikitable" border="1"
|-
! Offset || Size || Description
|-
| 0x0 || 0x4 || [[#ServiceId]]
|-
| 0x4 || 0x4 || Task ID
|-
| 0x8 || 0x2 || [[#TaskType]]
|-
| 0xA || 0x1 || Initiate
|-
| 0xB || 0x1 || Padding
|-
| 0xC || 0x4 || Packet data size
|-
| 0x10 || 0x10 || Padding
|}
All packets sent and received by tma begin with this header, the data following the header is specific to each task type.
Including the header, a packet can be up to 0xE020 bytes large
Initiate will be set to 1 on the first packet associated with an task/operation and cleared on any/all subsequent packets.
== ServiceId ==
{| class="wikitable" border="1"
! Service ID || Service Name
|-
| 0x378D2DB4 || BenchmarkReportService
|-
| 0xBA2C1174 || BenchmarkService
|-
| 0xC191DAC9 || EnvService
|-
| 0x5FAE4D7E || HostIOService
|-
| 0xB04489F2 || HostDirectoryIOService
|-
| 0xB644D830 || HTCSService
|-
| 0xDDDE6636 || DebugService
|-
| 0x0955E925 || ControllerService
|}
This designates which tma "service" produced or will process a packet. These services are hosted over the host<->console interface, they are unrelated to hipc services.
The ServiceID values are derived from the Service Names strings using this hash:
<syntaxhighlight>
uint tmipc::HashString(char *param_1)
{
  uint uVar1;
  long lVar2;
  uint uVar3;
 
  uVar1 = (uint)(byte)*param_1;
  uVar3 = (uint)(byte)*param_1;
  if (uVar3 == 0) {
    lVar2 = 0;
  }
  else {
    lVar2 = 0;
    do {
      uVar1 = uVar1 * 0xf4243 ^ uVar3;
      uVar3 = (uint)(byte)param_1[lVar2 + 1];
      lVar2 = lVar2 + 1;
    } while (uVar3 != 0);
  }
  if (uVar1 != (uint)lVar2) {
    return (uint)lVar2 ^ uVar1;
  }
  assertion_failure();
}
</syntaxhighlight>
== TaskType ==
{| class="wikitable" border="1"
! Type || Name
|-
| 0x01 || [[#OpenFile_Task|OpenFile]]
|-
| 0x02 || [[#GetFileSize_Task|GetFileSize]]
|-
| 0x03 || [[#SetFileSize_Task|SetFileSize]]
|-
| 0x05 || [[#FileExists_Task|FileExists]]
|-
| 0x06 || [[#ReadFile_Task|ReadFile]]
|-
| 0x07 || [[#WriteFile_Task|WriteFile]]
|-
| 0x08 || [[#FlushFile_Task|FlushFile]]
|-
| 0x09 || [[#SetPriorityForFile_Task|SetPriorityForFile]]
|-
| 0x0A || [[#GetPriorityForFile_Task|GetPriorityForFile]]
|-
| 0x0B || [[#CloseFile_Task|CloseFile]]
|-
| 0x0C || [[#CreateFile_Task|CreateFile]]
|-
| 0x0D || [[#DeleteFile_Task|DeleteFile]]
|-
| 0x0E || [[#RenameFile_Task|RenameFile]]
|-
| 0x0F || [[#GetIOType_Task|GetIOType]]
|-
| 0x10 || [[#DirectoryExists_Task|DirectoryExists]]
|-
| 0x11 || [[#OpenDirectory_Task|OpenDirectory]]
|-
| 0x12 || [[#GetDirectoryEntryCount_Task|GetDirectoryEntryCount]]
|-
| 0x13 || [[#ReadDirectory_Task|ReadDirectory]]
|-
| 0x14 || [[#CloseDirectory_Task|ReadDirectory]]
|-
| 0x15 || [[#SetPriorityForDirectory_Task|SetPriorityForDirectory]]
|-
| 0x16 || [[#GetPriorityForDirectory_Task|GetPriorityForDirectory]]
|-
| 0x17 || [[#CreateDirectory_Task|CreateDirectory]]
|-
| 0x18 || [[#DeleteDirectory_Task|DeleteDirectory]]
|-
| 0x19 || [[#RenameDirectory_Task|RenameDirectory]]
|-
| 0x1A || Socket
|-
| 0x1B || Close
|-
| 0x1C || Connect
|-
| 0x1D || Bind
|-
| 0x1E || Listen
|-
| 0x1F || Accept
|-
| 0x20 || Recv
|-
| 0x21 || Send
|-
| 0x22 || Shutdown
|-
| 0x23 || Fcntl
|-
| 0x26 || Debug (Debugger)
|-
| 0x29 || [[#GetVar_Task|GetVar (GetEnvironmentVariable)]]
|-
| 0x2B || [[#GetFileTimeStamp_Task|GetFileTimeStamp]]
|}
Each task is associated with a specific [[#ServiceId|Service]], there seems to be no overlap in task type values between services.
== EnvService ==
Creates tasks for requesting environment variables from host, it's used by [[#GetEnvironmentVariable]] and [[#GetEnvironmentVariableLength]].
=== GetVar Task ===
This is used by [[#GetEnvironmentVariable]] and [[#GetEnvironmentVariableLength]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || variable || Environment variable name
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x4 || Result
|-
| 0x4 || variable || Null terminated environment variable string
|}
Up to <buffer size> bytes of the environment variable string are copied to a provided buffer and the length of string is counted.
[[#GetEnvironmentVariableLength]] provides no buffer so the string is discarded completely, only the size is returned.
[[#GetEnvironmentVariable]] provides its caller supplied hipc buffer.
== HostIOService ==
Creates tasks for host file operations, it's used by all [[#file_io]] File commands and [[#GetIOType]].
=== OpenFile Task ===
This is used by [[#OpenFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (always -1)
|-
| 0x8 || variable || File path
|-
| variable || 0x4 || Open mode
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== GetFileSize Task ===
This is used by [[#GetFileSize]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || File size
|}
=== SetFileSize Task ===
This is used by [[#SetFileSize]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x8 || File size
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== FileExists Task ===
This is used by [[#FileExists]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (always -1)
|-
| 0x8 || variable || File path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || File exists (cast to a bool)
|}
=== ReadFile Task ===
This is used by [[#ReadFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x8 || Read offset
|-
| 0x10 || 0x8 || Read size
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x4 || Sent size
|-
| 0x4 || 0x4 || Result
|-
| 0x8 || variable || <sent size> bytes
|}
tma will receive responses until <read size> bytes have been received, result>0 is received, or an empty packet (<sent size>=0) is received.
=== WriteFile Task ===
This is used by [[#WriteFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x8 || Read offset
|-
| 0x10 || 0x4 || Write size (of current packet)
|-
| 0x14 || 0x1 || End
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x4 || Total written size? (unused)
|-
| 0x4 || 0x4 || Result
|}
tma sends write requests containing up to 0xdfdf bytes of data until until all data has been sent. The last request will have End=1, prior requests will have End=0.
=== FlushFile Task ===
This is used by [[#FlushFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== SetPriorityForFile Task ===
This is used by [[#SetPriorityForFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Priority
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== GetPriorityForFile Task ===
This is used by [[#GetPriorityForFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Priority (cast to a u32/s32)
|}
=== CloseFile Task ===
This is sent when an [[#IFileAccessor]] session is closed. The result value is discarded.
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== CreateFile Task ===
This is used by [[#CreateFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (always -1)
|-
| 0x8 || variable || File path
|-
| variable || 0x8 || File size
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== DeleteFile Task ===
This is used by [[#DeleteFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (always -1)
|-
| 0x8 || variable || File path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== RenameFile Task ===
This is used by [[#RenameFile]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (always -1)
|-
| 0x8 || variable || Source file path
|-
| variable || variable || Dest file path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== GetIOType Task ===
This is used by [[#GetIOType]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (always -1)
|-
| 0x8 || variable || File path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Entry type (cast to a u32/[[Filesystem_services#DirectoryEntryType|DirectoryEntryType]])
|}
=== GetFileTimeStamp Task ===
This is used by [[#GetFileTimeStamp]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (always -1)
|-
| 0x8 || variable || File path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || File descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || CreatedTime
|-
| 0x14 || 0x8 || AccessTime
|-
| 0x2C || 0x8 || ModifiedTime
|}
== HostDirectoryIOService ==
Creates tasks for host directory operations, it's used by all [[#file_io]] Directory commands.
=== DirectoryExists Task ===
This is used by [[#DirectoryExists]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (always -1)
|-
| 0x8 || variable || Directory path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Directory exists (cast to a bool)
|}
=== OpenDirectory Task ===
This is used by [[#OpenDirectory]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (always -1)
|-
| 0x8 || variable || Directory path
|-
| variable || 0x8 || Tag
|-
| variable || 0x4 || Open mode
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|-
| 0x24 || 0x8 || Tag (must be the same as Tag in request)
|}
=== GetDirectoryEntryCount Task ===
This is used by [[#GetDirectoryEntryCount]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Entry count
|}
=== ReadDirectory Task ===
This is used by [[#ReadDirectory]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x4 || Max out entry count
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x4 || Result
|-
| 0x8 || 0x1 || Entry type
|-
| 0x9 || variable || Entry path (up to FS_MAX_PATH chars)
|-
| variable || 0x8 || Entry size
|}
tma receives response packets until result>0 or it's received <max out entry count> entries. Entries with an empty path are ignored but still count toward <max out count>.
Response packets are converted to a [[Filesystem_services#DirectoryEntry]]. The path and size are copied directly and type is flipped (0->1 (File), 1->0 (Directory))
=== CloseDirectory Task ===
This is used when an [[#IDirectoryAccessor]] session is closed. The result value is discarded.
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== SetPriorityForDirectory Task ===
This is used by [[#SetPriorityForDirectory]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x8 || Priority
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== GetPriorityForDirectory Task ===
This is used by [[#GetPriorityForDirectory]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Priority
|}
=== CreateDirectory Task ===
This is used by [[#CreateDirectory]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (always -1)
|-
| 0x8 || variable || Directory path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== DeleteDirectory Task ===
This is used by [[#DeleteDirectory]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (always -1)
|-
| 0x8 || variable || Directory path
|-
| variable || 0x1 || Is recursive (0=not, 1=recursive)
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
=== RenameDirectory Task ===
This is used by [[#RenameDirectory]].
Console request:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (always -1)
|-
| 0x8 || variable || Src path
|-
| variable || variable || Dst path
|}
Host response:
{| class="wikitable" border="1"
! Offset || Size || Description
|-
| 0x0 || 0x8 || Directory descriptor? (unused)
|-
| 0x8 || 0x4 || Result
|-
| 0xC || 0x8 || Unused
|}
== HTCSService ==
Creates tasks for htcs operations, it's used by all [[#htcs]] commands.
== DebugService ==
Process debugger.
[[


[[Category:Services]]
[[Category:Services]]