/*++ 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); }