TOMIII@MTUS5.BITNET (Thomas Dwyer III) (09/21/90)
Well, I think I finally found a way to run Windows and PC-NFS together without having the window manager choke and die on all the drive letters that do not have disks mounted on them. You don't need the undocumented "/d" option in the config sys either (which nukes the ability to see spool files on the T: U: and V: drives). Clearing the upper 2 bits of offset 0x43 in the current directury structure for a given drive makes the drive "invalid" as far as DOS is concerned. All one needs to do is scan through all the drives through LASTDRIVE and "nuke" any drive letter that has no disk mounted to it. I use IOCTL (int 0x21, function 0x44, subfunction 9) to determine if the drive is "remote" (a drive IS mounted) or "local" (a drive IS NOT mounted) to determine this. Once all the unused drive letters are gone, fire up Windows and poof - no more errors accessing phantom disks. Now there is one small disadvantage in doing this. If, after you've nuked all your excess drive letters, you mount or unmount a drive (yes, NET USE still works) the new drive will still be invalid, and the dropped drive will still exist (as far as DOS is concerned). My solution is to first mark every drive letter as valid, then check each drive and mark the invalid ones. After any NET USE command, simply repeat this process to reflect the change. Here is my code. Please feel free to make suggestions, comments, etc. ----- Cut Here ----- /***********************************************************************\ * * * REFRESH * * * * This program scans the array of current directory structures * * looking for PC-NFS drives. If it finds a device letter that * * is reserved by PCNFS.SYS it checks to see if an NFS drive is * * actually mounted on that letter. If not, the device letter * * is marked as "invalid". * * * * Compiled with Turbo C version 1.5 * * * * Written by Thomas Dwyer III 09/19/90 * * Copyright Michigan Technological University 09/19/90 * * * \***********************************************************************/ #include <dos.h> #define DOS3_OFFSET 0x12 #define DOS4_OFFSET 0x13 #define DOS4_CDS_ARRAY_SIZE 0x58 #define DOS3_CDS_ARRAY_SIZE 0x51 #define STATUS_BYTE_OFFSET 0x44 #define PCNFS_SIGNATURE_OFFSET 0x2B /***********************************************************************\ * * * GET_DOS_VERSION - returns the major DOS version number * * * \***********************************************************************/ int get_dos_version() { union REGS regs; regs.h.ah = 0x30; intdos(®s, ®s); return(regs.h.al); } /***********************************************************************\ * * * IS_PCNFS - returns TRUE if "ptr" points to the PCNFS.SYS * * device driver header, FALSE if not. * * * \***********************************************************************/ int is_pcnfs(ptr) unsigned char far *ptr; { static char array[] = "PC-NFS"; char *pcnfs_ptr = array; ptr += PCNFS_SIGNATURE_OFFSET; while (*pcnfs_ptr) if (*ptr++ != *pcnfs_ptr++) return(0); return(1); } /***********************************************************************\ * * * RESTORE DRIVE - sets the "physical drive" bit in the CDS * * pointed to by "ptr". * * * \***********************************************************************/ void restore_drive(ptr) unsigned char far *ptr; { *(ptr+STATUS_BYTE_OFFSET) |= 0x40; return; } /***********************************************************************\ * * * CHECK_DRIVE - tests for a mounted drive, and clears both * * the "physical drive" and the "network drive" * * bits in the CDS. * * * \***********************************************************************/ void check_drive(ptr, drive) unsigned char far *ptr; int drive; { union REGS regs; struct SREGS sregs; unsigned long far *device_header; if (drive > 2) { /* A=0, B=1, etc. We want to start at D: */ regs.h.ah = 0x32; regs.h.dl = drive+1; intdosx(®s, ®s, &sregs); if (get_dos_version() == 4) device_header = MK_FP(sregs.ds, regs.x.bx+DOS4_OFFSET); else device_header = MK_FP(sregs.ds, regs.x.bx+DOS3_OFFSET); if (is_pcnfs(*device_header)) { regs.x.ax = 0x4409; regs.h.bl = drive+1; intdos(®s, ®s); if (regs.x.dx & 0x1000) printf("\t%c:\n", drive+'A'); else *(ptr+STATUS_BYTE_OFFSET) &= !0xC0; } } return; } main() { union REGS regs; struct SREGS sregs; int i, num_drives; unsigned char far *ptr; unsigned long far *addr_ptr; regs.h.ah = 0x52; intdosx(®s, ®s, &sregs); ptr = MK_FP(sregs.es, regs.x.bx); addr_ptr = MK_FP(sregs.es, regs.x.bx+0x16); num_drives = *(ptr+0x20); ptr = (unsigned char far *) *addr_ptr; printf("%d drives reserved starting at %Fp\n", num_drives, ptr); printf("The following are valid PC-NFS drives:\n", num_drives); for (i=0; i<num_drives; i++) { restore_drive(ptr); check_drive(ptr, i); if (get_dos_version() == 4) ptr += DOS4_CDS_ARRAY_SIZE; else ptr += DOS3_CDS_ARRAY_SIZE; } }