Creating Random Numbers
This program creates its own list of random bytes for creating passwords, overwriting files before deletion and for other uses.
The random numbers makes uses of hard disk data as well window functions.
The SHA function is used on the data to create a random output. It has been found by experiment that the time it takes to do a loop function

for (retc = 0; retc < 10000; retc++)
 { 
 	z++; 
 }

Is quite variable and unpredictable. This makes it useful to use doing the creation of random characters. Some of the the code usied to create random numbers is as follows:

void FAR PASCAL GetSHAforInitialise10ByteVector()
{
	//	If encrypting, generate 10 random numbers (0-255 range). 
	//	Write these as the first 10 bytes of the output file
	//	GetTickCount function retrieves the number of milliseconds
	//	that have elapsed since Windows was started. 
	OSVERSIONINFO ov;
	HWND h;
	h = GetActiveWindow();
	SYSTEMTIME  ST;
	GetSystemTime(&ST);
	MEMORYSTATUS MS;
	GlobalMemoryStatus(&MS);
	POINT P;
	GetCursorPos(&P);
	DWORD time2, l;
	DWORD z;
	z = GetTickCount();
	l = 0;
	for (;;)
	{ 
		//	remain in loop until tickcount increases by 1
		time2 = GetTickCount();
		if (z < time2)
		{
		 	break;
		}
		l++;
		Gvar.tstring[0] = (char) (l % 256);	//	calculation to increase loop time
	}
	//	l is very variable dependant on system processes
	lVar.c = Gvar.tstring;
	GetVersionEx(&ov);
	MoveMemory (lVar.c, &ov, sizeof(OSVERSIONINFO));
	lVar.c += sizeof(OSVERSIONINFO);
	MoveMemory (lVar.c, &h, sizeof(HWND));
	lVar.c += sizeof(HWND);
	MoveMemory (lVar.c, &z, sizeof(DWORD));
	lVar.c += sizeof(DWORD);	//	4 chars
	MoveMemory (lVar.c, &ST, sizeof(SYSTEMTIME));
	lVar.c += sizeof(SYSTEMTIME); //  16 chars
	MoveMemory (lVar.c, &MS, sizeof(MEMORYSTATUS));
	lVar.c += sizeof(MEMORYSTATUS);	//	8x4 = 32 chars
	MoveMemory (lVar.c, &P, sizeof(POINT));
	lVar.c += sizeof(POINT);
	MoveMemory (lVar.c, &l, sizeof(l));
	lVar.c += sizeof(l);
	//	we can also use the contents of lVar.password
	//	this can be a variable independent of input password
	//	we will take just 50 chars from this
	MoveMemory (lVar.c, lVar.password, 50);
	lVar.c += 50;
	//	various memory items have handles
	//	these can be zero or have a value depending where we are
	//	so we can generate a handle - get its value - then lose the memory handle
	HANDLE handle1, handle2, handle3;
	unsigned int *a1, *a2, *a3;
	handle1 = HeapCreate(0, sizeof(unsigned int), 0);
	handle2 = HeapCreate(0, sizeof(unsigned int), 0); 
	handle3 = HeapCreate(0, sizeof(unsigned int), 0);
	MoveMemory (lVar.c, &handle1, sizeof(HANDLE));
	lVar.c += sizeof(HANDLE);
	MoveMemory (lVar.c, &handle2, sizeof(HANDLE));
	lVar.c += sizeof(HANDLE);
	MoveMemory (lVar.c, &handle3, sizeof(HANDLE));
	lVar.c += sizeof(HANDLE);
	
	a1 = (unsigned int *) HeapAlloc(handle1,
								 HEAP_ZERO_MEMORY, sizeof(unsigned int));
	a2 = (unsigned int *) HeapAlloc(handle2,
								 HEAP_ZERO_MEMORY, sizeof(unsigned int));
	a3 = (unsigned int *) HeapAlloc(handle2,
								 HEAP_ZERO_MEMORY, sizeof(unsigned int));
	*a1 = (unsigned int) &handle1;
	*a2 = (unsigned int) &handle2;
	*a3 = (unsigned int) &handle3;

	MoveMemory (lVar.c, a1, sizeof(a1));
	lVar.c += sizeof(a1);
	MoveMemory (lVar.c, a2, sizeof(a2));
	lVar.c += sizeof(a2);
	MoveMemory (lVar.c, a3, sizeof(a3));
	lVar.c += sizeof(a3);

	*a1 = (unsigned int) &a1;
	*a2 = (unsigned int) &a2;
	*a3 = (unsigned int) &a3;
	*a1 = (*a1)*(*a2)*(*a3);

	MoveMemory (lVar.c, a1, sizeof(a1));
	lVar.c += sizeof(a1);
	MoveMemory (lVar.c, a2, sizeof(a2));
	lVar.c += sizeof(a2);
	MoveMemory (lVar.c, a3, sizeof(a3));
	lVar.c += sizeof(a3);

	*a1 = (unsigned int) lVar.d;
	*a2 = (unsigned int) Gvar.astring;
	*a3 = (unsigned int) Gvar.tstring;
	*a1 = (*a1)+(*a2)*(*a3);

	MoveMemory (lVar.c, a1, sizeof(a1));
	lVar.c += sizeof(a1);
	MoveMemory (lVar.c, a2, sizeof(a2));
	lVar.c += sizeof(a2);
	MoveMemory (lVar.c, a3, sizeof(a3));
	lVar.c += sizeof(a3);

	*a1 = (unsigned int) &lVar.i;
	*a2 = (unsigned int) &lVar.j;
	*a3 = (unsigned int) &Gvar.i;
	*a1 = (*a1)*(*a2)*(*a3);

	MoveMemory (lVar.c, a1, sizeof(a1));
	lVar.c += sizeof(a1);
	MoveMemory (lVar.c, a2, sizeof(a2));
	lVar.c += sizeof(a2);
	MoveMemory (lVar.c, a3, sizeof(a3));
	lVar.c += sizeof(a3);

	//	we may have password list set up
	*a1 = (unsigned int) PasswordList;
	*a2 = (unsigned int) &Fvar.i;
	*a3 = (unsigned int) &Fvar.j;
	*a1 = (*a1)+(*a2)*(*a3);

	MoveMemory (lVar.c, a1, sizeof(a1));
	lVar.c += sizeof(a1);
	MoveMemory (lVar.c, a2, sizeof(a2));
	lVar.c += sizeof(a2);
	MoveMemory (lVar.c, a3, sizeof(a3));
	lVar.c += sizeof(a3);

	*a1 = (unsigned int) String;
	*a2 = (unsigned int) Hashoforiginaldecomfilediff;
	*a3 = (unsigned int) YoucannotuseinPassword;
	*a1 = (*a1)+(*a2)*(*a3);

	MoveMemory (lVar.c, a1, sizeof(a1));
	lVar.c += sizeof(a1);
	MoveMemory (lVar.c, a2, sizeof(a2));
	lVar.c += sizeof(a2);
	MoveMemory (lVar.c, a3, sizeof(a3));
	lVar.c += sizeof(a3);

	HeapDestroy(handle1);
	HeapDestroy(handle2);
	HeapDestroy(handle3);

	//	now we can have variables
	//	lVar.j, lVar.d, Gvar.astring address
	MoveMemory (lVar.c, &lVar.j, sizeof(lVar.j));
	lVar.c += sizeof(lVar.j);
	
	h = GetDesktopWindow();
	MoveMemory (lVar.c, &h, sizeof(HANDLE));
	lVar.c += sizeof(HANDLE);
	lVar.i = lVar.c - Gvar.tstring;

	SHA(Gvar.astring, (unsigned char *) Gvar.tstring, lVar.i);
}
BOOL FAR PASCAL CreatePassword(BOOL FILEERASE)
{
//	lVar.d = lVar.password;
	if (!testasm())
	{
		return FALSE;
	}
	    //	if this function fails we still have 40 chars to play with
	OpenFiles(NULL); // added in 5.98oulw sees what files are open
     // use SHA of open file list to modify first 20 bytes of Gvar.tstring
	ShowProcessData(0, FALSE);  // added in 5.98oulw sees the processes running
     // use SHA process list to modify 20 bytes 20 to 39 (0 is first byte) of Gvar.tstring

	//	we can come from previous routine with contents in lVar.password
	//	and contents in lVar.password2
	char *a;
	lVar.d = lVar.password;
	lVar.c = Gvar.tstring;
	a = lVar.password2;
	
	for (lVar.i = 0; lVar.i < 60; lVar.i++)
	{
		*lVar.d += *lVar.c;
		*lVar.d += *a;
		lVar.c++;
		lVar.d++;
		a++;
	}
		//	this keeps feed back going
		//	lVar.password can = 0 or some number
		
	
	lVar.d = lVar.password;
	for (lVar.j = 0; lVar.j <3; lVar.j++)
	{
    	GetSHAforInitialise10ByteVector();
	//	this function takes and uses Gvar.astring & Gvar.tstring
	//	SHA in Gvar.astring
	//	it also uses lVar.password
		CopyMemory(lVar.d, Gvar.astring, 20);
		lVar.d += 20;
	}

	CopyMemory(lVar.password2, lVar.password, 60);
	//	this will enable use to keep the feedback going
	lVar.d = lVar.password;
	for (lVar.j = 0; lVar.j <3; lVar.j++)
	{
    	GetSHAforInitialise10ByteVector();
	//	this function takes and uses Gvar.astring & Gvar.tstring
	//	SHA in Gvar.astring
		MoveMemory(lVar.d, Gvar.astring, 20);
		lVar.d += 20;
	}
	
	
	if (FILEERASE)
	{
		//	this is used for deletion so leave all possibilities in
		//	so better randomising
		return TRUE;
	}
	//	we are allowed 50 maximum in password
	//	we lose last ten characters of password
	ZeroMemory(&lVar.password[50], 10);
	ZeroMemory(&lVar.password2[50], 10);
	CheckPasswordString(lVar.password, 49);	//	must have 50 = 0
	CheckPasswordString(lVar.password2, 49); //	must have 50 = 0
	//	we now put these in the respective boxes
	return TRUE;
}
BOOL FAR PASCAL testasm()
{
	//	we ensure preservation of 40 SHA in Gvar.tstring
	if (lVar.SHADBASE == CM_TEST || lVar.SHADBASE  == 507 || 
		lVar.SHADBASE  == 0 || lVar.SHADBASE  == CM_RANDOMISEMEMORY ||
		lVar.SHADBASE  == CM_CLEARVCACHE1 ||
		lVar.SHADBASE  == CM_CLEARVCACHE1SHUTDOWN)
		{
			//	we specifically are creating random numbers
			lVar.j = VmSpace(NULL, lVar.j, FALSE);
			if (lVar.j == -1)
			{
				return FALSE;
			}
			//	have  Fvar.fdirname3 with 40 chars
			MoveMemory(&Fvar.BufferJee[160], Fvar.fdirname3, 40);
		}
		sprintf(Gvar.tstring, "%c:\\", 'C');
		Fvar.i = GetDriveType(Gvar.tstring);
		if (Fvar.i == DRIVE_FIXED)
		{
			if (!DoDrive(Gvar.tstring[0], FALSE, FALSE))
			{
				return FALSE;
			}
		}
		
		MoveMemory(&Fvar.BufferJee[120], Gvar.tstring, 40);
		if (lVar.SHADBASE == CM_TEST || lVar.SHADBASE  == 507 || 
			lVar.SHADBASE  == 0)
		{
			//	CM_TEST used in check routine
			//	0 is used to make password
			//	507 is random number generator

			//	we do not need this for randomise memory as
			//	randomise is not as important as it is for password

			//	we do not need for secure delete overwrite as we need reasonable random and 
			//	unpredictable for this
			if(dwPlatformId != VER_PLATFORM_WIN32_NT)
			{
				//	we found that this takes a long time in XP
				//	so not viable
				sprintf(Gvar.tstring, "%c:\\", 'D');
				Fvar.i = GetDriveType(Gvar.tstring);
				if (Fvar.i == DRIVE_FIXED)
				{
					if (!DoDrive(Gvar.tstring[0], FALSE, FALSE))
					{
						return FALSE;
					}
					MoveMemory(&Gvar.tstring[40], &Fvar.BufferJee[120], 40);
					SHA(&Fvar.BufferJee[120], (unsigned char *) Gvar.tstring, 80);
				}
			
				sprintf(Gvar.tstring, "%c:\\", 'E');
				Fvar.i = GetDriveType(Gvar.tstring);
				if (Fvar.i == DRIVE_FIXED)
				{
					if (!DoDrive(Gvar.tstring[0], FALSE, FALSE))
					{
						return FALSE;
					}
					MoveMemory(&Gvar.tstring[40], &Fvar.BufferJee[120], 40);
					SHA(&Fvar.BufferJee[120], (unsigned char *) Gvar.tstring, 80);
				}
				
				sprintf(Gvar.tstring, "%c:\\", 'F');
				Fvar.i = GetDriveType(Gvar.tstring);
				if (Fvar.i == DRIVE_FIXED)
				{
					if (!DoDrive(Gvar.tstring[0], FALSE, FALSE))
					{
						return FALSE;
					}
					MoveMemory(&Gvar.tstring[40], &Fvar.BufferJee[120], 40);
					SHA(&Fvar.BufferJee[120], (unsigned char *) Gvar.tstring, 80);
				}
			}
			else
			{
				DoHardDisk(NULL);
				MoveMemory(&Gvar.tstring[40], &Fvar.BufferJee[120], 40);
				MoveMemory(&Gvar.tstring[80], &Gvar.astring[160], 40);
				SHA(&Fvar.BufferJee[120], (unsigned char *) Gvar.tstring, 120);
			}
		}
		
		MoveMemory(Gvar.tstring, &Fvar.BufferJee[100], 20);
		SHA(&Gvar.tstring[20], (unsigned char *) &Fvar.BufferJee[100], 60);
		MoveMemory(&Fvar.BufferJee[120], Gvar.tstring, 40);

	//	&Fvar.BufferJee[100] has been mixed across the drives
	//	&Fvar.BufferJee[120] has c drive SHA contents 40 long
	//	Gvar.tstring is contents from last do drive

	//	data of interest in Gvar.tstring
	//	

	//	we can use getwindows directory
	//	count how many tempory files there are
	//	get size of dao file
	
		GetWindowsDirectory(Gvar.tstring, MAX_PATH);
		Fvar.i = strlen(Gvar.tstring);
		
		//	Fvar.i, Fvar.BufferJee 

		HANDLE          hFind;
		WIN32_FIND_DATA *fd;	
		BOOL            bRet = TRUE;
		HANDLE hfd;
		
		hfd = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, sizeof( WIN32_FIND_DATA ));
		fd = (WIN32_FIND_DATA *) GlobalLock(hfd);


		//	\APPLOG\E_CRP_R5.5.LGC
		//	\Desktop\WinZip.lnk
		//	\TEMP\atest.tx0
		lVar.c = &Fvar.BufferJee[160];
		sprintf(String, "%s\\APPLOG\\*.*",Gvar.tstring);
		Fvar.i = 0;
		bRet = TRUE;
		hFind = FindFirstFile(String, fd );
		__int64 TotalFileSize1;
		TotalFileSize1 = 0;
		while ( hFind != INVALID_HANDLE_VALUE && bRet )
		{
			//	we are only interested in counting contents
			while ( hFind != INVALID_HANDLE_VALUE && bRet )
			{
				Fvar.i++;
				TotalFileSize1 += fd->nFileSizeLow;
				bRet = FindNextFile( hFind, fd );
			}
		}
		FindClose( hFind );
		MoveMemory(&Fvar.j, lVar.c, sizeof(int));
		Fvar.i += Fvar.j;
		MoveMemory(lVar.c, &Fvar.i, sizeof(int));
		lVar.c += sizeof(int);
		MoveMemory(lVar.c, &TotalFileSize1, sizeof(__int64));
		lVar.c += sizeof(__int64);
		TotalFileSize1 = 0;
		sprintf(String, "%s\\Desktop\\*.*",Gvar.tstring);
		Fvar.i = 0;
		bRet = TRUE;
		hFind = FindFirstFile(String, fd );
			
		while ( hFind != INVALID_HANDLE_VALUE && bRet )
		{
			//	we are only interested in counting contents
			while ( hFind != INVALID_HANDLE_VALUE && bRet )
			{
				Fvar.i++;
				TotalFileSize1 += fd->nFileSizeLow;
				bRet = FindNextFile( hFind, fd );
			}
		}
		FindClose( hFind );
		MoveMemory(&Fvar.j, lVar.c, sizeof(int));
		Fvar.i += Fvar.j;
		MoveMemory(lVar.c, &Fvar.i, sizeof(int));
		lVar.c += sizeof(int);
		MoveMemory(lVar.c, &TotalFileSize1, sizeof(__int64));
		lVar.c += sizeof(__int64);
		
		sprintf(String, "%s\\TEMP\\*.*",Gvar.tstring);
		Fvar.i = 0;
		bRet = TRUE;
		hFind = FindFirstFile(String, fd );
		TotalFileSize1 = 0;
		while ( hFind != INVALID_HANDLE_VALUE && bRet )
		{
			//	we are only interested in counting contents
			while ( hFind != INVALID_HANDLE_VALUE && bRet )
			{
				Fvar.i++;
				TotalFileSize1 += fd->nFileSizeLow;
				bRet = FindNextFile( hFind, fd );
			}
		}
		FindClose( hFind );
		MoveMemory(&Fvar.j, lVar.c, sizeof(int));
		Fvar.i += Fvar.j;
		MoveMemory(lVar.c, &Fvar.i, sizeof(int));
		lVar.c += sizeof(int);
		MoveMemory(lVar.c, &TotalFileSize1, sizeof(__int64));
		lVar.c += sizeof(__int64);
		Fvar.i = lVar.c - &Fvar.BufferJee[160];
		TotalFileSize1 = 0;
		GlobalUnlock(hfd);
		GlobalFree(hfd);
		hfd = 0;
		ZeroMemory(String, D2000);

		//	we use Gvar.tstring in calling programs
		MoveMemory(Gvar.tstring, &Fvar.BufferJee[100], 20);
		SHA(&Gvar.tstring[20], (unsigned char *) &Fvar.BufferJee[100], 99);
		//	last altered value = &Fvar.BufferJee[96];
		if (lVar.SHADBASE == CM_TEST || lVar.SHADBASE  == 507 || 
		lVar.SHADBASE  == 0)
		{
			char *a, *b;
			a = Gvar.tstring;
			b = Fvar.fdirname3;
			for (Fvar.i = 0; Fvar.i < 40; Fvar.i++)
			{
				*a = *a + *b;
				a++;
				b++;
			}

		}

		//	checktiming() - uses 40 chars and removes certain chars as in password
		//	CreatePassword - uses 60 chars and copies into lVar.password
		//	CreateRandumNo - uses 40 chars and copies into lVar.password

	return TRUE;
}
BOOL FAR PASCAL DoDrive(char Drive, BOOL ADRIVE, BOOL DISKFILE)
{
//	BOOL bFat12 = FALSE, bFat16 = FALSE, bFat32 = FALSE;
//    unsigned short sector_size, sectors_per_fat, sectors_per_clus;
//	DWORD dwReservedSectors,
	DWORD	first_fat_sector1, second_fat_sector1;
    BYTE* pReadBuf;	
//	char szFSType[9];
    int vol1, volz, retc;

	// One-based volume number
    vol1 = Drive - 'A' + 1; // requested volume, 'A'=1, 'B'=2, 'C'=3, etc.
    // Zero-based volume number
    volz = vol1 - 1;
	BOOL MEMAVAILABLE;
	
	if (Fvar.hpAddress == 0)
	{
		MEMAVAILABLE = FALSE;
		if (!CreateHpAddress(HASHSIZE, TRUE))
		{
			return FALSE;
		}
	}
	else MEMAVAILABLE = TRUE;
	
	Fvar.h1 = Fvar.hpAddress;
//	MID media;
	if (!ADRIVE)
	{
		GetUniqueParams();
		
		if (!hVWin32Device)
		{
			Fvar.BufferJee[0] = Drive;
				Fvar.BufferJee[1] = ':';
				Fvar.BufferJee[2] = '\\';
				Fvar.BufferJee[3] = '\0';
			GetVolumeInformation(Fvar.BufferJee,
					&Fvar.BufferJee[5], 12, (DWORD *) &Fvar.BufferJee[20], NULL,
					(DWORD *)   &Fvar.BufferJee[42], &Fvar.BufferJee[50], 100);
			
			SHA(&Fvar.BufferJee[160], (unsigned char *) Fvar.BufferJee, 15);
				ConvertTo40Hex(&Fvar.BufferJee[160], (char *) Fvar.h1);
				Fvar.h1 += strlen((char *) Fvar.h1);
				WriteFileString("\r\n");

		}
	
	}
	//	drive = ? if disk image and not floppy
	if(!ReadDiskParam(Drive, FALSE, DISKFILE))
	{
		// Non-standard bootsector (Linux,BeOS...)
		if (hVWin32Device)
		{
			UnlockLogicalVolume(vol1, lVar.FAT32LOCK);
			CloseHandle( hVWin32Device );
			hVWin32Device = 0;	
		}
		if (ADRIVE)
		{
			if (Gvar.hWnd1)
			{
				EndDialog(Gvar.hWnd1, IDCANCEL);
				Gvar.hWnd1 = 0;
			}
			
		}

		if (!ADRIVE && !DISKFILE)
		{
			//	this is getting password
			//	we have hit NTFS drive
			//	could be XP NT
			//	should have DParams

			//	should have DParams even if value could be funny disk
			SHA(&Fvar.BufferJee[160], (unsigned char *) &DParams, sizeof(struct DiskParams));
				ConvertTo40Hex(&Fvar.BufferJee[160], (char *) Fvar.h1);
				Fvar.h1 += strlen((char *) Fvar.h1);
				WriteFileString("\r\n");

			ULARGE_INTEGER i64FreeBytesToCaller, i64TotalBytes, i64FreeBytes;
			Fvar.BufferJee[0] = Drive;
			Fvar.BufferJee[1] = ':';
			Fvar.BufferJee[2] = '\\';
			Fvar.BufferJee[2] = '\0';
			GetDiskFreeSpaceEx  (Fvar.BufferJee,
						&i64FreeBytesToCaller,
						&i64TotalBytes,
						&i64FreeBytes);
			Fvar.i = 0;
			//Gvar.hWnd1 = 0;
			 
			WriteFileString("%c*%I64d*%I64d*%I64d",
				Drive, i64FreeBytesToCaller,
				i64TotalBytes, i64FreeBytes);

			return TRUE;
		}
		
		return	FALSE;
	}

	

	first_fat_sector1 = DParams.dwReservedSectors;
    pReadBuf = (BYTE*)malloc( DParams.SectorSize);


	// Read the first sector of the first FAT
    if ( DParams.bFat32 ) 
	{
        if ( ReadAbsoluteSectors32( vol1, first_fat_sector1, 1, pReadBuf) != 0 )
		{
			return ErrorExit2( vol1, Drive, first_fat_sector1, DParams.bFat32, pReadBuf );
		}
	}
    else 
	{
		if (DISKFILE)
		{
			CopyMemory (pReadBuf,
				Fvar.hpAddress2+(first_fat_sector1*DParams.SectorSize),	//bsBytesPerSec),
				DParams.SectorSize);	//bs.bsBytesPerSec);
		}
		else
		{
			if ( ReadAbsoluteSectors( volz, first_fat_sector1, 1, pReadBuf) < 0 )
			{
				return ErrorExit2( vol1, Drive, first_fat_sector1, DParams.bFat32, pReadBuf );
			}
		}
	}

	WriteFileString("\r\nSector %d - First File Allocation Table ...\r\n", DParams.dwReservedSectors);
	second_fat_sector1 = DParams.dwReservedSectors + DParams.SectorsPerFat;	
    // **********************
	if (!DISKFILE)
	{
		DumpFat( pReadBuf, DParams.bFat12, DParams.bFat16, DParams.bFat32 , DISKFILE);
       
		memset( pReadBuf, 0, DParams.SectorSize );
		

		WriteFileString("== Start Read Second FAT (%lxH)", second_fat_sector1);

		// Read the first sector of the second FAT
		if ( DParams.bFat32 ) 
		{
			if ( ReadAbsoluteSectors32( vol1, second_fat_sector1, 1, pReadBuf ) != 0 )
			{
				return ErrorExit2( vol1, Drive, second_fat_sector1, DParams.bFat32, pReadBuf );
			}
		}
		else 
		{
			//if (DISKFILE)
		//	{
		//		CopyMemory (pReadBuf,
		//			Fvar.hpAddress2+(second_fat_sector1*bs.bsBytesPerSec),
		//			bs.bsBytesPerSec);
		//	}
		//	else
			{
				if ( ReadAbsoluteSectors( volz, second_fat_sector1, 1, pReadBuf) < 0 )
				{
					return ErrorExit2( vol1, Drive, second_fat_sector1, DParams.bFat32, pReadBuf );
				}
			}
		}

		WriteFileString("\n Sector %d - Second File Allocation Table ...\n", second_fat_sector1);
		// *******
		DumpFat( pReadBuf, DParams.bFat12, DParams.bFat16, DParams.bFat32 , DISKFILE);
	//    printf( "  ...\n" );
		WriteFileString( "  ...\r\n" );
	}
	else
	{
		WriteFileString("Sector %d - Second File Allocation Table ...\r\n", second_fat_sector1);
	}
    free( pReadBuf );

	// Dump out the Root Directory Entries
	WriteFileString( "Root Directory Entries\r\n" );
	unsigned short sect_cnt=0;
	if (!DParams.bFat32 ) 
	{
		sect_cnt = ((32 * DParams.bsRootDirEnts) + DParams.SectorSize - 1)/DParams.SectorSize;
		DWORD root_dir_ent = DParams.dwReservedSectors + DParams.SectorsPerFat*2;
		pReadBuf = (BYTE *)malloc( sect_cnt * DParams.SectorSize );
		memset( pReadBuf, 0, sect_cnt * DParams.SectorSize );

		if (DISKFILE)
		{
			CopyMemory (pReadBuf,
				Fvar.hpAddress2+(root_dir_ent*DParams.SectorSize),
				sect_cnt*DParams.SectorSize);
		}
		else
		{
			//	dwRootDirStartSector
			if ( ReadAbsoluteSectors( volz, root_dir_ent, sect_cnt, pReadBuf) < 0 )
			{
				return ErrorExit2( vol1, Drive, root_dir_ent, DParams.bFat32, pReadBuf );
			}
		}
//		printf( "\n Sector %d - Root Directory Entries ...\n", root_dir_ent );
		//dwRootDirStartSector
		WriteFileString("Sector %d - Root Directory Entries ...", root_dir_ent );
	
		//DumpDirEntries( pReadBuf );
		// *****
		DumpDirEntries( pReadBuf, sect_cnt * DParams.SectorSize,
			DISKFILE, FALSE);
//		printf( "  ...\n" );
		WriteFileString( "  ...\r\n" );
	//	free( pReadBuf );

//	    printf( "\n Sector %d - First available cluster.\n", root_dir_ent + sect_cnt );
		WriteFileString("\r\n Sector %d - First available cluster.\n", root_dir_ent + sect_cnt );
		
	}
	else 
	{
		//DWORD dwRootDirStartClus, dwStartSector;	//, dwRootDirStartSector;
	    pReadBuf = (BYTE*)malloc( DParams.SectorSize * DParams.SectorsPerCluster );

		//dwRootDirStartClus = (bs32.bpb.A_BF_BPB_RootDirStrtClusHi << 16) + 
		//					  bs32.bpb.A_BF_BPB_RootDirStrtClus;
	//	dwRootDirStartClus = DParams.dwRootDirStartClus;
	//	dwRootDirStartClus -= 2; // the first two clusters in the FAT are reserved
	//	dwStartSector = DParams.dwReservedSectors + DParams.SectorsPerFat*2;
	//	DParams.dwRootDirStartSector = dwStartSector + 
	//						   dwRootDirStartClus * DParams.SectorSize;	//bs32.bpb.A_BF_BPB_SectorsPerCluster;
		
		//	For FAT32 drives, space is not reserved for Root Directory Entries.
		//	The Root Directory Entries are allocated clusters just like any
		//	other file.
//	    printf( "\n Sector %d - First available cluster.\n", dwStartSector );
		WriteFileString("\n Sector %d - First available cluster.\n", DParams.FirstDataSector);
	

		//	Read in one whole cluster of the Root Directory cluster chain
        if ( ReadAbsoluteSectors32( vol1,
			DParams.dwRootDirStartSector, DParams.SectorsPerCluster, pReadBuf ) != 0 )
		{
			return ErrorExit2( vol1, Drive, DParams.dwRootDirStartSector, DParams.bFat32, pReadBuf );
		}

//		printf( "\n Sector %d - Root Directory Entries ...\n", dwRootDirStartSector );
		WriteFileString("\n Sector %d - Root Directory Entries ...\n",
			DParams.dwRootDirStartSector);
		
	//	DumpDirEntries(pReadBuf );
		// ******
		DumpDirEntries(pReadBuf, DParams.SectorSize * DParams.SectorsPerCluster,
			DISKFILE, FALSE);
//		printf( "  ...\n" );
		WriteFileString( "  ...\n" );
	//	free( pReadBuf );
	}

	if (!ADRIVE)
	{
		//	we can muddy waters a bit more by reading a sector in the middle of the disk
		//	taking an taking SHA of sector size
		//	converting to SHA0 HEX
		unsigned int readsector;
		if ( DParams.bFat32 ) 
		{
			
			readsector = (unsigned int) DParams.TotalSectors/2;
				//((bs32.bpb.A_BF_BPB_BigTotalSectorsHigh << 16)
				//			+ bs32.bpb.A_BF_BPB_BigTotalSectors)/2;

			if ( ReadAbsoluteSectors32( vol1, readsector, 1, pReadBuf ) != 0 )
			{
				return ErrorExit2( vol1, Drive, readsector, DParams.bFat32, pReadBuf );
			}
			//	SHA0 only used here
			SHA(Fvar.BufferJee, pReadBuf, DParams.SectorSize * DParams.SectorsPerCluster);
		}
		else 
		{
			readsector = (unsigned int) DParams.TotalSectors/2; 
			if ( ReadAbsoluteSectors( volz, readsector, 1, pReadBuf) < 0)
			{
				return ErrorExit2( vol1, Drive, readsector, DParams.bFat32, pReadBuf );
			}
			//	SHA0 only used here
			SHA(Fvar.BufferJee, pReadBuf, sect_cnt * DParams.SectorSize);
		}
		
		ConvertTo40Hex(Fvar.BufferJee, (char *) Fvar.h1);
		Fvar.h1 += 40;
	}


	free( pReadBuf );
	if (!DISKFILE)
	{
		if (hVWin32Device)
		{
			UnlockLogicalVolume( vol1, lVar.FAT32LOCK);
			CloseHandle( hVWin32Device );
			hVWin32Device = 0;
		}
	}

	if (!ADRIVE)
	{
		//	we have Fvar.hpAddress to take SHA of
		GetUniqueParams();
		
	}
	retc = strlen((char *)Fvar.hpAddress);
	if (ADRIVE)
	{
		//	we need to put details into list
		Fvar.b = (char *) Fvar.hpAddress;
		Fvar.a = Gvar.tstring;
		while (*Fvar.b)
		{
			*Fvar.a = *Fvar.b;
			if (*Fvar.a == '\r' || *Fvar.a == '\n')
			{
				*Fvar.a = '\0';
				Fvar.b += 2;	//	get past \r\n
				AddFileName(Gvar.tstring);
				ZeroMemory(Gvar.tstring, sizeof(Gvar.tstring));
				Fvar.a = Gvar.tstring;
				if (*Fvar.b == 0) break;
			}
			else
			{
				Fvar.a++;
				Fvar.b++;
			}
		}
		
		if (Gvar.hWnd1)
		{
			EndDialog(Gvar.hWnd1, IDCANCEL);
			Gvar.hWnd1 = 0;
		}

		
		sprintf(Gvar.tstring, "Floppy - Deleted entries marked with %c",
			0xE5);
		ProcesshDlgModelessListBox(Gvar.hWnd, 1001);
		 
	}
	/*
	//	this enables use to check routine
	HANDLE dumpfile;
	sprintf(Fvar.dirname1, "G:\\DISKDUMP\\%ctest.txt", Drive);
	dumpfile = CreateFile(Fvar.dirname1,
				GENERIC_WRITE, 0, NULL,
				CREATE_ALWAYS, FILE_FLAG_RANDOM_ACCESS,
				NULL);

	WriteFile(dumpfile, Fvar.hpAddress, retc,
		(unsigned long *) &Fvar.AmountWrite, NULL);

	CloseHandle(dumpfile);
	dumpfile = 0;
	*/
		
	retc /=2;
	CopyMemory(Fvar.h1, Gvar.tstring, 40);
	Fvar.h1 = Fvar.hpAddress + retc;
	//	SHA0 only used here
	SHA(Gvar.tstring, Fvar.hpAddress, retc);
	SHA(&Gvar.tstring[20], Fvar.h1, retc+40);

	ZeroMemory(&DParams, sizeof(struct DiskParams));
	


	if (!MEMAVAILABLE)
	{
		RemoveHpAddress();
	}

	if (!ADRIVE)
	{
		//	this is called from testasm()
		//	used for seeding
		//	&Fvar.BufferJee[100] is not used until this point
		//	thus we use Fvar.BufferJee[100] to ensure good mixing
		MoveMemory(&Gvar.tstring[40], &Fvar.BufferJee[100], 20);
		SHA(&Fvar.BufferJee[100], (unsigned char *)Gvar.tstring, 60);
		//	Gvar.tstring gets lost in testasm
	}
	return TRUE;
}