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(dfTim Size, &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; }