This forum uses cookies. Click X button to hide this message. What is stored? / Privacy
Total Commander Forum Index Total Commander
Forum - Public Discussion and Support
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Slow response to drive state(DVD,SD) if no disk in drive
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Total Commander Forum Index -> TC9.1x bug reports (English) Printable version
View previous topic :: View next topic  
Author Message
BORG52
Junior Member
Junior Member


Joined: 23 Apr 2011
Posts: 24

PostPosted: Sat Jun 02, 2018 4:30 am    Post subject: Slow response to drive state(DVD,SD) if no disk in drive Reply with quote

Hello,
If "no disk" in drive - after click to any removable drive icon(DVD,SD), TCMD has very slow response to drive state.(similar as link to network drive)
Windows explorer response is fast.

TCMD use history and trying link to latest(removed) medium inserted to removable drive. Restart TCMD solve problem with (no)linked medium, but this is not optimal solution - response to drive(no medium) state is always slow.
FDD drive(with no floppy) response is OK in TCMD.
TCMD912/XP32
Back to top
View user's profile Send private message
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35956
Location: Switzerland

PostPosted: Sun Jun 03, 2018 4:26 am    Post subject: Reply with quote

I don't think there is anything I can do. TC uses functions like FindFirstFile or SetCurrentDirectory, and they sometimes have a long timeout. TC should show a wait dialog after about 1 second where you can cancel the operation.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
MarcinW
Power Member
Power Member


Joined: 23 Jan 2012
Posts: 852
Location: Poland

PostPosted: Sun Jun 03, 2018 2:18 pm    Post subject: Reply with quote

I can confirm the problem.

My DVD drive is E: - when it is empty:

- when I call FindFirst('E:\*.*', ...) - it immediately returns ERROR_NOT_READY

- when I call SetCurrentDirectory('E:') - it immediately fails with ERROR_NOT_READY

- when I select E: in 32-bit or 64-bit TC, mouse cursor is changed to a waiting state and TC is thinking for about 3 seconds before displaying an error message.

Regards
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35956
Location: Switzerland

PostPosted: Tue Jun 05, 2018 2:01 am    Post subject: Reply with quote

I cannot reproduce your report: When FindFirstFile and/or SetCurrentDirectory is fast, TC is fast too. Tried with two different CD drives, one internal and one connected via USB.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
MarcinW
Power Member
Power Member


Joined: 23 Jan 2012
Posts: 852
Location: Poland

PostPosted: Tue Jun 05, 2018 8:53 am    Post subject: Reply with quote

I found the reason: TC assumes a default CDCloseDoor=1 configuration seting. After adding CDCloseDoor=0 to [Configuration] in wincmd.ini, the problem is solved.



For CDCloseDoor=1 setting (Totalcmd.exe, 9.20 Beta 5):

1) at 0x0041C20E, a call is executed: mciSendStringA('open e: type cdaudio alias ding', nil, 0, 0) - this call blocks execution for about 2 seconds

2) at 0x0041C20E, a call is executed: mciSendStringA('set ding door closed wait', nil, 0, 0) - this call blocks execution for about 0.5 second

3) at 0x0041C20E, a call is executed: mciSendStringA('close ding', nil, 0, 0)

4) at 0x0041C2EC, Sleep(500) is executed

5) at 0x0041C431, Sleep(1000) is executed



What is a purpose of these MCI calls?

Regards
Back to top
View user's profile Send private message Send e-mail
BORG52
Junior Member
Junior Member


Joined: 23 Apr 2011
Posts: 24

PostPosted: Tue Jun 05, 2018 12:03 pm    Post subject: Reply with quote

With CDCloseDoor=0 is response the same as windows explorer. This solve problem with "response to drive state"
MarcinW: thank

MCI call: I also noticed it's. I am not programmer, but when testing TCMD in Dependency Walker i found MCI call, when make door closed/open .TCMD sounds are not associated with eject/close-here is no relation.
Here is relation with CD audio. TCMD tests if audioCD inserted and load/unload anytime mcicda.dll. Probably therefore is slow response(?). I mean, that TCMD first check for audioCD,no for data.This should be optimized.
Back to top
View user's profile Send private message
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35956
Location: Switzerland

PostPosted: Wed Jun 06, 2018 10:42 am    Post subject: Reply with quote

TC calls these to close an open CD drawer, so you can just open the drawer, put the CD/DVD in, and then switch to it in TC without closing the CD drawer manually.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
BORG52
Junior Member
Junior Member


Joined: 23 Apr 2011
Posts: 24

PostPosted: Sat Jun 09, 2018 8:32 am    Post subject: Reply with quote

OK, thank for ifo about MCI function in this case.
For me is this function here unnecessary, but in some cases this may be usefull.
Therefore any switch for CDCloseDoor in TCMD config bar is need.

When I have to strain my hand to the DVD mechanic to insert or remove the media, it will make it easier for me to press the button on the mechanics before somewhere to catch something with the mouse. Very Happy
Back to top
View user's profile Send private message
MarcinW
Power Member
Power Member


Joined: 23 Jan 2012
Posts: 852
Location: Poland

PostPosted: Sat Jun 09, 2018 2:58 pm    Post subject: Reply with quote

It seems that the current TC behavior can be made much faster, without any compatibility loss. I'll investigate this and let you know here.

Regards
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35956
Location: Switzerland

PostPosted: Mon Jun 11, 2018 7:37 am    Post subject: Reply with quote

You can disable it:
wincmd.ini
[Configuration]
CdCloseDoor=0
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
MarcinW
Power Member
Power Member


Joined: 23 Jan 2012
Posts: 852
Location: Poland

PostPosted: Mon Jun 11, 2018 8:03 am    Post subject: Reply with quote

I found some info here: https://ws0.org/windows-how-to-get-the-tray-status-of-the-optical-drive/

By using DeviceIoControl API with IOCTL_STORAGE_CHECK_VERIFY2 and IOCTL_SCSI_PASS_THROUGH_DIRECT control codes, we can check if:
- tray is ejected,
- tray is closed with some media inside,
- tray is closed with no media inside.

In opposite to MCI calls, IOCTL calls return immediately.


I created a piece of test code by using a sample code from the article mentioned above (I made some corrections though). Curently TC code looks like:
Code:
if CDCloseDoor <> 0 then
  call MCI functions to close the CD tray


This could be improved in the following way:
Code:
if CDCloseDoor <> 0 then
if IsCDTrayEjected(DriveNum) then
  call MCI functions to close the CD tray



Thanks to this change, TC could respond immediately, even for CDCloseDoor=1. The IsCDTrayEjected() function always returns True in case of any errors, so it will not break compatibility. It may even work on Win 9x systems, if the CD driver supports needed IOCTL codes (in other cases just True is returned). The code below has been sucessfully tested on two physical machines with DVD drives, where TC hangs for few seconds when accessing the drive - on Win 98, Win 2000 and Win 7 64-bit (both as 32-bit and 64-bit code).

Code:
program CDTest;

uses
  Windows;

type
  SCSI_PASS_THROUGH_DIRECT = record
    Length : Word;
    ScsiStatus : Byte;
    PathId : Byte;
    TargetId : Byte;
    Lun : Byte;
    CdbLength : Byte;
    SenseInfoLength : Byte;
    DataIn : Byte;
    DataTransferLength : Cardinal;
    TimeOutValue : Cardinal;
    DataBuffer : Pointer;
    SenseInfoOffset : Cardinal;
    Cdb : array[0..15] of Byte;
  end;

const
  IOCTL_STORAGE_CHECK_VERIFY2 = $002D0800;
  IOCTL_SCSI_PASS_THROUGH_DIRECT = $0004D014;

const
  SCSI_IOCTL_DATA_IN = 1;

const
  FILE_SHARE_DELETE = 4;

// DriveNum: 0=A:, 1=B:, 2=C:, ...
function IsCDTrayEjected(DriveNum : Byte) : Boolean;
var
  DeviceName : array[0..6] of WideChar;
  HDevice : THandle;
  BytesReturned : DWORD;
  SCSIBuffer : record
    SPTD : SCSI_PASS_THROUGH_DIRECT;
    SenseBuffer : array[0..17] of Byte;
  end;
  DataBuffer : array[0..7] of Byte;
begin
  Result:=True; // Return True in case of any errors

  DeviceName[0]:='\';
  DeviceName[1]:='\';
  DeviceName[2]:='.';
  DeviceName[3]:='\';
  DeviceName[4]:=WideChar(Ord('A')+DriveNum);
  DeviceName[5]:=':';
  DeviceName[6]:=#0;

  HDevice:=CreateFileW(DeviceName,0,FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  if HDevice = INVALID_HANDLE_VALUE then
    Exit;
  try
    Result:=not DeviceIoControl(HDevice,IOCTL_STORAGE_CHECK_VERIFY2,nil,0,nil,0,BytesReturned,nil);
  finally
    CloseHandle(hDevice);
  end;

  if not Result then // Tray closed, media present
    Exit;

  HDevice:=CreateFileW(DeviceName,GENERIC_READ or GENERIC_WRITE,FILE_SHARE_READ or FILE_SHARE_WRITE or FILE_SHARE_DELETE,nil,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
  if HDevice = INVALID_HANDLE_VALUE then
    Exit;
  try
    FillChar(SCSIBuffer,SizeOf(SCSIBuffer),0);
    with SCSIBuffer do
    begin
      SPTD.Length:=SizeOf(SPTD);
      SPTD.CdbLength:=10;
      SPTD.SenseInfoLength:=SizeOf(SenseBuffer);
      SPTD.DataIn:=SCSI_IOCTL_DATA_IN;
      SPTD.DataTransferLength:=SizeOf(DataBuffer);
      SPTD.TimeOutValue:=1;
      SPTD.DataBuffer:=@DataBuffer;
      SPTD.SenseInfoOffset:=HINST(@SenseBuffer)-HINST(@SCSIBuffer);
      SPTD.Cdb[0]:=$4A;
      SPTD.Cdb[1]:=$01;
      SPTD.Cdb[4]:=$10;
      SPTD.Cdb[8]:=$08;
    end;
    FillChar(DataBuffer,SizeOf(DataBuffer),0);

    BytesReturned:=0;
    Result:=DeviceIoControl(HDevice,IOCTL_SCSI_PASS_THROUGH_DIRECT,@SCSIBuffer,SizeOf(SCSIBuffer),@SCSIBuffer,SizeOf(SCSIBuffer),BytesReturned,nil);
  finally
    CloseHandle(hDevice);
  end;

  if (not Result) or (BytesReturned < SizeOf(SCSIBuffer.SPTD)) then // Error
  begin
    Result:=True;
    Exit;
  end;

  case DataBuffer[5] of
    0  : Result:=False; // Tray closed, no media
    1  : Result:=True;  // Tray ejected
    else Result:=False; // Tray closed, media present
  end;
end;

var
  DriveNum : Byte; // 0=A:, 1=B:, 2=C:, ...
begin
  DriveNum:=0;
  while True do
  begin
    if GetDriveType(PChar(string(Char(Ord('A')+DriveNum))+':')) = DRIVE_CDROM then
      Break;
    if DriveNum = 26 then
    begin
      MessageBox(0,'No CD drive found','Error',MB_ICONSTOP);
      Exit;
    end;
    Inc(DriveNum);
  end;

  if IsCDTrayEjected(DriveNum) then
    MessageBox(0,'Tray ejected (or error occured)',PChar('Drive '+Char(Ord('A')+DriveNum)+':'),MB_ICONINFORMATION)
  else
    MessageBox(0,'Tray closed',PChar('Drive '+Char(Ord('A')+DriveNum)+':'),MB_ICONINFORMATION);
end.


Regards
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35956
Location: Switzerland

PostPosted: Mon Jun 11, 2018 8:15 am    Post subject: Reply with quote

Unfortunately I have had mixed results with ioctl calls, it really depends on the driver and hardware. I'm using some calls to check whether a medium is in the drive or not when using HideRemovableNoMedia options. But I had to disable this because some users had complete lockups or long delays when this was enabled. The functions I use with CDCloseDoor have worked for many years. I prefer not to change them. The user can just set CdCloseDoor=0 if he doesn't need this function.
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
MarcinW
Power Member
Power Member


Joined: 23 Jan 2012
Posts: 852
Location: Poland

PostPosted: Mon Jun 11, 2018 8:19 am    Post subject: Reply with quote

Ok, thanks for your explanation.

Maybe it would be good to move this thread to the English forum?

Regards
Back to top
View user's profile Send private message Send e-mail
ghisler(Author)
Site Admin
Site Admin


Joined: 04 Feb 2003
Posts: 35956
Location: Switzerland

PostPosted: Mon Jun 11, 2018 8:22 am    Post subject: Reply with quote

Or to suggestions?
_________________
Author of Total Commander
http://www.ghisler.com
Back to top
View user's profile Send private message Send e-mail Visit poster's website
MarcinW
Power Member
Power Member


Joined: 23 Jan 2012
Posts: 852
Location: Poland

PostPosted: Mon Jun 11, 2018 8:27 am    Post subject: Reply with quote

Well, both places are good, but I suppose that most of the users read just English forum, not the Suggestions forum - so English forum might be a better place to find a solution for a slow CD/DVD response.
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
Post new topic   Reply to topic    Total Commander Forum Index -> TC9.1x bug reports (English) All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Imprint/Impressum: This site is maintained by Ghisler Software GmbH
Privacy Policy | Datenschutzerklärung | Politique de Confidentialité

Using phpBB © phpBB Group