dosemu2 / dosemu2

Run DOS programs under linux:
http://dosemu2.github.io/dosemu2/
GNU General Public License v2.0
550 stars 57 forks source link

lredir doesn't check cds flags #695

Closed stsp closed 4 years ago

stsp commented 5 years ago

Currently as we know, the redirector initialization may fail if we don't have the right command.com. For example comcom32 doesn't support ae00 yet. But lredir/lredir2 displays the redirections as if they are all there, while there are none. They should check cds for every drive, and if the redirection is not there, write (disabled) suffix, or something like that. This problem is not present in dosemu1 for hundreds of different reasons, one of which being, IIRC, that mfs always re-calculated the redirections at run-time, depending on CDS flags. We don't have that code, and the code that redirects on file open was also removed, etc etc. Basically there is no way back, we just need to finish the new redirector model properly.

So for now lredir2 should be updated to check cds.

andrewbird commented 5 years ago

Okay will do, but I think it's best that the redirector int2f/11/1e GetRedirection() look at the CDS flags and set a bit in CX (next to readonly) for lredir(2) to display.

stsp commented 5 years ago

Thanks, would be cool if you do! :)

stsp commented 5 years ago

As you probably know, I am at the last stages of stabilizing the fdpp+comcom32 combo. With the latest patches I was able to run windows properly, and even mouse works (which required quite a work to make int33 revectored and modify emufs.sys and dpmi accordingly). The only remaining problem is redirector, which in that combination doesn't work at all. So I am going to concentrate on that.

Btw, the interesting thing happened when I was debugging the windows startup on fdpp. When fdpp is crashing, it stops dosemu with the message "fdpp crashed, press any key to exit". When that msg appears, windows GUI freezes, but the windows's mouse cursor was still moving and could even take a form of hour glasses. So the amazing (to me) thing was that while coopth stopped the DOS thread, it was still allowing the higher priority windows threads to run, so mouse still worked.

andrewbird commented 5 years ago

I pushed a new branch https://github.com/andrewbird/dosemu2/tree/mfs22 but I see an odd effect on FDPP (with FreeCOM from FreeDOS 1.2)

MFS: Entering dos_fs_redirect, FN=1E                                            
MFS: selecting drive fn=1e                                                      
MFS: Control redirect, subfunction 2                                            
MFS: GetRedirection, index=0                                                    
MFS: redirection root =/clients/common/dosemu2.git/test-imagedir/dXXXXs/c/      
MFS: resource name =\\LINUX\FS\clients\common\dosemu2.git\test-imagedir\dXXXXs\c\
MFS: device name =C:                                                            
MFS: GetCDSInDOS for C:                                                         
dispatch int2F_12_handler                                                       
dispatch int2F_12_handler done                                                  
MFS: GetRedirection CDS flags are 0x645c (JOIN,READY)                           
MFS: GetRedirection CX=0082                                                     
MFS: Finished dos_fs_redirect                                                   

whereas on MS-DOS 3.31 (and similar on FreeDOS 1.20) I see

MFS: Entering dos_fs_redirect, FN=1E                                            
MFS: selecting drive fn=1e                                                      
MFS: Control redirect, subfunction 2                                            
MFS: GetRedirection, index=0                                                    
MFS: redirection root =/clients/common/dosemu2.git/test-imagedir/dXXXXs/c/      
MFS: resource name =\\LINUX\FS\clients\common\dosemu2.git\test-imagedir\dXXXXs\c\
MFS: device name =C:                                                            
MFS: GetCDSInDOS for C:                                                         
MFS: GetRedirection CDS flags are 0xc080 (NOTNET,READY,REMOTE)                  
MFS: GetRedirection CX=0080                                                     
MFS: Finished dos_fs_redirect                                                   

Yet on both MS-DOS and FDPP the drive does appear to be redirected as far as DOS is concerned DIR shows the correct free space and no serial number.

Here's the FDPP /lredir showing the result of the incorrect flags fdpp

andrewbird commented 5 years ago

There seems to be problem with GetCDSInDOS() on FDPP, I get different values for the same drive

MFS: cds from GetCDSInDOS is 0xb00e4000                                         
MFS: cds from drive_cds is 0xb008b840

The value that drive_cds() returns is the one that DOS is looking at, as if you disable the call to calculate_drive_pointers() DOS no longer sees the drive as redirected.

stsp commented 5 years ago

How can I reproduce this?

andrewbird commented 5 years ago

I also notice that GetCDSInDOS() always returns the same value no matter if drive is C: or D:

MFS: cds from GetCDSInDOS is 0xb00e4000
MFS: cds from GetCDSInDOS is 0xb00e4000
MFS: cds from GetCDSInDOS is 0xb00e4000
MFS: cds from GetCDSInDOS is 0xb00e4000
andrewbird commented 5 years ago

Just add these lines and check the log

index 82bdc3781..3c278e823 100644
--- a/src/dosext/mfs/mfs.c
+++ b/src/dosext/mfs/mfs.c
@@ -1662,6 +1662,8 @@ calculate_drive_pointers(int dd)

   cds = drive_cds(dd);

+  Debug0((dbg_fd, "cds from drive_cds is %p\n", cds));
+
   /* if it's already done then don't bother */
   if ((cds_flags(cds) & (CDS_FLAG_REMOTE | CDS_FLAG_READY)) ==
       (CDS_FLAG_REMOTE | CDS_FLAG_READY))
@@ -2536,6 +2538,8 @@ static int RedirectDisk(struct vm86_regs *state, int drive, char *resourceName)
     return FALSE;
   }

+  Debug0((dbg_fd, "cds from GetCDSInDOS is %p\n", cds));
+
   path[0] = 0;
   path_to_ufs(path, 0, &resourceName[strlen(LINUX_RESOURCE)], 1, 0);

@@ -2546,6 +2550,7 @@ static int RedirectDisk(struct vm86_regs *state, int drive, char *resourceName)
     return FALSE;
   }

+
   calculate_drive_pointers(drive);

   cds_flags(cds) = CDS_FLAG_READY | CDS_FLAG_REMOTE | CDS_FLAG_NOTNET;
stsp commented 5 years ago

Looking at fdpp sources, this boils down directly to get_cds_unvalidated(), so I wonder what could go wrong here.

andrewbird commented 5 years ago

ajb@polly:/clients/common/dosemu2.git$ grep 'cds from GetCDSInDOS' test.log Same test done on MS-DOS 3.31

MFS: cds from GetCDSInDOS is 0xb008dde2
MFS: cds from GetCDSInDOS is 0xb008de33
MFS: cds from GetCDSInDOS is 0xafffbe72
MFS: cds from GetCDSInDOS is 0xafffbec3

See the CDS move between line 2 and 3. See the 0x51 byte sizeof CDS entry between 1 and 2 / 3 and 4

andrewbird commented 5 years ago

get_cds() should suffer the same problem as get_cds_unvalidated() on FDPP.

stsp commented 5 years ago
ERROR: cds from drive_cds is 0x7f9390f837a0
ERROR: cds from drive_cds is 0x7f9390f837f8
ERROR: cds from drive_cds is 0x7f9390f83850
ERROR: cds from drive_cds is 0x7f9390f838a8

This is a log from mfs.c:1665

andrewbird commented 5 years ago

That's correct the CDS entry size on that version of the redirector is 0x58, what does the GetCDSInDOS() value show in the same log?

stsp commented 5 years ago
ERROR: cds from GetCDSInDOS is 0x7f7b21fdc000
ERROR: cds from drive_cds is 0x7f7b21f837a0
ERROR: cds from GetCDSInDOS is 0x7f7b21fdc000
ERROR: cds from drive_cds is 0x7f7b21f837f8
ERROR: cds from GetCDSInDOS is 0x7f7b21fdc000
ERROR: cds from drive_cds is 0x7f7b21f83850
ERROR: cds from GetCDSInDOS is 0x7f7b21fdc000
ERROR: cds from drive_cds is 0x7f7b21f838a8

What???

andrewbird commented 5 years ago

Yep that's what I'm seeing - constant value from GetCDSInDOS()

stsp commented 5 years ago

Well, so what, wrong format char... Just replace %p with %s and see this:

ERROR: fdpp booting, this is very experimental!
ERROR: cds from GetCDSInDOS is C:
ERROR: cds from GetCDSInDOS is D:
ERROR: cds from GetCDSInDOS is E:
ERROR: cds from GetCDSInDOS is F:
andrewbird commented 5 years ago

Yes it looks better, but I can't believe it's correct.

Since we use GetCDSInDOS() elsewhere in Dosemu, I think what you are seeing when using %s is a write of Drive: to a fixed location somewhere immediately prior to us querying it.

andrewbird commented 5 years ago

So running with gdb I see

Thread 1 "dosemu.bin" hit Breakpoint 2, int2F_12_handler (r=...) at inthndlr.cc:1907
1907            r.FLAGS &= ~FLG_CARRY;
+p/x r.callerARG1
$21 = 0x2
+p * (cds *) &lowmem_base[(cdsp.ptr.seg<<4)+cdsp.ptr.off]
$22 = {cdsCurrentPath = "C:\\", '\000' <repeats 63 times>, cdsFlags = 49280, cdsDpb = {ptr = {off = 6380, seg = 217}}, _cdsUnion = {_cdsRedirRec = {ptr = {off = 0, seg = 65535}}, 
    _cdsRedir = {_cdsStrtClst = 0, _cdsParam = 65535}}, cdsStoreUData = 65535, cdsBackslashOffset = 2, cdsNetFlag1 = 0 '\000', cdsIfs = {ptr = {off = 0, seg = 0}}, cdsNetFlags2 = 0}
+p/x * (cds *) &lowmem_base[(cdsp.ptr.seg<<4)+cdsp.ptr.off]
$23 = {cdsCurrentPath = {0x43, 0x3a, 0x5c, 0x0 <repeats 64 times>}, cdsFlags = 0xc080, cdsDpb = {ptr = {off = 0x18ec, seg = 0xd9}}, _cdsUnion = {_cdsRedirRec = {ptr = {off = 0x0, 
        seg = 0xffff}}, _cdsRedir = {_cdsStrtClst = 0x0, _cdsParam = 0xffff}}, cdsStoreUData = 0xffff, cdsBackslashOffset = 0x2, cdsNetFlag1 = 0x0, cdsIfs = {ptr = {off = 0x0, seg = 0x0}}, 
  cdsNetFlags2 = 0x0}
+p/x r.DS
$24 = 0x547
+p/x r.SI
$25 = 0xb0

and dosemu in GetRedirection() just after sees

CDS entry: #2 @0xb00f5520 (2) 'C:\'
MFS: GetCDSInDOS for C:
MFS: GetRedirection GetCDSInDOS CDS is 0xb01e4000
MFS: GetRedirection GetCDSInDOS CDS flags are 0x645c (JOIN,READY)
stsp commented 5 years ago

Could you please be more specific, I guess you are pointing to flags mismatch?

andrewbird commented 5 years ago

Flags wrong, pointer value unchanging, and when you change format to string you only see C: not C:\, plus same code works on freedos and msdos.

stsp commented 5 years ago

Confirmed, investigating.

stsp commented 5 years ago

I applied the fix, please retry.

andrewbird commented 5 years ago

Thanks that works well. As a test I commented out calculate_drive_pointers(), ran the tests and nothing broke, so that's certainly fixed. Note: calculate_drive_pointers() can not be removed until we can stop lfn.c using CDS directly. I'm just revising the patch in my mfs22 branch, will post a PR shortly.

andrewbird commented 5 years ago

It would be interesting for you to run your FDPP/comcom/windows test again, as I'm sure that GetCDSInDOS() problem would have seriously screwed things up?

stsp commented 5 years ago

It still works, didn't regress. :) Since its running w/o redirector anyway, there should be no change. But overall this was a very important fix indeed.

andrewbird commented 5 years ago

Yes, but I wondered if it would work with redirector now?

stsp commented 5 years ago

The problem is missing ae00, why do you think it would change?

andrewbird commented 5 years ago

Oh only that, I figured you had more fundamental problems. Did you try using the post_boot() hook you added for DOS < 3.30 just to see it works?

stsp commented 5 years ago

Oh only that, I figured you had more fundamental problems.

All of them are fixed within this week. Only this remained.

Did you try using the post_boot() hook you

But it works fine even w/o the redirector now. Yes if you edit some file in notepad, the edits are not saved etc. And yet it all works. :)

stsp commented 5 years ago

I had to revert this patch as it was wrong. See commit msg. Could you please re-do it?

andrewbird commented 5 years ago

So I'm looking to test the Netware 4.x client and its netuser tool so I may see how it interacts with the redirector. Do you know the name of the netware archive that contains it, as it's not with the 16bit client tools (VLM etc)?

andrewbird commented 5 years ago

I found v4.2, but can't get the netuser command to query the redirector without being logged in to netware server, but not sure I can be bothered to set one up yet.

stsp commented 5 years ago

Is this all just for this 0x80 flag?

andrewbird commented 5 years ago

Yeah, sad isn't it.

stsp commented 5 years ago

I think you can just ignore that.

stsp commented 5 years ago

So how about ignoring this silly flag? If we take care about every small detail found in a legacy code, we'll never release any beta, and I really hope we can do so this year.

andrewbird commented 5 years ago

I've been playing with pcgeos to reproduce the effect found by @bolle732 in #710 as at the moment it's the only client I know of that uses int21/5f02 and I can get working. BTW I wanted to try the MS client. but that needs an NDIS network driver. I looked for a Packet -> NDIS shim like PDEther does Packet -> ODI and didn't find one, I don't suppose you know of any? Anyway currently I have a dosemu crash with pcgeos immediately after the drive is restored, so I'm trying to track that down first. Yes I'd be happy to drop the 0x80 bit, at least then if someone is bothered by the problem we should be able to get a proper Netware test case, and if the Netware client sets the signature perhaps conditionally set it.

stsp commented 5 years ago

My memory may be wrong, but I seem to recall msclient worked under dosemu. You probably can't get ndis, but IIRC msclient supported other backends via some setup program. It was like 15 years since I tried that, so maybe this is all wrong.

Crash of pcgeos is usually cured by STACKS=0 in config.sys

andrewbird commented 5 years ago

but IIRC msclient supported other backends via some setup program.

I'll have a further look for this then.

Crash of pcgeos is usually cured by STACKS=0 in config.sys

I'll try that, the strange thing is that only in the case of network drive restoration does it crash, whereas in normal operation it works fine for me.

stsp commented 5 years ago

https://forums.techguy.org/threads/networking-dos-operating-system.855447/

 ftp://ftp.microsoft.com/bussys/clients/msclient/dsk3-2.exe
Extract it into the same folder as Disk 1; there are 2 duplicate files, AVEXTRA.TXT and LICENSE.TXT. 
You can overwrite or not, they are the same file.
Then, in step 12, after removing IPX, choose TCP/IP instead of NetBEUI.

So my memory is not wrong on that it was configurable. I think I used IPX as a back-end. There was some major IPX stack update in dosemu by me in that era, so maybe indeed I was able to get the msclient running that way. Can't remember.

andrewbird commented 5 years ago

I just watched this https://www.youtube.com/watch?v=ngtk3vPBCRo which suggests that it's possible to use packet driver with msclient, BUT he has an NDIS driver in the network card directory, so I'm not really convinced he's using the packet driver. Still I'll try it after doing the dosdebug thing.

stsp commented 5 years ago

Would be very interesting to find more documentation on tcpdrv.dos API than this: http://www.delorie.com/djgpp/doc/rbinter/id/54/28.html

stsp commented 5 years ago

BUT he has an NDIS driver in the network card directory, so I'm not really convinced

He is also referring to 0x60 as being a memory address...

andrewbird commented 5 years ago

Reading the boot messages I see the packet driver v3.40 loaded and later a v3.23 network driver, which I presume is the NDIS, so I think he's loading the packet driver unnecessarily and fooling himself that it's actually doing something.

stsp commented 5 years ago

Yep, at "address 0x60" that is.

There is no ndis over pkt, but if we had a pktdrv.dos API description, we could implement it in dosemu2. Anyway, his video shows you can use also ipx, netbeui and "other protocols..."

andrewbird commented 5 years ago

I managed to find ndis201.txt which is contemporary to the msclient. I thought if the spec were small enough (it isn't) then a built in ndis driver (just like we have for pkt) might be fairly simple. To give us a head start, source to a network card's DOS NDIS driver would be excellent, but I don't know if manufacturers ever release these things at EOL.

Anyway, his video shows you can use also ipx, netbeui and "other protocols..."

I can understand how IPX could work as I believe dosemu has built in IPX, but won't the other protocols require a driver too?

stsp commented 5 years ago

ndis is out of question even if you find sources (very unlikely). What we could implement is a tcpdrv.dos API. That driver works on top of ndis and should have a fairly small api.

Ipx can work over packet driver.

stsp commented 5 years ago

Your document says that it describes only the mac driver and other document will describe the transport driver. This other document doesnt seem to be available.

andrewbird commented 5 years ago

I found ndis201.txt via the wayback machine. If you have dead links to the tcpdrv doc, you might be able to find it there.

stsp commented 5 years ago

In fact, mac driver is not that difficult as well.

This is not something to write in a day, but is not a rocket science either.