Category : Files from Magazines
Archive   : DDJ0292.ZIP
Filename : UNDOCWIN.ASC
by Paul Chui
[LISTING ONE]
#define NOCOMM
#include
#include
#include
#include "getdrvx.h"
#define CDS_SUBST (0x1000)
#define DOS3_CDS_SIZE 81
#define DOS4_CDS_SIZE 88
#define CDS_PATH 0x00
#define CDS_FLAGS 0x43
#define CDS_DPB 0x45
#define DPB_FATS 8
#define MK_FP(seg,ofs) ((void far *) (((unsigned long)(seg) << 16) | (unsigned)(ofs)))
#define _DS GetDS()
/* Documented Windows functions not declared in WINDOWS.H */
DWORD FAR PASCAL GlobalDosAlloc(DWORD dwBytes);
WORD FAR PASCAL GlobalDosFree(WORD wSelector);
/* Undocumented Windows functions */
VOID FAR PASCAL SetSelectorBase(WORD wSelector, DWORD dwBase);
VOID FAR PASCAL SetSelectorLimit(WORD wSelector, DWORD dwLimit);
/* Global Variables */
WORD _wSelector; // a data selector
/* Types */
// DOS list of lists structure (for DOS 3.1 or better)
typedef struct {
BYTE x[22]; // (don't care)
BYTE far* cds;
BYTE xx[7]; // (don't care)
BYTE lastdrive;
// ... the rest of DOS List of Lists
} DOSLISTS;
// DPMI real-mode call structure
typedef struct {
DWORD edi, esi, ebp, reserved, ebx, edx, ecx, eax;
WORD flags, es, ds, fs, gs, ip, cs, sp, ss;
} REALMODECALL;
int GetDosVersionMajor(void)
{
int dosver;
_asm mov ah, 0x30;
_asm int 0x21;
_asm mov dosver, ax;
return (BYTE)dosver;
}
unsigned GetDS(void)
{
_asm mov ax, ds;
return; // return value in AX
}
/****************************************************************************
BOOL DPMI_RealModeInt(int intno, REALMODECALL far* r)
PURPOSE: DPMI simulate real-mode interrupt function. The
following is an excerpt from the DPMI Specification:
PARAMETERS:
int intno real-mode interrupt to simulate
REALMODECALL far* r
RETURNS: TRUE if interrupt is successful, FALSE on error
NOTES: The following is an excerpt from INTEL's DPMI specs:
To Call
AX = 0300h
BL = Interrupt number
BH = Flags
Bit 0 = 1 resets the interrupt controller and A20
line
Other flags reserved and must be 0
CX = Number of words to copy from protected mode to
real-mode stack
ES:(E)DI = Selector:Offset of real-mode call structure
Returns
If function was successful:
Carry flag is clear.
ES:(E)DI = Selector:Offset of modified real-mode call
structure
If function was not successful:
Carry flag is set.
****************************************************************************/
BOOL DPMI_RealModeInt(int intno, REALMODECALL far* r)
{
intno &= 0x00FF; // reset high byte (flags)
_asm {
push di
mov bx, intno // flags | real-mode interrupt to call
mov cx, 0 // don't copy anything from protected mode stack
les di, r // es:di -> real-mode call structure
mov ax, 0x0300 // DPMI simulate real-mode interrupt function
int 0x31
pop di
jc error
}
return TRUE;
error:
return FALSE;
}
/****************************************************************************
BYTE far* PMODE_ADDR(WORD wSel, BYTE far* RMODE_ADDR)
PURPOSE: Get the Current Directory Structure
PARAMETERS:
WORD wSel A valid selector
BYTE far* RMODE_ADDR A real mode address
RETURNS: a protected-mode address of RMODE_ADDR
NOTES: The base address of selector wSel is set to the segment of
RMODE_ADDR.
*****************************************************************************/
BYTE far* PMODE_ADDR(WORD wSel, BYTE far* RMODE_ADDR)
{
SetSelectorBase(wSel, (DWORD) FP_SEG(RMODE_ADDR) << 4);
return MK_FP(wSel, FP_OFF(RMODE_ADDR));
}
/****************************************************************************
BYTE far* GetCDS(int nDrive)
PURPOSE: Get the Current Directory Structure
PARAMETERS: int nDrive The drive to retrieve
RETURNS: a real-mode pointer to the Current Directory Structure of
drive nDrive.
*****************************************************************************/
BYTE far* GetCDS(int nDrive)
{
DOSLISTS far* doslists;
REALMODECALL r;
// Get DOS list of lists (INT 21h, Function 52h)
_fmemset(&r, 0, sizeof(REALMODECALL));
r.eax = 0x5200;
if (!DPMI_RealModeInt(0x21, &r))
return NULL;
// Pointer to DOS list of lists is returned in ES:BX
doslists = (DOSLISTS far*)
PMODE_ADDR( _wSelector, MK_FP(r.es, LOWORD(r.ebx)) );
if (GetDosVersionMajor() < 4)
return doslists->cds + (nDrive * DOS3_CDS_SIZE);
else
return doslists->cds + (nDrive * DOS4_CDS_SIZE);
}
/****************************************************************************
BOOL isCDROM(int nDrive)
PURPOSE: Tests if nDrive is a CD ROM drive
PARAMETERS: int nDrive The drive to test
RETURNS: TRUE if nDrive is a CD ROM
*****************************************************************************/
BOOL isCDROM(int nDrive)
{
WORD saveAX, saveBX;
_asm mov cx, nDrive;
_asm mov ax, 0x150B;
_asm int 0x2F;
_asm mov saveAX, ax;
_asm mov saveBX, bx;
return saveBX == 0xADAD && saveAX != 0;
}
/****************************************************************************
BOOL isSubstDrive(int nDrive)
PURPOSE: Tests for drives created using the DOS SUBST command
PARAMETERS: int nDrive The drive to test
RETURNS: TRUE if nDrive is a SUBST drive
*****************************************************************************/
BOOL isSubstDrive(int nDrive)
{
BYTE far* cds; // Current Directory Structure
WORD cds_flags;
cds = PMODE_ADDR(_wSelector, GetCDS(nDrive));
cds_flags = *(WORD far*)(cds+CDS_FLAGS);
if (cds_flags & (CDS_SUBST))
return TRUE;
return FALSE;
}
/****************************************************************************
BOOL isRamDrive(int nDrive)
PURPOSE: Tests for Ram drives
PARAMETERS: int nDrive The drive to test
RETURNS: TRUE if nDrive is a ram drive
NOTES: This function tests to see if the drive has only one FAT. It
is assumed that if this is true, then the drive must be a RAM drive.
*****************************************************************************/
BOOL isRamDrive(int nDrive)
{
BYTE far* cds; // Current Directory Structure
BYTE far* dpb; // Drive Parameter Block
cds = PMODE_ADDR(_wSelector, GetCDS(nDrive));
dpb = *(BYTE far* far*)(cds+CDS_DPB);
dpb = PMODE_ADDR(_wSelector, dpb);
if (*(dpb+DPB_FATS) == 1)
return TRUE;
return FALSE;
}
/****************************************************************************
WORD FAR PASCAL GetDriveTypeX(int nDrive)
PURPOSE: Determines drive type
PARAMETERS:
int nDrive The drive number. 0 = A:, 1 = B:,
2 = C:, 3 = D:, ...
RETURNS:
DRIVE_UNKNOWN Unknown drive type
DRIVE_NOTEXIST Drive does not exist
DRIVE_REMOVE Removable (floppy) drive
DRIVE_FIXED Fixed (hard) drive
DRIVE_REMOTE Remote (network) drive
DRIVE_CDROM CD ROM drive
DRIVE_RAM Ram drive
DRIVE_SUBST SUBST drive
*****************************************************************************/
WORD FAR PASCAL GetDriveTypeX(int nDrive)
{
WORD wDriveType;
// Get a new selector, using the current DS as the prototype
_wSelector = AllocSelector(_DS);
SetSelectorLimit(_wSelector, 0xFFFF);
wDriveType = GetDriveType(nDrive);
if (isCDROM(nDrive))
wDriveType = DRIVE_CDROM;
else
if (wDriveType != DRIVE_REMOTE && isSubstDrive(nDrive))
wDriveType = DRIVE_SUBST;
else
if (isRamDrive(nDrive))
wDriveType = DRIVE_RAM;
FreeSelector(_wSelector);
return wDriveType;
}
/****************************************************************************
BOOL FAR PASCAL GetCanonicalPath(LPSTR lpszRelPath, LPSTR lpszTruePath)
PURPOSE: Resolve path string to canonical path string
PARAMETERS:
LPSTR lpszRelPath Relative path string or directory name
LPSTR lpszTruePath Destination for canonical fully qualified
path
RETURNS:
TRUE if successful
*****************************************************************************/
BOOL FAR PASCAL GetCanonicalPath(LPSTR lpszRelPath, LPSTR lpszTruePath)
{
BOOL retval;
DWORD dw;
WORD wSelector;
WORD wSegment;
LPSTR lpszDosBuf;
REALMODECALL r;
dw = GlobalDosAlloc(128);
if (dw == NULL)
return FALSE;
wSelector = LOWORD(dw);
wSegment = HIWORD(dw);
lpszDosBuf = MK_FP(wSelector, 0);
_fmemcpy(lpszDosBuf, lpszRelPath, 128);
r.eax = 0x6000;
r.ds = wSegment;
r.esi = 0;
r.es = wSegment;
r.edi = 0;
retval = DPMI_RealModeInt(0x21, &r);
_fmemcpy(lpszTruePath, lpszDosBuf, 128);
GlobalDosFree(wSelector);
return retval;
}
Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!
This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.
But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/