windows-nt/Source/XPSP1/NT/base/ntsetup/textmode/winnt/dncompv.c
2020-09-26 16:20:57 +08:00

307 lines
8.5 KiB
C

/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
dncompv.c
Abstract:
Code for determining whether volumes are compressed (DoubleSpace,
Stacker, etc).
Author:
Ted Miller (tedm) 1-April-1993
Revision History:
--*/
#include "winnt.h"
#include "dncompvp.h"
/****************************************************************************
*
* WORD IsStackerLoaded (uchar *pchSwappedDrives)
*
* Returns NZ if Stacker driver loaded.
*
* Parameters:
* pchSwappedDrives - array[26] to return swapped drives in.
* To find out if a drive is swapped, look at pchSwappedDrives[Drive].
* If pchSwappedDrives[Drive] == Drive, drive isn't swapped.
* Otherwise, pchSwappedDrives[Drive] = drive it's swapped with.
*
* Return Value:
* 0 if not loaded, else version# * 100.
****************************************************************************/
//uint IsStackerLoaded (uchar *paucSwappedDrives)
unsigned IsStackerLoaded (unsigned char *paucSwappedDrives)
{
unsigned rc;
_asm {
sub sp, 1024
mov ax, 0cdcdh
mov bx, sp
mov cx, 1
xor dx, dx
mov word ptr [bx], dx
push ds
pop es
push bp
mov bp, bx
int 25h
pop cx ; Int25h leaves flags on stack. Nuke them.
pop bp
xor ax, ax
mov bx, sp
cmp word ptr [bx], 0CDCDh
jnz sl_exit
cmp word ptr 2[bx], 1
jnz sl_exit
les di, 4[bx]
cmp word ptr es:[di], 0A55Ah
jnz sl_exit
; mov word ptr st_ptr, di
; mov word ptr st_ptr+2, es
mov ax, es:[di+2]
cmp ax, 200d
jb sl_exit
;
; Sanity Check, make sure 'SWAP' is at es:di+52h
;
; cmp word ptr es:[di+52h],'WS'
cmp word ptr es:[di+52h], 05753h
jnz sl_exit ; AX contains version.
; cmp word ptr es:[di+54h],'PA'
cmp word ptr es:[di+54h], 05041h
jnz sl_exit ; AX contains version.
;
; Copy swapped drive array.
push ds ; Save DS
;
; Source is _StackerPointer + 56h.
;
push es
pop ds
mov ax, di
add ax, 56h
mov si, ax
push es
push di
;
; Destination is ss:paucSwappedDrives
;
les di, paucSwappedDrives
;mov di, paucSwappedDrives ; SwappedDrives array is stack relative.
;push ss
;pop es
mov cx, 26d ; Copy 26 bytes.
cld
rep movsb ; Copy array.
pop di ; Restore _StackerPointer.
pop es
pop ds ; Restore DS
mov ax, es:[di+2] ; Get version number of stacker, again.
sl_exit:
mov word ptr [rc],ax ; do this to prevent compiler warning
add sp, 1024
}
return(rc); // do this to prevent compiler warning
}
/*** DRVINFO.C - IsDoubleSpaceDrive function
*
#ifdef EXTERNAL
* Version 1.00.03 - 5 January 1993
#else
* Microsoft Confidential
* Copyright (C) Microsoft Corporation 1992-1993
* All Rights Reserved.
*
* History:
* 27-Sep-1992 bens Initial version
* 06-Nov-1992 bens Improved comments
* 05-Jan-1993 bens Update for external release
#endif
*/
/*** IsDoubleSpaceDrive - Get information on a DoubleSpace drive
*
* Entry:
* drive - Drive to test (0=A, 1=B, etc.)
* NOTE: No parameter checking is done on drive.
* pdrHost - Receives drive number of host drive
* pfSwapped - Receives TRUE/FALSE indicating if drive is swapped.
* pseq - Receives CVFs sequence number if DoubleSpace drive
*
* Exit:
* returns TRUE, if DoubleSpace drive:
* *pdrHost = current drive number of host drive (0=A,...)
* *pfSwapped = TRUE, if drive is swapped with host,
* FALSE, if drive is not swapped with host
* *pseq = CVF sequence number (always zero if swapped
* with host drive)
*
* NOTE: The full file name of the CVF is:
* *pdrHost:\DBLSPACE.*pseq
*
* pdrHost pseq Full Path
* ------- ---- -----------
* 0 1 a:\dblspace.001
* 3 0 d:\dblspace.000
*
* returns FALSE, if *not* DoubleSpace drive:
* *pdrHost = drive number of host drive at boot time
* *pfSwapped = TRUE, if swapped with a DoubleSpace drive
* FALSE, if not swapped with a DoubleSpace drive
*/
BOOL IsDoubleSpaceDrive(BYTE drive, BOOL *pfSwapped, BYTE *pdrHost, int *pseq)
{
BYTE seq;
BYTE drHost;
BOOL fSwapped;
BOOL fDoubleSpace;
// Assume drive is a normal, non-host drive
drHost = drive;
fSwapped = FALSE;
fDoubleSpace = FALSE;
seq = 0;
_asm
{
mov ax,4A11h ; DBLSPACE.BIN INT 2F number
mov bx,1 ; bx = GetDriveMap function
mov dl,drive ;
int 2Fh ; (bl AND 80h) == DS drive flag
; (bl AND 7Fh) == host drive
or ax,ax ; Success?
jnz gdiExit ; NO, DoubleSpace not installed
test bl,80h ; Is the drive compressed?
jz gdiHost ; NO, could be host drive
; We have a DoubleSpace Drive, need to figure out host drive.
;
; This is tricky because of the manner in which DBLSPACE.BIN
; keeps track of drives.
;
; For a swapped CVF, the current drive number of the host
; drive is returned by the first GetDriveMap call. But for
; an unswapped CVF, we must make a second GetDriveMap call
; on the "host" drive returned by the first call. But, to
; distinguish between swapped and unswapped CVFs, we must
; make both of these calls. So, we make them, and then check
; the results.
mov fDoubleSpace,1 ; Drive is DS drive
mov seq,bh ; Save sequence number
and bl,7Fh ; bl = "host" drive number
mov drHost,bl ; Save 1st host drive
mov dl,bl ; Set up for query of "host" drive
mov ax,4A11h ; DBLSPACE.BIN INT 2F number
mov bx,1 ; bx = GetDriveMap function
int 2Fh ; (bl AND 7Fh) == 2nd host drive
and bl,7Fh ; bl = 2nd host drive
cmp bl,drive ; Is host of host of drive itself?
mov fSwapped,1 ; Assume CVF is swapped
je gdiExit ; YES, CVF is swapped
mov fSwapped,0 ; NO, CVF is not swapped
mov drHost,bl ; True host is 2nd host drive
jmp short gdiExit
gdiHost:
and bl,7Fh ; bl = host drive number
cmp bl,dl ; Is drive swapped?
je gdiExit ; NO
mov fSwapped,1 ; YES
mov drHost,bl ; Set boot drive number
gdiExit:
}
*pdrHost = drHost;
*pfSwapped = fSwapped;
*pseq = seq;
return fDoubleSpace;
}
///////////////////////////////////////////////////////////////////////////////
BOOLEAN
DnIsDriveCompressedVolume(
IN unsigned Drive,
OUT unsigned *HostDrive
)
/*++
Routine Description:
Determine whether a drive is actually a compressed volume.
Currently we detect Stacker and DoubleSpace volumes.
Arguments:
Drive - drive (1=A, 2=B, etc).
Return Value:
TRUE if drive is non-host compressed volume.
FALSE if not.
--*/
{
static BOOLEAN StackerMapBuilt = FALSE;
static unsigned StackerLoaded = 0;
static unsigned char StackerSwappedDrives[26];
BOOL Swapped;
BYTE Host;
int Seq;
Drive--;
if(!StackerMapBuilt) {
StackerLoaded = IsStackerLoaded(StackerSwappedDrives);
StackerMapBuilt = TRUE;
}
if(StackerLoaded && (StackerSwappedDrives[Drive] != (UCHAR)Drive)) {
*HostDrive = StackerSwappedDrives[Drive];
return(TRUE);
}
if(IsDoubleSpaceDrive((BYTE)(Drive),&Swapped,&Host,&Seq)) {
*HostDrive = Host+1;
return(TRUE);
}
return(FALSE);
}