Procházet zdrojové kódy

Merge pull request #420 from nielsmh/fix/toolboxmiscfixes

Various Toolbox fixes
John Morio Sakaguchi před 1 rokem
rodič
revize
546f1f6da9

+ 2 - 2
lib/SCSI2SD/src/firmware/vendor.c

@@ -115,12 +115,12 @@ void scsiVendorCommandSetLen(uint8_t command, uint8_t* command_length)
 		// Apple CD-ROM with CD audio over the SCSI bus
 		if (scsiDev.target->cfg->quirks == S2S_CFG_QUIRKS_APPLE && (command == 0xD8 || command == 0xD9))
 		{
-			scsiDev.cdbLen =  12;
+			*command_length =  12;
 		}
 		// Plextor CD-ROM vendor extensions 0xD8
 		if (unlikely(scsiDev.target->cfg->vendorExtensions & VENDOR_EXTENSION_OPTICAL_PLEXTOR) && command == 0xD8)
 		{
-			scsiDev.cdbLen =  12;
+			*command_length =  12;
 		}
 	}
 

+ 95 - 62
src/Toolbox.cpp

@@ -30,12 +30,16 @@ extern "C" {
 }
 
 
+const uint8_t MAX_FILE_LISTING_FILES = 100;
+
+
 extern "C" int8_t scsiToolboxEnabled()
 {
     static int8_t enabled = -1;
     if (enabled == -1)
     {
         enabled = ini_getbool("SCSI", "EnableToolbox", 0, CONFIGFILE);
+        logmsg("Toolbox enabled = ", enabled);
     }
     return enabled == 1;
 }
@@ -71,15 +75,19 @@ static void doCountFiles(const char * dir_name, bool isCD = false)
             break;
         }
         bool isDir = file.isDirectory();
-        file.getName(name, MAX_FILE_PATH);
+        size_t len = file.getName(name, MAX_FILE_PATH);
         file.close();
         if (isCD && isDir)
             continue;
+        // truncate filename the same way listing does, before validating name
+        if (len > MAX_MAC_PATH)
+            name[MAX_MAC_PATH] = 0x0;
+        dbgmsg("TOOLBOX COUNT FILES: truncated filename is '", name, "'");
         // only count valid files.
         if(toolboxFilenameValid(name, isCD))
         {
             file_count = file_count + 1;
-            if(file_count > 100) {
+            if(file_count > MAX_FILE_LISTING_FILES) {
                 scsiDev.status = CHECK_CONDITION;
                 scsiDev.target->sense.code = ILLEGAL_REQUEST;
                 scsiDev.target->sense.asc = OPEN_RETRO_SCSI_TOO_MANY_FILES;
@@ -97,107 +105,121 @@ static void doCountFiles(const char * dir_name, bool isCD = false)
 static void onListFiles(const char * dir_name, bool isCD = false) {
     FsFile dir;
     FsFile file;
+    const size_t ENTRY_SIZE = 40;
 
-    memset(scsiDev.data, 0, 4096);
-    int ENTRY_SIZE = 40;
+    memset(scsiDev.data, 0, ENTRY_SIZE * (MAX_FILE_LISTING_FILES + 1));
     char name[MAX_FILE_PATH] = {0};
+    uint8_t index = 0;
+    uint8_t file_entry[ENTRY_SIZE] = {0};
+
     dir.open(dir_name);
     dir.rewindDirectory();
-    uint8_t index = 0;
-    uint8_t file_entry[40] = {0};
     while (file.openNext(&dir, O_RDONLY))
     {   
+        memset(name, 0, sizeof(name));
+        // get base information
         uint8_t isDir = file.isDirectory() ? 0x00 : 0x01;
-        int len = file.getName(name, MAX_FILE_PATH);
-        if (len > MAX_MAC_PATH)
-            name[MAX_MAC_PATH] = 0x0;
+        size_t len = file.getName(name, MAX_FILE_PATH);
         uint64_t size = file.fileSize();
         file.close();
+        // truncate filename to fit in destination buffer
+        if (len > MAX_MAC_PATH)
+            name[MAX_MAC_PATH] = 0x0;
+        dbgmsg("TOOLBOX LIST FILES: truncated filename is '", name, "'");
+        // validate file is allowed for this listing
         if (!toolboxFilenameValid(name, isCD))
             continue;
         if (isCD && isDir == 0x00)
             continue;
+        // fill output buffer
         file_entry[0] = index;
         file_entry[1] = isDir;
-        int c = 0; // Index of char in name[]
-
-        for(int i = 2; i < (MAX_MAC_PATH + 1 + 2); i++) {   // bytes 2 - 34
-            file_entry[i] = name[c++];
+        for(int i = 0; i < MAX_MAC_PATH + 1 ; i++) {
+            file_entry[i + 2] = name[i];   // bytes 2 - 34
         }
         file_entry[35] = 0; //(size >> 32) & 0xff;
         file_entry[36] = (size >> 24) & 0xff;
         file_entry[37] = (size >> 16) & 0xff;
         file_entry[38] = (size >> 8) & 0xff;
         file_entry[39] = (size) & 0xff;
+        // send to SCSI output buffer
         memcpy(&(scsiDev.data[ENTRY_SIZE * index]), file_entry, ENTRY_SIZE);
+        // increment index
         index = index + 1;
+        if (index >= MAX_FILE_LISTING_FILES) break;
     }
     dir.close();
 
-    scsiDev.dataLen = 4096;
+    scsiDev.dataLen = ENTRY_SIZE * index;
     scsiDev.phase = DATA_IN;
+    dbgmsg("TOOLBOX LIST FILES: returning ", index, " files for size ", scsiDev.dataLen);
 }
 
 static FsFile get_file_from_index(uint8_t index, const char * dir_name, bool isCD = false)
 {
-  FsFile dir;
-  FsFile file_test;
-  char name[MAX_FILE_PATH] = {0};
+    FsFile dir;
+    FsFile file_test;
+    char name[MAX_FILE_PATH] = {0};
 
-  dir.open(dir_name);
-  dir.rewindDirectory(); // Back to the top
-  int count = 0;
-  while (file_test.openNext(&dir, O_RDONLY))
-  {
-    
-    // If error there is no next file to open.
-    if(file_test.getError() > 0) {
-      file_test.close();
-      break;
-    }
-    file_test.getName(name, MAX_FILE_PATH);
-    if (isCD && file_test.isDirectory())
-    {
-        file_test.close();
-        continue;
-    }
-    if(!toolboxFilenameValid(name, isCD))
-    {
-        file_test.close();
-        continue;
-    }
-    if (count == index)
-    {
-      dir.close();
-      return file_test;
-    }
-    else
+    dir.open(dir_name);
+    dir.rewindDirectory(); // Back to the top
+    int count = 0;
+    while (file_test.openNext(&dir, O_RDONLY))
     {
-      file_test.close();
+        // If error there is no next file to open.
+        if(file_test.getError() > 0) {
+            file_test.close();
+            break;
+        }
+        // no directories in CD image listing
+        if (isCD && file_test.isDirectory())
+        {
+            file_test.close();
+            continue;
+        }
+        // truncate filename the same way listing does, before validating name
+        size_t len = file_test.getName(name, MAX_FILE_PATH);
+        if (len > MAX_MAC_PATH)
+            name[MAX_MAC_PATH] = 0x0;
+        // validate filename
+        if(!toolboxFilenameValid(name, isCD))
+        {
+            file_test.close();
+            continue;
+        }
+        // found file?
+        if (count == index)
+        {
+            dir.close();
+            return file_test;
+        }
+        else
+        {
+            file_test.close();
+        }
+        count++;
     }
-    count++;
-  }
-  file_test.close();
-  dir.close();
-  return file_test;
+    file_test.close();
+    dir.close();
+    return file_test;
 }
 
 // Devices that are active on this SCSI device.
 static void onListDevices()
 {
-  for (int i = 0; i < NUM_SCSIID; i++)
-  {
-    const S2S_TargetCfg* cfg = s2s_getConfigById(i);
-    if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
-    {
-        scsiDev.data[i] = (int)cfg->deviceType; // 2 == cd
-    }
-    else
+    for (int i = 0; i < NUM_SCSIID; i++)
     {
-        scsiDev.data[i] = 0xFF; // not enabled target.
+        const S2S_TargetCfg* cfg = s2s_getConfigById(i);
+        if (cfg && (cfg->scsiId & S2S_CFG_TARGET_ENABLED))
+        {
+            scsiDev.data[i] = (int)cfg->deviceType; // 2 == cd
+        }
+        else
+        {
+            scsiDev.data[i] = 0xFF; // not enabled target.
+        }
     }
-  }
-  scsiDev.dataLen = NUM_SCSIID;
+    scsiDev.dataLen = NUM_SCSIID;
 }
 
 static void onSetNextCD(const char * img_dir)
@@ -348,58 +370,69 @@ extern "C" int scsiToolboxCommand()
     if (unlikely(command == TOOLBOX_COUNT_FILES))
     {
         char img_dir[MAX_FILE_PATH];
+        dbgmsg("TOOLBOX_COUNT_FILES");
         getToolBoxSharedDir(img_dir);
         doCountFiles(img_dir);
     }
     else if (unlikely(command == TOOLBOX_LIST_FILES))
     {
         char img_dir[MAX_FILE_PATH];
+        dbgmsg("TOOLBOX_LIST_FILES");
         getToolBoxSharedDir(img_dir);
         onListFiles(img_dir);
     }
     else if (unlikely(command == TOOLBOX_GET_FILE))
     {
         char img_dir[MAX_FILE_PATH];
+        dbgmsg("TOOLBOX_GET_FILE");
         getToolBoxSharedDir(img_dir);
         onGetFile10(img_dir);
     }
     else if (unlikely(command == TOOLBOX_SEND_FILE_PREP))
     {
         char img_dir[MAX_FILE_PATH];
+        dbgmsg("TOOLBOX_SEND_FILE_PREP");
         getToolBoxSharedDir(img_dir);
         onSendFilePrep(img_dir);
     }
     else if (unlikely(command == TOOLBOX_SEND_FILE_10))
     {
+        dbgmsg("TOOLBOX_SEND_FILE_10");
         onSendFile10();
     }
     else if (unlikely(command == TOOLBOX_SEND_FILE_END))
     {
+        dbgmsg("TOOLBOX_SEND_FILE_END");
         onSendFileEnd();
     }
     else if(unlikely(command == TOOLBOX_TOGGLE_DEBUG))
     {
+        dbgmsg("TOOLBOX_TOGGLE_DEBUG");
         onToggleDebug();
     }
     else if(unlikely(command == TOOLBOX_LIST_CDS))
     {
         char img_dir[4];
+        dbgmsg("TOOLBOX_LIST_CDS");
         snprintf(img_dir, sizeof(img_dir), CD_IMG_DIR, (int)img.scsiId & S2S_CFG_TARGET_ID_BITS);
         onListFiles(img_dir, true);
     }
     else if(unlikely(command == TOOLBOX_SET_NEXT_CD))
     {
         char img_dir[4];
+        dbgmsg("TOOLBOX_SET_NEXT_CD");
         snprintf(img_dir, sizeof(img_dir), CD_IMG_DIR, (int)img.scsiId & S2S_CFG_TARGET_ID_BITS);
         onSetNextCD(img_dir);
     }
     else if(unlikely(command == TOOLBOX_LIST_DEVICES))
     {
+        dbgmsg("TOOLBOX_LIST_DEVICES");
         onListDevices();
     }
     else if (unlikely(command == TOOLBOX_COUNT_CDS))
     {
         char img_dir[4];
+        dbgmsg("TOOLBOX_COUNT_CDS");
         snprintf(img_dir, sizeof(img_dir), CD_IMG_DIR, (int)img.scsiId & S2S_CFG_TARGET_ID_BITS);
         doCountFiles(img_dir, true);
     }

+ 4 - 1
src/ZuluSCSI_cdrom.cpp

@@ -1250,7 +1250,10 @@ bool cdromSwitchNextImage(image_config_t &img, const char* next_filename)
         {
             if (next_filename != nullptr)
             {
-                img.ejected = false;
+                // present the drive as ejected until the host queries it again,
+                // to make sure host properly detects the media change
+                img.ejected = true;
+                img.reinsert_after_eject = true;
                 img.cdrom_events = 2; // New Media
             }
             return true;

+ 11 - 2
src/ZuluSCSI_log_trace.cpp

@@ -100,8 +100,17 @@ static const char *getCommandName(uint8_t cmd)
         case 0xA8: return "Read12";
         case 0xC0: return "OMTI-5204 DefineFlexibleDiskFormat";
         case 0xC2: return "OMTI-5204 AssignDiskParameters";
-        case 0xD8: return "Vendor 0xD8 Command";
-        case 0xD9: return "Vendor 0xD9 Command";
+        case 0xD0: return "Vendor 0xD0 Command (Toolbox list files)";
+        case 0xD1: return "Vendor 0xD1 Command (Toolbox get file)";
+        case 0xD2: return "Vendor 0xD2 Command (Toolbox count files)";
+        case 0xD3: return "Vendor 0xD3 Command (Toolbox send file prep)";
+        case 0xD4: return "Vendor 0xD4 Command (Toolbox send file 10)";
+        case 0xD5: return "Vendor 0xD5 Command (Toolbox send file end)";
+        case 0xD6: return "Vendor 0xD6 Command (Toolbox toggle debug)";
+        case 0xD7: return "Vendor 0xD7 Command (Toolbox list CDs)";
+        case 0xD8: return "Vendor 0xD8 Command (Toolbox set next CD/Apple/Plextor)";
+        case 0xD9: return "Vendor 0xD9 Command (Toolbox list devices/Apple)";
+        case 0xDA: return "Vendor 0xDA Command (Toolbox count CDs)";
         case 0xE0: return "Xebec RAM Diagnostic";
         case 0xE4: return "Xebec Drive Diagnostic";              
         default:   return "Unknown";