www.pudn.com > SaveDisk(11.13).rar > SaveDisk.cpp


// loaddll.cpp : Defines the entry point for the application. 
// 
 
#include "stdafx.h" 
#include "resource.h" 
#include  
#include "SaveDisk.h" 
#include  
#pragma comment(lib,"winmm") 
#include  
#include  
#pragma comment(lib,"comctl32.lib") 
#include  
#pragma comment(lib,"setupapi.lib") 
#include  
#include  
//#include  
#include  
#include "ntddstor.h" 
#include  
 
HWND AfxMainHwnd; 
HINSTANCE MainInstance; 
HANDLE SaveThread; 
BOOL CancelSave; 
HINSTANCE AFXInstance; 
LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK	About(HWND, UINT, WPARAM, LPARAM); 
 
#define OOPS() Oops(__FILE__, __LINE__)  //调用OOPS宏,可以以消息框形式显示调用处的行号,所在的文件名 
 
 
//输出调试信息到文件里 
BOOL PrintToFile(PUCHAR Buffer,//打印信息 
				 ULONG OLen,   //打印信息长度 
				 BOOL IsChar){ //打印信息以字符形式显示还是以数值形式显示 
	char tembuf[1000]=""; 
	CHAR tem[10]=""; 
	HANDLE DFileHandle; 
	DWORD nNumberOfBytesToWrite,i; 
	DFileHandle = CreateFile("DbgInfor.txt",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_WRITE|FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_ARCHIVE,NULL); 
	if(DFileHandle==INVALID_HANDLE_VALUE) 
		return FALSE; 
	nNumberOfBytesToWrite=OLen; 
	ZeroMemory(tembuf,sizeof(tembuf)); 
	if(!IsChar){ 
		for(i=0;i=0;i--) 
	{	iChar=Char[i]; 
	if ( iChar >= '0' && iChar <= '9' ) 
		mBCD = mBCD+(iChar -'0')*de; 
	else if ( iChar >= 'A' && iChar <= 'F' )  
		mBCD =mBCD+ (iChar - 'A' + 0x0a)*de; 
	else if ( iChar >= 'a' && iChar <= 'f' ) 
		mBCD =mBCD+ (iChar - 'a' + 0x0a)*de; 
	else return(0); 
	de*=16; 
	} 
	return(mBCD); 
} 
 
double GetCurrentTimerVal(){//获取硬件计数器已运行时间,ms为单位,比GetTickCount更准确 
	LARGE_INTEGER litmp;  
	double dfFreq,QPart1;  
	QueryPerformanceFrequency(&litmp);  //频率以HZ为单位 
	dfFreq = (double)litmp.QuadPart;    //获得计数器的时钟频率 
	QueryPerformanceCounter(&litmp); 
	QPart1 = (double)litmp.QuadPart;        //获得初始值 
	return(QPart1 *1000/ dfFreq  );  //获得对应的时间值=振荡次数/振荡频率,单位为秒 
} 
 
//延时函数,以ms为单位 
VOID DelayTime1(double TimerVal){//定时值为ms,其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关 
	LARGE_INTEGER litmp;  
	LONGLONG QPart1,QPart2; 
	double dfMinus, dfFreq, dfTim,NewTimerVal;  
	NewTimerVal = TimerVal*0.001;       //将ms定时值转成s值 
	QueryPerformanceFrequency(&litmp);  //频率以HZ为单位 
	dfFreq = (double)litmp.QuadPart;    //获得计数器的时钟频率 
	QueryPerformanceCounter(&litmp); 
	QPart1 = litmp.QuadPart;            //获得初始值 
	do{ 
		QueryPerformanceCounter(&litmp); 
		QPart2 = litmp.QuadPart;        //获得中止值 
		dfMinus = (double)(QPart2-QPart1); 
		dfTim = dfMinus / dfFreq;       //获得对应的时间值=振荡次数/振荡频率,单位为秒		 
	}while(dfTimSize,				 
			&dwOutBytes,							 
			(LPOVERLAPPED)NULL); 
	return bResult; 
} 
PVOID trim(PVOID str)  //去除字符串中的前后空格 
{ 
	PCHAR x; 
	char y[1000]="",z[1000]=""; 
	x=(char *)str; 
	if (lstrlen(x)==0) return(NULL) ; 
	while(*x==' '|| *x==0x09 )  //trimleft 
		x++; 
	if (*x==NULL) 
		return(NULL); 
	else 
		strcpy(y,x); 
	x=y+lstrlen(y); 
	x--; 
	while(*x==' '|| *x==0x09) x--; 
	memcpy(z,y,x-y+1); 
    z[lstrlen(z)]='\0'; 
	return(&z[0]); 
} 
//读磁盘扇区 
int ReadSector	(HANDLE DevHandle,int nsects, int lsect,PVOID buffer) 
{ 
	ULONG	i, j; 
	CHAR   tem[512]="";	 
	 
	i = lsect*512; 
	j = SetFilePointer( DevHandle, i, NULL, FILE_BEGIN );  // 指定读扇区起始号 
	if ( i != j ) {//指定读扇区起始号出错 
		return( 3 ); 
	} 
	i = nsects*512; 
	if ( ! ReadFile( DevHandle, buffer, i, &i, NULL ) ) {  // 读一个扇区512字节 
		return( 4 ); 
	} 
	if ( i != (ULONG)(nsects*512) ) { 
		return( 5 ); 
	} 
	return(0); 
} 
void SearchUDisk()//搜索指定U盘 
{ 
	HANDLE mDevice; 
	ULONG i; 
	CHAR DiskID[512],DiskDesc[512],Buf[1024],logicname[100]=""; 
	PCHAR str; 
	PSTORAGE_DEVICE_DESCRIPTOR pDevDesc=NULL; 
	 
	pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)Buf; 
	i = 0; 
	for(i=1;i<10;i++) 
	{ 
		//打开指定的盘符,获取盘符的设备号 
		sprintf(&logicname[0],"\\\\.\\PhysicalDrive%d",i); 
		mDevice = CreateFile( &logicname[0], GENERIC_READ | GENERIC_WRITE, 
			FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, 
			NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );	 
		if(mDevice==INVALID_HANDLE_VALUE){ 
			continue; 
		} 
		//获取U盘属性			 
		pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1; 
		if(GetDisksProperty(mDevice, pDevDesc)) 
		{ 
			if(pDevDesc->BusType != BusTypeUsb)//寻找USB接口磁盘 
			{					 
				CloseHandle(mDevice); 
				continue; 
			}		 
		}				 
		{ 
			CHAR SectorData[512]=""; 
			if(ReadSector(mDevice,1,0,SectorData))//读DBR扇区错误. 
			{ 
				CloseHandle(mDevice); 
				continue; 
			} 
			if( (SectorData[509]!='W') || (SectorData[510]!='C') || (SectorData[511]!='H') ) 
			{ 
				CloseHandle(mDevice); 
				continue;			 
			} 
		} 
		{//保存物理盘的ID字符串 
			ULONG k; 
			PCHAR p= (char*)pDevDesc; 
			str = (pDevDesc->VendorIdOffset ? &p[pDevDesc->VendorIdOffset]:"(NULL)");				 
			strcpy(&DiskID[0],"VEN_"); 
			strcat(DiskID,(PCHAR)trim(str)); 
			strcat(DiskID,"&PROD_"); 
			str=(pDevDesc->ProductIdOffset ? &p[pDevDesc->ProductIdOffset]:"(NULL)"); 
			strcat(DiskID,(PCHAR)trim(str)); 
			for(k=0;k=FileCount)//最后一个文件要保存的剩余扇区数 
			FileSects = SectorCount - i*MinSectsPerFile ; 
		else 
			FileSects = MinSectsPerFile; 
 
		//每次从磁盘中读1024扇区(受内存限制) 
		MinSectsPerRead = 1024; 
		ReadCount = (FileSects+MinSectsPerRead-1)/MinSectsPerRead;//文件要分批读的次数 
		for( j=0;j=ReadCount ) //文件的最后一批扇区读 
				ReadSects = FileSects - j*MinSectsPerRead; 
			else 
				ReadSects = MinSectsPerRead;			 
			ReadSector(mDevice,ReadSects,ReadStartSect,&SectorData[0]); 
			 
			SaveToFile(FullFileName,SectorData,ReadSects*512,j==0);			 
			SingStep = MinSectsPerFile*i + (MinSectsPerRead*j+ReadSects); //已完成扇区数 
			sprintf(tem,"已保存扇区数%ld-%d%%",SingStep,SingStep*100/SectorCount); 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_Proc),tem); 
			SendDlgItemMessage(AfxMainHwnd,IDC_PROGRESS1,PBM_SETPOS ,SingStep*100/SectorCount,0); 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_PROGRESS1),tem); 
			 
			if(CancelSave) 
			{ 
				CloseHandle(mDevice); 
				EnableWindow(GetDlgItem(AfxMainHwnd,IDC_CancelSave),FALSE); 
				return 0; 
			} 
		}		 
	} 
	CloseHandle(mDevice); 
	EnableWindow(GetDlgItem(AfxMainHwnd,IDC_CancelSave),FALSE); 
	return 0; 
} 
 
int APIENTRY WinMain(HINSTANCE hInstance, 
                     HINSTANCE hPrevInstance, 
                     LPSTR     lpCmdLine, 
                     int       nCmdShow){ 
	AFXInstance = hInstance; 
	return 	DialogBox(hInstance, (LPCTSTR)IDD_MainWnd, 0, (DLGPROC)WndProc); 
} 
 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam){ 
	int wmId, wmEvent; 
	DWORD ThreadID; 
	AfxMainHwnd=hWnd; 
	switch (message) { 
	case WM_INITDIALOG: 
		{ 
			INITCOMMONCONTROLSEX CommStruc={0}; 
			CommStruc.dwSize = sizeof(CommStruc); 
			CommStruc.dwICC = ICC_PROGRESS_CLASS; 
			InitCommonControlsEx(&CommStruc); 
 
			HICON  hIcon = LoadIcon(AFXInstance, MAKEINTRESOURCE(IDI_SAVEDISK)); 
			SendMessage(hWnd, WM_SETICON, ICON_BIG, (LPARAM)hIcon);  
			SendMessage(hWnd, WM_SETICON, ICON_SMALL, (LPARAM)hIcon); 
 
			SearchUDisk(); 
			SendDlgItemMessage(AfxMainHwnd,IDC_UList,CB_SETCURSEL,0,0); 
			UpdataSetting(); 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_MinSaveUnit),"100"); 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_FileName),"UDiskPart"); 
			EnableWindow(GetDlgItem(AfxMainHwnd,IDC_CancelSave),FALSE); 
			SendDlgItemMessage(AfxMainHwnd,IDC_PROGRESS1,PBM_SETRANGE32,0,100); 
			SendDlgItemMessage(AfxMainHwnd,IDC_PROGRESS1,PBM_SETSTEP,1,0);			 
			SendDlgItemMessage(AfxMainHwnd,IDC_PROGRESS1,PBM_SETPOS ,0,0); 
 
			CHAR FilePath[200]; 
			GetCurrentDirectory(200,FilePath); 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_SavePath),FilePath); 
		} 
		break;  
	case WM_COMMAND: 
		wmId    = LOWORD(wParam);  
		wmEvent = HIWORD(wParam);  
		// Parse the menu selections: 
		switch (wmId) 
		{ 
		case IDC_SearchDisk:			 
			SendDlgItemMessage(AfxMainHwnd,IDC_UList,CB_RESETCONTENT,0,0); 
			SearchUDisk(); 
			SendDlgItemMessage(AfxMainHwnd,IDC_UList,CB_SETCURSEL,0,0); 
			UpdataSetting(); 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_MinSaveUnit),"100"); 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_FileName),"UDiskPart"); 
			break; 
		case IDC_SAVEDISK: 
			CancelSave = FALSE; 
			SetWindowText(GetDlgItem(AfxMainHwnd,IDC_Proc),"已保存扇区数0-0%"); 
			SaveThread = CreateThread(NULL,0,SaveDataProc,NULL,0,&ThreadID); 
			if(SaveThread==INVALID_HANDLE_VALUE) 
			{ 
				MessageBox(AfxMainHwnd,"创建线程失败","WndProc",0); 
				break; 
			} 
			break; 
		case IDC_CancelSave: 
			CancelSave = TRUE; 
			break; 
		case IDC_SaveDir: 
			{ 
				CHAR FileName[MAX_PATH]; 
				BROWSEINFO BrowseInfo={0}; 
				LPITEMIDLIST pidl; 
				BrowseInfo.hwndOwner = hWnd; 
				BrowseInfo.pidlRoot = NULL; 
				BrowseInfo.pszDisplayName = FileName; 
				BrowseInfo.lpszTitle = "Select directory to save"; 
				BrowseInfo.lpfn = NULL; 
				BrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_EDITBOX; 
				pidl = SHBrowseForFolder(&BrowseInfo); 
				if(pidl==NULL) 
					break; 
				SHGetPathFromIDList (pidl, FileName); 
				SetWindowText(GetDlgItem(hWnd,IDC_SavePath),FileName); 
			} 
			break; 
		case WM_DESTROY: 
			CancelSave = TRUE; 
			Sleep(10); 
			CloseHandle(SaveThread); 
			DestroyWindow(hWnd); 
			break; 
		default: 
			return DefWindowProc(hWnd, message, wParam, lParam); 
		} 
		break;		 
		case WM_DESTROY: 
			PostQuitMessage(0); 
			break;		 
	} 
	return 0; 
}