Continuing petabyte's
work, I further reverse engineered a few Canon-specific PTP operations that can be used executing code on camera.
These could be useful for implementing card preparation without a card reader, and more. The operations are available on PowerShots running DryOS r31 (not all r31 cameras) and later. They are also available on EOS cameras (don't know which models). An additional check will prevent (ab)using these operations on DIGIC 8 and later cameras - until someone reverses the new 0x9050/0x905c handlers.
The operations are (names come from EOS debug strings, following is from
here):
#define PTP_OC_CANON_InitiateEventProc0 0x9050
#define PTP_OC_CANON_TerminateEventProc_051 0x9051
#define PTP_OC_CANON_ExecuteEventProc 0x9052
#define PTP_OC_CANON_GetEventProcReturnData 0x9053
#define PTP_OC_CANON_IsEventProcRunning 0x9057
#define PTP_OC_CANON_QuerySizeOfTransparentMemory 0x9058
#define PTP_OC_CANON_LoadTransparentMemory 0x9059
#define PTP_OC_CANON_SaveTransparentMemory 0x905a
#define PTP_OC_CANON_QuickLoadTransparentMemory 0x905b
#define PTP_OC_CANON_InitiateEventProc1 0x905c
#define PTP_OC_CANON_TerminateEventProc_05D 0x905d
InitiateEventProc 0x9050, 0x905c
TerminateEventProc 0x9051, 0x905d
These are for enabling and disabling operations between 0x9052 ... 0x905b. Some EOS cameras seem to register those handlers by default.
ExecuteEventProc 0x9052
Executes a registered event procedure. Parameter passing and more are detailed later. Returns the eventproc's one-word result as PTP param.
GetEventProcReturnData 0x9053
Returns data from a fixed buffer, but only after an appropriate ExecuteEventProc operation.
IsEventProcRunning 0x9057
Self-explanatory name, but I did not try calling it. Can return up to 3 params.
reyalp's findingsQuerySizeOfTransparentMemory 0x9058
LoadTransparentMemory 0x9059
SaveTransparentMemory 0x905a
QuickLoadTransparentMemory 0x905b
Not researched, transparent memory is something like a named allocation from regular heap.
Now, ExecuteEventProc in details.
Eventproc name and its arguments are sent in the payload (data phase).
This operation has 2 PTP params that I know of:
- 1st parameter: async execution flag. When nonzero, the eventproc is executed in a separate task (so that it can run for longer).
- 2nd parameter: return data flag. When nonzero, the eventproc is expected to create data that can be returned in a GetEventProcReturnData operation.
When this flag is set, the eventproc will get 3 fixed arguments first, followed by those specified by caller.
- 1st arg will contain the available buffer space in bytes
- 2nd arg will point to the return size (the eventproc can set the actual return data amount which defaults to zero)
- 3rd arg will point to the return data buffer
Eventproc name and arguments are to be sent in an unaligned stream of bytes.
Encoding:
- evproc name as string of chars, terminated by 0 char
The rest comes right after, is not word-aligned, words are in LE byte order.
- 32bit value: num of args (10 or less)
- for each arg:
- 5*4 bytes data:
- word1: type, 4 for long arg
(0=uint8, 1=int16, 2=(u)int32, 3=(u)int64), PS and EOS treat every non-4 type as (u)int32 - word2: arg value when word1 isn't 4
- word3: (ignored, treated as 0)
(high-order word of 64-bit integer arg, but not on PS and EOS) - word4:
(? picked up but not used?) index of long arg - word5: (size of data when word1=4)
- 32bit value: num of long args (not limited here, but has to be 10 or less)
- for each long arg:
- 32bit value
(? picked up, but unknown purpose) index of long arg, should match word4 above - variable length data (length specified by word5, must be larger than zero, size only limited by camera heap memory)
I expect the above to work on all (< DIGIC 8) cameras that implement these operations.
There might be details that I missed, corrections are welcome.
A demo is attached, in python (I have 3.6), along with a patch against
https://github.com/petabyt/sequoia-ptpy . I'm not very familiar with python, it just seemed the easiest choice to make a demo.
edit:
description is fixed, plus link added that explains 0x9057 (also, read on for other findings)