⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wffat.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "precomp.h"

void WritePattern(void* buf, DWORD* pattern, long size)
{
	char* buffer = (char*)buf;
	int patternSize = sizeof(DWORD) * 256;

	if(size <= patternSize)
	{
		memcpy(buffer, pattern, size);
	}
	else
	{
		int passes = size / patternSize;
		int remainder = size % patternSize;
		int i;

		for(i = 0; i < passes; i++)
		{
			memcpy(buffer + (i * patternSize), pattern, patternSize);
		}

		memcpy(buffer + (i * patternSize), pattern, remainder);
	}
}

DWORD ClusterToSector(VOLINFO *vi,DWORD Cluster)
{
	return ((Cluster-0x2)*vi->sectors_per_clus)+vi->dwStartSector;
}

int ReadAbsoluteSectors( HANDLE hDev,int volume, DWORD start_sector, 
                         WORD num_sectors, LPBYTE pBuf ) 
{
	DIOC_REGISTERS reg;
	DISKIO di;
	BOOL bResult;
	DWORD cb;

	reg.reg_EAX      = volume-1;  // zero-based volume number
	reg.reg_EBX      = (DWORD)&di;
	reg.reg_ECX      = 0xffff;  // use DISKIO structure
	reg.reg_Flags    = 1;       // preset the carry flag
	di.diStartSector = start_sector;
	di.diSectors     = num_sectors;
	di.diBuffer      = (DWORD)pBuf;
	bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_INT25,
              &reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 ); 

	if ( !bResult || (reg.reg_Flags & 1) ) return -1;
	return 0;
}

BOOL WriteAbsoluteSectors(HANDLE hDev,
                          int    bDrive,
                          DWORD  dwStartSector,
                          WORD   wSectors,
                          LPBYTE lpSectBuff)
{
	BOOL           fResult;
	DWORD          cb;
	DIOC_REGISTERS reg = {0};
	DISKIO         di = {0};

//	if(bDrive!=1)
//		return FALSE;

	di.diStartSector = dwStartSector;
	di.diSectors      = wSectors;
	di.diBuffer      = (DWORD)lpSectBuff;

	reg.reg_EAX = bDrive - 1;    // Int 26h drive numbers are 0-based.
	reg.reg_EBX = (DWORD)&di;
	reg.reg_ECX = 0xFFFF;        // use DISKIO struct

	fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_INT26,
                                &reg, sizeof(reg),
                                &reg, sizeof(reg), &cb, 0);

      // Determine if the DeviceIoControl call and the write succeeded.
	fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);

	return fResult;
}

int ReadAbsoluteSectors32( HANDLE hDev,int volume, DWORD start_sector, 
                           WORD num_sectors, LPBYTE pBuf ) 
{
	DIOC_REGISTERS reg;
	DISKIO di;
	BOOL bResult;
	DWORD cb;

	reg.reg_EAX      = 0x7305;  // Ext_ABSDiskReadWrite
	reg.reg_EBX      = (DWORD)&di;
	reg.reg_ECX      = 0xffff;  // use DISKIO structure
	reg.reg_EDX      = volume;  // one-based volume number
	reg.reg_ESI      = 0;       // READ operation
	reg.reg_Flags    = 0;       // preset the carry flag
	di.diStartSector = start_sector;
	di.diSectors     = num_sectors;
	di.diBuffer      = (DWORD)pBuf;

	bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_DRIVEINFO,
              &reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 ); 

	if ( /*!bResult ||*/ (reg.reg_Flags & 1) ) return -1;
	return 0;
}

BOOL WriteAbsoluteSectors32(HANDLE hDev,
                            int    bDrive,
                            DWORD  dwStartSector,
                            WORD   wSectors,
                            LPBYTE lpSectBuff)
{
	BOOL           fResult;
	DWORD          cb;
	DIOC_REGISTERS reg = {0};
	DISKIO         di;

//	if(bDrive!=1)
//		return FALSE;

	di.diStartSector = dwStartSector;
	di.diSectors      = wSectors;
	di.diBuffer       = (DWORD)lpSectBuff;

	reg.reg_EAX = 0x7305;   // Ext_ABSDiskReadWrite
	reg.reg_EBX = (DWORD)&di;
	reg.reg_ECX = -1;
	reg.reg_EDX = bDrive;   // Int 21h, fn 7305h drive numbers are 1-based

	reg.reg_ESI = 0x6001;   // Normal file data (See function
                             // documentation for other values)


	fResult = DeviceIoControl(hDev, VWIN32_DIOC_DOS_DRIVEINFO,
                               &reg, sizeof(reg),
                               &reg, sizeof(reg), &cb, 0);

	// Determine if the DeviceIoControl call and the write succeeded.
	fResult = fResult && !(reg.reg_Flags & CARRY_FLAG);

	return fResult;
}

BOOL UserPressedCancel(VOLINFO *vi)
{
	MSG msg;

	while(PeekMessage(&msg,vi->hwnd,0,0,PM_REMOVE))
	{
		if(!IsDialogMessage(vi->hwnd,&msg))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}
	}

	if(bGlobalCancel)
		return TRUE;

	return FALSE;
}

DWORD ReadSectors(VOLINFO *vi,DWORD start_sector, 
                 WORD num_sectors,LPBYTE pBuf) 
{
	DWORD RetVal;

	RetVal=WFE_NOERROR;

	if(vi->dwFS==FS_FAT32) 
	{
		if(ReadAbsoluteSectors32(vi->hVWin32,vi->vol1,
				start_sector,num_sectors,pBuf)!=0)
			RetVal=WFE_COULDNOTREAD;
	}
	else
	{
		if(ReadAbsoluteSectors(vi->hVWin32,vi->vol1,
				start_sector,num_sectors,pBuf)<0)
			RetVal=WFE_COULDNOTREAD;
	}

	if(UserPressedCancel(vi))
		RetVal=WFE_USERCANCEL;

	return RetVal;
}

int GetLockFlagState( HANDLE hDev,int volume,BOOL bFlatFAT ) 
{
	DIOC_REGISTERS reg;
	BOOL bResult,fResult;
	DWORD cb;

	reg.reg_EAX = 0x440d; // generic IOCTL
	reg.reg_ECX = bFlatFAT ? 0x486c : 0x086c; // lock logical volume 
	reg.reg_EBX = volume; // 1 based
	reg.reg_Flags = 1; // preset the carry flag

	bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_IOCTL,
		&reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 ); 

	fResult = bResult && !(reg.reg_Flags & CARRY_FLAG);

	if(!fResult)
		return -1;

	return (reg.reg_EAX & 0xffff);
}

int LockLogicalVolume( HANDLE hDev,int volume, int lock_level, 
                       int permissions, BOOL bFlatFAT ) 
{
	DIOC_REGISTERS reg;
	BOOL bResult;
	DWORD cb;

	reg.reg_EAX = 0x440d; // generic IOCTL
	reg.reg_ECX = bFlatFAT ? 0x484a : 0x084a; // lock logical volume 
	reg.reg_EBX = volume | (lock_level << 8);
	reg.reg_EDX = permissions;
	reg.reg_Flags = 1; // preset the carry flag

	bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_IOCTL,
              &reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 ); 

	if(bResult)
		return 0;

	return (reg.reg_EAX & 0xffff);

//	if ( !bResult || (reg.reg_Flags & 1) ) 
//		return (reg.reg_EAX & 0xffff);

	return 0;
}

int UnlockLogicalVolume( HANDLE hDev,int volume, BOOL bFlatFAT ) 
{
	DIOC_REGISTERS reg;
	BOOL bResult;
	DWORD cb;

	reg.reg_EAX = 0x440d;
	reg.reg_ECX = bFlatFAT ? 0x486a : 0x086a; // lock logical volume 
	reg.reg_EBX = volume;
	reg.reg_Flags = 1; // preset the carry flag

	bResult = DeviceIoControl( hDev, VWIN32_DIOC_DOS_IOCTL,
              &reg, sizeof( reg ), &reg, sizeof( reg ), &cb, 0 ); 

	if ( !bResult || (reg.reg_Flags & 1) ) return -1;
	return 0;
}

DWORD WriteSectors(VOLINFO *vi,DWORD start_sector, 
                 WORD num_sectors,LPBYTE pBuf) 
{
	DWORD RetVal;
	BOOL bFat32;
    
	RetVal=WFE_NOERROR;
	bFat32=(vi->dwFS==FS_FAT32);

	if(vi->bCountClusters)
	{
		char StrRes[500];

		LoadString (g_hinst, IDS_SCANNINGDISK, StrRes, sizeof(StrRes));

		if(vi->dwClusterCount==0)
			StatusMessage(StrRes, FALSE);

		vi->dwClusterCount++;
		if(UserPressedCancel(vi))
			RetVal=WFE_USERCANCEL;
		return RetVal;
	}

	// Get Level2 Exclusive Volume Lock
	if(LockLogicalVolume(vi->hVWin32,vi->vol1, 
		LEVEL2_LOCK, 
		0,
		bFat32)!=0)
	{
		RetVal=WFE_COULDNOTLOCK;
	}
	else
	{
		// Get Level3 Exclusive Volume Lock
		if(LockLogicalVolume(vi->hVWin32,vi->vol1, 
			LEVEL3_LOCK, 
			0,
			bFat32)!=0)
		{
			RetVal=WFE_COULDNOTLOCK;
		}
		else
		{
			// Make sure nobody has been writing to the disk.
			if(GetLockFlagState(vi->hVWin32,vi->vol1,bFat32)!=0)
			{
				RetVal=WFE_DISKMODIFIED;
			}
			else
			{
				if(bFat32)
				{
					if(!WriteAbsoluteSectors32(vi->hVWin32,
						vi->vol1,start_sector,num_sectors,pBuf))
					{
						RetVal=WFE_COULDNOTWRITE;
					}
				}
				else
				{
					if(!WriteAbsoluteSectors(vi->hVWin32,
						vi->vol1,start_sector,num_sectors,pBuf))
					{
						RetVal=WFE_COULDNOTWRITE;
					}
				}
			}
			// Free Level 3 lock
			UnlockLogicalVolume(
				vi->hVWin32, 
				vi->vol1, 
				bFat32);
		}
		// Free Level 2 lock
		UnlockLogicalVolume(
			vi->hVWin32, 
			vi->vol1, 
			bFat32);
	}

	if(RetVal==WFE_NOERROR)
	{
		char StrRes[500];
		char statusmsg[500];

		vi->dwClustersWritten=vi->dwClustersWritten+1;
		
		if(vi->dwClustersWritten%10==0)
		{
			float pos;

			LoadString (g_hinst, IDS_PERCENTWRITTEN, StrRes, sizeof(StrRes));

			sprintf(statusmsg,
				StrRes,
				vi->dwClustersWritten,vi->dwClusterCount);

			StatusMessage(statusmsg, FALSE);

			pos = 10 + 
				( (float)vi->dwClustersWritten / 
				  (float)vi->dwClusterCount )
				* 90;

			WipeProgress((int)pos); 
		}
	}

	if(UserPressedCancel(vi))
		RetVal=WFE_USERCANCEL;

	return RetVal;
}

DWORD Fat32Item(unsigned char *FATbuffer,DWORD FlatIndex)
{
	DWORD dwFat32index;
	DWORD dwFat32value;
	DWORD *pFat;

	dwFat32index=FlatIndex*32/8;
	pFat = (DWORD *)(&(FATbuffer[dwFat32index]));

	// upper 4 bits are masked off
	dwFat32value=0x0fffffff & (*pFat);

	return dwFat32value;
}

DWORD Fat16Item(unsigned char *FATbuffer,DWORD FlatIndex)
{
	DWORD dwFat16index;
	DWORD dwFat16value;
	WORD *pFat;

	dwFat16index=FlatIndex*16/8;
	pFat = (WORD *)(&(FATbuffer[dwFat16index]));

	dwFat16value=0xffff & (DWORD)(*pFat);

	return dwFat16value;
}

DWORD Fat12Item(unsigned char *FATbuffer,DWORD FlatIndex)
{
	DWORD dwFat12index;
	DWORD dwFat12value;
	DWORD nib;
	unsigned char* pFat;

	// Depending if we're odd or even, we may
	// get need 8 bits then 4 bits, or 4 bits
	// then 8 bits.
	dwFat12index=FlatIndex*12/8;
	pFat = &(FATbuffer[dwFat12index]);

	if(FlatIndex%2==0) // Even
	{   // Get the 8 bits
		dwFat12value = 0xff & (DWORD)(*pFat);
		pFat++;
		// Get the 4 bits
		nib = 0x0f & (DWORD)(*pFat);
		// Shift the 4 bit portion as MSB.
		nib <<= 8;
		dwFat12value |= nib;
	}
	else // Odd
	{   // Get the 4 bits.
		nib = 0xf0 & (DWORD)(*pFat);
		pFat++;
		// Get the 8 bits
		dwFat12value = 0xff & (DWORD)(*pFat);
		// Shift the 8 bit portion MSB.
		dwFat12value <<= 4;
		// Shift the 4 bit portion LSB.
		nib >>= 4;
		dwFat12value |= nib;
	}

	return dwFat12value;
}

DWORD FatItem(VOLINFO *vi,DWORD index)
{
	switch(vi->dwFS)
	{
		case FS_FAT12:
			return(Fat12Item(vi->pFatBuf,index));

		case FS_FAT16:
			return(Fat16Item(vi->pFatBuf,index));

		case FS_FAT32:
			return(Fat32Item(vi->pFatBuf,index));
	}

	return 0;
}

BOOL IsntEnd(VOLINFO *vi,DWORD dwIndexCluster)
{
	switch(vi->dwFS)
	{
		case FS_FAT12:
			if(dwIndexCluster<0xff0)
				return TRUE;
			break;

		case FS_FAT16:
			if(dwIndexCluster<0xfff0)
				return TRUE;
			break;

		case FS_FAT32:
			if(dwIndexCluster<0x0ffffff0)
				return TRUE;
			break;
	}
	return FALSE;
}

BOOL IsClusterError(VOLINFO *vi,DWORD dwIndexCluster)
{
	switch(vi->dwFS)
	{
		case FS_FAT12:
			if(dwIndexCluster==0xff7)
				return TRUE;
			break;

		case FS_FAT16:
			if(dwIndexCluster==0xfff7)
				return TRUE;
			break;

		case FS_FAT32:
			if(dwIndexCluster==0x0ffffff7)
				return TRUE;
			break;
	}
	return FALSE;
}

BOOL PushDirStack(DIRSTACK **ds,
				  DWORD dwStartCluster)
{
	DIRSTACK *newds;

	newds=(DIRSTACK *)malloc(sizeof(DIRSTACK));
	if(newds)
	{
		memset(newds,0x00,sizeof(DIRSTACK));
		newds->dwStartCluster=dwStartCluster;
		newds->next=*ds;
		*ds=newds;
		return TRUE;
	}
	return FALSE;
}

BOOL PopDirStack(DIRSTACK **ds,
				 DWORD *dwStartCluster)
{
	DIRSTACK *FreeAtLast;

	if(*ds==0)
		return FALSE;

	FreeAtLast=*ds;

	*dwStartCluster=(*ds)->dwStartCluster;
	*ds=(*ds)->next;

	free(FreeAtLast);

	return TRUE;
}

DWORD DoFileSlack(VOLINFO *vi,
				 DWORD dwCluster,
				 DWORD dwLength)
{
	DWORD dwLastCluster;
	DWORD RetVal,err;

	RetVal=WFE_NOERROR;

	// Starting cluster is invalid? Something wrong
	if(!IsntEnd(vi,dwCluster))
		return WFE_CLUSTERERROR;

	dwLastCluster=dwCluster;
	dwCluster=FatItem(vi,dwCluster);

	// Find the last cluster and the remainder length
	while(IsntEnd(vi,dwCluster))
	{
		dwLastCluster=dwCluster;
		dwLength-=vi->dwClusterSize;
		dwCluster=FatItem(vi,dwCluster);
	}

	// Cluster with an error is in the chain
	if(IsClusterError(vi,dwCluster))
		return WFE_CLUSTERERROR;

	// File length and cluster chain don't agree
	// Since we're unsigned, less than zero is accounted for
	if(dwLength>vi->dwClusterSize)
		return WFE_CLUSTERERROR;

	memset(vi->pClusterBuf,0x00,vi->dwClusterSize);

	if(vi->bCountClusters)
	{
		// Since we're just counting, no need to read in
		// the last sector.... it won't be written anyway.
		// Speeds things up greatly.
		err=WFE_NOERROR;
	}
	else
	{
		// Read in last cluster of file
		err=ReadSectors(vi,
			ClusterToSector(vi,dwLastCluster), 
			vi->sectors_per_clus,
			vi->pClusterBuf);
	}

	if(err!=WFE_NOERROR)
	{
		RetVal=err;
	}
	else
	{
		// wipe off the slack
		WritePattern(	&((vi->pClusterBuf)[dwLength]),
						vi->pattern_buffer,
						vi->dwClusterSize-dwLength);

		//memset(&((vi->pClusterBuf)[dwLength]),0x00,
		//	vi->dwClusterSize-dwLength);

		// Write out last cluster of file
		err=WriteSectors(vi,
			ClusterToSector(vi,dwLastCluster), 
			vi->sectors_per_clus,
			vi->pClusterBuf);

		if(err!=WFE_NOERROR)
			RetVal=err;
	}

	return RetVal;
}

DWORD DoDirAndSlack(VOLINFO *vi,
				   char *pBuf,int bufsize) 
{
	unsigned char *pDir = pBuf;
	unsigned char *pEnd = pDir+bufsize;
	DWORD dwStartCluster;
	DWORD dwTotalLength,err,RetVal;
	PDIRENTRY pd;

	RetVal=WFE_NOERROR;

	while((*pDir)&&(RetVal==WFE_NOERROR)) 
	{
		// Skip over and erase deleted directory entries
		if (*pDir == 0xe5)
		{
//			WritePattern(&(pDir[1]),vi->pattern_buffer,sizeof(DIRENTRY)-1);
//			Maybe this is a problem... yah.. long filenames are mislinked.				
			memset(&(pDir[1]),0x00,sizeof(DIRENTRY)-1);
			pDir += sizeof( DIRENTRY );
		}
		else if (*(pDir+0x0b) == 0xf && *(pDir+0x0c) == 0 ) 
		{
			// Type 0 "long" directory entry
			// We don't really care about these. leave em be.
			pDir += sizeof( DIRENTRY );
		}
		// Other Type "long" directory entry
	    else if (*(pDir+0x0b) == 0xf && *(pDir+0x0c) != 0 ) 
		{
			// Other Type "long" directory entry
			// We don't care about these either.
			pDir += sizeof( DIRENTRY );
		}
		// "Short" directory entry
		else 
		{
			// "Short" directory entry
			// Every file has one of these. It has our info.
			pd = (PDIRENTRY)pDir;

			dwTotalLength=pd->deFileSize;

    		if (vi->dwFS!=FS_FAT32)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -