diff --git a/Marlin/src/MarlinCore.cpp b/Marlin/src/MarlinCore.cpp
index 78a881a1d8..85ee920e72 100644
--- a/Marlin/src/MarlinCore.cpp
+++ b/Marlin/src/MarlinCore.cpp
@@ -331,18 +331,14 @@ void disable_all_steppers() {
 }
 
 /**
- * A Print Job exists when the timer is running or SD printing
+ * A Print Job exists when the timer is running or SD is printing
  */
-bool printJobOngoing() {
-  return print_job_timer.isRunning() || IS_SD_PRINTING();
-}
+bool printJobOngoing() { return print_job_timer.isRunning() || IS_SD_PRINTING(); }
 
 /**
- * Printing is active when the print job timer is running
+ * Printing is active when a job is underway but not paused
  */
-bool printingIsActive() {
-  return !did_pause_print && (print_job_timer.isRunning() || IS_SD_PRINTING());
-}
+bool printingIsActive() { return !did_pause_print && printJobOngoing(); }
 
 /**
  * Printing is paused according to SD or host indicators
@@ -367,7 +363,7 @@ void startOrResumeJob() {
 
   inline void abortSDPrinting() {
     IF_DISABLED(NO_SD_AUTOSTART, card.autofile_cancel());
-    card.endFilePrint(TERN_(SD_RESORT, true));
+    card.abortFilePrintNow(TERN_(SD_RESORT, true));
 
     queue.clear();
     quickstop_stepper();
@@ -748,7 +744,7 @@ void idle(TERN_(ADVANCED_PAUSE_FEATURE, bool no_stepper_sleep/*=false*/)) {
 
   // Handle Power-Loss Recovery
   #if ENABLED(POWER_LOSS_RECOVERY) && PIN_EXISTS(POWER_LOSS)
-    if (printJobOngoing()) recovery.outage();
+    if (IS_SD_PRINTING()) recovery.outage();
   #endif
 
   // Run StallGuard endstop checks
@@ -901,7 +897,7 @@ void stop() {
     thermalManager.set_fans_paused(false); // Un-pause fans for safety
   #endif
 
-  if (IsRunning()) {
+  if (!IsStopped()) {
     SERIAL_ERROR_MSG(STR_ERR_STOPPED);
     LCD_MESSAGEPGM(MSG_STOPPED);
     safe_delay(350);       // allow enough time for messages to get out before stopping
diff --git a/Marlin/src/MarlinCore.h b/Marlin/src/MarlinCore.h
index d016151c2d..ce1b106bfa 100644
--- a/Marlin/src/MarlinCore.h
+++ b/Marlin/src/MarlinCore.h
@@ -70,6 +70,7 @@ inline bool IsRunning() { return marlin_state >= MF_RUNNING; }
 inline bool IsStopped() { return marlin_state == MF_STOPPED; }
 
 bool printingIsActive();
+bool printJobOngoing();
 bool printingIsPaused();
 void startOrResumeJob();
 
diff --git a/Marlin/src/feature/pause.cpp b/Marlin/src/feature/pause.cpp
index 93b4a2aa81..58e0c3df0d 100644
--- a/Marlin/src/feature/pause.cpp
+++ b/Marlin/src/feature/pause.cpp
@@ -649,7 +649,7 @@ void resume_print(const_float_t slow_load_length/*=0*/, const_float_t fast_load_
   #if ENABLED(SDSUPPORT)
     if (did_pause_print) {
       --did_pause_print;
-      card.startFileprint();
+      card.startOrResumeFilePrinting();
       // Write PLR now to update the z axis value
       TERN_(POWER_LOSS_RECOVERY, if (recovery.enabled) recovery.save(true));
     }
diff --git a/Marlin/src/feature/powerloss.cpp b/Marlin/src/feature/powerloss.cpp
index 3736cac453..9d6e0b42f5 100644
--- a/Marlin/src/feature/powerloss.cpp
+++ b/Marlin/src/feature/powerloss.cpp
@@ -137,7 +137,7 @@ void PrintJobRecovery::load() {
  * Set info fields that won't change
  */
 void PrintJobRecovery::prepare() {
-  card.getAbsFilename(info.sd_filename);  // SD filename
+  card.getAbsFilenameInCWD(info.sd_filename);  // SD filename
   cmd_sdpos = 0;
 }
 
diff --git a/Marlin/src/gcode/queue.cpp b/Marlin/src/gcode/queue.cpp
index 47b7d1febb..c007537398 100644
--- a/Marlin/src/gcode/queue.cpp
+++ b/Marlin/src/gcode/queue.cpp
@@ -550,7 +550,8 @@ void GCodeQueue::get_serial_commands() {
   inline void GCodeQueue::get_sdcard_commands() {
     static uint8_t sd_input_state = PS_NORMAL;
 
-    if (!IS_SD_PRINTING()) return;
+    // Get commands if there are more in the file
+    if (!IS_SD_FETCHING()) return;
 
     int sd_count = 0;
     while (!ring_buffer.full() && !card.eof()) {
diff --git a/Marlin/src/gcode/sd/M1001.cpp b/Marlin/src/gcode/sd/M1001.cpp
index 415fbb6fa7..418e594deb 100644
--- a/Marlin/src/gcode/sd/M1001.cpp
+++ b/Marlin/src/gcode/sd/M1001.cpp
@@ -25,6 +25,7 @@
 #if ENABLED(SDSUPPORT)
 
 #include "../gcode.h"
+#include "../../module/planner.h"
 #include "../../module/printcounter.h"
 
 #if DISABLED(NO_SD_AUTOSTART)
@@ -64,6 +65,11 @@
  * M1001: Execute actions for SD print completion
  */
 void GcodeSuite::M1001() {
+  planner.synchronize();
+
+  // SD Printing is finished when the queue reaches M1001
+  card.flag.sdprinting = card.flag.sdprintdone = false;
+
   // If there's another auto#.g file to run...
   if (TERN(NO_SD_AUTOSTART, false, card.autofile_check())) return;
 
diff --git a/Marlin/src/gcode/sd/M24_M25.cpp b/Marlin/src/gcode/sd/M24_M25.cpp
index 89b166f908..f46a964af0 100644
--- a/Marlin/src/gcode/sd/M24_M25.cpp
+++ b/Marlin/src/gcode/sd/M24_M25.cpp
@@ -70,7 +70,7 @@ void GcodeSuite::M24() {
   #endif
 
   if (card.isFileOpen()) {
-    card.startFileprint();            // SD card will now be read for commands
+    card.startOrResumeFilePrinting();            // SD card will now be read for commands
     startOrResumeJob();               // Start (or resume) the print job timer
     TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
   }
diff --git a/Marlin/src/gcode/sd/M27.cpp b/Marlin/src/gcode/sd/M27.cpp
index a76070fda8..f6e48d4ae8 100644
--- a/Marlin/src/gcode/sd/M27.cpp
+++ b/Marlin/src/gcode/sd/M27.cpp
@@ -35,7 +35,7 @@
 void GcodeSuite::M27() {
   if (parser.seen('C')) {
     SERIAL_ECHOPGM("Current file: ");
-    card.printFilename();
+    card.printSelectedFilename();
     return;
   }
 
diff --git a/Marlin/src/gcode/sd/M32.cpp b/Marlin/src/gcode/sd/M32.cpp
index ea893c9232..3baa552e6e 100644
--- a/Marlin/src/gcode/sd/M32.cpp
+++ b/Marlin/src/gcode/sd/M32.cpp
@@ -49,7 +49,7 @@ void GcodeSuite::M32() {
 
     if (parser.seenval('S')) card.setIndex(parser.value_long());
 
-    card.startFileprint();
+    card.startOrResumeFilePrinting();
 
     // Procedure calls count as normal print time.
     if (!call_procedure) startOrResumeJob();
diff --git a/Marlin/src/gcode/sd/M524.cpp b/Marlin/src/gcode/sd/M524.cpp
index 089d2e2f0c..e715915565 100644
--- a/Marlin/src/gcode/sd/M524.cpp
+++ b/Marlin/src/gcode/sd/M524.cpp
@@ -33,7 +33,7 @@
 void GcodeSuite::M524() {
 
   if (IS_SD_PRINTING())
-    card.flag.abort_sd_printing = true;
+    card.abortFilePrintSoon();
   else if (card.isMounted())
     card.closefile();
 
diff --git a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
index 2e5f967c2f..85430c18b0 100644
--- a/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
+++ b/Marlin/src/lcd/HD44780/marlinui_HD44780.cpp
@@ -755,7 +755,7 @@ inline uint8_t draw_elapsed_or_remaining_time(uint8_t timepos, const bool blink)
   char buffer[14];
 
   #if ENABLED(SHOW_REMAINING_TIME)
-    const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && (printingIsActive() || marlin_state == MF_SD_COMPLETE);
+    const bool show_remain = TERN1(ROTATE_PROGRESS_DISPLAY, blink) && printingIsActive();
     if (show_remain) {
       #if ENABLED(USE_M73_REMAINING_TIME)
         duration_t remaining = ui.get_remaining_time();
@@ -889,7 +889,7 @@ void MarlinUI::draw_status_screen() {
 
           #else // !HAS_DUAL_MIXING
 
-            const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE);
+            const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
 
             if (show_e_total) {
               #if ENABLED(LCD_SHOW_E_TOTAL)
diff --git a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
index 33cb9575f1..010d9a6680 100644
--- a/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
+++ b/Marlin/src/lcd/dogm/status_screen_DOGM.cpp
@@ -41,7 +41,7 @@
 #include "../../gcode/parser.h" // for units (and volumetric)
 
 #if ENABLED(LCD_SHOW_E_TOTAL)
-  #include "../../MarlinCore.h" // for printingIsActive(), marlin_state and MF_SD_COMPLETE
+  #include "../../MarlinCore.h" // for printingIsActive()
 #endif
 
 #if ENABLED(FILAMENT_LCD_DISPLAY)
@@ -464,7 +464,7 @@ void MarlinUI::draw_status_screen() {
     #endif
   #endif
 
-  const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive() || marlin_state == MF_SD_COMPLETE);
+  const bool show_e_total = TERN0(LCD_SHOW_E_TOTAL, printingIsActive());
 
   // At the first page, generate new display values
   if (first_page) {
diff --git a/Marlin/src/lcd/dwin/e3v2/dwin.cpp b/Marlin/src/lcd/dwin/e3v2/dwin.cpp
index 620b267bd2..76118d6814 100644
--- a/Marlin/src/lcd/dwin/e3v2/dwin.cpp
+++ b/Marlin/src/lcd/dwin/e3v2/dwin.cpp
@@ -1891,7 +1891,7 @@ void HMI_SDCardUpdate() {
       else if (checkkey == PrintProcess || checkkey == Tune || printingIsActive()) {
         // TODO: Move card removed abort handling
         //       to CardReader::manage_media.
-        card.flag.abort_sd_printing = true;
+        card.abortFilePrintSoon();
         wait_for_heatup = wait_for_user = false;
         dwin_abort_flag = true; // Reset feedrate, return to Home
       }
@@ -2311,7 +2311,7 @@ void HMI_PauseOrStop() {
         checkkey = Back_Main;
         if (HMI_flag.home_flag) planner.synchronize(); // Wait for planner moves to finish!
         wait_for_heatup = wait_for_user = false;       // Stop waiting for heating/user
-        card.flag.abort_sd_printing = true;            // Let the main loop handle SD abort
+        card.abortFilePrintSoon();                     // Let the main loop handle SD abort
         dwin_abort_flag = true;                        // Reset feedrate, return to Home
         #ifdef ACTION_ON_CANCEL
           host_action_cancel();
diff --git a/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp b/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp
index c502d0ae27..c0b3b60a16 100644
--- a/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp
+++ b/Marlin/src/lcd/extui/dgus/mks/DGUSScreenHandler.cpp
@@ -289,7 +289,7 @@ void DGUSScreenHandler::ScreenChangeHook(DGUS_VP_Variable &var, void *val_ptr) {
   // if robin nano is printing. when it is, dgus will enter the printing
   // page to continue print;
   //
-  //if (print_job_timer.isRunning() || print_job_timer.isPaused()) {
+  //if (printJobOngoing() || printingIsPaused()) {
   //  if (target == MKSLCD_PAUSE_SETTING_MOVE || target == MKSLCD_PAUSE_SETTING_EX
   //    || target == MKSLCD_SCREEN_PRINT || target == MKSLCD_SCREEN_PAUSE
   //  ) {
@@ -324,7 +324,7 @@ void DGUSScreenHandler::ScreenBackChange(DGUS_VP_Variable &var, void *val_ptr) {
 
 void DGUSScreenHandler::ZoffsetConfirm(DGUS_VP_Variable &var, void *val_ptr) {
   settings.save();
-  if (print_job_timer.isRunning())
+  if (printJobOngoing())
     GotoScreen(MKSLCD_SCREEN_PRINT);
   else if (print_job_timer.isPaused)
     GotoScreen(MKSLCD_SCREEN_PAUSE);
@@ -1442,8 +1442,7 @@ bool DGUSScreenHandler::loop() {
     }
 
     #if ENABLED(DGUS_MKS_RUNOUT_SENSOR)
-      if (booted && (IS_SD_PRINTING() || IS_SD_PAUSED()))
-        DGUS_Runout_Idle();
+      if (booted && printingIsActive()) DGUS_Runout_Idle();
     #endif
   #endif // SHOW_BOOTSCREEN
 
diff --git a/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp b/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp
index ff642be294..6d207b86a7 100644
--- a/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp
+++ b/Marlin/src/lcd/extui/mks_ui/draw_dialog.cpp
@@ -91,8 +91,8 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
         cur_name = strrchr(list_file.file_name[sel_id], '/');
 
         SdFile file, *curDir;
-        card.endFilePrint();
-        const char * const fname = card.diveToFile(true, curDir, cur_name);
+        card.abortFilePrintNow();
+        const char * const fname = card.diveToFile(false, curDir, cur_name);
         if (!fname) return;
         if (file.open(curDir, fname, O_READ)) {
           gCfgItems.curFilesize = file.fileSize();
@@ -108,7 +108,7 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
             planner.flow_percentage[1] = 100;
             planner.e_factor[1]        = planner.flow_percentage[1] * 0.01f;
           #endif
-          card.startFileprint();
+          card.startOrResumeFilePrinting();
           #if ENABLED(POWER_LOSS_RECOVERY)
             recovery.prepare();
           #endif
@@ -124,8 +124,8 @@ static void btn_ok_event_cb(lv_obj_t *btn, lv_event_t event) {
     lv_draw_ready_print();
 
     #if ENABLED(SDSUPPORT)
-      uiCfg.print_state           = IDLE;
-      card.flag.abort_sd_printing = true;
+      uiCfg.print_state = IDLE;
+      card.abortFilePrintSoon();
     #endif
   }
   else if (DIALOG_IS(TYPE_FINISH_PRINT)) {
diff --git a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp
index 4134759b75..76898997eb 100644
--- a/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp
+++ b/Marlin/src/lcd/extui/mks_ui/draw_ui.cpp
@@ -638,19 +638,18 @@ char *creat_title_text() {
         W25QXX.SPI_FLASH_BufferWrite(bmp_public_buf, BAK_VIEW_ADDR_TFT35 + row * 400, 400);
       #endif
       row++;
+      card.abortFilePrintNow();
       if (row >= 200) {
         size = 809;
         row  = 0;
 
         gcode_preview_over = false;
 
-        card.closefile();
         char *cur_name = strrchr(list_file.file_name[sel_id], '/');
 
         SdFile file;
         SdFile *curDir;
-        card.endFilePrint();
-        const char * const fname = card.diveToFile(true, curDir, cur_name);
+        const char * const fname = card.diveToFile(false, curDir, cur_name);
         if (!fname) return;
         if (file.open(curDir, fname, O_READ)) {
           gCfgItems.curFilesize = file.fileSize();
@@ -667,13 +666,12 @@ char *creat_title_text() {
             planner.flow_percentage[1] = 100;
             planner.e_factor[1]        = planner.flow_percentage[1] * 0.01;
           #endif
-          card.startFileprint();
+          card.startOrResumeFilePrinting();
           TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
           once_flag = false;
         }
         return;
       }
-      card.closefile();
     #endif // SDSUPPORT
   }
 
diff --git a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp
index 1e3262be3b..be693a748f 100644
--- a/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp
+++ b/Marlin/src/lcd/extui/mks_ui/wifi_module.cpp
@@ -505,7 +505,7 @@ int write_to_file(char *buf, int len) {
 
       if (res == -1) {
         upload_file.close();
-        const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath);
+        const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath);
 
         if (upload_file.open(upload_curDir, fname, O_WRITE)) {
           upload_file.setpos(&pos);
@@ -732,12 +732,10 @@ static void wifi_gcode_exec(uint8_t *cmd_line) {
                 if (!gcode_preview_over) {
                   char *cur_name = strrchr(list_file.file_name[sel_id], '/');
 
-                  card.endFilePrint();
-
                   SdFile file;
                   SdFile *curDir;
-                  card.endFilePrint();
-                  const char * const fname = card.diveToFile(true, curDir, cur_name);
+                  card.abortFilePrintNow();
+                  const char * const fname = card.diveToFile(false, curDir, cur_name);
                   if (!fname) return;
                   if (file.open(curDir, fname, O_READ)) {
                     gCfgItems.curFilesize = file.fileSize();
@@ -754,7 +752,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) {
                       planner.flow_percentage[1] = 100;
                       planner.e_factor[1] = planner.flow_percentage[1] * 0.01f;
                     #endif
-                    card.startFileprint();
+                    card.startOrResumeFilePrinting();
                     TERN_(POWER_LOSS_RECOVERY, recovery.prepare());
                     once_flag = false;
                   }
@@ -814,7 +812,7 @@ static void wifi_gcode_exec(uint8_t *cmd_line) {
             clear_cur_ui();
             #if ENABLED(SDSUPPORT)
               uiCfg.print_state = IDLE;
-              card.flag.abort_sd_printing = true;
+              card.abortFilePrintSoon();
             #endif
 
             lv_draw_ready_print();
@@ -1317,7 +1315,7 @@ static void file_first_msg_handle(uint8_t * msg, uint16_t msgLen) {
 
     card.cdroot();
     upload_file.close();
-    const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath);
+    const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath);
 
     if (!upload_file.open(upload_curDir, fname, O_CREAT | O_APPEND | O_WRITE | O_TRUNC)) {
       clear_cur_ui();
@@ -1370,7 +1368,7 @@ static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) {
       int res = upload_file.write(public_buf, file_writer.write_index);
       if (res == -1) {
         upload_file.close();
-        const char * const fname = card.diveToFile(true, upload_curDir, saveFilePath);
+        const char * const fname = card.diveToFile(false, upload_curDir, saveFilePath);
         if (upload_file.open(upload_curDir, fname, O_WRITE)) {
           upload_file.setpos(&pos);
           res = upload_file.write(public_buf, file_writer.write_index);
@@ -1378,7 +1376,7 @@ static void file_fragment_msg_handle(uint8_t * msg, uint16_t msgLen) {
       }
       upload_file.close();
       SdFile file, *curDir;
-      const char * const fname = card.diveToFile(true, curDir, saveFilePath);
+      const char * const fname = card.diveToFile(false, curDir, saveFilePath);
       if (file.open(curDir, fname, O_RDWR)) {
         gCfgItems.curFilesize = file.fileSize();
         file.close();
@@ -1744,7 +1742,7 @@ void mks_wifi_firmware_update() {
     if (wifi_upload(0) >= 0) {
       card.removeFile((char *)ESP_FIRMWARE_FILE_RENAME);
       SdFile file, *curDir;
-      const char * const fname = card.diveToFile(true, curDir, ESP_FIRMWARE_FILE);
+      const char * const fname = card.diveToFile(false, curDir, ESP_FIRMWARE_FILE);
       if (file.open(curDir, fname, O_READ)) {
         file.rename(curDir, (char *)ESP_FIRMWARE_FILE_RENAME);
         file.close();
diff --git a/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp b/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp
index cb5bb762d0..4a8e473a5c 100644
--- a/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp
+++ b/Marlin/src/lcd/extui/mks_ui/wifi_upload.cpp
@@ -625,7 +625,7 @@ void upload_spin() {
 
 // Try to upload the given file at the given address
 void SendUpdateFile(const char *file, uint32_t address) {
-  const char * const fname = card.diveToFile(true, update_curDir, ESP_FIRMWARE_FILE);
+  const char * const fname = card.diveToFile(false, update_curDir, ESP_FIRMWARE_FILE);
   if (!update_file.open(update_curDir, fname, O_READ)) return;
 
   esp_upload.fileSize = update_file.fileSize();
diff --git a/Marlin/src/lcd/extui/ui_api.cpp b/Marlin/src/lcd/extui/ui_api.cpp
index 9cc8b9962c..faa23665bb 100644
--- a/Marlin/src/lcd/extui/ui_api.cpp
+++ b/Marlin/src/lcd/extui/ui_api.cpp
@@ -54,6 +54,7 @@
 #include "../../module/printcounter.h"
 #include "../../libs/duration_t.h"
 #include "../../HAL/shared/Delay.h"
+#include "../../MarlinCore.h"
 #include "../../sd/cardreader.h"
 
 #if ENABLED(PRINTCOUNTER)
@@ -106,9 +107,6 @@ namespace ExtUI {
     #if ENABLED(JOYSTICK)
       uint8_t jogging : 1;
     #endif
-    #if ENABLED(SDSUPPORT)
-      uint8_t was_sd_printing : 1;
-    #endif
   } flags;
 
   #ifdef __SAM3X8E__
@@ -1017,27 +1015,17 @@ namespace ExtUI {
   void setUserConfirmed() { TERN_(HAS_RESUME_CONTINUE, wait_for_user = false); }
 
   void printFile(const char *filename) {
-    UNUSED(filename);
-    TERN_(SDSUPPORT, card.openAndPrintFile(filename));
+    TERN(SDSUPPORT, card.openAndPrintFile(filename), UNUSED(filename));
   }
 
   bool isPrintingFromMediaPaused() {
-    return TERN0(SDSUPPORT, isPrintingFromMedia() && !IS_SD_PRINTING());
+    return TERN0(SDSUPPORT, isPrintingFromMedia() && printingIsPaused());
   }
 
-  bool isPrintingFromMedia() {
-    #if ENABLED(SDSUPPORT)
-      // Account for when IS_SD_PRINTING() reports the end of the
-      // print when there is still SD card data in the planner.
-      flags.was_sd_printing = card.isFileOpen() || (flags.was_sd_printing && commandsInQueue());
-      return flags.was_sd_printing;
-    #else
-      return false;
-    #endif
-  }
+  bool isPrintingFromMedia() { return IS_SD_PRINTING(); }
 
   bool isPrinting() {
-    return (commandsInQueue() || isPrintingFromMedia() || TERN0(SDSUPPORT, IS_SD_PRINTING())) || print_job_timer.isRunning() || print_job_timer.isPaused();
+    return commandsInQueue() || isPrintingFromMedia() || printJobOngoing() || printingIsPaused();
   }
 
   bool isPrintingPaused() {
diff --git a/Marlin/src/lcd/marlinui.cpp b/Marlin/src/lcd/marlinui.cpp
index f83d129b2f..4c33b924c4 100644
--- a/Marlin/src/lcd/marlinui.cpp
+++ b/Marlin/src/lcd/marlinui.cpp
@@ -1487,7 +1487,7 @@ void MarlinUI::update() {
   void MarlinUI::abort_print() {
     #if ENABLED(SDSUPPORT)
       wait_for_heatup = wait_for_user = false;
-      card.flag.abort_sd_printing = true;
+      card.abortFilePrintSoon();
     #endif
     #ifdef ACTION_ON_CANCEL
       host_action_cancel();
diff --git a/Marlin/src/module/endstops.cpp b/Marlin/src/module/endstops.cpp
index 14c5f13367..d7f728ad4b 100644
--- a/Marlin/src/module/endstops.cpp
+++ b/Marlin/src/module/endstops.cpp
@@ -395,7 +395,7 @@ void Endstops::event_handler() {
 
     #if BOTH(SD_ABORT_ON_ENDSTOP_HIT, SDSUPPORT)
       if (planner.abort_on_endstop_hit) {
-        card.endFilePrint();
+        card.abortFilePrintNow();
         quickstop_stepper();
         thermalManager.disable_all_heaters();
         print_job_timer.stop();
diff --git a/Marlin/src/sd/cardreader.cpp b/Marlin/src/sd/cardreader.cpp
index a54884bec1..3f6b50dd4b 100644
--- a/Marlin/src/sd/cardreader.cpp
+++ b/Marlin/src/sd/cardreader.cpp
@@ -161,7 +161,7 @@ CardReader::CardReader() {
     #endif
   #endif
 
-  flag.sdprinting = flag.mounted = flag.saving = flag.logging = false;
+  flag.sdprinting = flag.sdprintdone = flag.mounted = flag.saving = flag.logging = false;
   filesize = sdpos = 0;
 
   TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0);
@@ -379,7 +379,7 @@ void CardReader::ls() {
 //
 // Echo the DOS 8.3 filename (and long filename, if any)
 //
-void CardReader::printFilename() {
+void CardReader::printSelectedFilename() {
   if (file.isOpen()) {
     char dosFilename[FILENAME_LENGTH];
     file.getDosName(dosFilename);
@@ -487,9 +487,9 @@ void CardReader::manage_media() {
 void CardReader::release() {
   // Card removed while printing? Abort!
   if (IS_SD_PRINTING())
-    card.flag.abort_sd_printing = true;
+    abortFilePrintSoon();
   else
-    endFilePrint();
+    endFilePrintNow();
 
   flag.mounted = false;
   flag.workDirIsRoot = true;
@@ -516,9 +516,10 @@ void CardReader::openAndPrintFile(const char *name) {
  * since you cannot browse files during active printing.
  * Used by M24 and anywhere Start / Resume applies.
  */
-void CardReader::startFileprint() {
+void CardReader::startOrResumeFilePrinting() {
   if (isMounted()) {
     flag.sdprinting = true;
+    flag.sdprintdone = false;
     TERN_(SD_RESORT, flush_presort());
   }
 }
@@ -526,14 +527,19 @@ void CardReader::startFileprint() {
 //
 // Run tasks upon finishing or aborting a file print.
 //
-void CardReader::endFilePrint(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
+void CardReader::endFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
   TERN_(ADVANCED_PAUSE_FEATURE, did_pause_print = 0);
   TERN_(DWIN_CREALITY_LCD, HMI_flag.print_finish = flag.sdprinting);
-  flag.sdprinting = flag.abort_sd_printing = false;
+  flag.abort_sd_printing = false;
   if (isFileOpen()) file.close();
   TERN_(SD_RESORT, if (re_sort) presort());
 }
 
+void CardReader::abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort/*=false*/)) {
+  flag.sdprinting = flag.sdprintdone = false;
+  endFilePrintNow(TERN_(SD_RESORT, re_sort));
+}
+
 void CardReader::openLogFile(const char * const path) {
   flag.logging = DISABLED(SDCARD_READONLY);
   IF_DISABLED(SDCARD_READONLY, openFileWrite(path));
@@ -542,7 +548,7 @@ void CardReader::openLogFile(const char * const path) {
 //
 // Get the root-relative DOS path of the selected file
 //
-void CardReader::getAbsFilename(char *dst) {
+void CardReader::getAbsFilenameInCWD(char *dst) {
   *dst++ = '/';
   uint8_t cnt = 1;
 
@@ -608,7 +614,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ
         }
 
         // Store current filename (based on workDirParents) and position
-        getAbsFilename(proc_filenames[file_subcall_ctr]);
+        getAbsFilenameInCWD(proc_filenames[file_subcall_ctr]);
         filespos[file_subcall_ctr] = sdpos;
 
         // For sub-procedures say 'SUBROUTINE CALL target: "..." parent: "..." pos12345'
@@ -623,7 +629,7 @@ void CardReader::openFileRead(const char * const path, const uint8_t subcall_typ
     #endif
   }
 
-  endFilePrint();
+  abortFilePrintNow();
 
   SdFile *diveDir;
   const char * const fname = diveToFile(true, diveDir, path);
@@ -659,7 +665,7 @@ void CardReader::openFileWrite(const char * const path) {
   announceOpen(2, path);
   TERN_(HAS_MEDIA_SUBCALLS, file_subcall_ctr = 0);
 
-  endFilePrint();
+  abortFilePrintNow();
 
   SdFile *diveDir;
   const char * const fname = diveToFile(false, diveDir, path);
@@ -712,7 +718,7 @@ bool CardReader::fileExists(const char * const path) {
 void CardReader::removeFile(const char * const name) {
   if (!isMounted()) return;
 
-  //endFilePrint();
+  //abortFilePrintNow();
 
   SdFile *curDir;
   const char * const fname = diveToFile(false, curDir, name);
@@ -856,6 +862,9 @@ uint16_t CardReader::countFilesInWorkDir() {
 /**
  * Dive to the given DOS 8.3 file path, with optional echo of the dive paths.
  *
+ * On entry:
+ *  - The workDir points to the last-set navigation target by cd, cdup, cdroot, or diveToFile(true, ...)
+ *
  * On exit:
  *  - Your curDir pointer contains an SdFile reference to the file's directory.
  *  - If update_cwd was 'true' the workDir now points to the file's directory.
@@ -865,6 +874,8 @@ uint16_t CardReader::countFilesInWorkDir() {
  * A nullptr result indicates an unrecoverable error.
  */
 const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, const char * const path, const bool echo/*=false*/) {
+  DEBUG_SECTION(est, "diveToFile", true);
+
   // Track both parent and subfolder
   static SdFile newDir1, newDir2;
   SdFile *sub = &newDir1, *startDir;
@@ -872,12 +883,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
   // Parsing the path string
   const char *item_name_adr = path;
 
-  DEBUG_ECHOLNPAIR("diveToFile: path = '", path, "'");
+  DEBUG_ECHOLNPAIR(" path = '", path, "'");
 
   if (path[0] == '/') {               // Starting at the root directory?
     diveDir = &root;
     item_name_adr++;
-    DEBUG_ECHOLNPAIR("diveToFile: CWD to root: ", hex_address((void*)diveDir));
+    DEBUG_ECHOLNPAIR(" CWD to root: ", hex_address((void*)diveDir));
     if (update_cwd) workDirDepth = 0; // The cwd can be updated for the benefit of sub-programs
   }
   else
@@ -885,7 +896,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
 
   startDir = diveDir;
 
-  DEBUG_ECHOLNPAIR("diveToFile: startDir = ", hex_address((void*)startDir));
+  DEBUG_ECHOLNPAIR(" startDir = ", hex_address((void*)startDir));
 
   while (item_name_adr) {
     // Find next subdirectory delimiter
@@ -902,7 +913,7 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
 
     if (echo) SERIAL_ECHOLN(dosSubdirname);
 
-    DEBUG_ECHOLNPAIR("diveToFile: sub = ", hex_address((void*)sub));
+    DEBUG_ECHOLNPAIR(" sub = ", hex_address((void*)sub));
 
     // Open diveDir (closing first)
     sub->close();
@@ -914,24 +925,24 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
 
     // Close diveDir if not at starting-point
     if (diveDir != startDir) {
-      DEBUG_ECHOLNPAIR("diveToFile: closing diveDir: ", hex_address((void*)diveDir));
+      DEBUG_ECHOLNPAIR(" closing diveDir: ", hex_address((void*)diveDir));
       diveDir->close();
     }
 
     // diveDir now subDir
     diveDir = sub;
-    DEBUG_ECHOLNPAIR("diveToFile: diveDir = sub: ", hex_address((void*)diveDir));
+    DEBUG_ECHOLNPAIR(" diveDir = sub: ", hex_address((void*)diveDir));
 
     // Update workDirParents and workDirDepth
     if (update_cwd) {
-      DEBUG_ECHOLNPAIR("diveToFile: update_cwd");
+      DEBUG_ECHOLNPAIR(" update_cwd");
       if (workDirDepth < MAX_DIR_DEPTH)
         workDirParents[workDirDepth++] = *diveDir;
     }
 
     // Point sub at the other scratch object
     sub = (diveDir != &newDir1) ? &newDir1 : &newDir2;
-    DEBUG_ECHOLNPAIR("diveToFile: swapping sub = ", hex_address((void*)sub));
+    DEBUG_ECHOLNPAIR(" swapping sub = ", hex_address((void*)sub));
 
     // Next path atom address
     item_name_adr = name_end + 1;
@@ -939,11 +950,12 @@ const char* CardReader::diveToFile(const bool update_cwd, SdFile* &diveDir, cons
 
   if (update_cwd) {
     workDir = *diveDir;
-    DEBUG_ECHOLNPAIR("diveToFile: final workDir = ", hex_address((void*)diveDir));
+    DEBUG_ECHOLNPAIR(" final workDir = ", hex_address((void*)diveDir));
     flag.workDirIsRoot = (workDirDepth == 0);
     TERN_(SDCARD_SORT_ALPHA, presort());
   }
 
+  DEBUG_ECHOLNPAIR(" returning string ", item_name_adr ?: "nullptr");
   return item_name_adr;
 }
 
@@ -1225,21 +1237,21 @@ uint16_t CardReader::get_num_Files() {
 // Return from procedure or close out the Print Job
 //
 void CardReader::fileHasFinished() {
-  planner.synchronize();
   file.close();
-
   #if HAS_MEDIA_SUBCALLS
     if (file_subcall_ctr > 0) { // Resume calling file after closing procedure
       file_subcall_ctr--;
       openFileRead(proc_filenames[file_subcall_ctr], 2); // 2 = Returning from sub-procedure
       setIndex(filespos[file_subcall_ctr]);
-      startFileprint();
+      startOrResumeFilePrinting();
       return;
     }
   #endif
 
-  endFilePrint(TERN_(SD_RESORT, true));
-  marlin_state = MF_SD_COMPLETE;
+  endFilePrintNow(TERN_(SD_RESORT, true));
+
+  flag.sdprintdone = true;        // Stop getting bytes from the SD card
+  marlin_state = MF_SD_COMPLETE;  // Tell Marlin to enqueue M1001 soon
 }
 
 #if ENABLED(AUTO_REPORT_SD_STATUS)
diff --git a/Marlin/src/sd/cardreader.h b/Marlin/src/sd/cardreader.h
index 5fdd1222ae..6f1633d30e 100644
--- a/Marlin/src/sd/cardreader.h
+++ b/Marlin/src/sd/cardreader.h
@@ -70,6 +70,7 @@ typedef struct {
   bool saving:1,
        logging:1,
        sdprinting:1,
+       sdprintdone:1,
        mounted:1,
        filenameIsDir:1,
        workDirIsRoot:1,
@@ -147,23 +148,33 @@ public:
 
   // Select a file
   static void selectFileByIndex(const uint16_t nr);
-  static void selectFileByName(const char * const match);
+  static void selectFileByName(const char * const match);  // (working directory only)
 
   // Print job
-  static void openAndPrintFile(const char *name);   // (working directory)
-  static void fileHasFinished();
-  static void getAbsFilename(char *dst);
-  static void printFilename();
-  static void startFileprint();
-  static void endFilePrint(TERN_(SD_RESORT, const bool re_sort=false));
   static void report_status();
-  static inline void pauseSDPrint() { flag.sdprinting = false; }
-  static inline bool isPaused() { return isFileOpen() && !flag.sdprinting; }
-  static inline bool isPrinting() { return flag.sdprinting; }
+  static void getAbsFilenameInCWD(char *dst);
+  static void printSelectedFilename();
+  static void openAndPrintFile(const char *name);   // (working directory or full path)
+  static void startOrResumeFilePrinting();
+  static void endFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false));
+  static void abortFilePrintNow(TERN_(SD_RESORT, const bool re_sort=false));
+  static void fileHasFinished();
+  static inline void abortFilePrintSoon() { flag.abort_sd_printing = true; }
+  static inline void pauseSDPrint()       { flag.sdprinting = false; }
+  static inline bool isPrinting()         { return flag.sdprinting; }
+  static inline bool isPaused()           { return isFileOpen() && !isPrinting(); }
   #if HAS_PRINT_PROGRESS_PERMYRIAD
-    static inline uint16_t permyriadDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 9999) / 10000) : 0; }
+    static inline uint16_t permyriadDone() {
+      if (flag.sdprintdone) return 10000;
+      if (isFileOpen() && filesize) return sdpos / ((filesize + 9999) / 10000);
+      return 0;
+    }
   #endif
-  static inline uint8_t percentDone() { return (isFileOpen() && filesize) ? sdpos / ((filesize + 99) / 100) : 0; }
+  static inline uint8_t percentDone() {
+    if (flag.sdprintdone) return 100;
+    if (isFileOpen() && filesize) return sdpos / ((filesize + 99) / 100);
+    return 0;
+  }
 
   // Helper for open and remove
   static const char* diveToFile(const bool update_cwd, SdFile* &curDir, const char * const path, const bool echo=false);
@@ -186,15 +197,20 @@ public:
     static void removeJobRecoveryFile();
   #endif
 
-  static inline bool isFileOpen() { return isMounted() && file.isOpen(); }
-  static inline uint32_t getIndex() { return sdpos; }
-  static inline uint32_t getFileSize() { return filesize; }
-  static inline bool eof() { return sdpos >= filesize; }
-  static inline void setIndex(const uint32_t index) { file.seekSet((sdpos = index)); }
-  static inline char* getWorkDirName() { workDir.getDosName(filename); return filename; }
-  static inline int16_t get() { int16_t out = (int16_t)file.read(); sdpos = file.curPosition(); return out; }
-  static inline int16_t read(void *buf, uint16_t nbyte) { return file.isOpen() ? file.read(buf, nbyte) : -1; }
+  // Current Working Dir - Set by cd, cdup, cdroot, and diveToFile(true, ...)
+  static inline char* getWorkDirName()  { workDir.getDosName(filename); return filename; }
+
+  // Print File stats
+  static inline uint32_t getFileSize()  { return filesize; }
+  static inline uint32_t getIndex()     { return sdpos; }
+  static inline bool isFileOpen()       { return isMounted() && file.isOpen(); }
+  static inline bool eof()              { return getIndex() >= getFileSize(); }
+
+  // File data operations
+  static inline int16_t get()                            { int16_t out = (int16_t)file.read(); sdpos = file.curPosition(); return out; }
+  static inline int16_t read(void *buf, uint16_t nbyte)  { return file.isOpen() ? file.read(buf, nbyte) : -1; }
   static inline int16_t write(void *buf, uint16_t nbyte) { return file.isOpen() ? file.write(buf, nbyte) : -1; }
+  static inline void setIndex(const uint32_t index)      { file.seekSet((sdpos = index)); }
 
   // TODO: rename to diskIODriver()
   static DiskIODriver* diskIODriver() { return driver; }
@@ -318,7 +334,8 @@ private:
   #define IS_SD_INSERTED() true
 #endif
 
-#define IS_SD_PRINTING()  card.flag.sdprinting
+#define IS_SD_PRINTING()  (card.flag.sdprinting && !card.flag.abort_sd_printing)
+#define IS_SD_FETCHING()  (!card.flag.sdprintdone && IS_SD_PRINTING())
 #define IS_SD_PAUSED()    card.isPaused()
 #define IS_SD_FILE_OPEN() card.isFileOpen()
 
@@ -327,6 +344,7 @@ extern CardReader card;
 #else // !SDSUPPORT
 
 #define IS_SD_PRINTING()  false
+#define IS_SD_FETCHING()  false
 #define IS_SD_PAUSED()    false
 #define IS_SD_FILE_OPEN() false