139139}
140140
141141# Storage IDs struct
142+ _MTP_STORAGE_ID = const (0x00010001 )
143+
142144_MTP_STORAGE_IDS_DESC = {
143145 "count" : 0 | uctypes .UINT32 ,
144146 "storage_ids" : (4 | uctypes .ARRAY , 1 | uctypes .UINT32 ) # Variable length array
@@ -199,7 +201,7 @@ def __init__(self, storage_path="/", rx_size=_DEFAULT_RX_BUF_SIZE, tx_size=_DEFA
199201
200202 # Filesystem attributes
201203 self ._storage_path = storage_path
202- self ._storage_id = 0x00010001 # Fixed ID for the single storage we support
204+ self ._storage_id = _MTP_STORAGE_ID # Fixed ID for the single storage we support
203205 self ._next_object_handle = 0x00000001 # Start object handles at 1
204206 self ._object_handles = {} # Maps object handles to file paths
205207 self ._parent_map = {} # Maps handles to parent handles
@@ -226,6 +228,8 @@ def _log(self, msg, *args):
226228 def desc_cfg (self , desc , itf_num , ep_num , strs ):
227229 """Build the USB configuration descriptor for this interface."""
228230 self ._log ("Building descriptors: itf_num={}, ep_num={}" , itf_num , ep_num )
231+
232+ # Add the interface identifier to the strings
229233 i_interface = len (strs )
230234 strs .append ("MTP" )
231235
@@ -535,22 +539,24 @@ def _cmd_get_device_info(self):
535539 # Handle variable-length data after the fixed struct
536540 offset = 8 # Start after the fixed part of the struct
537541
542+
538543 # MTP extensions description string - Microsoft extension
539544 # MTP extension strings are ASCII strings in PIMA format (8-bit length + 8-bit chars with null terminator)
540- ext_string = "microsoft.com: 1.0" # Standard Microsoft extension string
545+ offset += self ._write_mtp_string (data , offset , "microsoft.com: 1.0" )
546+ # ext_string = "microsoft.com: 1.0" # Standard Microsoft extension string
541547
542- # String length (8-bit, including null terminator)
543- data [offset ] = len (ext_string ) + 1
544- offset += 1
548+ # # String length (8-bit, including null terminator)
549+ # data[offset] = len(ext_string) * 2 + 1
550+ # offset += 1
545551
546- # String data as ASCII
547- for c in ext_string :
548- data [offset ] = ord (c )
549- offset += 1
552+ # # String data as ASCII
553+ # for c in ext_string:
554+ # data[offset] = ord(c)
555+ # offset += 1
550556
551- # ASCII null terminator
552- data [offset ] = 0
553- offset += 1
557+ # # ASCII null terminator
558+ # data[offset] = 0
559+ # offset += 1
554560
555561 # Functional mode
556562 struct .pack_into ("<H" , data , offset , 0 ) # Standard mode
@@ -573,25 +579,25 @@ def _cmd_get_device_info(self):
573579 ]
574580
575581 # Number of operations
576- struct .pack_into ("<H " , data , offset , len (operations ))
577- offset += 2
582+ struct .pack_into ("<I " , data , offset , len (operations ))
583+ offset += 4
578584
579585 # List of operation codes
580586 for op in operations :
581587 struct .pack_into ("<H" , data , offset , op )
582588 offset += 2
583589
584590 # Supported events (array of event codes) - empty for now
585- struct .pack_into ("<H " , data , offset , 0 ) # No events supported
586- offset += 2
591+ struct .pack_into ("<I " , data , offset , 0 ) # No events supported
592+ offset += 4
587593
588594 # Supported device properties - empty for now
589- struct .pack_into ("<H " , data , offset , 0 ) # No device properties
590- offset += 2
595+ struct .pack_into ("<I " , data , offset , 0 ) # No device properties
596+ offset += 4
591597
592598 # Supported capture formats - empty for now
593- struct .pack_into ("<H " , data , offset , 0 ) # No capture formats
594- offset += 2
599+ struct .pack_into ("<I " , data , offset , 0 ) # No capture formats
600+ offset += 4
595601
596602 # Supported playback formats (file formats we support)
597603 formats = [
@@ -601,8 +607,8 @@ def _cmd_get_device_info(self):
601607 ]
602608
603609 # Number of formats
604- struct .pack_into ("<H " , data , offset , len (formats ))
605- offset += 2
610+ struct .pack_into ("<I " , data , offset , len (formats ))
611+ offset += 4
606612
607613 # List of format codes
608614 for fmt in formats :
@@ -710,7 +716,7 @@ def _cmd_get_storage_info(self, params):
710716 storage_info = uctypes .struct (uctypes .addressof (data ), _MTP_STORAGE_INFO_DESC , uctypes .LITTLE_ENDIAN )
711717
712718 # Fill in the fixed fields
713- storage_info .storage_type = _MTP_STORAGE_FIXED_RAM
719+ storage_info .storage_type = _MTP_STORAGE_FIXED_MEDIA
714720 storage_info .filesystem_type = 0x0002 # Generic hierarchical
715721 storage_info .access_capability = _MTP_STORAGE_READ_WRITE # Read-write access
716722 storage_info .max_capacity = total_bytes
@@ -765,13 +771,18 @@ def _cmd_get_object_handles(self, params):
765771 parent_handle = params [2 ] if len (params ) > 2 else 0
766772
767773 if storage_id != 0xFFFFFFFF and storage_id != self ._storage_id :
774+ self ._log ("Error invalid storage id: {}" , storage_id )
768775 self ._send_response (_MTP_RESPONSE_INVALID_STORAGE_ID )
769776 return
770777
771778 # Collect filtered handles
772779 handles = []
780+ self ._log ("get handles: {} {} {}" , storage_id , format_code , parent_handle )
781+ self ._log ("handles: {}" , self ._object_handles )
782+ self ._log ("parent: {}" , self ._parent_map )
783+
773784 for handle , parent in self ._parent_map .items ():
774- if (parent_handle == 0 or parent == parent_handle ) and handle in self ._object_handles :
785+ if (parent_handle in ( 0 , 0xFFFFFFFF ) or parent == parent_handle ) and handle in self ._object_handles :
775786 # Apply format filter if specified
776787 if format_code == 0 or self ._get_format_by_path (self ._object_handles [handle ]) == format_code :
777788 handles .append (handle )
@@ -830,7 +841,7 @@ def _cmd_get_object_info(self, params):
830841 # Get filename (basename of the path)
831842 parts = filepath .split ('/' )
832843 filename = parts [- 1 ] if parts [- 1 ] else parts [- 2 ] # Handle trailing slash for dirs
833-
844+ self . _log ( '***** filename {}' , filename )
834845 # Prepare object info dataset
835846 data = bytearray (256 )
836847 offset = 0
@@ -847,9 +858,9 @@ def _cmd_get_object_info(self, params):
847858 struct .pack_into ("<H" , data , offset , 0 )
848859 offset += 2
849860
850- # Object size (in bytes)
851- struct .pack_into ("<I" , data , offset , filesize )
852- offset += 4
861+ # # Object size (in bytes)
862+ # struct.pack_into("<I", data, offset, filesize)
863+ # offset += 4
853864
854865 # Object compressed size (same as size)
855866 struct .pack_into ("<I" , data , offset , filesize )
@@ -1385,12 +1396,14 @@ def _write_mtp_string(self, buffer, offset, string):
13851396 """
13861397 if not string :
13871398 # Empty string - just write a 0 length
1388- struct .pack_into ("<H " , buffer , offset , 0 )
1389- return 2
1399+ struct .pack_into ("<B " , buffer , offset , 0 )
1400+ return 1
13901401
1391- # String length in 16-bit characters (including null terminator)
1392- struct .pack_into ("<H" , buffer , offset , len (string ) + 1 )
1393- offset += 2
1402+ start = offset
1403+
1404+ # String length in 8-bit characters (including null terminator)
1405+ struct .pack_into ("<B" , buffer , offset , len (string ) + 1 )
1406+ offset += 1
13941407
13951408 # String data (each character as 16-bit Unicode)
13961409 # Use little-endian UTF-16 encoding with BOM (Byte Order Mark)
@@ -1404,7 +1417,7 @@ def _write_mtp_string(self, buffer, offset, string):
14041417 offset += 2
14051418
14061419 # Return total bytes written
1407- return 2 + (len (string ) + 1 ) * 2
1420+ return offset - start # 2 + (len(string) + 1) * 2
14081421
14091422 def _format_timestamp (self , timestamp ):
14101423 """Format a timestamp into MTP date string format."""
0 commit comments